mhz19b - Driver for MH-Z19B NDIR CO₂ sensor connected to UART

group mhz19b

ESP-IDF driver for MH-Z19B NDIR CO2 sensor connected to UART.

Inspired from https://github.com/Erriez/ErriezMHZ19B

Copyright (c) 2020 Erriez https://github.com/Erriez Copyright (c) 2021 David Douard david.douard@sdfa3.org

BSD Licensed as described in the file LICENSE

Defines

MHZ19B_WARMING_UP_TIME_MS

3 minutes warming-up time after power-on before valid data returned

MHZ19B_WARMING_UP_TIME_US
MHZ19B_READ_INTERVAL_MS

Minimum response time between CO2 reads (EXPERIMENTALLY DEFINED)

MHZ19B_SERIAL_RX_BYTES

Fixed 9 Bytes response.

MHZ19B_SERIAL_BUF_LEN

128 is the minimal value the UART driver will accept (at least on esp32)

MHZ19B_SERIAL_RX_TIMEOUT_MS

Response timeout between 15..120 ms at 9600 baud works reliable for all commands.

MHZ19B_CMD_SET_AUTO_CAL

set auto calibration on/off

MHZ19B_CMD_READ_CO2

read CO2 concentration

MHZ19B_CMD_CAL_ZERO_POINT

calibrate zero point at 400ppm

MHZ19B_CMD_CAL_SPAN_PIONT

calibrate span point (NOT IMPLEMENTED)

MHZ19B_CMD_SET_RANGE

set detection range

MHZ19B_CMD_GET_AUTO_CAL

get auto calibration status (NOT DOCUMENTED)

MHZ19B_CMD_GET_RANGE

get range detection (NOT DOCUMENTED)

MHZ19B_CMD_GET_VERSION

get firmware version (NOT DOCUMENTED)

Enums

enum mhz19b_range_t

PPM range.

Values:

enumerator MHZ19B_RANGE_2000

2000 ppm

enumerator MHZ19B_RANGE_5000

5000 ppm (Default)

Functions

esp_err_t mhz19b_init(mhz19b_dev_t *dev, uart_port_t uart_port, gpio_num_t tx_gpio, gpio_num_t rx_gpio)

Initialize device descriptor.

Parameters
  • dev – Pointer to the sensor device data structure

  • uart_port – UART poert number

  • tx_gpio – GPIO pin number for TX

  • rx_gpio – GPIO pin number for RX

Returns

ESP_OK on success

esp_err_t mhz19b_free(mhz19b_dev_t *dev)

Free device descriptor.

Parameters

dev – Pointer to the sensor device data structure

Returns

ESP_OK on success

bool mhz19b_detect(mhz19b_dev_t *dev)

Detect sensor by checking range response.

Parameters

dev – Pointer to the sensor device data structure

Returns

true if sensor is detected

bool mhz19b_is_warming_up(mhz19b_dev_t *dev, bool smart_warming_up)

Check if sensor is warming up.

Parameters
  • dev – Pointer to the sensor device data structure

  • smart_warming_up – Smart check

Returns

true if sensor is warming up

bool mhz19b_is_ready(mhz19b_dev_t *dev)

Check minimum interval between CO2 reads.

Not described in the datasheet, but it is the same frequency as the built-in LED blink.

Parameters

dev – Pointer to the sensor device data structure

Returns

true if ready to call mhz19b_read_co2()

esp_err_t mhz19b_read_co2(mhz19b_dev_t *dev, int16_t *co2)

Read CO2 from sensor.

Parameters
  • dev – Pointer to the sensor device data structure

  • co2[out] CO2 level

    • < 0: MH-Z19B response error codes.

    • 0..399 ppm: Incorrect values. Minimum value starts at 400ppm outdoor fresh air.

    • 400..1000 ppm: Concentrations typical of occupied indoor spaces with good air exchange.

    • 1000..2000 ppm: Complaints of drowsiness and poor air quality. Ventilation is required.

    • 2000..5000 ppm: Headaches, sleepiness and stagnant, stale, stuffy air. Poor concentration, loss of attention, increased heart rate and slight nausea may also be present.

    • Higher values are extremely dangerous and cannot be measured.

Returns

ESP_OK on success

esp_err_t mhz19b_get_version(mhz19b_dev_t *dev, char *version)

Get firmware version (NOT DOCUMENTED)

This is an undocumented command, but most sensors returns ASCII “0430 or “0443”.

Parameters
  • dev – Pointer to the sensor device data structure

  • version[out]

    Returned character pointer to version (must be at least 5 Bytes)

    Only valid when return is set to ESP_OK.

Returns

ESP_OK on success

esp_err_t mhz19b_set_range(mhz19b_dev_t *dev, mhz19b_range_t range)

Set CO2 range.

Parameters
  • dev – Pointer to the sensor device data structure

  • range – Range of the sensor (2000 or 5000, in ppm)

Returns

ESP_OK on success

esp_err_t mhz19b_get_range(mhz19b_dev_t *dev, uint16_t *range)

Get CO2 range in PPM (NOT DOCUMENTED)

This function verifies valid read ranges of 2000 or 5000 ppm.

Note: Other ranges may be returned, but are undocumented and marked as invalid.

Parameters
  • dev – Pointer to the sensor device data structure

  • range – Current value of the range of the sensor (output)

Returns

ESP_OK on success

esp_err_t mhz19b_set_auto_calibration(mhz19b_dev_t *dev, bool calibration_on)

Enable or disable automatic calibration.

Parameters
  • dev – Pointer to the sensor device data structure

  • calibration_on

    • true: Automatic calibration on.

    • false: Automatic calibration off.

Returns

ESP_OK on success

esp_err_t mhz19b_get_auto_calibration(mhz19b_dev_t *dev, bool *calibration_on)

Get status of automatic calibration (NOT DOCUMENTED)

Parameters
  • dev – Pointer to the sensor device data structure

  • calibration_on[out] Automatic calibration status

Returns

ESP_OK on success

esp_err_t mhz19b_start_calibration(mhz19b_dev_t *dev)

Start Zero Point Calibration manually at 400ppm.

The sensor must be powered-up for at least 20 minutes in fresh air at 400ppm room temperature. Then call this function once to execute self calibration.

Recommended to use this function when auto calibration is off.

Parameters

dev – Pointer to the sensor device data structure

Returns

ESP_OK on success

esp_err_t mhz19b_send_command(mhz19b_dev_t *dev, uint8_t cmd, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6, uint8_t b7)

Send serial command to sensor and read response.

Send command to sensor and read response, protected with a receive timeout.

Result is available in the device descriptor buffer.

Parameters
  • dev – Pointer to the sensor device data structure

  • cmd – Command Byte

  • b3 – Byte 3 (default 0)

  • b4 – Byte 4 (default 0)

  • b5 – Byte 5 (default 0)

  • b6 – Byte 6 (default 0)

  • b7 – Byte 7 (default 0)

uint8_t mhz19b_calc_crc(uint8_t *data)

Calculate CRC on 8 data Bytes buffer.

Parameters

data – Buffer pointer to calculate CRC.

Returns

Calculated 8-bit CRC.

struct mhz19b_dev_t
#include <mhz19b.h>

MHZ19B sensor device data structure.

Public Members

uart_port_t uart_port

UART port used to communicate.

uint8_t *buf

read buffer attached to this device

int16_t last_value

last read value

int64_t last_ts

timestamp of the last sensor co2 level reading