CO2濃度モニタリング機運の高まりを感じています。完成品のCO2miniとかはほぼ在庫切れ、banggoodとかaliexpressとかから買って利益を乗せて売るだけの怪しい中華製品がバッコバコに跳梁跋扈しています。そんななか、比較的安価で手に入るNDIR式のCO2濃度センサー、MH-Z19Cを秋月電子さんが販売開始しました:

今回はこれとM5StickCでモニタリングしていきましょう。大部分は以下のブログ記事のコードを流用していますが、使用ライブラリの記述がなかったのと、使ってるっぽいライブラリがMH-Z19C対応してなかったので修正しています。あと、データ取得頻度も30秒から5秒に変更しました。

 

ロジック部の元になったソースコード:

 

 

で、今回使うライブラリはこれです:

src/MHZ19_uart.hとsrc/MHZ19_uart.cppを直接ダウンロードしてきちゃいましょう。

そしたら、以下のソースコードをarduino IDEで作ります:

#include  <M5StickC.h>

#include "MHZ19_uart.h"

#define RX_PIN 36 // Rx pin which the MHZ19 Tx pin is attached to
#define TX_PIN 26 // Tx pin which the MHZ19 Rx pin is attached to

#define LCD_MODE_DIGIT 0
#define LCD_MODE_GRAPH 1

#define BRIGHTNESS 8

MHZ19_uart mhz19; // Constructor for library

bool lcdOn = true;
int lcdMode = LCD_MODE_DIGIT;

bool ledOn = false;
bool ledValue = false;
unsigned long nextLedOperationTime = 0;

unsigned long getDataTimer = 0;

int history[160] = {};
int historyPos = 0;

void setup() {
  M5.begin();
  M5.Axp.ScreenBreath(BRIGHTNESS);

  Serial.begin(9600); // Device to serial monitor feedback
  mhz19.begin(RX_PIN, TX_PIN);
  mhz19.setAutoCalibration(false);
  delay(3000);
  //  while( mhz19.isWarming() ) {
  //    Serial.print("MH-Z19 now warming up...  status:");
  //    Serial.println(mhz19.getStatus());
  //    delay(1000);
  //  }

  M5.Lcd.setRotation(1);
  render();

  pinMode(M5_LED, OUTPUT);
}

void loop() {
  auto now = millis();

  // Aボタン: モードを切り替える
  M5.update();
  if (M5.BtnA.wasPressed()) {
    lcdMode = (lcdMode + 1) % 2;
    render();
  }

  // Bボタン: 画面表示を ON/OFF する
  if (M5.BtnB.wasPressed()) {
    lcdOn = !lcdOn;

    if (lcdOn) {
      render();
      M5.Axp.ScreenBreath(BRIGHTNESS);
    } else {
      M5.Axp.ScreenBreath(0);
    }
  }

  if ((ledOn || !ledValue) && nextLedOperationTime <= now) { ledValue = !ledValue; digitalWrite(M5_LED, ledValue); // Lチカ if (ledValue) { nextLedOperationTime = now + 2000; } else { nextLedOperationTime = now + 800; } } if (now - getDataTimer >= 5000) {
    /* note: getCO2() default is command "CO2 Unlimited". This returns the correct CO2 reading even
      if below background CO2 levels or above range (useful to validate sensor). You can use the
      usual documented command with getCO2(false) */

    int co2ppm = mhz19.getPPM();
    int temp = mhz19.getTemperature();

    //    if (co2ppm > 0) {
    Serial.print("CO2 (ppm): ");
    Serial.print(co2ppm);
    Serial.print(", Temperature (C): ");
    Serial.println(temp);

    ledOn = co2ppm >= 1000;

    // 測定結果の表示
    historyPos = (historyPos + 1) % (sizeof(history) / sizeof(int));
    history[historyPos] = co2ppm;
    render();
    //    }

    getDataTimer = now;
  }
}

void render() {
  if (!lcdOn) {
    return;
  }

  // Clear
  int height = M5.Lcd.height();
  int width = M5.Lcd.width();
  M5.Lcd.fillRect(0, 0, width, height, BLACK);

  switch (lcdMode) {
  case LCD_MODE_DIGIT:
    M5.Lcd.drawString("CO2 [ppm]", 12, 0, 2);
    M5.Lcd.drawRightString("    " + (String) history[historyPos], width, 24, 7);
    break;
  case LCD_MODE_GRAPH:
    int len = sizeof(history) / sizeof(int);
    for (int i = 0; i < len; i++) {
      auto value = max(0, history[(historyPos + 1 + i) % len] - 400);
      auto y = min(height, (int)(value * (height / 1200.0)));
      auto color = min(255, (int)(value * (255 / 1200.0)));
      M5.Lcd.drawLine(i, height - y, i, height, M5.Lcd.color565(255, 255 - color, 255 - color));
    }
    break;
  }
}

 

できたらいったんファイルを保存し、できたフォルダ内に、最初にダウンロードしたMHZ19_uart.hとMHZ19_uart.cppを配置します。

それからarduinoIDEでソースコードをコンパイル&アップロードします。

  • Board: M5Stick-C
  • Upload Speed: 115200

 

ではMH-Z19CとM5 Stick-Cを接続しましょう:

  • GND – GND
  • VIN – 5V→
  • Tx – G36
  • Rx – G26

(左がMH-Z19Cのピンです)

たったこれだけ。簡単ですね。

実際に運用する前には、ゼロキャリブレーションを行った方が良いです。外気に20分以上放置したあと、MH-Z19CのHDピンとGNDピンを7秒以上つないだ状態にします。ゼロキャリブレーションが行われたときの二酸化炭素濃度を、外気の二酸化炭素濃度(400ppm)としてセンサーが設定されます。室内運用の場合は一度設定すればOKです。

二酸化炭素をモニタリングしながらいろいろ換気方法を試したのですが、個人的な正解は「キッチンの換気扇を24時間つけっぱなしにする」でした。窓を全開にするぐらい効果があるうえに、花粉とか気温変化の影響を受けにくいです。

関連記事

fitbitの睡眠スコアを90弱で安定させる良い睡眠を続ける簡単な方法

m1 ipad pro 12.9 2021のusb-cハブはコレがベスト

Time Machine不要!Macを11.2.3にダウングレードして原神をm1 macbook airでプレイする

【神軽量HMD】Avegant Glyph 改造: 瓶詰堂さんのaltglyphを作った

PC、iPad、Android、switchもドックいらず!あまりに万能なusb-cハブが最強だった

磯野~WSL2でCUDAしようぜ~

コメント

  1. アニモ

    参考にさせていただきながら開発している者です。ソースコードの1番最初の#includeの後には何が入るのでしょうか???
    それとも何も入れないのでしょうか?

    • Drunkar 作成者

      ありがとうございます。1行目は#include です。間違って消してしまっていたようでしたので修正しました!

  2. ても

    M5StickCとMH Z19Cの組み合わせでただりつきました。
    2点ほど不思議な動作がありました
    (1)1000超えたときにLチカが短周期で目に痛い。
    (2)3桁の間、表示が更新されない。

    原因は[if ((ledOn || !ledValue)] の行から センサーのコメントの行まで改行がされていない影響のようでした。
    おそらくWebに張り付けたときにそのあたりの改行がされなかったのだと思います。
    コードとしてらしい改行をしてみたところ、うまく動きました!

    大変有用な情報を公開いただきありがとうございます。

アニモ へ返信する コメントをキャンセル

メールアドレスが公開されることはありません。 が付いている欄は必須項目です