先日入手した、CO2 Sensor Module(MH-Z19C)をシリアル接続して値を取ってみた。普通にデータを取得すると以下のような値で、これは高すぎると思われる。
sensing CO2 ['0xff', '0x86', '0x7', '0x89', '0x46', '0x0', '0x0', '0x0', '0xa4'] value:1929 (0789H)
単純に、上位8bit+下位8bitで演算した結果がCO2濃度(PPM)らしいのですが、、CO2濃度が1929ppmってこれが本当なら危険なぐらいにCO2濃度が高い。キャリブレーションをやり直すか、なんかその辺がおかしいのではと思える。コマンドでもキャリブレーション(Zero Point On/Off?)を指定できるらしいので、、コマンド経由で指示するか。。
マニュアルでは「デフォルトでAuto-CalibrationがONに設定されていて、24H周期でキャリブレーションがなされる」と読み取ったのだが、、手っ取り早くPin1(HD; zero point calibration)を一定時間Lに固定してCalibrationを実行させた。現在は404ppmとなっている。
sensing CO2 ['0xff', '0x86', '0x1', '0x94', '0x47', '0x0', '0x0', '0x0', '0x9e'] value:404 (0194H)
電源投入後に、HDピンをLに落とす機能を作るべきかどうするか、、マニュアルでは24時間周期でZero Point Calibrationが実行されると書かれているので、それを信じて今は実装しない。今回作成したCO2Sensor(MH-Z19C)用のライブラリは以下*1
from machine import UART from machine import Pin import utime uart0 = None READ_CO2 = bytes((0xff, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79)) SENSOR_TX_PIN = 16 SENSOR_RX_PIN = 17 def setup_CO2_sensor(): global uart0 uart0 = UART(0, baudrate=9600, tx=Pin(SENSOR_TX_PIN), rx=Pin(SENSOR_RX_PIN)) def get_co2_sensing(): value = 0 uart0.write(READ_CO2) data = uart0.read() if data and len(data) == 9: value = data[2] << 8 value += data[3] return value def get_check_sum(packet): checksum = 0 for data in packet[1:]: # to skip Start Byte(0xff), use [1:] checksum += data checksum &= 0xff if checksum == 0: return 0 else: return 0x100 - checksum # # set calibration for Zero Point On/Off # def set_calibration(cb_zp_on=True): calib_zp = bytearray((0xff,0x01,0x79,0x00,0x00,0x00,0x00,0x00,0x00)) if cb_zp_on: calib_zp[3] = 0xa0 else: calib_zp[3] = 0x00 calib_zp[-1] = get_check_sum(calib_zp[-1:]) uart0.write(calib_zp) def co2_monitoring(): while True: print("sensing CO2") value = get_co2_sensing() print(f"value:{value:d} ({value:04x}H)") utime.sleep(3)
先日AppSheetで作成した部屋の空気質の見える化アプリにCO2を加えた。夏なので窓開けっぱなしのせいか、ずっと400ppmを維持している。
■関連URL
MH-Z19Cの仕様書
https://www.winsen-sensor.com/d/files/mh-z19c-pins%26terminal-type-co2-manual(ver1_2).pdf
ちなみに、、checksumの実装例がC言語で掲載されているが、これは間違っていると思う(最後にchecksum += 1が必要では?)