I am using an MH-Z19 CO2 sensor with an Arduino Mega using UART. As per the specifications of this sensor, after we send a command, we expect the response in a particular 9 byte format (with starting bytes as 0xFF and 0x86).
byte cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
byte response[9];
Serial.flush();
Serial.write(cmd,9);
while (Serial.available()<9) {}
for(int n=0; n<9; n++) {
response[n] = Serial.read();
}
if (response[0] != 0xFF) {
//Error
predictCo2 = 0;
} else if (response[1] != 0x86) {
//Error
predictCo2 = 1;
} else {
predictCo2=((response[2]*256)+response[3]);
}
I wait till all the 9 bytes are filled in to read the values.
The problem here is that, when I turn the board ON, most of the times the response isn't in the required format (starting bytes aren't 0xFF or 0x86). But, if I press the Arduino reset button, it starts reading values in proper format straight away.
I'm wondering why this is happening. Why is the UART response not in the proper format immediately after I turn on the Arduino, and I have to explicitly do a reset? Is the reset button clearing the serial stream? How can this be achieved through software?
I included serial.flush()
before sending the command, but that didn't help either.
-
Sounds like a startup delay needed. See revspace.nl/MHZ19#Log_of_MH-Z19_response_at_startup.Mikael Patel– Mikael Patel2017年01月17日 13:53:23 +00:00Commented Jan 17, 2017 at 13:53
1 Answer 1
Serial.flush()
only empties the output buffer, so that won't achieve anything. Reading exactly 9 bytes and hoping they match the input stream is not very effective, as you found. If you are out of sync with the incoming bytes, you will stay out of sync.
It would be better to keep reading (single bytes) until you get 0xFF or 0x86 and then read the rest.