Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mk-fg/mpy-mhz19-co2-eink-logger
DIY CO2 sensor device with timestamped log of its measurements on a persistent EInk screen
https://github.com/mk-fg/mpy-mhz19-co2-eink-logger
air-quality co2 diy-electronics eink epaper mcu meter mh-z19 micropython python rp2040 rtc sensor
Last synced: about 1 month ago
JSON representation
DIY CO2 sensor device with timestamped log of its measurements on a persistent EInk screen
- Host: GitHub
- URL: https://github.com/mk-fg/mpy-mhz19-co2-eink-logger
- Owner: mk-fg
- License: wtfpl
- Created: 2024-09-04T21:02:57.000Z (2 months ago)
- Default Branch: master
- Last Pushed: 2024-09-11T15:25:50.000Z (2 months ago)
- Last Synced: 2024-09-30T07:07:34.826Z (about 2 months ago)
- Topics: air-quality, co2, diy-electronics, eink, epaper, mcu, meter, mh-z19, micropython, python, rp2040, rtc, sensor
- Language: Python
- Homepage:
- Size: 317 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: COPYING
Awesome Lists containing this project
README
Micropython MH-Z19x CO2 EInk Logger
===================================Micropython script for running an autonomous CO2 (CO₂, [Carbon Dioxide]) meter
device, printing timestamped log of its measurements on a persistent EInk screen
(or ePaper one actually).Components involved:
- RPi-Pico-like rp2040 board running [micropython firmware].
- [Winsen MH-Z19E NDIR CO2 Sensor], or any other MH-Z19 one.
- WaveShare 3-color (black-white-red) [2.13inch e-Paper HAT (B) V4] display.
- Analog Devices (ex Dallas Semiconductor) [DS3231 RTC] with a battery.
- 5V ± 0.1V power supply - [needs to be this stable for MH-Z19C+ sensors].This particular small display/layout fits ~25 lines of readings
(some 6-8h at default 20min intervals).
EInk display keeps the info even when powered-off, but it does not get
stored anywhere else, so will be lost when it's cleared (e.g. on next use).Intended use is to plug or drop the thing with a powerbank in a place
temporarily, to pick it up and check how CO2 levels vary there over time later.[Carbon Dioxide]: https://en.wikipedia.org/wiki/Carbon_dioxide
[micropython firmware]: https://micropython.org/
[Winsen MH-Z19E NDIR CO2 Sensor]:
https://www.winsen-sensor.com/sensors/co2-sensor/mh-z19e.html
[2.13inch e-Paper HAT (B) V4]:
https://www.waveshare.com/wiki/2.13inch_e-Paper_HAT_(B)_Manual
[DS3231 RTC]: https://www.analog.com/en/products/ds3231.html
[needs to be this stable for MH-Z19C+ sensors]:
https://emariete.com/en/sensor-co2-mh-z19b/#Variacion_con_el_voltaje_de_alimentacionTable of Contents for this README:
- [How to use](#hdr-how_to_use)
- [Optional features](#hdr-optional_features)
- [Disabling sensor zero-point self-calibration]
- [Display average (median) of multiple sensor readings]
- [CO2 PPM threshold labels](#hdr-co2_ppm_threshold_labels)
- [Pre-byte-compile main script](#hdr-pre-byte-compile_main_script)
- [Helper scripts](#hdr-helper_scripts_and_debugging)
- [Links](#hdr-links)[Disabling sensor zero-point self-calibration]:
#hdr-disabling_sensor_zero-point_self-calibration
[Display average (median) of multiple sensor readings]:
#hdr-display_average_median_of_multiple_senso.f3RiRepository URLs:
-
-
-It's just one self-contained [main.py] micropython script, using an
[ini configuration file] with a list of pins and tunable parameters.One possible wiring diagram for e.g. [RPi Pico (rp2040) board],
and pins/interfaces from [config.example.ini] file:![WireViz rp2040 wiring diagram][]
(generated by `wireviz -fs rp2040-wiring.yaml`
from [rp2040-wiring.yaml] file using [WireViz tool])Screen used in this script is a hat/cape specific to RPi Pico pin layout,
so for other boards would need to either be connected in a more complicated way,
or different screen and code for updating it used.[main.py]: main.py
[ini configuration file]: config.example.ini
[RPi Pico (rp2040) board]: https://pico.pinout.xyz/
[config.example.ini]: config.example.ini
[rp2040-wiring.yaml]: rp2040-wiring.yaml
[WireViz rp2040 wiring diagram]:
https://mk-fg.github.io/mpy-mhz19-co2-eink-logger/rp2040-wiring.svg
[WireViz tool]: https://github.com/wireviz/WireViz/Main script can be configured, uploaded and run like this:
``` console
## Upload micropython firmware to the device, install "mpremote" tool% cp config.example.ini config.ini
## Edit that config.ini file, to setup local device/network parameters% mpremote cp config.ini :
% mpremote run main.py
## Should either work or print some errors to console## To setup this to run on board boot
% mpremote cp main.py :
% mpremote reset
```Running it should clear the screen on start, then wait for sensor `init-delay`
(aka "preheat time", 3-4 minutes by default), then get and add every new sensor
readings with configured `interval` value (15-20 min).Some less obvious features are default-disabled in the configuration file,
to keep default operation most straightforward, but can be useful,
if you understand what these do.
### Disabling sensor zero-point self-calibration(also sometimes referred to as ABC - Automatic Baseline Correction mode)
Default configuration keeps it enabled, as it might not be obvious/possible to
do manually, but afaik it's better to do manually, unless sensor runs in a space
that is expected to be well-ventilated at least once a day, which is where it
sets its baseline from every 24 hours.Manual calibration is easy - set `self-calibration = no` in the config file,
let sensor run for 20+ minutes in (fresh) outdoor air, then connect its HD pin
to the ground for 7+ seconds.
Next PPM readings should be 400 or so, indicating that it set its 400ppm level
from that air. Datasheet recommends doing this at least every 6 months.See [Bible of MH-Z19x CO2 sensors] for a lot more details on all this.
Also, if sensor is off in outdoor air even after calibration, there is
`ppm-offset` option to add/subtract a fixed value from it, though maybe
it's better to replace it in that case - might be off in more than one way.[Bible of MH-Z19x CO2 sensors]: https://emariete.com/en/sensor-co2-mh-z19b/
### Display average (median) of multiple sensor readingsConfig has default-empty `median-read-delays` option, which allows to do that.
Presumably sensor itself tracks some kind of average, but I don't have good data
on that, so if you want to have more reliable "not a fluke" reading, can take
multiple samples within an interval and take the median one.["median" value] is the one you'd get in the middle of a sorted list of samples.\
E.g. with `[654, 1210, 641, 657, 650]` list of readings, when sorted, it'd look
like this - `[641, 650, 654, 657, 1210]`, and median value there is `654`,
disregarding a likely-bogus `1210` sample in this instance.It is disabled by default, to present most intuitive single-sample value,
without any extra processing like this.["median" value]: https://en.wikipedia.org/wiki/Median
`[co2-ppm-thresholds]` section allows to set different labels that are printed
in rightmost column after CO₂ PPM concentration values, to visually highlight
any issues with those, so that one can easily tell if these were ok/good/bad/etc
at a glance.Defaults are listed in [config.example.ini] and at the top of [main.py] script.
### Pre-byte-compile main scriptNot that important here, will only make it startup some ms faster and use less
memory, which it isn't really using much anyway.Follow [instructions from rp2040-sen5x-air-quality-webui-monitor project],
just maybe use co2log.mpy instead of aqm.mpy filename for clarity.[instructions from rp2040-sen5x-air-quality-webui-monitor project]:
https://github.com/mk-fg/rp2040-sen5x-air-quality-webui-monitor#hdr-setup_to_auto-run_efficiently_as_.mpy_file
## Helper scripts and debuggingEvery component can have `verbose = yes` option in the config file to enable
verbose logging to USB/UART console - wherever micropython dumps output by default.
[mpremote] or any other serial console tool can be used to see these logs as
script produces them.Repository also has couple scripts for testing and configuring individual components.
[mpremote]: https://docs.micropython.org/en/latest/reference/mpremote.html
**[edp-png.py]**
Regular-python script to use with `test-export = yes` screen-config option,
to convert and see bitmaps output to console (instead of display) as PNG files.
Related `test-fill = yes` option can be used to also generate fake data to
test various text layout and graphical tweaks.For example, to run the script, dump images to `test.b64` file, then parse it
and see a last display state as PNG image (using common [feh] image viewer):```
mpremote run main.py | tee test.b64
./edp-png.py -i test.b64 -o test.png && feh --zoom 400 test.png
```Requires [python "pillow" module] (aka PIL) to make PNG.
[edp-png.py]: edp-png.py
[feh]: https://wiki.archlinux.org/title/Feh
[python "pillow" module]: https://pypi.org/project/pillow/**[rtc-set.py]**
Script to set correct time on Real-Time Clock module, using mpremote from console:
```
tt=`python -c 'import time; print((time.localtime()[:-1]))'` && \
sed "s/tt_now =.*/tt_now = $tt/" rtc-set.py > rtc-set.py.tmp && \
mpremote a1 run rtc-set.py.tmp
```These three chained commands get the current localtime tuple for the script, use
`sed` to put that onto `tt_now = ...` line in it, then run the script to set time.It parses same `config.ini` file for `[rtc]` section i2c/pin info on device, if any.
Will read and print RTC time back after updating it.Local time is used for RTC (as opposed to more conventional UTC) to avoid needing
to configure timezones and their DST quirks, so in timezones with DST, such time
adjustment has to be run every six months (or TZ offsets handling added to main.py).[rtc-set.py]: rtc-set.py
- [The Bible of MH-Z19x CO2 sensors] - great rundown of everything related
to these devices (up to MH-Z19D variant), including all sorts of quirks.- [WifWaf/MH-Z19 driver for MH-Z19x CO2 sensors] - not used here,
but has a good amount of technical and protocol information and
documentation on these devices, which datasheets lack.- [Waveshare ePaper Display "Precautions" section] - for recommendations on
minimum refresh interval, long-term storage, etc - to avoid damaging it.- [ESPHome] - more comprehensive home automation system, which also supports
this family of sensors (among many others) connected to microcontrollers,
for a more complex setup to see/control everything in a centralized manner.- [rp2040-sen5x-air-quality-webui-monitor] - similar project to monitor
particulate matter (PM) air pollution via autonomous device.[The Bible of MH-Z19x CO2 sensors]: https://emariete.com/en/sensor-co2-mh-z19b/
[WifWaf/MH-Z19 driver for MH-Z19x CO2 sensors]: https://github.com/WifWaf/MH-Z19
[Waveshare ePaper Display "Precautions" section]:
https://www.waveshare.com/wiki/2.13inch_e-Paper_HAT_(B)_Manual#Precautions
[ESPHome]: https://esphome.io/components/sensor/mhz19.html
[rp2040-sen5x-air-quality-webui-monitor]:
https://github.com/mk-fg/rp2040-sen5x-air-quality-webui-monitor