Skip to content

Instantly share code, notes, and snippets.

@cretep
Created November 1, 2020 09:38
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save cretep/f96606dc6a4eae0d85993d6085959220 to your computer and use it in GitHub Desktop.
Winsen ZE08-CH2O (Formaldehyde sensor) for ESPHome
esphome:
includes:
- winsen_ze08.h
uart:
- id: uart_ze08
rx_pin: GPIO16
tx_pin: GPIO17
baud_rate: 9600
custom_component:
- lambda: |-
auto ze08 = new WinsenZE08Sensor(id(uart_ze08), id(ze08_ch2o));
App.register_component(ze08);
return {ze08};
sensor:
- platform: template
name: Formaldehyde
id: ze08_ch2o
unit_of_measurement: ppb
accuracy_decimals: 0
#include "esphome.h"
// https://www.winsen-sensor.com/sensors/ch2o-gas-sensor/ze08-ch2o.html
// Pinouts on page 4 of datasheet:
// https://www.winsen-sensor.com/d/files/PDF/Gas%20Sensor%20Module/Formaldehyde%20Detection%20Module/ZE08-CH2O%20V1.0.pdf
static const char *TAG = "custom";
static const uint8_t ZE08_SET_QA_MODE[] = {0xFF, 0x01, 0x78, 0x41, 0x00, 0x00, 0x00, 0x00, 0x46};
//static const uint8_t ZE08_SET_ACTIVE_MODE[] = {0xFF, 0x01, 0x78, 0x40, 0x00, 0x00, 0x00, 0x00, 0x47};
static const uint8_t ZE08_QUESTION[] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
static const char *ZE08_MODE_QA = "QA";
//static const char *ZE08_MODE_ACTIVE = "ACTIVE";
static const char *ZE08_MODE = ZE08_MODE_QA;
class WinsenZE08Sensor : public PollingComponent, public UARTDevice {
Sensor *ch2o_ppb_ {nullptr};
public:
WinsenZE08Sensor(UARTComponent *parent, Sensor *ch2o_ppb) : UARTDevice(parent), ch2o_ppb_(ch2o_ppb) {}
void setup() override {
this->set_update_interval(5000);
if (ZE08_MODE == ZE08_MODE_QA) {
write_array(ZE08_SET_QA_MODE, sizeof(ZE08_SET_QA_MODE));
}
}
void loop() override {
}
void update() override {
write_array(ZE08_QUESTION, sizeof(ZE08_QUESTION));
unsigned char buf[9];
if (this->available() != sizeof(buf)) {
ESP_LOGE(TAG, "Bad response from ZE08! received %d bytes.", this->available());
//this->mark_failed();
return;
}
readBytes(buf, sizeof(buf));
// message of 9 bytes, same reading two units:
// ug/m3 ppb
// st cm high low res res high low ch
unsigned short concentration_ugm3 = (buf[2] << 8) | buf[3];
unsigned short concentration_ppb = (buf[6] << 8) | buf[7];
ESP_LOGD(TAG, "Received %d %d.", concentration_ugm3, concentration_ppb);
unsigned char checksum_calc = ~(buf[1] + buf[2] + buf[3] + buf[4] + buf[5] + buf[6] + buf[7]) + 1;
if (buf[8] != checksum_calc) {
ESP_LOGE(TAG, "Bad checksum from ZE08! received %d != %d.", buf[8], checksum_calc);
}
ch2o_ppb_->publish_state(concentration_ppb);
}
};
@lwh201314
Copy link

lwh201314 commented Dec 3, 2021

Esphome compilation error

In file included from src/main.cpp:28:0:
src/winsen_ze08.h: In member function 'virtual void WinsenZE08Sensor::update()':
src/winsen_ze08.h:41:33: error: 'readBytes' was not declared in this scope
readBytes(buf, sizeof(buf));
^
*** [.pioenvs/stream-server/src/main.cpp.o] Error 1

@haplm
Copy link

haplm commented Feb 17, 2022

Having the same problem, it seems that something changed in the ESPHome interfaces (or in the SDK). Would it be possible to tak a look, please?

@marianri
Copy link

marianri commented Mar 2, 2022

You can replace:
readBytes(buf, sizeof(buf));
with:
read_array(buf, sizeof(buf));

@haplm
Copy link

haplm commented Mar 2, 2022

Perfect, thank you, that worked!

@DJTerentjev
Copy link

The sensor I have seems to overestimate readings - 25 ppb even outside. Don't know if there is a way to correct it. If any one can share experience with ze08-ch2o .

@BatrakovSV
Copy link

Hello. Could I use your library (winsen_ze08.h) for ZE25?
https://github.com/lukas-kurka/winsen-sensors-lib/blob/main/lib/ZE25-O3/ZE25.h
Снимок экрана 2024-02-05 в 12 21 53

@cretep
Copy link
Author

cretep commented Feb 5, 2024

Hello. Could I use your library (winsen_ze08.h) for ZE25?

Yes, and to re-licence any parts under GNU GPL as necessary.

(I'm not actively using this sensor at present so cannot provide further details/support.)

@BatrakovSV
Copy link

I didn't ask about the license...
I looked at the datasheet for the ZE25-O3 and it looks like your code can be completely used.
I don't understand programming.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment