|
| 1 | +# MH-Z19 CO2 sensor driver for MicroPython. |
| 2 | +# MIT license; Copyright (c) 2018 Fredrik Strupe |
| 3 | + |
| 4 | +import machine |
| 5 | +import utime |
| 6 | + |
| 7 | + |
| 8 | +class TimeoutError(Exception): |
| 9 | + pass |
| 10 | + |
| 11 | + |
| 12 | +class MHZ19: |
| 13 | + """MH-Z19 CO2 sensor driver""" |
| 14 | + |
| 15 | + def __init__(self, pin, max_value=5000): |
| 16 | + """ |
| 17 | + Args: |
| 18 | + pin: the pin that the PWM pin on the MH-Z19 is connected to. |
| 19 | + max_value: upper bound of measuring range. usually 2000 or 5000. |
| 20 | + """ |
| 21 | + self.pin = pin |
| 22 | + self.max_value = max_value |
| 23 | + |
| 24 | + def _wait_on_condition(self, cond, timeout=5000): |
| 25 | + start = utime.ticks_ms() |
| 26 | + while not cond(): |
| 27 | + if utime.ticks_diff(utime.ticks_ms(), start) > timeout: |
| 28 | + raise TimeoutError |
| 29 | + |
| 30 | + def pwm_read(self): |
| 31 | + """Read CO2 value via PWM pin. |
| 32 | +
|
| 33 | + Reading usually takes 1-2 seconds. |
| 34 | +
|
| 35 | + Returns: |
| 36 | + CO2 value in ppm (parts per million), with an accuracy of |
| 37 | + ±(50 + result * 0.05) ppm. |
| 38 | + Raises: |
| 39 | + TimeoutError: if the reading takes more than 5 seconds. |
| 40 | + """ |
| 41 | + # Wait until a new cycle starts |
| 42 | + self._wait_on_condition(lambda: self.pin.value() == 0) |
| 43 | + |
| 44 | + # Measure high and low duration during cycle |
| 45 | + t_h = machine.time_pulse_us(self.pin, 1, 1500000) |
| 46 | + t_l = machine.time_pulse_us(self.pin, 0, 1500000) |
| 47 | + |
| 48 | + return self.max_value * (t_h - 2000) / (t_h + t_l - 4000) |
0 commit comments