Measuring CO2 using MH-Z19B and D1 mini pro

By Atomstar on Thursday 20 December 2018 20:59 - Comments (1)
Categories: ESP8266, Smarthome, Views: 6.298

In this article I describe how to measure CO2 levels using an MH-Z19B CO2 sensor connected to D1 mini pro and push these somewhere over wifi.

CO2 sensor

There are numerous CO2 sensors available, a non-exhaustive follows here:
  • NetAtmo Home Coach (100 EUR) - measures VOC (volatile organic compounds) as proxy for CO2, not CO2 directly. It's also relatively expensive
  • S8 SenseAir - similar to MH-Z19, but more expensive
  • MH-Z14 - appears to be an older version of MH-Z19
  • CCS811 VOC - appears to measure only VOC
  • Voltcraft CO-100 - could be used as well
  • AirBeam - great device that does almost everything I want, but quite expensive at $250
  • Airquality
Regarding the MH-Z19, there are two versions (see also this GitHub thread and this GoT post):
  1. MH-Z19, sometimes also denoted as MH-Z19A: original version, with a less optimal auto-calibration function
  2. MH-Z19B: improved version which you want

Connecting MH-Z19B

The MH-Z19B requires 5V to operate. I've connected the sensor as follows (based on this article and this pinout):
  • MH-Z19B-GND: connect to ground
  • MH-Z19B-Vin: connect to 5V
  • MH-Z19B-Rx: connect to pin 5 / SCL = D1 (for UART)
  • MH-Z19B-Tx: connect to pin 4 / SDA = D2 (for UART)
  • MH-Z19B-PWM: connect to pin 16 / SLEEP = D0 (for PWM)

Reading data

I used the "MH-Z CO2 Sensors" library by Tobias Schürg to read out the sensor. You can install this in the Arduino IDE via the library manager.

In the example program, I updated the pins using the above connection:
// pin for uart reading
#define CO2_IN D0

// pin for pwm reading
#define MH_Z19_RX D2
#define MH_Z19_TX D1
Once updated, compile and upload the program to the D1 mini and open the serial monitor (at the right baud rate) to read the CO2 values. Once everything is correct, you should see something like (in this case with debugging turned on):
-- read CO2 uart ---
  >> Sending CO2 request.
  << FF  86  9  B9  3D  0  7C  0  FF  
 # PPM UART: 2489
 # Temperature? 17
 Status  OK: 0
PPMuart: 2489, Temperature: 17
One issue I have is that the sensor reports values that are way too high indoors (2500 to 5000 ppm) , which might be because of ABC not working, or the sensor being broken (or maybe I'm not as alive as I feel ;)).


Volgende: StrongSwan IKEv2 VPN on Raspberry pi 12-'18 StrongSwan IKEv2 VPN on Raspberry pi
Volgende: Getting started with LOLIN D1 mini/DHT22 on Mac 12-'18 Getting started with LOLIN D1 mini/DHT22 on Mac


By jay, Thursday 23 April 2020 03:14

Hey, thanks for posting this. It is a great help! I was wondering if you happen to know how to implement this using the 64x64 OLED D1 shield for a display? Please let me know if this is possible!



Comments are closed