Hi all,
I am helping out a colleague with a project using Winsen ZE25-O3 Ozone sensor (data sheet: https://www.winsen-sensor.com/d/files/air-quality/ze25-o3-ozone-module--manual1_1.pdf), and I keep running into some trouble with the UART communication. I would appreciate any help that you can give, and if anyone has any experience with Winsen sensors, I would appreciate your wisdom, as well.
For the details, there is no library currently available for this sensor (although if I am able to get this working, I will try to add it as a library), but there were some examples for Arduino (like this one: https://forum.arduino.cc/index.php?topic=630111.0). I tried piecing information from that and the datasheet together to write my code. I had initially written this as a library, but after running into several issues with not receiving the expected return value back from the sensor, I simplified things to the following code:
SYSTEM_MODE(MANUAL); // this project is using a Particle Argon, but temporarily WiFi is unreliable.
// number of bytes for UART communication
#define buffer_length 9
// commands from the datasheet.
const byte active_upload_off[] = {0xFF, 0x01, 0x78, 0x41, 0x00, 0x00, 0x00, 0x00, 0x46};
const byte active_upload_on[] = {0xFF, 0x01, 0x78, 0x40, 0x00, 0x00, 0x00, 0x00, 0x47};
const byte qa_read_concentration[] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
void setup() {
// for communication with computer
Serial.begin(9600);
// opening UART Serial for the Winzen ZE25-O3
Serial1.begin(9600, SERIAL_8N1);
// setting the sensor in active upload
Serial1.write(active_upload_on, buffer_length);
}
void loop() {
// initializing char buffer to receive information from the sensor
char raw_buff[buffer_length];
// Waiting for a response from the Serial
while(!Serial.read()){
}
// reading the data
Serial1.readBytes(raw_buff, buffer_length);
// printing raw
Serial.print("Character Packet: ");
for(int ii = 0; ii < buffer_length; ii++){
Serial.print(int(raw_buff[ii]), HEX);
Serial.print(" ");
}
Serial.println("\n");
}
With this particular piece of firmware, I get the following packet as a response {0x8B, 0x40, 0x03, 0x00, 0x80, 0x6C, 0x00, 0x20, 0x00}. This does not match up to the expected response based on the data sheet. The data sheet lists two “return command for reading gas concentration” {0xFF, 0x86, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x30} and {0xFF, 0x2A, 0x04, 0x00, 0x00, 0x25, 0x27, 0x10, 0x75}. In the first one bytes 2 and 3 correspond to the ozone concentration, and in the second one bytes 4 and 5 correspond to the ozone concentration. I had assumed that the first one corresponds to question and answer mode, and the other corresponds to active upload mode. I am not 100% sure about that; the datasheet was a bit sparse. If anyone else has other suggestions of how to interpret those, I am all ears! The response I am getting back does not match either of them though.
I checked a few other things. There seems to be no difference in response to active upload or question and answer mode. The data sheet says that it is in active upload mode by default, so I have tried including and removing “Serial1.write(active_upload_on, buffer_length);”, and that does not seem to make a difference either. In the data sheet, it says that it is a has a baud rate of 9600, and the packets are 8 bytes with 1 stop bit and Null for stop bits. As far as I understand from the Argon documentation, that would mean that in Serial1.begin, I should have 9600 first and SERIAL_8N1 second. I have tried a few other things like SERIAL_9N1 and using a buffer length of 8. Any of those permutation gives a slightly different packet response, but not the expected one. This may just be a decoding issue, and I am not the most familiar with UART. I would appreciate any help or advice. Thank you!!