{"id":16148878,"url":"https://github.com/erriez/erriezmhz19b","last_synced_at":"2025-03-18T18:33:12.201Z","repository":{"id":85067611,"uuid":"291297682","full_name":"Erriez/ErriezMHZ19B","owner":"Erriez","description":"Erriez MH-Z19B and MH-Z19C CO2 sensor library for Arduino","archived":false,"fork":false,"pushed_at":"2024-01-01T01:09:46.000Z","size":8640,"stargazers_count":27,"open_issues_count":0,"forks_count":4,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-10-11T00:35:14.906Z","etag":null,"topics":["air","arduino","atmega328","calibration","co2","documentation","esp32","esp8266","example","hardware","library","mh-z19b","mh-z19c","quality","school","sensor","serial","software","uno","usage"],"latest_commit_sha":null,"homepage":"https://github.com/Erriez/ErriezArduinoLibrariesAndSketches","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Erriez.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-08-29T15:30:59.000Z","updated_at":"2024-07-06T16:16:39.000Z","dependencies_parsed_at":"2024-01-06T13:09:08.085Z","dependency_job_id":"6aa8615f-4dbf-4d81-a5a0-72b834ed0bf2","html_url":"https://github.com/Erriez/ErriezMHZ19B","commit_stats":{"total_commits":43,"total_committers":1,"mean_commits":43.0,"dds":0.0,"last_synced_commit":"6a27877f4eb32f89bda76ca1057a63eb4cd444f2"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Erriez%2FErriezMHZ19B","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Erriez%2FErriezMHZ19B/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Erriez%2FErriezMHZ19B/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Erriez%2FErriezMHZ19B/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Erriez","download_url":"https://codeload.github.com/Erriez/ErriezMHZ19B/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221715904,"owners_count":16868641,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["air","arduino","atmega328","calibration","co2","documentation","esp32","esp8266","example","hardware","library","mh-z19b","mh-z19c","quality","school","sensor","serial","software","uno","usage"],"created_at":"2024-10-10T00:35:10.584Z","updated_at":"2024-10-27T18:15:06.195Z","avatar_url":"https://github.com/Erriez.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Licence MIT](https://img.shields.io/badge/license-MIT-green)](https://github.com/Erriez/ErriezMHZ19B/blob/master/LICENSE)\n[![Language C/C++](https://img.shields.io/badge/language-C%2FC%2B%2B-informational)](https://github.com/Erriez/ErriezMHZ19B)\n[![Release tag](https://img.shields.io/github/v/release/Erriez/ErriezMHZ19B?display_name=tag)](https://github.com/Erriez/ErriezMHZ19B/releases)\n[![Open issue](https://shields.io/github/issues-raw/Erriez/ErriezMHZ19B)](https://github.com/Erriez/ErriezMHZ19B/issues)\n[![PlatformIO CI](https://github.com/Erriez/ErriezMHZ19B/actions/workflows/actions.yml/badge.svg)](https://github.com/Erriez/ErriezMHZ19B/actions/workflows/actions.yml)\n\n# Erriez MH-Z19B/C CO2 sensor library for Arduino\n\nThis is a MH-Z19B / MH-Z19C CO2 sensor library for Arduino. It has been built from scratch to support hardware \nand software serial with a small footprint.\n\nThe MH-Z19 is a NDIR (Non-Dispersive Infrared) type gas sensor with built-in temperature\ncompensation to measure CO2 concentration in air.\n\n![MHZ19B](https://raw.githubusercontent.com/Erriez/ErriezMHZ19B/master/extras/MHZ19B.png)\n\n\n## Library features\n\n* Small code/memory footprint\n* Hardware and software serial interface at 9600 baud 8N1\n* Read CO2 concentration 400..5000 ppm +/-50ppm+3% minimum 5 seconds interval\n* Chip detection\n* Smart warming-up detection\n* Read firmware version\n* Set/get range 2000 or 5000 ppm\n* Set/get auto calibration (Automatic Baseline Correction 24h interval)\n* Manual 400ppm calibration command\n* CRC checks on communication protocol and timeout handling\n* Interface for sending undocumented commands\n\n### Pins\n\nWARNING: The pins between MH-Z19B and MH-Z19C are different. See tables below: \n\n```c++\n//     __     _______\n// +------------------+\n// |                  |\n// |   . . . . . . .  |\n// |   1 2 3 4 5 6 7  |\n// +------------------+\n//\n// MH-Z19B front connector:\n//   Pin 1: Yellow  None\n//   Pin 2: Green   UART (TXD) TTL Level Data Output  -\u003e TO RXD\n//   Pin 3: Blue    UART (RXD) TTL Level Data Input   -\u003e TO TXD\n//   Pin 4: Red     Positive Power Supply (Vin +5V)\n//   Pin 5: Black   Negative Power Supply (GND)\n//   Pin 6: White   None\n//   Pin 7: Brown   Analog Output Vo (Not used)\n//\n// MH-Z19C front connector:\n//   Pin 1: PWM\n//   Pin 2: UART (TXD) TTL Level data output  -\u003e TO RXD\n//   Pin 3: UART (RXD) TTL Level data input   -\u003e TO TXD\n//   Pin 4: Positive Power Supply (Vin +5V)\n//   Pin 5: Negative Power Supply (GND)\n//   Pin 6: Analog Output Vo\n//   Pin 7: HD (Hand-operated calibration)\n//\n// The following ESP8266 pins are reserved:\n//    TX/RX:  Serial (in use)\n//    A0:     Analog (cannot be used)\n//    D0-RST: Wake (cannot be used)\n//    D1/D2:  I2C (can be used when I2C not used)\n//    D3:     Output data flash (corrupts MH-Z19B on boot)\n//    D4:     Boot (in use by boot pin / LED)\n//    D5..D8: SPI \u003c- Can be used when SPI not used\n```\n\n\n## Tested Hardware\n\nThe following targets are supported and tested:\n\n* AVR: UNO, MINI, Pro Mini 8/16 MHz, ATMega2560, Leonardo\n* ARM: DUE\n* ESP8266: Mini D1 \u0026 D2, NodeMCU\n* ESP32: Lolin D32\n\n\n## Examples\n\n* [ErriezMHZ19BGettingStarted](https://github.com/Erriez/ErriezMHZ19B/tree/master/examples/ErriezMHZ19BGettingStarted) \n* [ErriezMHZ19BSerialPlottter](https://github.com/Erriez/ErriezMHZ19B/tree/master/examples/ErriezMHZ19BSerialPlottter)\n* [ErriezMHZ19B7SegmentDisplay](https://github.com/Erriez/ErriezMHZ19B/tree/master/examples/ErriezMHZ19B7SegmentDisplay)\n\n\n## Documentation\n\n- [Online HTML](https://erriez.github.io/ErriezMHZ19B)\n- [Doxygen PDF](https://github.com/Erriez/ErriezMHZ19B/blob/gh-pages/ErriezMHZ19B.pdf)\n- [MH-Z19B datasheet PDF](https://github.com/Erriez/ErriezMHZ19B/blob/master/extras/mh-z19b-co2-ver1_0.pdf)\n- [MH-Z19C datasheet PDF](https://github.com/Erriez/ErriezMHZ19B/blob/master/extras/mh-z19c-co2-ver1_21.pdf)\n\n\n## CO2 Concentrations\n\nThe table below displays the human impact of CO2:\n\n| CO2 ppm    | Description                                                  |\n| ---------- | ------------------------------------------------------------ |\n| 0..399     | Incorrect values. Minimum value starts at 400ppm outdoor fresh air. |\n| 400..1000  | Concentrations typical of occupied indoor spaces with good air exchange. |\n| 1000..2000 | Complaints of drowsiness and poor air quality. Ventilation is required. |\n| 2000..5000 | Headaches, sleepiness and stagnant, stale, stuffy air. Poor concentration, loss of attention, increased heart rate and slight nausea may also be present. |\n| \u003e5000      | Higher values are extremely dangerous and cannot be measured by this sensor. |\n\n\n## Usage\n\n* Operating voltage is between 4.5 and 5VDC, 150mA peak current (average \u003c 60mA).\n* UART pins are compatible with processors running at 3.3V without level converters.\n* Keep sensor outside direct sunlight.\n\n### Calibration\n\nThe sensor requires an internal calibration regularly. Without it, the minimum value drifts away \nwhich is noticeable after a few weeks of operation. With my experiments, the minimum value was \ndrifted to 800ppm after 3 months continues operation without a calibration.\n\nThere are two calibration options:\n\n1. Automatic calibration, performed every 24 hours (default).\n2. Manual calibration.\n\n### 1. Automatic Calibration\n\nAutomatic calibration is recommended when the sensor cannot be moved outdoor with fresh air. This \ncalibration method requires a regularly ventilated room at 400ppm, at least once in 1..3 weeks. \nAdditionally, it requires continues power-up without interruptions, otherwise the calibration data \nwill not be updated correctly.\n\nAutomatic calibration configuration:\n\n* Set auto calibration on: `setAutoCalibration(true)` (Default from manufacture).\n* Set auto calibration off: `setAutoCalibration(false)`.\n\nThe status can be read with function `getAutoCalibration()`.\n\n**Note:**  \nFor simplicity, this library uses the terminology `Automatic Calibration` which is identical to the\n`ABC (Automatic Baseline Correction) logic on/off` mentioned in the datasheet.\n\n### 2. Manual ZERO Calibration (400ppm)\n\nProcedure for manual calibration at 400ppm:\n\n* Turn automatic calibration off.\n* Power the sensor up outdoor in fresh air for at least 20 minutes. (Not in a forest or a farm \n  which produces background CO2)\n* Call `startZeroCalibration()` once. This will send command `0x87 Zero Point Calibration`, but \n  is not a zero calibration as stated in the datasheet. There is no nitrogen needed as this \n  calibration is performed at 400ppm.\n\nNow the sensor is calibrated. Repeat the sequence more often for higher accuracy.\n\n### 3. MH-Z19B only: Manual SPAN Calibration\n\nThe SPAN point calibration procedure is not implemented in this library as it requires special\ncalibration equipment. This functionality is not available in MH-Z19C.\n\n### 4. MH-Z19C only: Hand-operated calibration\n\nProcedure according to the MH-Z19C datasheet: \n- Connect module’s HD pin to low level(0V), lasting for 7 seconds at least.\n- Before calibrating the zero point, please ensure that the sensor is stable for more than 20 \n  minutes at 400ppm ambient environment.\n- The application is responsible to control the external MH-Z19C HD pin and is not available on\n  the MH-Z19B. \n\n## MH-Z19B/C API\n\n**Initialization Software Serial**\n\nUse a Software Serial when no hardware serial is available. Sometimes a 3rd party library is\nrequired, for example for ESP32 targets by installing `ESPSoftwareSerial`. It must be installed into \n`.arduino15/packages/esp32/hardware/esp32/\u003cversion\u003e/libraries/EspSoftwareSerial`, because the \nlibrary contains a naming conflict with existing `SoftwareSerial.h` built-in libraries.\n\n```c++\n#include \u003cErriezMHZ19B.h\u003e\n#include \u003cSoftwareSerial.h\u003e\n\n// Pin defines\n#define MHZ19B_TX_PIN        4\n#define MHZ19B_RX_PIN        5\n\n// Create software serial object\nSoftwareSerial mhzSerial(MHZ19B_TX_PIN, MHZ19B_RX_PIN);\n\n// Create MHZ19B object with software serial\nErriezMHZ19B mhz19b(\u0026mhzSerial);\n```\n\n**Initialization Hardware Serial**\n\nAny hardware serial like `Serial`, `Serial1`, `Serial2` etc can be used when supported by the CPU.\nMultiple hardware serial ports are only available on targets like ATMEGA2560, Leonardo and SAM DUE \nboards:\n\n```c++\n#include \u003cErriezMHZ19B.h\u003e\n\n// Create MHZ19B object with hardware serial\nErriezMHZ19B mhz19b(\u0026Serial1);\n```\n\n**General initialization**\n\nThe optional items of the initialization sequence can be omitted.\n\n```c++\nvoid setup()\n{\n    // Initialize serial\n    Serial.begin(115200);\n    Serial.println(F(\"\\nErriez MH-Z19B CO2 Sensor example\"));\n\n    // Initialize software serial at fixed baudrate\n    mhzSerial.begin(9600);\n\n    // Optional: Detect MH-Z19B sensor (check wiring / power)\n    while ( !mhz19b.detect() ) {\n        Serial.println(F(\"Detecting MH-Z19B sensor...\"));\n        delay(2000);\n    };\n\n    // Sensor requires 3 minutes warming-up after power-on\n    while (mhz19b.isWarmingUp()) {\n        Serial.println(F(\"Warming up...\"));\n        delay(2000);\n    };\n}\n```\n\n**Read CO2 loop**\n\nRead CO2 with minimum interval asynchronous function `isReady()`.\nA good practice is to check error returns `\u003c 0`.\n\n```c++\nvoid loop()\n{\n    int16_t result;\n\n    // Minimum interval between CO2 reads\n    if (mhz19b.isReady()) {\n        // Read CO2 from sensor\n        result = mhz19b.readCO2();\n\n        // Print result\n        if (result \u003c 0) {\n            // Print error code\n            switch (result) {\n                case MHZ19B_RESULT_ERR_CRC:\n                    Serial.println(F(\"CRC error\"));\n                    break;\n                case MHZ19B_RESULT_ERR_TIMEOUT:\n                    Serial.println(F(\"RX timeout\"));\n                    break;\n                default:\n                    Serial.print(F(\"Error: \"));\n                    Serial.println(result);\n                    break;\n            }\n        } else {\n            // Print CO2 concentration in ppm\n            Serial.print(result);\n            Serial.println(F(\" ppm\"));\n        }\n    }\n}\n```\n\n**Print internal settings**\n\nAll tests are performed with sensor version string `\"0443\"`.\n\n```c++\nchar firmwareVersion[5];\n\n// Optional: Print firmware version\nSerial.print(F(\"  Firmware: \"));\nmhz19b.getVersion(firmwareVersion, sizeof(firmwareVersion));\nSerial.println(firmwareVersion);\n\n// Optional: Set CO2 range 2000ppm or 5000ppm (default) once\n// Serial.print(F(\"Set range...\"));\n// mhz19b.setRange2000ppm();\n// mhz19b.setRange5000ppm();\n\n// Optional: Print operating range\nSerial.print(F(\"  Range: \"));\nSerial.print(mhz19b.getRange());\nSerial.println(F(\"ppm\"));\n\n// Optional: Print Automatic Baseline Calibration status\nSerial.print(F(\"  Auto calibrate: \"));\nSerial.println(mhz19b.getAutoCalibration() ? F(\"On\") : F(\"Off\"));\n```\n\n**Set automatic calibration**\n\nTurn automatic calibration on or off once at startup:\n\n```c++\n// Optional: Set automatic calibration on (true) or off (false) once\nmhz19b.setAutoCalibration(true);\n```\n\n\n### Documented commands\n\nThe following commands are documented, used and tested by the library:\n\n| Command | Description                                  |\n| ------- | -------------------------------------------- |\n| 0x79    | Set auto calibration on/off                  |\n| 0x86    | Read CO2 concentration                       |\n| 0x87    | Calibration zero point at 400ppm (not 0 ppm) |\n| 0x88    | Calibrate span point (NOT IMPLEMENTED)       |\n| 0x99    | Set detection range                          |\n\n\n### Not documented commands (tested)\n\nThe following commands are **not documented**, are used and tested  by the library:\n\n| Command | Description                                  |\n| ------- | -------------------------------------------- |\n| 0x7D    | Get auto calibration status (NOT DOCUMENTED) |\n| 0x9B    | Get range detection (NOT DOCUMENTED)         |\n| 0xA0    | Get firmware version (NOT DOCUMENTED)        |\n\nMore information about undocumented commands: https://revspace.nl/MH-Z19B.\n\n**NOTE:** Sending untested commands may damage the sensor permanently! Use at your own risk.\n\n```c++\nint16_t result;\n\nresult = mhz19b.sendCommand(MHZ19B_CMD_NOT_DOCUMENTED, 0x00, 0x00, 0x00, 0x00, 0x00);\n\n// 9 Bytes response is located in mhz19b.rxBuffer[9]\n```\n\n\n## Library configuration\n\nUnfortunately, the sensor has no possibility to read warming-up status, so the library must wait\nat least 3 minutes after reset or power-on. To speedup the boot process, macro \n`MHZ19B_SMART_WARMING_UP` can be enabled in `ErriezMHZ19B.h` to enable smart warming-up when the \nMCU is reset and MH-Z19B powered \u003e 3 minutes.\n\n\n## Response timing\n\nThe screenshot below displays the response timing of a synchronous readCO2() call which takes 22.1ms\non an Arduino UNO:\n* 9.4ms: Transmit 9 Bytes at 9600 baud\n* 3.2ms: MH-Z19B to process command\n* 9.3ms: Return response 9 Bytes at 9600 baud\n* 183us: Arduino UNO to process response with Software Serial. \n\n![Logic Analyzer Screenshot MHZ19B UNO readCO2()](extras/LogicAnalyzerScreenshotMHZ19BUNOReadCO2.png)\n\n\n## Library installation\n\nPlease refer to the [Wiki](https://github.com/Erriez/ErriezArduinoLibrariesAndSketches/wiki) page.\n\n\n## Other Arduino Libraries and Sketches from Erriez\n\n[Erriez Libraries and Sketches](https://github.com/Erriez/ErriezArduinoLibrariesAndSketches)\n\n\n## MIT License\n\nThis project is published under [MIT license](https://github.com/Erriez/ErriezMHZ19B/blob/master/LICENSE)\nwith an additional end user agreement (next section).\n\n\n## End User Agreement :ukraine:\n\nEnd users shall accept the [End User Agreement](https://github.com/Erriez/ErriezMHZ19B/blob/master/END_USER_AGREEMENT.md)\nholding export restrictions to Russia to stop the WAR before using this project.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferriez%2Ferriezmhz19b","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferriez%2Ferriezmhz19b","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferriez%2Ferriezmhz19b/lists"}