2023-01-07 09:48:40 -05:00
|
|
|
|
|
|
|
[![Arduino CI](https://github.com/RobTillaart/MHZCO2/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
|
|
|
|
[![Arduino-lint](https://github.com/RobTillaart/MHZCO2/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/MHZCO2/actions/workflows/arduino-lint.yml)
|
|
|
|
[![JSON check](https://github.com/RobTillaart/MHZCO2/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/MHZCO2/actions/workflows/jsoncheck.yml)
|
2023-11-14 04:25:54 -05:00
|
|
|
[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/MHZCO2.svg)](https://github.com/RobTillaart/MHZCO2/issues)
|
|
|
|
|
2023-01-07 09:48:40 -05:00
|
|
|
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/MHZCO2/blob/master/LICENSE)
|
|
|
|
[![GitHub release](https://img.shields.io/github/release/RobTillaart/MHZCO2.svg?maxAge=3600)](https://github.com/RobTillaart/MHZCO2/releases)
|
2023-11-14 04:25:54 -05:00
|
|
|
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/MHZCO2.svg)](https://registry.platformio.org/libraries/robtillaart/MHZCO2)
|
2023-01-07 09:48:40 -05:00
|
|
|
|
|
|
|
|
|
|
|
# MHZCO2
|
|
|
|
|
|
|
|
Arduino Library for MHZ series CO2 sensors.
|
|
|
|
|
|
|
|
|
|
|
|
## Description
|
|
|
|
|
2023-07-27 10:14:19 -04:00
|
|
|
The MHZCO2 is an experimental library for the MHZ19B CO2 sensor
|
|
|
|
with a Serial (RS232-TTL) interface and compatibles.
|
2023-01-07 09:48:40 -05:00
|
|
|
|
|
|
|
The library offers a base class and derived classes to prepare for specific functionality.
|
2023-07-27 10:14:19 -04:00
|
|
|
The base class is based upon the MHZ19B specification.
|
|
|
|
This might change in the future as compatibles might differ on detail.
|
2023-01-07 09:48:40 -05:00
|
|
|
|
2023-07-27 10:14:19 -04:00
|
|
|
Reference: user manual MHZ129B 2019-04-25 version 1.4
|
2023-01-07 09:48:40 -05:00
|
|
|
|
2024-09-02 14:21:08 -04:00
|
|
|
|
|
|
|
### Version 0.2.1
|
|
|
|
|
|
|
|
Minor breaking change as **Measure()** will only update lastMeasurement
|
|
|
|
in case the measurement was successful. See #11.
|
|
|
|
|
|
|
|
|
|
|
|
### Version 0.2.0
|
2023-12-29 10:57:01 -05:00
|
|
|
|
|
|
|
Version 0.2.0 fixes a bug in **setPPM()** which makes older versions obsolete.
|
|
|
|
|
|
|
|
|
2024-09-02 14:21:08 -04:00
|
|
|
### Compatibles
|
2023-01-07 09:48:40 -05:00
|
|
|
|
|
|
|
This list is not verified although these devices should be compatible based upon datasheet.
|
|
|
|
|
2023-12-29 10:57:01 -05:00
|
|
|
There exists different models of 400-2000 PPM and 400-5000 PPM and 400-10000 PPM.
|
|
|
|
As far as known these have the same interface as there is very little information to be found.
|
|
|
|
|
|
|
|
|
2023-01-07 09:48:40 -05:00
|
|
|
| type | precision | notes |
|
|
|
|
|:-----------|:----------:|:--------|
|
|
|
|
| MHZ1311A | 50ppm + 5% | energy saving version
|
|
|
|
| MHZ19 | 50ppm + 5% |
|
|
|
|
| MHZ19B | 50ppm + 3% | test device
|
2023-12-29 10:57:01 -05:00
|
|
|
| MHZ19C | 50ppm + 5% | (1)
|
2023-01-07 09:48:40 -05:00
|
|
|
| MHZ19D | 50ppm + 5% |
|
|
|
|
| MHZ19E | 50ppm + 5% |
|
|
|
|
|
2023-12-29 10:57:01 -05:00
|
|
|
Note (1):
|
|
|
|
There exists different models of the MHZ19C and probably others.
|
|
|
|
The range can go from 400-2000 PPM, 400-5000 PPM and 400-10000 PPM.
|
|
|
|
As far as known these have the same interface as there is very little
|
|
|
|
information to be found. See #9.
|
|
|
|
|
2023-01-07 09:48:40 -05:00
|
|
|
Note: The calibration of the MHZ1311A is different than MHZ19x series
|
|
|
|
|
|
|
|
If there are compatible devices missing in this list, please let me know.
|
|
|
|
|
2023-07-27 10:14:19 -04:00
|
|
|
In previous versions the MTP40F was incorrectly mentioned as compatible.
|
|
|
|
|
|
|
|
|
2024-09-02 14:21:08 -04:00
|
|
|
### Related
|
2023-01-07 09:48:40 -05:00
|
|
|
|
|
|
|
- https://emariete.com/en/sensor-co2-mh-z19b/
|
|
|
|
- https://emariete.com/en/sensor-co2-low-consumption-mh-z1311a-winsen/
|
|
|
|
- https://revspace.nl/MHZ19
|
2023-07-27 10:14:19 -04:00
|
|
|
- https://www.co2.earth/ - current outdoor CO2 level can be used for calibrating.
|
|
|
|
- https://keelingcurve.ucsd.edu/ - historical outdoor CO2 level.
|
|
|
|
- https://github.com/RobTillaart/MTP40C
|
|
|
|
- https://github.com/RobTillaart/MTP40F
|
|
|
|
- https://github.com/RobTillaart/Cozir
|
2023-01-07 09:48:40 -05:00
|
|
|
|
|
|
|
|
|
|
|
## Connection
|
|
|
|
|
|
|
|
- check datasheet of your sensor.
|
|
|
|
|
|
|
|
|
|
|
|
## Interface
|
|
|
|
|
2023-11-14 04:25:54 -05:00
|
|
|
```cpp
|
|
|
|
#include "MHZCO2.h"
|
|
|
|
```
|
|
|
|
|
2024-09-02 14:21:08 -04:00
|
|
|
### Constructor
|
2023-01-07 09:48:40 -05:00
|
|
|
|
|
|
|
- **MHZCO2()** base class constructor.
|
2023-07-27 10:14:19 -04:00
|
|
|
- **MHZ19()** constructor. Also 19B, C, D, E
|
|
|
|
- **void begin(Stream \* str)** set the Serial port to use, e.g Serial1,
|
|
|
|
or a softwareSerial port.
|
2024-09-02 14:21:08 -04:00
|
|
|
**begin()** also resets all internal variables.
|
2023-01-07 09:48:40 -05:00
|
|
|
- **uint32_t uptime()** returns milliseconds since 'instantiation'.
|
|
|
|
|
|
|
|
|
2024-09-02 14:21:08 -04:00
|
|
|
### Range
|
|
|
|
|
|
|
|
To set the max range of the actual sensor.
|
2023-01-07 09:48:40 -05:00
|
|
|
|
2024-09-02 14:21:08 -04:00
|
|
|
- **void setPPM(uint16_t PPM)** PPM = 2000, 5000, 10000.
|
|
|
|
The value set is persistent over reboots (see issue #9).
|
|
|
|
- **uint16_t getPPM()** returns the cached PPM value.
|
|
|
|
Note: initially this function returns zero / 0 as the cache is not
|
|
|
|
filled by **setPPM()** yet.
|
2023-01-07 09:48:40 -05:00
|
|
|
|
|
|
|
|
2024-09-02 14:21:08 -04:00
|
|
|
### Measure
|
2023-01-07 09:48:40 -05:00
|
|
|
|
2023-12-29 10:57:01 -05:00
|
|
|
- **int measure()** workhorse, send command to read the sensor and
|
|
|
|
waits until an answer is received. Return values see below.
|
2024-09-02 14:21:08 -04:00
|
|
|
Will only update lastMeasurement if the measurement is successful (0.2.1)
|
2023-07-27 10:14:19 -04:00
|
|
|
- **uint32_t lastMeasurement()** timestamp in milliseconds of last measurement.
|
2023-01-07 09:48:40 -05:00
|
|
|
- **int getCO2()** returns CO2 PPM last measurement.
|
|
|
|
- **int getTemperature()** returns temperature last measurement.
|
2024-09-02 14:21:08 -04:00
|
|
|
Note that the temperature can be negative.
|
2023-01-07 09:48:40 -05:00
|
|
|
- **int getAccuracy()** returns accuracy last measurement.
|
2024-09-02 14:21:08 -04:00
|
|
|
Note: check datasheet.
|
2023-01-07 09:48:40 -05:00
|
|
|
- **int getMinCO2()** returns minCO2 last measurement.
|
|
|
|
|
|
|
|
The latter two might not be supported by all MH sensors.
|
|
|
|
|
2024-09-02 14:21:08 -04:00
|
|
|
#### Return values of **measure()**
|
2023-12-29 10:57:01 -05:00
|
|
|
|
|
|
|
| value | Name | Description |
|
|
|
|
|:-------:|:------------------:|:--------------|
|
|
|
|
| 0 | MHZCO2_OK | measurement succeeded.
|
2024-09-02 14:21:08 -04:00
|
|
|
| -10 | MHZCO2_TIMEOUT | took too long to receive an answer.
|
2023-12-29 10:57:01 -05:00
|
|
|
| -11 | MHZCO2_ERROR_CRC | Checksum error, handle answer with care.
|
|
|
|
|
|
|
|
|
2024-09-02 14:21:08 -04:00
|
|
|
#### CRC error
|
|
|
|
|
|
|
|
In case of an checksum error the values received may be corrupted.
|
|
|
|
Best strategy is to ignore the measurement. However this is not always
|
|
|
|
possible so a strategy might be to compare the values of the measurement
|
|
|
|
with the previous ones.
|
|
|
|
Often one can determine the failing ones but definitely not always.
|
|
|
|
|
|
|
|
|
|
|
|
### Calibration
|
2023-01-07 09:48:40 -05:00
|
|
|
|
|
|
|
**WARNING:** use with care, read the datasheet as these commands may disrupt your sensor.
|
|
|
|
|
2023-07-27 10:14:19 -04:00
|
|
|
- **void calibrateZero()** Only use when sensor is at least 30 minutes
|
|
|
|
in a calibrated **400** PPM environment.
|
|
|
|
- **void calibrateSpan(uint16_t span)** Only use when sensor is at least 30 minutes
|
|
|
|
in a calibrated **2000** PPM environment.
|
2023-01-07 09:48:40 -05:00
|
|
|
- **void calibrateAuto(bool mode = true)**
|
|
|
|
|
2023-07-27 10:14:19 -04:00
|
|
|
Note the outdoor calibration CO2 level differs per day and one should check
|
|
|
|
a local airport or weather station for a good reference.
|
|
|
|
|
|
|
|
The University of San Diego keeps track of CO2 for a long time now.
|
|
|
|
See - https://keelingcurve.ucsd.edu/
|
|
|
|
|
2023-01-07 09:48:40 -05:00
|
|
|
|
2024-09-02 14:21:08 -04:00
|
|
|
### Timeout
|
|
|
|
|
|
|
|
These functions are used to set the default timeout in the receive function.
|
|
|
|
The faster the baud rate used, the smaller this value can be. As the **receive()**
|
|
|
|
call has to read 9 bytes at (default) 9600 baud. This is max 1 character per
|
|
|
|
millisecond. To receive 9 bytes one needs therefore at least 10 to 15 milliseconds
|
|
|
|
under ideal circumstances. So setting the timeout lower makes little sense.
|
|
|
|
|
|
|
|
If the timeout is set to zero / 0 there will be no time out checking.
|
|
|
|
|
|
|
|
Use with care!
|
|
|
|
|
|
|
|
- **void setTimeOut(uint16_t timeout = 1000)** set the stream reading timeout,
|
|
|
|
defaults to 1000 milliseconds.
|
|
|
|
- **uint16_t getTimeOut()** returns the set stream reading timeout.
|
|
|
|
|
|
|
|
|
2023-01-07 09:48:40 -05:00
|
|
|
## Future
|
|
|
|
|
|
|
|
#### Must
|
2023-01-18 10:59:34 -05:00
|
|
|
|
2023-01-07 09:48:40 -05:00
|
|
|
- improve documentation
|
|
|
|
- buy hardware MHZ19B / MHZ19C
|
|
|
|
- test with hardware
|
|
|
|
- verify timeout
|
|
|
|
|
2023-01-18 10:59:34 -05:00
|
|
|
#### Should
|
|
|
|
|
2024-09-02 14:21:08 -04:00
|
|
|
- check 5000 and 10000 PPM and possible others?
|
|
|
|
- is there an effect on the PWM output.
|
|
|
|
- should the PPM be a parameter of the constructor?
|
|
|
|
- default to 2000? or model based?
|
2023-01-07 09:48:40 -05:00
|
|
|
|
|
|
|
#### Could
|
2023-01-18 10:59:34 -05:00
|
|
|
|
2023-01-07 09:48:40 -05:00
|
|
|
- add type info for derived classes?
|
2023-07-27 10:14:19 -04:00
|
|
|
- A .. E ?
|
2023-01-07 09:48:40 -05:00
|
|
|
- save RAM? possible?
|
2024-09-02 14:21:08 -04:00
|
|
|
- all arrays start with 0xFF, 0x01
|
|
|
|
- reduce data types?
|
|
|
|
- **uint16_t send()** could return bytes send?
|
|
|
|
- would allow higher level functions to check.
|
|
|
|
- add **int maxCO2()** by keeping track myself?
|
|
|
|
- extend unit tests if needed.
|
|
|
|
- fix SoftwareSerial - https://github.com/Arduino-CI/arduino_ci/issues/346
|
2023-01-18 10:59:34 -05:00
|
|
|
|
2023-01-07 09:48:40 -05:00
|
|
|
#### Won't
|
|
|
|
|
2023-11-14 04:25:54 -05:00
|
|
|
|
|
|
|
## Support
|
|
|
|
|
|
|
|
If you appreciate my libraries, you can support the development and maintenance.
|
|
|
|
Improve the quality of the libraries by providing issues and Pull Requests, or
|
|
|
|
donate through PayPal or GitHub sponsors.
|
|
|
|
|
|
|
|
Thank you,
|
|
|
|
|