秋月電子で取り扱いの始まったCO2センサーMH-Z19CをArduino Nano Everyで使ってみました。
MH-Z19Cについて
MH-Z19CはNDIR方式のCO2センサで、電源電圧は5.0±0.1V、データの出力はPWMかUART(3.3Vで5.0Vにも対応)です。測定できる範囲はPWMを使うと公称値は400~2000ppm(実測では400~5000ppm)、UARTでは400~5000ppmです(CO2濃度は大気中で約400ppm、室内で約1000ppm、呼気で約30000ppmが目安)。ピンヘッダは2.54mmピッチですが、ピンヘッダとピンヘッダとの間隔が合わずユニバーサル基板に挿すのは難しいので注意してください。
ここでは5V駆動のArduino Nano Everyを使い、PWMとUART両方のデータを読んでみます。
ハードウェア
使ったもの
- MH-Z19C
- Arduino Nano Every
- 5V出力昇圧DCDCコンバーターとコンデンサー
Arduinoの5V OUTピンの電圧を測ると4.72-4.78Vでセンサーの電圧の範囲から外れていたので、一応4.9~5.1V出力(実測4.98V)のDCDCコンバーターと100μFのコンデンサーをつけました。
接続
MH-Z19C | |
---|---|
Vin | DCDCコンバーター ← Arduino 3.3V |
GND | Arduino GND |
PWM | Arduino A7 |
Hd | Arduino A6 |
Rx | Arduino TX1 |
Tx | Arduino RX1 |
ソフトウェア
MH-Z19Cの仕様
データシートはここで読めます。以下の画像はデータシートのものです。
UART
UARTでCO2濃度の読み取りと自動キャリブレーションの設定ができます。
PWM
データシートでは上のようになっていますが、Cppm=5*(パルス幅[ms]-1.2)とするとUARTと同じデータが読み込めました。Arduino Nano EveryのpulseInかセンサーのPWM出力のどちらかが原因だと思います。
手動キャリブレーションはHdピンを使うのでPWMでもできますが、自動キャリブレーションの設定はPWMだけではできません。デフォルトでは24時間ごとに自動キャリブレーションが行われます。(キャリブレーション時にどんな濃度でもそれを400ppmと認識するのではなく、24時間経ったあたりで400ppmに近い状態と判断するとキャリブレーションを行うようです)
プログラム
uint16_t uartco2;
unsigned long pwmco2;
bool reset = false;
byte ReadCO2[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
byte SelfCalOn[9] = {0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xE6};
byte SelfCalOff[9] = {0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86};
byte retval[9];
void setup() {
pinMode(A7, INPUT);
pinMode(A6, OUTPUT);
Serial.begin(9600);
Serial.print("400ppm");
Serial.print(",");
Serial.print("UART");
Serial.print(",");
Serial.println("PWM");
delay(2000);
Serial1.begin(9600);
Serial1.write(SelfCalOn,sizeof SelfCalOn);
}
void loop() {
//PWMでデータ取得
pwmco2=pulseIn(A7,HIGH,2000000);
//UARTでデータ取得
Serial1.write(ReadCO2,sizeof ReadCO2);
Serial1.readBytes((char *)retval, sizeof retval);
uartco2 = retval[2]*256 + retval[3];
//PCに送信
Serial.print(2*(202000-2000)/1000);
Serial.print(",");
Serial.print(uartco2);
Serial.print(",");
Serial.println(5*(pwmco2-1200)/1000);
delay(100);
//起動20分後手動キャリブレーション
if(millis()>1200000 && !reset){
digitalWrite(A6,LOW);
delay(8000);
digitalWrite(A6,HIGH);
reset=true;
}
}
測定結果
Arduino IDEのシリアルプロッタを使って可視化しました。縦軸がCO2濃度[ppm],横軸が起動からの時間(1が100ms)です。