「Parts:Sensor:MH-Z19C」の版間の差分

提供: robot-jp wiki
ナビゲーションに移動検索に移動
 
(同じ利用者による、間の34版が非表示)
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
MH-Z19B (Software関連の詳細だけ参照)
+
[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
119行目: 121行目:
 
:{| class="wikitable"
 
:{| class="wikitable"
 
|-
 
|-
|センサーが一定期間連続して動作した後、検出したCO2濃度に応じて自動的にゼロ点を校正する機能です。
+
|センサーが一定期間連続して動作した後、検出したCO2濃度に応じて自動的にゼロ点を校正する機能
 
:校正周期    :電源投入時から 24 時間毎
 
:校正周期    :電源投入時から 24 時間毎
 
:校正するCO2濃度: 400ppm
 
:校正するCO2濃度: 400ppm
131行目: 133行目:
 
|-
 
|-
 
|ケースを拭き取れる溶剤   なし
 
|ケースを拭き取れる溶剤   なし
拭き取り方法        なし<BR />
+
拭き取り方法        なし<BR />外装の材質         非公開
外装の材質         非公開<BR />
+
 
 +
フィルタの材質       非公開<BR />
 
<BR />
 
<BR />
 
※メーカーは拭き掃除を許可していない。
 
※メーカーは拭き掃除を許可していない。
150行目: 153行目:
 
:{| class="wikitable"
 
:{| class="wikitable"
 
|-
 
|-
|コマンドによるキャリブレーション機能入り。
+
|(winsenによると)コマンドによるキャリブレーション機能入り(らしい)。
そのコマンド仕様はMH-Z19Bの仕様を参照。
+
そのコマンド仕様は[https://www.winsen-sensor.com/d/files/PDF/Infrared%20Gas%20Sensor/NDIR%20CO2%20SENSOR/MH-Z19%20CO2%20Ver1.0.pdf MH-Z19]/B等過去機種の仕様を参照。
 +
ただし、機能したことがない。
 
|}
 
|}
  
163行目: 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>
 +
{| 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 />
 +
上記のコードで通信すれば問題なし。(受信時のパリティーチェック省略)
  
 +
</blockquote>
 
===== ノイズ =====
 
===== ノイズ =====
 
<blockquote>
 
<blockquote>
207行目: 322行目:
 
:・瞬間的な電流消費対策:電源IC(XCL103)の手前にインダクタ100μHを追加すると
 
:・瞬間的な電流消費対策:電源IC(XCL103)の手前にインダクタ100μHを追加すると
 
: CPU側の電圧ドロップはなくなったが、Rebootは改善されなかった。
 
: CPU側の電圧ドロップはなくなったが、Rebootは改善されなかった。
:・起動時にRebootするのはENにReset-IC(2.9V)を入れたのが主な原因だった。
+
:・起動時にRebootするのはENにReset-IC(2.9V)を入れた事と、SPI-FLASHの動作不安定さが主な原因だった。
: ESP32のENにReset-ICを入れるとBootメッセージがUARTに出力されたり色々な事が起こるため除去。
+
: ESP32のENにReset-ICを入れるとBootメッセージがUARTに出力されたり色々な事が起こるため除去した方が気楽。
 
:・XCL103の入力側に330μH+470μFを追加するとXCL103が起動しなくなった。
 
:・XCL103の入力側に330μH+470μFを追加するとXCL103が起動しなくなった。
 
: 追加条件を変えてみた。
 
: 追加条件を変えてみた。
:{| class="wikitable"
+
::{| class="wikitable"
|+問題なかった組み合わせ
+
|+問題なかった組み合わせ<BR />
 +
<small>○:異常なし ×:Reboot</small>
 
|
 
|
|10μF
+
!10μF
|100μF
+
!100μF
|330μF
+
!330μF
|470μF
+
!470μF
 
|-
 
|-
|0μH
+
!0μH
 
|○
 
|○
 
|○
 
|○
|
+
|×
|
+
|×
 
|-
 
|-
|10μH
+
!10μH
 
|
 
|
 
|○
 
|○
231行目: 347行目:
 
|○
 
|○
 
|-
 
|-
|33μH
+
!33μH
 
|
 
|
 
|
 
|
237行目: 353行目:
 
|○
 
|○
 
|-
 
|-
|100μH
+
!100μH
 
|
 
|
 
|○
 
|○
|
+
|
|
+
|
 
|}
 
|}
 
: 100μH以下以下であれば問題ない。
 
: 100μH以下以下であれば問題ない。
270行目: 386行目:
 
<blockquote>
 
<blockquote>
 
他のCO2センサーとの比較表  https://canair.io/docs/co2_comparative.html
 
他のCO2センサーとの比較表  https://canair.io/docs/co2_comparative.html
 +
 +
偽物の情報 https://emariete.com/en/co2-mh-z19b-fake-sensors-2/
 
</blockquote>
 
</blockquote>
  
299行目: 417行目:
  
 
</blockquote>
 
</blockquote>
 +
|}

2023年2月25日 (土) 19:41時点における最新版

Name MH-Z19C
メーカー Winsen
Datasheet MH-Z19C コマンド:CO2濃度受信, SelfCalibration

MH-Z19B ABC Logic Functionの説明(automatic calibration)

MH-Z19

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

Name Func pin MH-Z19C.jpg pin Name Func
V0 N.C.

内部3.3Vモニタ

1 6 Vin 電源入力

精度保証範囲 5V±0.1V

動作保証範囲 5V±5%

電流 Peak 125mA(2秒に1回)

電流 Average <40mA

Rx UART入力

9600bps

2 7 GND
Tx UART出力

9600bps

3 8 AOT N.C.
SR N.C. 4 9 PWM PWM出力

1秒毎に測定値を出力

ただし測定値は2秒毎に更新される

HD キャリブレーション入力

7sec以上Lowで設定

約400ppm

5

仕様の補足

暖機時間 (Warm-up time)

購入直後の最初の起動時 24時間

条件          常温
毎回の起動時      1分(この間は出力データもデタラメな値を示すので破棄する必要がある)


CO2測定間隔

測定間隔     2秒

PWM出力間隔  1秒 ただし次の測定値が確定するまで前の値を出力する。
デジタル出力  随時 ただし次の測定値が確定するまで前の値を出力する。


セルフキャリブレーション

センサーが一定期間連続して動作した後、検出したCO2濃度に応じて自動的にゼロ点を校正する機能
校正周期    :電源投入時から 24 時間毎
校正するCO2濃度: 400ppm
想定する用途  :オフィス環境、家庭環境
適さない用途  :農業用温室、農場、冷蔵倉庫


拭き取り

ケースを拭き取れる溶剤   なし

拭き取り方法        なし
外装の材質         非公開

フィルタの材質       非公開

※メーカーは拭き掃除を許可していない。


部材の情報

ケース               非公開

コネクタ出しタイプのコネクタ品名  非公開

※推測:JVT connector


コマンド

(winsenによると)コマンドによるキャリブレーション機能入り(らしい)。

そのコマンド仕様はMH-Z19/B等過去機種の仕様を参照。 ただし、機能したことがない。


電源電圧

精度保証範囲 5±0.1V
動作範囲 5±0.5V
MHZ19Cは2秒周期で0.4秒のランプ点灯を繰り返す。
ランプが点灯する瞬間の大電流が流れるため、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が起動しなくなった。
 追加条件を変えてみた。
問題なかった組み合わせ
○:異常なし ×:Reboot
10μ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

偽物の情報 https://emariete.com/en/co2-mh-z19b-fake-sensors-2/

販売店

秋月電子通商 2480円

Winsen社製品の正規取り扱い店。

長期供給保証なし。在庫のみ。量産非対応。

技術サポート不可。(技術サポートは中国Winsen社が担当)

注意事項


戻る

Aliexpressに類似品が多く出回っている。仕様が全く異なるため要注意。

Winsen製であっても似たパッケージ・似たSPECが多い。

購入時には、pinタイプ/コネクタタイプ、測定範囲(400-5000ppm / 400-2000ppm)を選ぶ。

ただし、コネクタの品名は非公開。