「Parts:Sensor:MH-Z19C」の版間の差分
(→通信) |
|||
(同じ利用者による、間の48版が非表示) | |||
7行目: | 7行目: | ||
|- | |- | ||
! colspan="2" |Datasheet | ! colspan="2" |Datasheet | ||
− | |[https://www.winsen-sensor.com/d/files/infrared-gas-sensor/mh-z19c-pins-type-co2-manual-ver1_0.pdf MH-Z19C] | + | |[https://www.winsen-sensor.com/d/files/infrared-gas-sensor/mh-z19c-pins-type-co2-manual-ver1_0.pdf MH-Z19C] コマンド:CO2濃度受信, SelfCalibration |
+ | [https://www.winsen-sensor.com/d/files/infrared-gas-sensor/mh-z19b-co2-ver1_0.pdf MH-Z19B] ABC Logic Functionの説明(automatic calibration) | ||
+ | |||
+ | [https://www.winsen-sensor.com/d/files/PDF/Infrared%20Gas%20Sensor/NDIR%20CO2%20SENSOR/MH-Z19%20CO2%20Ver1.0.pdf MH-Z19] | ||
|- | |- | ||
! rowspan="2" |Accuracy | ! rowspan="2" |Accuracy | ||
18行目: | 21行目: | ||
! colspan="2" |3D data | ! colspan="2" |3D data | ||
|[https://robot-jp.com/share/index.php/s/FooIfPp8gJDLkge f3d(Fusion360), step] | |[https://robot-jp.com/share/index.php/s/FooIfPp8gJDLkge f3d(Fusion360), step] | ||
+ | |- | ||
+ | ! colspan="2" |Driver | ||
+ | |[https://github.com/nara256/mhz19_uart mhz19_uart] ※ESP32はHardwareSerial-UART2 | ||
|- | |- | ||
! rowspan="2" |販売店 | ! rowspan="2" |販売店 | ||
98行目: | 104行目: | ||
|- | |- | ||
|購入直後の最初の起動時 24時間 | |購入直後の最初の起動時 24時間 | ||
− | 条件 常温 | + | 条件 常温<BR /> |
− | |||
毎回の起動時 1分(この間は出力データもデタラメな値を示すので破棄する必要がある) | 毎回の起動時 1分(この間は出力データもデタラメな値を示すので破棄する必要がある) | ||
− | |||
|} | |} | ||
− | ''' | + | '''CO2測定間隔''' |
:{| class="wikitable" | :{| class="wikitable" | ||
|- | |- | ||
|測定間隔 2秒 | |測定間隔 2秒 | ||
− | + | PWM出力間隔 1秒 ただし次の測定値が確定するまで前の値を出力する。<BR /> | |
− | PWM出力間隔 1秒 ただし次の測定値が確定するまで前の値を出力する。 | ||
− | |||
デジタル出力 随時 ただし次の測定値が確定するまで前の値を出力する。 | デジタル出力 随時 ただし次の測定値が確定するまで前の値を出力する。 | ||
+ | |} | ||
+ | '''セルフキャリブレーション''' | ||
+ | :{| class="wikitable" | ||
+ | |- | ||
+ | |センサーが一定期間連続して動作した後、検出したCO2濃度に応じて自動的にゼロ点を校正する機能 | ||
+ | :校正周期 :電源投入時から 24 時間毎 | ||
+ | :校正するCO2濃度: 400ppm | ||
+ | :想定する用途 :オフィス環境、家庭環境 | ||
+ | :適さない用途 :農業用温室、農場、冷蔵倉庫 | ||
|} | |} | ||
122行目: | 133行目: | ||
|- | |- | ||
|ケースを拭き取れる溶剤 なし | |ケースを拭き取れる溶剤 なし | ||
− | 拭き取り方法 なし | + | 拭き取り方法 なし<BR />外装の材質 非公開 |
− | |||
− | 外装の材質 非公開 | ||
− | |||
+ | フィルタの材質 非公開<BR /> | ||
+ | <BR /> | ||
※メーカーは拭き掃除を許可していない。 | ※メーカーは拭き掃除を許可していない。 | ||
− | |||
|} | |} | ||
136行目: | 145行目: | ||
|- | |- | ||
|ケース 非公開 | |ケース 非公開 | ||
− | コネクタ出しタイプのコネクタ品名 非公開 | + | コネクタ出しタイプのコネクタ品名 非公開<BR /> |
− | + | :※推測:[http://www.wire-to-boardconnector.com/sale-10904946-1-25mm-pitch-shrouded-header-connector-2-pin-16-pin-right-angle-wire-connectors-vertical.html JVT connector] | |
− | |||
− | |||
|} | |} | ||
146行目: | 153行目: | ||
:{| class="wikitable" | :{| class="wikitable" | ||
|- | |- | ||
− | | | + | |(winsenによると)コマンドによるキャリブレーション機能入り(らしい)。 |
− | + | そのコマンド仕様は[https://www.winsen-sensor.com/d/files/PDF/Infrared%20Gas%20Sensor/NDIR%20CO2%20SENSOR/MH-Z19%20CO2%20Ver1.0.pdf MH-Z19]/B等過去機種の仕様を参照。 | |
− | + | ただし、機能したことがない。 | |
|} | |} | ||
160行目: | 167行目: | ||
|動作範囲 | |動作範囲 | ||
|5±0.5V | |5±0.5V | ||
+ | |} MHZ19Cは2秒周期で0.4秒のランプ点灯を繰り返す。 | ||
+ | :ランプが点灯する瞬間の大電流が流れるため、5V電源電圧が10ms程度の間Δ0.3V以上dropする事がある。 | ||
+ | :ここで言う電圧範囲は、どのタイミングの値の事を言っているのかも非公開。 | ||
+ | :おそらく発光開始から0.3~0.4秒のポイントで問題なければ精度に影響ないはず。電圧ドロップが大きすぎると中のCPU(16MHz)が誤動作するので、ほどほどに。 | ||
+ | : | ||
+ | |||
+ | |||
+ | '''CPU''' | ||
+ | :{| class="wikitable" | ||
+ | |- | ||
+ | |内部にはCPU(16MHz)が入っている。 | ||
|} | |} | ||
</blockquote> | </blockquote> | ||
− | == | + | == 通信 == |
− | + | とりあえずこれで動くけど、コマンドによるキャリブレーションが機能していない。Self-calibrationも未確認。<BR/> | |
− | + | 以下、理解して補足すれば、読み込みだけなら使えるプログラムです。<BR/> | |
<blockquote> | <blockquote> | ||
− | + | {| class="wikitable" | |
+ | |<syntaxhighlight lang="c++" style="border: 1px dashed gray;"> | ||
+ | /////// MHZ19C /////// | ||
+ | HardwareSerial mhz19(2); | ||
− | + | void mhz19_init(void){ | |
+ | delay(200); //電解コンデンサがチャージ完了するまで待つ | ||
+ | digitalWrite(pin_XCL103EN, 1); //mhz19の電源をONにする | ||
+ | delay(100); //電源が安定するのを待つ | ||
+ | mhz19.begin(9600); | ||
+ | //MHZ19C動作開始 ※5V用電解コンデンサは100μFにする事!470μFにするとXCL103が時々スタートしなくなる | ||
+ | digitalWrite(pin_whiteLED, 0); //calibで点灯、それ以外は消灯 | ||
+ | //mhz19setCalMode(1); //calmode=0:autocal=OFF / calmode=1:autocal=ON | ||
+ | } | ||
− | + | //返値:co2濃度、mhz19temp=温度、mhz19status=status | |
− | + | int mhz19readCO2() { // MH-Z19CからCO2濃度の値を読む<BR/> | |
+ | uint16_t co2Val; | ||
+ | byte ReadCO2Cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; | ||
+ | byte RetVal[9]; | ||
+ | while (mhz19.available())mhz19.read(); // 受信バッファクリア | ||
+ | memset(RetVal, 0x00, sizeof RetVal); // 変数をクリア | ||
+ | mhz19.write(ReadCO2Cmd, sizeof ReadCO2Cmd); // 測定コマンド送信 | ||
+ | mhz19.readBytes((char *)RetVal, sizeof RetVal); // 測定結果をMHZ19Cから受信 | ||
+ | if ((RetVal[0] == 0xff) && (RetVal[1] == 0x86)) { // 正常に読めた? 0xff=255 0x86=134 | ||
+ | co2Val = RetVal[2] * 256 + RetVal[3]; // CO2濃度を計算 | ||
+ | mhz19temp = RetVal[4];// - 40; // 内部温度 ※参考用 | ||
+ | mhz19status = RetVal[5]; // Status | ||
+ | } else { | ||
+ | co2Val = 0; // 異常値の場合 0 | ||
+ | }<BR/> | ||
+ | return co2Val; //返り値がCO2濃度:400-5000ppm。エラーなら0ppm | ||
+ | } | ||
− | + | //calmode=0 : セルフキャリブレーションON (ABC function) | |
+ | //calmode=1 : セルフキャリブレーションOFF | ||
+ | //calmode=2 : 今すぐキャリブレーション実施 | ||
+ | //calmode=3 : コマンドによるキャリブレーション ※HD端子を7秒LOWにする代わり (使用禁止:うまく動作できてない) | ||
+ | //NOTE:ZERO POINT is 400PPM, PLS MAKE SURE THE SENSOR HAD BEEN WORKED UNDER 400PPM FOR OVER 20MINUTES | ||
+ | void mhz19setCalMode(int calMode) { // ゼロ調モードを設定 | ||
+ | byte autocalOn[9] = {0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xE6}; | ||
+ | byte autocalOff[9] = {0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86}; | ||
+ | byte cmdCalib[9] = {0xFF, 0x01, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78}; | ||
+ | byte RetVal[9]; | ||
− | + | switch(calMode){ //Self-Calibration mode | |
+ | case 0: | ||
+ | mhz19.write(autocalOff, sizeof autocalOff); // OFF | ||
+ | Serial.println("CO2 Automatic Calibration mode : OFF"); | ||
+ | break; | ||
+ | case 1: | ||
+ | mhz19.write(autocalOn, sizeof autocalOn); // ON | ||
+ | Serial.println("CO2 Automatic Calibration mode : ON"); | ||
+ | break; | ||
+ | case 2: | ||
+ | mhz19.write(cmdCalib, sizeof cmdCalib); // キャリブレーション | ||
+ | Serial.println("Cal"); | ||
+ | calibration(); | ||
+ | break; | ||
+ | case 3: | ||
+ | mhz19.write(cmdCalib, sizeof cmdCalib); // コマンドによるキャリブレーション[NG] | ||
+ | Serial.println("CO2 Calibration by command : [x]"); | ||
+ | break; | ||
+ | default: | ||
+ | //何もしない | ||
+ | break; | ||
+ | } | ||
+ | mhz19.readBytes((char *)RetVal, sizeof RetVal); // clear read buffer | ||
+ | } | ||
− | + | void setup(){ | |
+ | mhz19_init(); | ||
+ | } | ||
+ | void loop(){ | ||
+ | int co2 = mhz19readCO2(); | ||
+ | sprintf(buf, "%d",co2); | ||
+ | Serial.println(buf); | ||
+ | delay(2000); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
− | + | == 経験からの対策 == | |
+ | 通信Error | ||
+ | <blockquote> | ||
+ | Core Debug LevelをDebug/Verboseとすると、通信するたびにDebug情報としてエラーの表示が現れる。<BR /> | ||
+ | {| class="wikitable" | ||
+ | |[E] addApbChangeCallback(): duplicate func=4000F8B7C arg=3FFBDF14 | ||
+ | |} | ||
+ | <BR /> | ||
+ | '''調査結果'''<BR /> | ||
+ | [https://github.com/nara256/mhz19_uart mhz19_uart]で通信するとRead/Write両方で上記エラーが毎回発生するけど機能上は問題ない。 | ||
− | + | [https://qiita.com/nara256/items/a3cecc5fbf043b2d042c 作者HP]<BR /> | |
+ | <BR /> | ||
+ | '''対策'''<BR /> | ||
+ | 上記のコードで通信すれば問題なし。(受信時のパリティーチェック省略) | ||
− | ・効果的な対策②:ESP32との接続配線を全て外すと問題が消えた。 | + | </blockquote> |
+ | ===== ノイズ ===== | ||
+ | <blockquote> | ||
+ | '''症状''' | ||
+ | :ESP32とMH-Z19CをUART&PWMの配線で接続すると、ESP32が定期的にリブートした。 | ||
+ | :リブートするのは起動から必ず一定の時間になっている。 | ||
+ | '''調査結果''' | ||
+ | :・起動からリブートまでの経過時間:100秒。1秒の誤差もない。 | ||
+ | :・電流との相関:CO2測定のためのランプ点滅周期とは無関係なタイミングでリブートする。 | ||
+ | :・Error表示(UART):リブート時のシリアル出力に出るメッセージでは、Flash Readができない記述になっている。 | ||
+ | :・効果的な対策①:ESP32のTXD端子出口と、ESP32のPWM受信端子に'''直列に100Ω'''を入れると問題が消えた。 | ||
+ | : 反射波が影響している可能性が高い。 | ||
+ | :・効果的な対策②:ESP32との接続配線を全て外すと問題が消えた。 | ||
'''原因の推測''' | '''原因の推測''' | ||
− | + | :MH-Z19Cとの通信部分に外部からのノイズが乗りやすい。 | |
− | MH-Z19Cとの通信部分に外部からのノイズが乗りやすい。 | + | :MH-Z19Cが不要なノイズを作っている可能性が高い。 |
− | + | :Wifi/Bluetoothかもしれない。(使ってないけど) | |
− | MH-Z19Cが不要なノイズを作っている可能性が高い。 | ||
− | |||
− | Wifi/Bluetoothかもしれない。(使ってないけど) | ||
'''対策''' | '''対策''' | ||
− | + | :ノイズが乗っても共振や反射波で誤動作レベルになりにくいように、終端抵抗を入れてみる。 | |
− | ノイズが乗っても共振や反射波で誤動作レベルになりにくいように、終端抵抗を入れてみる。 | + | :ESP32との通信部分(送信側)の配線は全て両端(ESP32側/MH-Z19C側)に100Ωを入れて反射波を抑える。 |
− | |||
− | ESP32との通信部分(送信側)の配線は全て両端(ESP32側/MH-Z19C側)に100Ωを入れて反射波を抑える。 | ||
'''結果''' | '''結果''' | ||
− | + | :この対策で問題が起きなくなった。 | |
− | この対策で問題が起きなくなった。 | + | :※ただし、確認済の機能や評価条件が少ないため、まだ要確認。 |
− | |||
− | ※ただし、確認済の機能や評価条件が少ないため、まだ要確認。 | ||
</blockquote> | </blockquote> | ||
211行目: | 314行目: | ||
<blockquote> | <blockquote> | ||
'''症状''' | '''症状''' | ||
− | :MH-Z19C内のランプが光るタイミングで+ | + | :MH-Z19C内のランプが光るタイミングで+5.0V電源電圧が約2V付近まで10μs程度の間だけ低下する。 |
:この時の電源はXCL103モジュール(秋月)+入出力に330μF追加。 | :この時の電源はXCL103モジュール(秋月)+入出力に330μF追加。 | ||
'''調査結果''' | '''調査結果''' | ||
218行目: | 321行目: | ||
:・電源モジュールをTDK製の[https://www.marutsu.co.jp/pc/i/74741/ CC10-0505SF-E]に変更するとドロップ時間が200ms程度にまで伸びて悪化した。 | :・電源モジュールをTDK製の[https://www.marutsu.co.jp/pc/i/74741/ CC10-0505SF-E]に変更するとドロップ時間が200ms程度にまで伸びて悪化した。 | ||
:・瞬間的な電流消費対策:電源IC(XCL103)の手前にインダクタ100μHを追加すると | :・瞬間的な電流消費対策:電源IC(XCL103)の手前にインダクタ100μHを追加すると | ||
− | : | + | : CPU側の電圧ドロップはなくなったが、Rebootは改善されなかった。 |
− | : | + | :・起動時にRebootするのはENにReset-IC(2.9V)を入れた事と、SPI-FLASHの動作不安定さが主な原因だった。 |
− | : | + | : ESP32のENにReset-ICを入れるとBootメッセージがUARTに出力されたり色々な事が起こるため除去した方が気楽。 |
− | : | + | :・XCL103の入力側に330μH+470μFを追加するとXCL103が起動しなくなった。 |
+ | : 追加条件を変えてみた。 | ||
+ | ::{| class="wikitable" | ||
+ | |+問題なかった組み合わせ<BR /> | ||
+ | <small>○:異常なし ×:Reboot</small> | ||
+ | | | ||
+ | !10μF | ||
+ | !100μF | ||
+ | !330μF | ||
+ | !470μF | ||
+ | |- | ||
+ | !0μH | ||
+ | |○ | ||
+ | |○ | ||
+ | |× | ||
+ | |× | ||
+ | |- | ||
+ | !10μH | ||
+ | | | ||
+ | |○ | ||
+ | |○ | ||
+ | |○ | ||
+ | |- | ||
+ | !33μH | ||
+ | | | ||
+ | | | ||
+ | |○ | ||
+ | |○ | ||
+ | |- | ||
+ | !100μH | ||
+ | | | ||
+ | |○ | ||
+ | |○ | ||
+ | |○ | ||
+ | |} | ||
+ | : 100μH以下以下であれば問題ない。 | ||
:・PCのUSBポートから電源を取っていたのを、単独USB充電器に変更してみたが、変化なし。 | :・PCのUSBポートから電源を取っていたのを、単独USB充電器に変更してみたが、変化なし。 | ||
: つまり、PCの電源起因の可能性は低い。 | : つまり、PCの電源起因の可能性は低い。 | ||
227行目: | 365行目: | ||
'''原因の推測''' | '''原因の推測''' | ||
:①スイッチング電源は電流0からの応答ではレスポンスが極端に悪化する特性がある。 | :①スイッチング電源は電流0からの応答ではレスポンスが極端に悪化する特性がある。 | ||
− | : | + | : その場合、微量な電流を常に負荷に流すようにすると改善されるはず。 |
:②入出力のコンデンサが大きいとチャージする時間が長くなるため、レスポンスが落ちて戻りにくくなる。 | :②入出力のコンデンサが大きいとチャージする時間が長くなるため、レスポンスが落ちて戻りにくくなる。 | ||
:③XCL103の短絡保護回路が働いて出力を止めている。 | :③XCL103の短絡保護回路が働いて出力を止めている。 | ||
+ | :④ESP32に追加で付けたReset-ICが誤動作している。 | ||
'''対策''' | '''対策''' | ||
:①漏れ電流:MH-Z19C用の+5V電源(+5VP)にLEDを付けて微弱な電流を流す。 | :①漏れ電流:MH-Z19C用の+5V電源(+5VP)にLEDを付けて微弱な電流を流す。 | ||
235行目: | 374行目: | ||
:②電流立ち上がりで高周波ノイズを除去しやすいように、 | :②電流立ち上がりで高周波ノイズを除去しやすいように、 | ||
: MH-Z19C手前のパスコン(XCL103出力側)をCE10μF×3に変更してみる。 | : MH-Z19C手前のパスコン(XCL103出力側)をCE10μF×3に変更してみる。 | ||
− | : | + | :③XCL103入力インダクタ・コンデンサを減らして、安全動作領域になるように変更する。 |
+ | :④Reset-IC除去。 | ||
'''結果''' | '''結果''' | ||
− | : | + | :① 問題なく動作した。 |
− | : | + | :② 問題なく動作した。 |
− | : | + | :③ 10μH+470μFが最もドロップ電圧とドロップ時間が少なかったため最適。 |
+ | :④ 起動時にRebootしなくなった。 | ||
</blockquote> | </blockquote> | ||
== 参考資料 == | == 参考資料 == | ||
− | + | <blockquote> | |
+ | 他のCO2センサーとの比較表 https://canair.io/docs/co2_comparative.html | ||
+ | |||
+ | 偽物の情報 https://emariete.com/en/co2-mh-z19b-fake-sensors-2/ | ||
+ | </blockquote> | ||
== 販売店 == | == 販売店 == | ||
− | + | <blockquote> | |
− | + | [https://akizukidenshi.com/catalog/g/gM-16142/ 秋月電子通商] 2480円 | |
+ | {| class="wikitable" | ||
|- | |- | ||
|Winsen社製品の正規取り扱い店。 | |Winsen社製品の正規取り扱い店。 | ||
254行目: | 400行目: | ||
技術サポート不可。(技術サポートは中国Winsen社が担当) | 技術サポート不可。(技術サポートは中国Winsen社が担当) | ||
|} | |} | ||
+ | </blockquote> | ||
+ | |||
+ | == 注意事項 == | ||
----[https://robot-jp.com/wiki/index.php 戻る] | ----[https://robot-jp.com/wiki/index.php 戻る] | ||
+ | <blockquote> | ||
+ | Aliexpressに類似品が多く出回っている。仕様が全く異なるため要注意。 | ||
+ | |||
+ | Winsen製であっても似たパッケージ・似たSPECが多い。 | ||
+ | |||
+ | 購入時には、pinタイプ/コネクタタイプ、測定範囲(400-5000ppm / 400-2000ppm)を選ぶ。 | ||
+ | |||
+ | ただし、コネクタの品名は非公開。 | ||
+ | |||
+ | </blockquote> | ||
+ | |} |
2023年2月25日 (土) 19:41時点における最新版
Name MH-Z19C メーカー Winsen Datasheet MH-Z19C コマンド:CO2濃度受信, SelfCalibration MH-Z19B ABC Logic Functionの説明(automatic calibration)
Accuracy CO2 ±(50ppm+5%) Temp ±---℃ 3D data f3d(Fusion360), step Driver mhz19_uart ※ESP32はHardwareSerial-UART2 販売店 日本 秋月電子通商 \2480 Amazon \2799
中国 Aliexpress winsen \2272/5p, \2360/1p Aliexpress mili technology $15.7/1p
Pin Function
仕様の補足
暖機時間 (Warm-up time)
購入直後の最初の起動時 24時間 条件 常温
毎回の起動時 1分(この間は出力データもデタラメな値を示すので破棄する必要がある)
CO2測定間隔
測定間隔 2秒 PWM出力間隔 1秒 ただし次の測定値が確定するまで前の値を出力する。
デジタル出力 随時 ただし次の測定値が確定するまで前の値を出力する。
セルフキャリブレーション
センサーが一定期間連続して動作した後、検出したCO2濃度に応じて自動的にゼロ点を校正する機能
- 校正周期 :電源投入時から 24 時間毎
- 校正するCO2濃度: 400ppm
- 想定する用途 :オフィス環境、家庭環境
- 適さない用途 :農業用温室、農場、冷蔵倉庫
拭き取り
ケースを拭き取れる溶剤 なし 拭き取り方法 なし
外装の材質 非公開フィルタの材質 非公開
※メーカーは拭き掃除を許可していない。
部材の情報
ケース 非公開 コネクタ出しタイプのコネクタ品名 非公開
- ※推測:JVT connector
コマンド
(winsenによると)コマンドによるキャリブレーション機能入り(らしい)。 そのコマンド仕様はMH-Z19/B等過去機種の仕様を参照。 ただし、機能したことがない。
電源電圧
MHZ19Cは2秒周期で0.4秒のランプ点灯を繰り返す。
精度保証範囲 5±0.1V 動作範囲 5±0.5V
- ランプが点灯する瞬間の大電流が流れるため、5V電源電圧が10ms程度の間Δ0.3V以上dropする事がある。
- ここで言う電圧範囲は、どのタイミングの値の事を言っているのかも非公開。
- おそらく発光開始から0.3~0.4秒のポイントで問題なければ精度に影響ないはず。電圧ドロップが大きすぎると中のCPU(16MHz)が誤動作するので、ほどほどに。
CPU
内部にはCPU(16MHz)が入っている。
通信
とりあえずこれで動くけど、コマンドによるキャリブレーションが機能していない。Self-calibrationも未確認。
以下、理解して補足すれば、読み込みだけなら使えるプログラムです。
/////// MHZ19C /////// HardwareSerial mhz19(2); void mhz19_init(void){ delay(200); //電解コンデンサがチャージ完了するまで待つ digitalWrite(pin_XCL103EN, 1); //mhz19の電源をONにする delay(100); //電源が安定するのを待つ mhz19.begin(9600); //MHZ19C動作開始 ※5V用電解コンデンサは100μFにする事!470μFにするとXCL103が時々スタートしなくなる digitalWrite(pin_whiteLED, 0); //calibで点灯、それ以外は消灯 //mhz19setCalMode(1); //calmode=0:autocal=OFF / calmode=1:autocal=ON } //返値:co2濃度、mhz19temp=温度、mhz19status=status int mhz19readCO2() { // MH-Z19CからCO2濃度の値を読む<BR/> uint16_t co2Val; byte ReadCO2Cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; byte RetVal[9]; while (mhz19.available())mhz19.read(); // 受信バッファクリア memset(RetVal, 0x00, sizeof RetVal); // 変数をクリア mhz19.write(ReadCO2Cmd, sizeof ReadCO2Cmd); // 測定コマンド送信 mhz19.readBytes((char *)RetVal, sizeof RetVal); // 測定結果をMHZ19Cから受信 if ((RetVal[0] == 0xff) && (RetVal[1] == 0x86)) { // 正常に読めた? 0xff=255 0x86=134 co2Val = RetVal[2] * 256 + RetVal[3]; // CO2濃度を計算 mhz19temp = RetVal[4];// - 40; // 内部温度 ※参考用 mhz19status = RetVal[5]; // Status } else { co2Val = 0; // 異常値の場合 0 }<BR/> return co2Val; //返り値がCO2濃度:400-5000ppm。エラーなら0ppm } //calmode=0 : セルフキャリブレーションON (ABC function) //calmode=1 : セルフキャリブレーションOFF //calmode=2 : 今すぐキャリブレーション実施 //calmode=3 : コマンドによるキャリブレーション ※HD端子を7秒LOWにする代わり (使用禁止:うまく動作できてない) //NOTE:ZERO POINT is 400PPM, PLS MAKE SURE THE SENSOR HAD BEEN WORKED UNDER 400PPM FOR OVER 20MINUTES void mhz19setCalMode(int calMode) { // ゼロ調モードを設定 byte autocalOn[9] = {0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xE6}; byte autocalOff[9] = {0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86}; byte cmdCalib[9] = {0xFF, 0x01, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78}; byte RetVal[9]; switch(calMode){ //Self-Calibration mode case 0: mhz19.write(autocalOff, sizeof autocalOff); // OFF Serial.println("CO2 Automatic Calibration mode : OFF"); break; case 1: mhz19.write(autocalOn, sizeof autocalOn); // ON Serial.println("CO2 Automatic Calibration mode : ON"); break; case 2: mhz19.write(cmdCalib, sizeof cmdCalib); // キャリブレーション Serial.println("Cal"); calibration(); break; case 3: mhz19.write(cmdCalib, sizeof cmdCalib); // コマンドによるキャリブレーション[NG] Serial.println("CO2 Calibration by command : [x]"); break; default: //何もしない break; } mhz19.readBytes((char *)RetVal, sizeof RetVal); // clear read buffer } void setup(){ mhz19_init(); } void loop(){ int co2 = mhz19readCO2(); sprintf(buf, "%d",co2); Serial.println(buf); delay(2000); }経験からの対策
通信Error
Core Debug LevelをDebug/Verboseとすると、通信するたびにDebug情報としてエラーの表示が現れる。
[E] addApbChangeCallback(): duplicate func=4000F8B7C arg=3FFBDF14
調査結果
mhz19_uartで通信するとRead/Write両方で上記エラーが毎回発生するけど機能上は問題ない。作者HP
対策
上記のコードで通信すれば問題なし。(受信時のパリティーチェック省略)ノイズ
症状
- ESP32とMH-Z19CをUART&PWMの配線で接続すると、ESP32が定期的にリブートした。
- リブートするのは起動から必ず一定の時間になっている。
調査結果
- ・起動からリブートまでの経過時間:100秒。1秒の誤差もない。
- ・電流との相関:CO2測定のためのランプ点滅周期とは無関係なタイミングでリブートする。
- ・Error表示(UART):リブート時のシリアル出力に出るメッセージでは、Flash Readができない記述になっている。
- ・効果的な対策①:ESP32のTXD端子出口と、ESP32のPWM受信端子に直列に100Ωを入れると問題が消えた。
- 反射波が影響している可能性が高い。
- ・効果的な対策②:ESP32との接続配線を全て外すと問題が消えた。
原因の推測
- MH-Z19Cとの通信部分に外部からのノイズが乗りやすい。
- MH-Z19Cが不要なノイズを作っている可能性が高い。
- Wifi/Bluetoothかもしれない。(使ってないけど)
対策
- ノイズが乗っても共振や反射波で誤動作レベルになりにくいように、終端抵抗を入れてみる。
- ESP32との通信部分(送信側)の配線は全て両端(ESP32側/MH-Z19C側)に100Ωを入れて反射波を抑える。
結果
- この対策で問題が起きなくなった。
- ※ただし、確認済の機能や評価条件が少ないため、まだ要確認。
電源電圧の低下
症状
- MH-Z19C内のランプが光るタイミングで+5.0V電源電圧が約2V付近まで10μs程度の間だけ低下する。
- この時の電源はXCL103モジュール(秋月)+入出力に330μF追加。
調査結果
- ・電圧低下のタイミングは常にランプが光り始める時。
- ・ランプの駆動は、2秒周期で毎回0.4秒だけ発光する。Max125mA。
- ・電源モジュールをTDK製のCC10-0505SF-Eに変更するとドロップ時間が200ms程度にまで伸びて悪化した。
- ・瞬間的な電流消費対策:電源IC(XCL103)の手前にインダクタ100μHを追加すると
- CPU側の電圧ドロップはなくなったが、Rebootは改善されなかった。
- ・起動時にRebootするのはENにReset-IC(2.9V)を入れた事と、SPI-FLASHの動作不安定さが主な原因だった。
- ESP32のENにReset-ICを入れるとBootメッセージがUARTに出力されたり色々な事が起こるため除去した方が気楽。
- ・XCL103の入力側に330μH+470μFを追加するとXCL103が起動しなくなった。
- 追加条件を変えてみた。
問題なかった組み合わせ
○:異常なし ×:Reboot10μF 100μF 330μF 470μF 0μH ○ ○ × × 10μH ○ ○ ○ 33μH ○ ○ 100μH ○ ○ ○
- 100μH以下以下であれば問題ない。
- ・PCのUSBポートから電源を取っていたのを、単独USB充電器に変更してみたが、変化なし。
- つまり、PCの電源起因の可能性は低い。
- ・USBケーブルを15cmまで短くしてみたが、変化なし。
原因の推測
- ①スイッチング電源は電流0からの応答ではレスポンスが極端に悪化する特性がある。
- その場合、微量な電流を常に負荷に流すようにすると改善されるはず。
- ②入出力のコンデンサが大きいとチャージする時間が長くなるため、レスポンスが落ちて戻りにくくなる。
- ③XCL103の短絡保護回路が働いて出力を止めている。
- ④ESP32に追加で付けたReset-ICが誤動作している。
対策
- ①漏れ電流:MH-Z19C用の+5V電源(+5VP)にLEDを付けて微弱な電流を流す。
- 白LED+100Ωで17.87mA(±5%で 17.13~18.69mA)が常に流れる。
- ②電流立ち上がりで高周波ノイズを除去しやすいように、
- MH-Z19C手前のパスコン(XCL103出力側)をCE10μF×3に変更してみる。
- ③XCL103入力インダクタ・コンデンサを減らして、安全動作領域になるように変更する。
- ④Reset-IC除去。
結果
- ① 問題なく動作した。
- ② 問題なく動作した。
- ③ 10μH+470μFが最もドロップ電圧とドロップ時間が少なかったため最適。
- ④ 起動時にRebootしなくなった。
参考資料
他のCO2センサーとの比較表 https://canair.io/docs/co2_comparative.html
販売店
秋月電子通商 2480円
Winsen社製品の正規取り扱い店。 長期供給保証なし。在庫のみ。量産非対応。
技術サポート不可。(技術サポートは中国Winsen社が担当)
注意事項
戻るAliexpressに類似品が多く出回っている。仕様が全く異なるため要注意。
Winsen製であっても似たパッケージ・似たSPECが多い。
購入時には、pinタイプ/コネクタタイプ、測定範囲(400-5000ppm / 400-2000ppm)を選ぶ。
ただし、コネクタの品名は非公開。