M5Stack+VSCode+MH-Z19D+DHT22で二酸化炭素濃度と温湿度を取得するよ
概要
リモートワークが続いているが、冬に入り窓は締め切り・・・
Co2センサーはずっとやってみたいテーマだったので、これを機に重い腰を上げる!
前に温湿度センサーをやったのはラズパイだったので、今回はM5Stackで。
ひとまず、温湿度センサーとCO2センサーを同時に接続して、画面に表示してみるテスト。
やったこと
M5Stackの環境を整備
Arduino IDEでも開発は十分にできるけど、VSCodeを入れた。
こちらの記事がとても良くまとまっていて良いです。
以前は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を入手。
バージョンの違いは以下がわかりやすい。
M5StackのI/Oは3.3V、MH-Z19Dも3.3Vで直接接続で問題なし。(電源は5V)
こちらのサイトに書いてあることがすべてです。
ハマったのが、VSCodeだとシリアルモニタがうまくうごかない・・・?
こちらのサイトにあるようにシリアルモニタを表示して、COMポート番号も合っているけど、出力されない・・・
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にも。
ブレッドボードの手持ちがなく、配線雑ですが、一応動きました。
その後
しばらく動かしっぱなしにしていたら、400~410PPMしか指さなくなった。
挙動的には、室内の濃度でvoid calibrateZero()
されてしまった・・・?
最低値が400ppmなので、ほぼ常に400を指すみたい。
void setAutoCalibration(bool autocalib)
は指定しているが、何かのきっかけでキャリブレーションされてしまったのかな。
とりあえず、外気でキャリブレートを実施。
こちらを参考に。
キャリブレート後、値が1400ppm近くまで線形に上昇、その後数値が下がってきて、正常値と思われる830ppmまで下がった。
最初は値が安定しないみたい。(最初に動作させたときにそんな挙動しなかったけど、そもそも値が怪しかった可能性・・・)
データシートによると、プレヒート3分とあるので、この間は値の読み捨てが必要そう。
今後
値が取れることがわかったので、数値をクラウドに上げて、グラフ化やアラートの通知を実装したい。
AWS IoTを使ってみるのも目標。
Discussion