I have an MD02 sensor (SHT20). In the storefront it says that this sensor is part of the MD02 series and not the XY-MD02.
But the store description says it can be configured according to the XY-MD02 register. After I tried, the register couldn't be used on the modbus poll. I used the register datasheet on the web http://www.sah.rs/media/sah/techdocs/xy-md02-manual.pdf
I also tried to read Modbus using HW0519 and ESP32, but the result is still the same. The register does not issue any output.
My Code:
#define RXD2 16
#define TXD2 17
byte ByteArray[250];
int ByteData[20];
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
}
void loop() {
// put your main code here, to run repeatedly:
delay(1000);
byte msg[] = {0x01,0x04,0x00,0x01,0x00,0x01,0x60,0x0A};
int i;
int len=8;
Serial.println("Sending Data...");
for(i=0 ; i < len ; i++){
Serial2.write(msg[i]);
Serial.print("[");
Serial.print(i);
Serial.print("]");
Serial.print("=");
Serial.print(String(msg[i],HEX));
}
len = 0;
Serial.println();
Serial.println();
int a = 0;
while(Serial2.available()){
ByteArray[a] = Serial2.read();
a++;
}
int b = 0;
String Register;
Serial.println("Receiving Data...");
for(b=0;b<a;b++){
Serial.print("[");
Serial.print(b);
Serial.print("]");
Serial.print("=");
Register = String(ByteArray[b],HEX);
Serial.print(Register);
Serial.print(" ");
}
Serial.println();
Serial.println();
}
I've made sure the wiring diagram is correct. How to fix it? I'm very confused, because there are no relevant solutions on the internet.
i have same problem. But, i solved this.
The solution
Change your modbus poll with odd/even parity. I swear that the description is wrong.
That the result if changing your parity
Temp/Hum have 100 Resolution, just divide by 100.
Change your code using SERIAL_8E1 or SERIAL_8O1
The code:
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial2.begin(9600, SERIAL_8E1, RXD2, TXD2);
}
Have a nice day!!!
Although the manufacturer claimed the device worked on 9600 8N1 - my device only worked on 9600 8N2 (or 8X1 + any parity check). In addition, a large timeout for waiting for a response is required (in my case, a stable response was only with a timeout of 1000 ms or more).
Related
I want to save some values in memory and then be able to read them after turning off the esp.
I wrote the code based on the page https://randomnerdtutorials.com/esp32-flash-memory/. The code worked, so I decided to check what maximum memory size I can enter before errors occur.
like
EEPROM.begin(12345678);
EEPROM.write(12345644,0xff);
EEPROM.commit();
When I went back to smaller values that should work I got error:
[538][E][EEPROM.cpp:196] commit(): error in write
code that should work:
#include <Arduino.h>
#include <EEPROM.h>
#define EEPROM_SIZE 10
void setup() {
Serial.begin(9600);
Serial.println();
//read first 10 bytes
Serial.println();
Serial.println("read first 10 bytes");
Serial.println();
EEPROM.begin(EEPROM_SIZE);
for(int i =0 ;i<EEPROM_SIZE;i++)
{
int state = EEPROM.read(i);
Serial.print("addres: ");
Serial.print(i);
Serial.print(" value: ");
Serial.println(state);
}
EEPROM.end();
//write first 10 bytes
Serial.println();
Serial.println("write first 10 bytes");
EEPROM.begin(EEPROM_SIZE);
for(int i =0 ;i<EEPROM_SIZE;i++)
{
Serial.print(i);
Serial.print(" ");
EEPROM.write(i,0xff);
EEPROM.commit();
}
EEPROM.end();
//read addres 2
Serial.println();
Serial.println("read addres 2");
EEPROM.begin(EEPROM_SIZE);
int state = EEPROM.read(2);
Serial.print("value: ");
Serial.println(state);
EEPROM.end();
// Wait 10 seconds
Serial.println();
Serial.println("Restarting in 10 seconds...");
delay(10000);
// Restart ESP
ESP.restart();
}
void loop() {
}
the results of running the code on the console:
enter image description here
I was also using the Preferences library, but there was an error on saving here as well.
Is the error due to my attempts?
What should I do to make the code work?
I am facing a total weird problem one set of code is running and other ain't.
This code is working:
int pin = 2;
void setup() {
// put your setup code here, to run once:
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
}
void loop() {
// put your main code here, to run repeatedly:
}
And at the same time this is not working:
int pin = 2;
void setup() {
// put your setup code here, to run once:
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(pin,HIGH);
delay(5000);
digitalWrite(pin,LOW);
delay(5000);
}
Try putting an LED on your D2 pin to check whether it lights up or not. Make sure to add a resistor (220 ohm or 330 ohm) before the LED. Also, LED has polarity. The small leg should be towards the ground and the long leg (anode) should be towards the D2 pin.
If you don't have an LED or resistor, try using Serial.print() to display whether the system is going through your code or not. You can view your serial response through your serial monitor.
code dose not perfect work
int pushButton = 2;
int gearstatus = 0 ;
int buttonState;
void setup() {
Serial.begin(9600);
pinMode(pushButton, INPUT);
}
void gearfunction(){
buttonState = digitalRead(pushButton);
while(gearstatus <= 5){
Serial.println( gearstatus);
if(buttonState == HIGH){
gearstatus++;}
}
}
void loop() {
gearfunction();
}
in this code i am trying to if statement in while loop,
but code doesn't work . can some one give me how to did this ? i want to increase gearstatus up to 5 but value not increase .
It doesn't work because marking pushButton as INPUT wont make it equal to HIGH
You need to put inside setup function after the input instruction:
digitalWrite(pushButton,HIGH)
A Button-Pin has to be initialized on Setup, like in the preceding answer or with:
pinMode(2, INPUT_PULLUP); //Pin-D2. This command activates it's internal
//resistor, so the resulting signal is clear HIGH and not floating like a duck...
Hint: on StartUp all pins of a uC are floating-inputs, so if pulled-UP
they may be grounded with a button or anything else like a sensor, NTC-Resistor, etc.), resulting in a clear "1" or "0" - or a defined Analog-Signal, which later may be scanned like:
boolean buttonState = digitalRead(2); //Pin D2
//or
int value = analogRead(A0); //Pin A0
Can you please explain a little what you are trying to do, It would be better if you attach a small image of the circuit. I can suggest you the code and answer using circuits.io if you give the required info.
I am writing an I2C slave routine for PIC18F25K80 and I am stuck on a weird problem.
This is my routine:
void interrupt interruption_handler() {
PIE1bits.SSPIE = 0; // Disable Master Synchronous Serial Port Interrupt
if (PIR1bits.SSPIF != 1) {
//This is not I2C interruption;
PIE1bits.SSPIE = 1; // Enable Master Synchronous Serial Port Interrupt
return;
}
//Treat overflow
if ((SSPCON1bits.SSPOV) || (SSPCON1bits.WCOL)) {
dummy = SSPBUF; // Read the previous value to clear the buffer
SSPCON1bits.SSPOV = 0; // Clear the overflow flag
SSPCON1bits.WCOL = 0; // Clear the collision bit
SSPCON1bits.CKP = 1;
board_state = BOARD_STATE_ERROR;
} else {
if (!SSPSTATbits.D_NOT_A) {
//Slave address
debug(0, ON);
//Read address
address = SSPBUF; //Clear BF
while(BF); //Wait until completion
if (SSPSTATbits.R_NOT_W) {
SSPCON1bits.WCOL = 0;
unsigned char a = 0x01;
SSPBUF = a;//0x01 works //Deliver first byte
asm("nop");
}
} else {
if (SSPSTATbits.BF) {
dummy = SSPBUF; // Clear BF (just in case)
while(BF);
}
if (SSPSTATbits.R_NOT_W) {
//Multi-byte read
debug(1, ON);
SSPCON1bits.WCOL = 0;
SSPBUF = 0x02; //Deliver second byte
asm("nop");
} else {
//WRITE
debug(2, ON);
}
}
transmitted = TRUE;
SSPCON1bits.CKP = 1;
PIR1bits.SSPIF = 0;
PIE1bits.SSPIE = 1; // Enable Master Synchronous Serial Port Interrupt
}
}
It works like a charm if I set constant values on SSPBUF. For example, if you do:
SSPBUF = 0x01;
(...)
SSPBUF = 0x02;
I get the two bytes on the master. I can even see the wave forms of the bytes being transmitted on the oscilloscope. Quite fun!
But when I try to set SSPBUF using a variable like:
unsigned char a = 0x01;
SSPBUF = a;
I get zero on the master.
It is driving me crazy.
Some hypothesis I've discarded:
Watchdog timer is messing up interrupting in the middle of the protocol: It is not. It is disabled and the problem happens in both SSPBUF assignments
I need to wait until BF goes low to continue: I don't. AFAIK, you setup the SSPBUF, clear SSPIF, set CKP and return from interruption to take care of life in 4Mhz while the hardware send data in few Khz. It will interrupt you again when it finishes.
It makes no sense to me. How good it is if you cannot define an arbitrary value using a variable?
Please gurus out there, enlighten this poor programmer.
Thanks in advance.
It has something to do with how the compiler generates the code and some undocumented/unknown PIC restriction around SSPBUF (it is an special register anyway).
I found out that it works when the compiler uses movwf and does not work when the compiler uses movff.
I moved the question to another forum because I realized the audience there is more adequate.
You will find more details here:
https://electronics.stackexchange.com/questions/251763/writing-sspbuf-from-variable-in-i2c-slave-protocol-in-pic18/251771#251771
Try move declaration : "unsigned char a = 0x01;"
to the beginning of the function or try define it as volatile global variable.
take into accunte that SSPBUF is both read and write buffer.check if there are conditions that may cause I2C module to reset this buffer.
I am trying to communicate with my Arduino through popen() function. I wrote a simple Mac App in XCode:
- (IBAction)ButtonPressed:(id)sender {
popen("echo hello world > /dev/tty.usbmodem1411", "r");
}
And here is the Arduino Code:
int redPin = 8;
int greenPin = 9;
int bluePin = 10;
int inByte = 0; // for incoming serial data
void setup()
{
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
Serial.begin(8000);
}
void loop()
{
if (Serial.available() > 0) {
// get incoming byte:
inByte = Serial.read();
Serial.print(inByte);
setColor(inByte,inByte,inByte);
delay(1000);
setColor(0,0,0);
}
}
void setColor(int red, int green, int blue)
{
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
}
Now, when I try to use Arduino Serial Monitor and write some gibberish there my LED's light up fine and I see that it is working. When I run my XCode program, press the button, nothing happens. I did set break points and I did check that the line of code gets executed. I double checked the serial port, it is all fine, but no luck. It still does not work.
Basically I solved the problem by using IOKit/ioctl. I am still not sure why popen() did not work, might be because Arduino IDE was using the port and thus it was not available, however IOKit works like a charm. Plus it allows more control and flexibility, you can actually search for ports before you start and see if they are available. If anyone runs in to the same problem check http://playground.arduino.cc/Interfacing/Cocoa#IOKit. Thanks for all help.