MHZ19 CO2 Sensor

Sming library supporting the MH-Z19 and MH-Z19B CO2 sensors.

Essentially a re-write of https://github.com/crisap94/MHZ19 to use Hardware serial port with callbacks.

See https://github.com/WifWaf/MH-Z19 for some very detailed and helpful background to the device.

Functionality is split into two main classes:

MHZ19::Uart

Access the sensor via serial port

MHZ19::PwmReader

Asynchronously decodes PWM signal from sensor

ESP8266 Connections

Communication requires use of UART0, as UART1 is output-only.

The samples in this library reconfigure the default Serial class to use UART1 for debug output.

UART0 is reconfigured to use the alternate pins by calling HardwareSerial::swap(). Connect as follows:

From

To

Notes

MHZ19 PWM

GPIO14 (D5)

MHZ19 TX

GPIO13 (D7)

UART0 RX

MHZ19 RX

GPIO15 (D8)

UART0 TX

GPIO2 (D4)

GPIO1 (TX)

Route UART1 output to USB

Note: A similar approach is used for I2S, see Tone Generator.

References

API Documentation

namespace MHZ19

Typedefs

using MeasurementCallback = Delegate<void(Measurement &m)>

Enums

enum DetectionRange

Device may be configured to output CO2 PPM values in various ranges.

Values:

enumerator PPM_2000
enumerator PPM_5000
enumerator PPM_10000
enum Command

Available commands.

Support differs by device variant

Values:

enumerator CMD_GasConcentration

-, B, C

enumerator CMD_CalibrateZeroPoint

-, B

enumerator CMD_CalibrateSpanPoint

-, B

enumerator CMD_SelfCalbrationOnOff

B, C.

enumerator CMD_SetDetectionRange

B.

enum Error

Values:

enumerator success
enumerator incompleteResponse
enumerator invalidResponse
enumerator timeout

Functions

unsigned pwmRead(uint8_t pwmPin, DetectionRange range)

Read PWM output from sensor.

Note

This will hang CPU for 1-2 seconds. Use PwmReader instead.

Parameters
  • pwmPin – GPIO to which the sensor is connected

  • range – Range sensor is configured for

struct Measurement
#include <Uart.h>
class PwmReader
#include <PwmReader.h>

Reads input pulse width asynchronously.

The ESP8266 lacks any timing capture hardware but as the pulse output from the MHZ19 is very slow it can be decoded using interrupts with high accuracy.

Once started, the PwmReader runs continuously and the last value can be obtained by calling getMeasurement.

Public Types

using Callback = Delegate<void(uint16_t ppm)>

Callback for regular readings.

Public Functions

void begin(uint8_t pin, DetectionRange range)

Start the PWM reader.

Runs continuously in background until end() is called.

Parameters
  • pin – GPIO to read PWM signal on

  • range – Configured device range

void end()

Stop the PWM reader.

uint16_t getMeasurement() const

Obtain the most recent measurement.

inline void setCallback(Callback callback)

Set a callback to be invoked whenever a valid reading is obtained.

bool suspend()

Temporarily suspend readings and disable interrupts on the PWM pin.

Returns

bool – true on success, false if reader not initialised

bool resume()

Resume reading after a call to suspend()

Returns

bool – true on success, false if reader not initialised

union Pulse
#include <PwmReader.h>

Used internally to measure a high/low pulse pair.

Public Functions

inline uint16_t getCycleTime() const
inline bool isValid() const
inline uint16_t calculatePpm(DetectionRange range)

Public Members

uint16_t low
uint16_t high
struct MHZ19::PwmReader::Pulse::[anonymous] [anonymous]
uint32_t value
struct Request
#include <Uart.h>
struct Response
#include <Uart.h>
class Uart
#include <Uart.h>

Access MHZ19 sensor via serial port.

Public Functions

inline Uart(HardwareSerial &serial)

Use device in UART mode.

Parameters

serial – Port and pins must be pre-configured

inline void setSensorNumber(uint8_t num)

Change sensor number field.

Original datasheet identifies first byte as sensor number, others as ‘reserved’. Provided if this value changes in future hardware versions.

inline uint8_t getSensorNumber() const

Get currently configured sensor number.

void setAutoCalibration(bool enable)

Enable/disable zero-point auto-calibration feature. On by default.

Calibrates 400ppm zero point reference automatically at power-on and every 24 hours. Suitable for home/office environment only. Refer to datasheet for details.

void calibrateZero()

Calibrate zero point manually.

Sensor must be in stable 400ppm CO2 environment. Refer to datasheet for detailed procedure.

void calibrateSpan(uint16_t ppm)

Calibrate span point.

Typical calibration value is 2000ppm, but must be above 1000ppm. Refer to datasheet for detailed procedure.

void setDetectionRange(DetectionRange range)

MHZ-19B has configurable detection range.

bool getMeasurement(MeasurementCallback callback)

Read measurement from device.

References

Used by

SoC support

  • esp32

  • esp32c3

  • esp32s2

  • esp32s3

  • esp8266

  • host

  • rp2040