mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.2.1 MHZCO2
This commit is contained in:
parent
a1e696709e
commit
f4b74b6d23
@ -6,6 +6,15 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
|
||||
## [0.2.1] - 2024-09-02
|
||||
- merge #11, update lastMeasurement only if read is successful (kudos JonNelson)
|
||||
- add **void setTimeOut(uint16_t timeout = 1000)** to configure timeout
|
||||
- add **uint16_t getTimeOut()**
|
||||
- add example **MHZCO2_sw_serial_timeout.ino**.
|
||||
- update unit tests
|
||||
- update readme.md
|
||||
- minor edits
|
||||
|
||||
## [0.2.0] - 2023-12-29
|
||||
- Fix #9 bug in **setPPM()**
|
||||
- fix race condition in **receive()**
|
||||
|
@ -1,7 +1,7 @@
|
||||
//
|
||||
// FILE: MHZCO2.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.2.0
|
||||
// VERSION: 0.2.1
|
||||
// PURPOSE: Arduino Library for MHZ series CO2 sensors
|
||||
// DATE: 2020-05-05
|
||||
// URL: https://github.com/RobTillaart/MHZCO2
|
||||
@ -20,6 +20,7 @@ void MHZCO2::begin(Stream * str)
|
||||
{
|
||||
_str = str;
|
||||
_lastMeasurement = 0;
|
||||
_timeout = 1000;
|
||||
_PPM = 0;
|
||||
_CO2 = 0;
|
||||
_temperature = 0;
|
||||
@ -56,8 +57,6 @@ uint16_t MHZCO2::getPPM()
|
||||
|
||||
int MHZCO2::measure()
|
||||
{
|
||||
_lastMeasurement = millis();
|
||||
|
||||
uint8_t data[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
data[8] = checksum(data);
|
||||
send(data, 9);
|
||||
@ -71,7 +70,10 @@ int MHZCO2::measure()
|
||||
_accuracy = data[5];
|
||||
_minCO2 = data[6] * 256 + data[7];
|
||||
}
|
||||
|
||||
if (rv == MHZCO2_OK)
|
||||
{
|
||||
_lastMeasurement = millis();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -133,6 +135,19 @@ void MHZCO2::calibrateAuto(bool mode)
|
||||
}
|
||||
|
||||
|
||||
void MHZCO2::setTimeOut(uint16_t timeout)
|
||||
{
|
||||
_timeout = timeout;
|
||||
}
|
||||
|
||||
|
||||
uint16_t MHZCO2::getTimeOut()
|
||||
{
|
||||
return _timeout;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
//
|
||||
// PROTECTED
|
||||
@ -159,12 +174,18 @@ int MHZCO2::receive(uint8_t * answer)
|
||||
}
|
||||
else
|
||||
{
|
||||
// note: hardcoded timeout
|
||||
if (millis() - start > 1000) return MHZCO2_TIMEOUT;
|
||||
// default _timeout = 1000
|
||||
if ((_timeout > 0) && (millis() - start > _timeout))
|
||||
{
|
||||
return MHZCO2_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
// verify checksum
|
||||
if (answer[8] != checksum(answer)) return MHZCO2_ERROR_CRC;
|
||||
if (answer[8] != checksum(answer))
|
||||
{
|
||||
return MHZCO2_ERROR_CRC;
|
||||
}
|
||||
|
||||
return MHZCO2_OK;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// FILE: MHZCO2.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.2.0
|
||||
// VERSION: 0.2.1
|
||||
// PURPOSE: Arduino Library for MHZ series CO2 sensors
|
||||
// DATE: 2020-05-05
|
||||
// URL: https://github.com/RobTillaart/MHZCO2
|
||||
@ -10,7 +10,7 @@
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#define MHZCO2_LIB_VERSION (F("0.2.0"))
|
||||
#define MHZCO2_LIB_VERSION (F("0.2.1"))
|
||||
|
||||
#define MHZCO2_OK 0
|
||||
#define MHZCO2_TIMEOUT -10
|
||||
@ -47,11 +47,18 @@ public:
|
||||
void calibrateSpan(uint16_t span);
|
||||
void calibrateAuto(bool mode = true);
|
||||
|
||||
// default = 1000 millisecond
|
||||
// depending on baud rate (9600) low values may fail
|
||||
// 0 means no time ut check.
|
||||
void setTimeOut(uint16_t timeout = 1000);
|
||||
uint16_t getTimeOut();
|
||||
|
||||
|
||||
protected:
|
||||
Stream * _str;
|
||||
uint32_t _startTime;
|
||||
uint32_t _lastMeasurement;
|
||||
Stream * _str = NULL;
|
||||
uint32_t _startTime = 0;
|
||||
uint32_t _lastMeasurement = 0;
|
||||
uint16_t _timeout = 1000;
|
||||
|
||||
uint16_t _PPM = 0;
|
||||
int _CO2 = 0;
|
||||
|
@ -25,12 +25,19 @@ This might change in the future as compatibles might differ on detail.
|
||||
|
||||
Reference: user manual MHZ129B 2019-04-25 version 1.4
|
||||
|
||||
#### Version 0.2.0
|
||||
|
||||
### 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
|
||||
|
||||
Version 0.2.0 fixes a bug in **setPPM()** which makes older versions obsolete.
|
||||
|
||||
|
||||
#### Compatibles
|
||||
### Compatibles
|
||||
|
||||
This list is not verified although these devices should be compatible based upon datasheet.
|
||||
|
||||
@ -60,7 +67,7 @@ If there are compatible devices missing in this list, please let me know.
|
||||
In previous versions the MTP40F was incorrectly mentioned as compatible.
|
||||
|
||||
|
||||
#### Links
|
||||
### Related
|
||||
|
||||
- https://emariete.com/en/sensor-co2-mh-z19b/
|
||||
- https://emariete.com/en/sensor-co2-low-consumption-mh-z1311a-winsen/
|
||||
@ -83,44 +90,61 @@ In previous versions the MTP40F was incorrectly mentioned as compatible.
|
||||
#include "MHZCO2.h"
|
||||
```
|
||||
|
||||
#### Constructor
|
||||
### Constructor
|
||||
|
||||
- **MHZCO2()** base class constructor.
|
||||
- **MHZ19()** constructor. Also 19B, C, D, E
|
||||
- **void begin(Stream \* str)** set the Serial port to use, e.g Serial1,
|
||||
or a softwareSerial port.
|
||||
**begin()** also resets all internal variables.
|
||||
- **uint32_t uptime()** returns milliseconds since 'instantiation'.
|
||||
|
||||
|
||||
#### Range
|
||||
### Range
|
||||
|
||||
To set the max range of the actual sensor.
|
||||
|
||||
- **void setPPM(uint16_t PPM)** PPM = 2000, 5000, 10000.
|
||||
- **uint16_t getPPM()** returns (cached) PPM value.
|
||||
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.
|
||||
|
||||
|
||||
#### Measure
|
||||
### Measure
|
||||
|
||||
- **int measure()** workhorse, send command to read the sensor and
|
||||
waits until an answer is received. Return values see below.
|
||||
Will only update lastMeasurement if the measurement is successful (0.2.1)
|
||||
- **uint32_t lastMeasurement()** timestamp in milliseconds of last measurement.
|
||||
- **int getCO2()** returns CO2 PPM last measurement.
|
||||
- **int getTemperature()** returns temperature last measurement.
|
||||
Note that the temperature can be negative.
|
||||
- **int getAccuracy()** returns accuracy last measurement.
|
||||
Note: check datasheet.
|
||||
- **int getMinCO2()** returns minCO2 last measurement.
|
||||
|
||||
The latter two might not be supported by all MH sensors.
|
||||
|
||||
|
||||
Return values of **measure()**
|
||||
#### Return values of **measure()**
|
||||
|
||||
| value | Name | Description |
|
||||
|:-------:|:------------------:|:--------------|
|
||||
| 0 | MHZCO2_OK | measurement succeeded.
|
||||
| -10 | MHZCO2_TIMEOUT | to too long to receive an answer
|
||||
| -10 | MHZCO2_TIMEOUT | took too long to receive an answer.
|
||||
| -11 | MHZCO2_ERROR_CRC | Checksum error, handle answer with care.
|
||||
|
||||
|
||||
#### Calibration
|
||||
#### 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
|
||||
|
||||
**WARNING:** use with care, read the datasheet as these commands may disrupt your sensor.
|
||||
|
||||
@ -137,6 +161,23 @@ The University of San Diego keeps track of CO2 for a long time now.
|
||||
See - https://keelingcurve.ucsd.edu/
|
||||
|
||||
|
||||
### 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.
|
||||
|
||||
|
||||
## Future
|
||||
|
||||
#### Must
|
||||
@ -146,22 +187,25 @@ See - https://keelingcurve.ucsd.edu/
|
||||
- test with hardware
|
||||
- verify timeout
|
||||
|
||||
|
||||
#### Should
|
||||
|
||||
- check 3000 PPM
|
||||
- fix SoftwareSerial - https://github.com/Arduino-CI/arduino_ci/issues/346
|
||||
|
||||
- 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?
|
||||
|
||||
#### Could
|
||||
|
||||
- investigate configurable timeout. now hardcoded 1 second.
|
||||
- 2 bytes + 2 functions.
|
||||
- extend unit tests
|
||||
- add type info for derived classes?
|
||||
- A .. E ?
|
||||
- save RAM? possible?
|
||||
|
||||
- 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
|
||||
|
||||
#### Won't
|
||||
|
||||
|
@ -0,0 +1,31 @@
|
||||
platforms:
|
||||
rpipico:
|
||||
board: rp2040:rp2040:rpipico
|
||||
package: rp2040:rp2040
|
||||
gcc:
|
||||
features:
|
||||
defines:
|
||||
- ARDUINO_ARCH_RP2040
|
||||
warnings:
|
||||
flags:
|
||||
|
||||
packages:
|
||||
rp2040:rp2040:
|
||||
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
|
||||
|
||||
compile:
|
||||
# Choosing to run compilation tests on 2 different Arduino platforms
|
||||
platforms:
|
||||
# - uno
|
||||
# - due
|
||||
# - zero
|
||||
# - leonardo
|
||||
# - m4
|
||||
# - esp32
|
||||
# - esp8266
|
||||
# - mega2560
|
||||
# - rpipico
|
||||
# external libraries
|
||||
libraries:
|
||||
# - "SoftwareSerial" does not work
|
||||
|
@ -0,0 +1,55 @@
|
||||
//
|
||||
// FILE: MHZCO2_sw_serial_timeout.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo
|
||||
// DATE: 2020-09-01
|
||||
|
||||
|
||||
#include "SoftwareSerial.h"
|
||||
#include "Arduino.h"
|
||||
#include "MHZCO2.h"
|
||||
|
||||
|
||||
const int TX = 4;
|
||||
const int RX = 5;
|
||||
SoftwareSerial ss(TX, RX);
|
||||
|
||||
|
||||
MHZ19B MHZ19B;
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("MHZCO2_LIB_VERSION: ");
|
||||
Serial.println(MHZCO2_LIB_VERSION);
|
||||
|
||||
MHZ19B.begin(&ss);
|
||||
ss.begin(9600);
|
||||
|
||||
MHZ19B.setTimeOut(200);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
int rv = MHZ19B.measure();
|
||||
Serial.print("Meas: ");
|
||||
Serial.println(rv); // 0 = OK, -10 = timeout, -11 = CRC
|
||||
|
||||
Serial.print("CO2: ");
|
||||
Serial.println(MHZ19B.getCO2());
|
||||
Serial.print("MCO2: ");
|
||||
Serial.println(MHZ19B.getMinCO2());
|
||||
Serial.print("Temp: ");
|
||||
Serial.println(MHZ19B.getTemperature());
|
||||
Serial.print("Accu: ");
|
||||
Serial.println(MHZ19B.getAccuracy());
|
||||
Serial.println();
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
@ -28,6 +28,9 @@ calibrateZero KEYWORD2
|
||||
calibrateSpan KEYWORD2
|
||||
calibrateAuto KEYWORD2
|
||||
|
||||
setTimeout KEYWORD2
|
||||
getTimeout KEYWORD2
|
||||
|
||||
|
||||
# Constants (LITERAL1)
|
||||
MHZCO2_LIB_VERSION LITERAL1
|
||||
|
@ -15,7 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/MHZCO2.git"
|
||||
},
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.1",
|
||||
"license": "MIT",
|
||||
"frameworks": "*",
|
||||
"platforms": "*",
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=MHZCO2
|
||||
version=0.2.0
|
||||
version=0.2.1
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino Library for MHZ series CO2 sensors.
|
||||
|
@ -54,6 +54,41 @@ unittest(test_constructor)
|
||||
}
|
||||
|
||||
|
||||
unittest(test_functions_no_measurement)
|
||||
{
|
||||
MHZCO2 A;
|
||||
|
||||
A.begin(&Serial);
|
||||
|
||||
// verify default
|
||||
assertEqual(0, A.getPPM());
|
||||
assertEqual(0, A.getCO2());
|
||||
assertEqual(0, A.getTemperature());
|
||||
assertEqual(0, A.getAccuracy());
|
||||
assertEqual(0, A.getMinCO2());
|
||||
}
|
||||
|
||||
|
||||
unittest(test_timeout)
|
||||
{
|
||||
MHZCO2 A;
|
||||
|
||||
A.begin(&Serial);
|
||||
|
||||
// verify default
|
||||
assertEqual(1000, A.getTimeOut());
|
||||
// just a value
|
||||
A.setTimeOut(2000);
|
||||
assertEqual(2000, A.getTimeOut());
|
||||
// zero should work.
|
||||
A.setTimeOut(0);
|
||||
assertEqual(0, A.getTimeOut());
|
||||
// default parameter
|
||||
A.setTimeOut();
|
||||
assertEqual(1000, A.getTimeOut());
|
||||
}
|
||||
|
||||
|
||||
unittest_main()
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user