😸

M5Stack+VSCode+MH-Z19D+DHT22で二酸化炭素濃度と温湿度を取得するよ

2021/12/11に公開

概要

リモートワークが続いているが、冬に入り窓は締め切り・・・
Co2センサーはずっとやってみたいテーマだったので、これを機に重い腰を上げる!
前に温湿度センサーをやったのはラズパイだったので、今回はM5Stackで。
ひとまず、温湿度センサーとCO2センサーを同時に接続して、画面に表示してみるテスト。

やったこと

M5Stackの環境を整備

Arduino IDEでも開発は十分にできるけど、VSCodeを入れた。
こちらの記事がとても良くまとまっていて良いです。
https://qiita.com/OharanD/items/bb8359b986dc24d68636

以前はPlatformIOを使う事が多かったと思うけど、最近はVSCodeの拡張モジュールとしてArduinoさえ入れれば、M5Stack開発は快適。
ちなみに、サンプルコードはコマンドパレット(F1キー)からArduino: Examplesで参照できる。

あとは、Github上で空のリポジトリを作成して、VSCode側で「ソース管理」アイコンからGithubリポジトリを参照して、フォルダを指定すれば開発環境が出来上がり。
.gitignoreファイルを作成して、.vscode/と書いておくと、設定ファイルがgit管理から除外されるので良きです。

DHT22の動作確認

まずは過去に前バージョンのDHT11をM5Stackで接続したことがあるので、DHT22を接続テストしてみる。
dht11のときのコード5行目をDHT22に修正。
#define DHTTYPE DHT22
問題なく動作した。

MH-Z19Dの動作確認

MH-Z19シリーズはAから始まりB,C,Dまでのリビジョンがある。
今回はAliExpressで最新のDを入手。

バージョンの違いは以下がわかりやすい。
https://toccho.net/2021/09/25/mh-z19d-arudino/
CとDはあまり差はない?
M5StackのI/Oは3.3V、MH-Z19Dも3.3Vで直接接続で問題なし。(電源は5V)
 
こちらのサイトに書いてあることがすべてです。
https://qiita.com/nara256/items/a3cecc5fbf043b2d042c

 
ハマったのが、VSCodeだとシリアルモニタがうまくうごかない・・・?
こちらのサイトにあるようにシリアルモニタを表示して、COMポート番号も合っているけど、出力されない・・・
https://qiita.com/motamura/items/87285434e520c504f2e2
Arduino IDEのシリアルモニタだと、ちゃんと表示される。
最初これで動作していないかと思って焦った。

LCDで温度、湿度、二酸化炭素濃度を表示

以前のコードとサンプルコードをほげほげして、LCDに表示。
人に見せるコードではないけど、以下のような感じ。

#include <M5Stack.h>
#include <DHT.h>
#include <MHZ19_uart.h>

#define DHTPIN 5
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

const int rx_pin = 16; //Serial rx pin no
const int tx_pin = 17; //Serial tx pin no

MHZ19_uart mhz19;

void setup()
{
  dacWrite(25, 0); // スピーカーのノイズ対策

  M5.begin();
  dht.begin();
  mhz19.begin(rx_pin, tx_pin);
  mhz19.setAutoCalibration(false);

  M5.Lcd.setTextSize(5);

  delay(10 * 1000); //
}

void loop() {

  delay(3000);

  // 値の取得
  float temperature = dht.readTemperature(); // 温度を取得
  float humidity = dht.readHumidity(); // 湿度を取得

  int co2ppm = mhz19.getCO2PPM();

  // 画面描画
  M5.Lcd.setCursor(20,20);
  M5.Lcd.printf("%2.0f C",temperature);
  M5.Lcd.setCursor(20,70);
  M5.Lcd.printf("%2.0f",humidity);
  M5.Lcd.println(" %");

  M5.Lcd.setCursor(20,120);
  M5.Lcd.print(co2ppm);
  M5.Lcd.println(" ppm  ");
}

こんなコードですが、一応Githubにも。
https://github.com/ka-zuu/m5stack_mh-z19_dht22_test

ブレッドボードの手持ちがなく、配線雑ですが、一応動きました。

その後

しばらく動かしっぱなしにしていたら、400~410PPMしか指さなくなった。
挙動的には、室内の濃度でvoid calibrateZero()されてしまった・・・?
最低値が400ppmなので、ほぼ常に400を指すみたい。
void setAutoCalibration(bool autocalib)は指定しているが、何かのきっかけでキャリブレーションされてしまったのかな。

とりあえず、外気でキャリブレートを実施。
こちらを参考に。

キャリブレート後、値が1400ppm近くまで線形に上昇、その後数値が下がってきて、正常値と思われる830ppmまで下がった。
最初は値が安定しないみたい。(最初に動作させたときにそんな挙動しなかったけど、そもそも値が怪しかった可能性・・・)

データシートによると、プレヒート3分とあるので、この間は値の読み捨てが必要そう。
https://www.winsen-sensor.com/d/files/PDF/Infrared Gas Sensor/NDIR CO2 SENSOR/MH-Z19 CO2 Ver1.0.pdf

今後

値が取れることがわかったので、数値をクラウドに上げて、グラフ化やアラートの通知を実装したい。
AWS IoTを使ってみるのも目標。

GitHubで編集を提案

Discussion