Blynkローカルサーバーを立ち上げてBlynk legacy が使い放題になったので、外気温に限らず各部屋の温度も表示させたりしています。
Raspberry Pi Pico を使用したCO2モニターを作成しましたが、今回は ESP8266 を使用してBlynkでうまく表示出来るかやってみます。
Rspberry Pi Pico を使用してCO2モニターを作成した記事。
どの様な仕様にするか
1. 1.3インチのOLEDにCO2濃度を表示させる。
2. Blynkで表示させるために作成した温度/湿度/気圧計からデータを取得する。
3. Blynkのスマフォ画面には温度・湿度・気圧・CO2濃度・時刻・リセットボタン・キャリブレーションボタン などを表示する。
4. CO2濃度に対応するLED点滅表示も行う、4段階表示。
5. 以前作成したCO2モニターのケースを修正して組み込む。
※ このプロジェクトはBlynk_legacy用です、Blynk_Local_Server を運用して動作させています、新バージョンでは試しておりません。
使用パーツ
CO2 センサーは MH-Z19E を使用します
Pico W を使用して作成したCO2モニターにはMH-Z19Cを使用しましたが、CとEのデーターの比較も行いたいと思います。
OLED 1.3inch SH1106driver White を使用します。
降圧モジュール
電源電圧が5.24Vと高いのでCO2モジュールの許容範囲に下げるため使用しました。
その他
3mm LED 4色、 2KΩ抵抗、USB-Cメス電源コネクター、ユニバーサル基板 など。
以前作成した温度/湿度/気圧計
Blynkで表示させるために作成した温度計のAUTH_TOKEN を、CO2モニターのプロジェクトAUTH_TOKENに変更してCO2プロジェクトで温度・湿度・気圧データーを表示させるようにします。
プログラム
CO2 Monitor のスケッチです
参考サイトのスケッチにOLED表示・LED表示とリセットを追加しています、セルフキャリブレーションはオフにしています。
回路図は単純なので載せません、スケッチを見て判断して下さい。
リセットボタンを設定したのは電源を入れたとき、リセットしないと正常に表示されない場合があったためです。
/* CO2-Monitor
* CO2センサーMH-Z19E
* OLED1.3inch SH1106 driver
* 参考サイト:https://intellectualcuriosity.hatenablog.com/entry/2020/01/02/221905
*/
#define BLYNK_PRINT Serial // Comment this out to disable prints and save space
#include <BlynkSimpleEsp8266.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
/*OLED設定*/
#define i2c_Address 0x3c
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // QT-PY / XIAO
Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
/*LED_pin*/
int LED_Blue = 1 ;
int LED_Green = 3 ;
int LED_Yellow = 14 ;
int LED_Red = 16 ;
/* Blynk Auth Token and WiFi credentials */
#define AUTH_TOKEN "Your AUTH_TOKEN"
#define WIFI_SSID "Your SSID"
#define WIFI_PASS "Your Pass"
/* Define ESP8266 TX RX pin */
#define ESP8266_TX 12
#define ESP8266_RX 13
/* MH-Z19 Commands */
byte cmd_read_co2[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};
byte cmd_calibrate_zero[9] = {0xFF,0x01,0x87,0x00,0x00,0x00,0x00,0x00,0x78};
byte cmd_Self_calibration_off[9] = {0xFF,0x01,0x79,0x00,0x00,0x00,0x00,0x00,0x86}; // Self-calibration OFF
byte cmd_Self_calibration_on[9] = {0xFF,0x01,0x79,0xA0,0x00,0x00,0x00,0x00,0xE6}; // Self-calibration ON
byte cmd_detection_range_2000[9] = {0xFF,0x01,0x99,0x00,0x00,0x00,0x07,0xD0,0x8F}; // 0~2000ppm
byte cmd_detection_range_5000[9] = {0xFF,0x01,0x99,0x00,0x00,0x00,0x13,0x88,0xCB}; // 0~5000ppm
/* Global Objects */
SoftwareSerial co2Serial (ESP8266_RX, ESP8266_TX) ;
BlynkTimer timer;
/* Calibration Button*/
BLYNK_WRITE(V2) {
if (param.asInt()) {
co2Serial.write(cmd_calibrate_zero, 9);
}
}
/* Soft reset Button*/
BLYNK_WRITE(V6) {
if (param.asInt()) {
ESP.restart();
}
}
void sendSensor() {
unsigned char response[9]; // for answer
co2Serial.write(cmd_read_co2, 9); // request PPM CO2
co2Serial.readBytes(response, 9);
unsigned int responseHigh = (unsigned int) response[2];
unsigned int responseLow = (unsigned int) response[3];
int ppm = (256 * responseHigh) + responseLow;
Blynk.virtualWrite(V1, ppm);
display.clearDisplay();
display.setTextColor(SH110X_WHITE);
display.setTextSize(1);
display.setCursor(15, 10);
display.println("CO2-Monitor(PPM)");
display.setTextSize(2);
display.setCursor(15, 35);
display.println("CO2: ");
display.setCursor(65, 35);
display.println(ppm);
display.display();
/* LED表示 */
if (ppm >= 3000) {
digitalWrite(LED_Red, HIGH);
digitalWrite(LED_Yellow, HIGH);
digitalWrite(LED_Green, HIGH);
digitalWrite(LED_Blue, HIGH);
delay(1000);
digitalWrite(LED_Red, LOW);
delay(1000);
}
else if (ppm > 2000) {
digitalWrite(LED_Red, LOW);
digitalWrite(LED_Yellow, HIGH);
digitalWrite(LED_Green, HIGH);
digitalWrite(LED_Blue, HIGH);
delay(1000);
digitalWrite((LED_Yellow, LOW);
delay(1000);
}
else if (ppm > 1000) {
digitalWrite(LED_Red, LOW);
digitalWrite(LED_Yellow, LOW);
digitalWrite(LED_Green, HIGH);
digitalWrite(LED_Blue, HIGH);
delay(1000);
digitalWrite((LED_Green, LOW);
delay(1000);
}
else {
digitalWrite(LED_Red, LOW);
digitalWrite(LED_Yellow, LOW);
digitalWrite(LED_Green, LOW);
digitalWrite(LED_, HIGH);
delay(1000);
digitalWrite((LED_Blue, LOW);
delay(1000);
}
}
void setup() {
Serial.begin(74880);
co2Serial.begin(9600);
display.begin(i2c_Address, true);
display.clearDisplay();
display.display();
/*LED設定*/
pinMode(LED_Blue, OUTPUT);
pinMode(LED_Green, OUTPUT);
pinMode(LED_Yellow, OUTPUT);
pinMode(LED_Red, OUTPUT);
/* Initialize MH-Z19 */
/* co2Serial.write(cmd_Self_calibration_on, 9); // 自己校正機能は使わない */
co2Serial.write(cmd_detection_range_5000, 9);
/* Initialize Blynk */
Blynk.begin(AUTH_TOKEN, WIFI_SSID, WIFI_PASS, IPAddress(192, 168, 0, 100 ), 8080); //Blynk Local Server のIPアドレスを設定する
/* Initialize BlynkTimer */
timer.setInterval(2000, sendSensor); // every 2 seconds
}
void loop() {
Blynk.run();
timer.run();
}
Blynk 側の設定
温度/湿度/気圧のデーター取得
CO2Monitorの新しいプロジェクトを作成したときに得たAUTH_TOKEN に 温度/湿度/気圧計スケッチのAUTH_TOKENを書き換える。
このときCO2Monitorの (V番号)が重複しないよう調整する、これでCO2Monitorのプロジェクトに温度計のデーターを表示出来るようになる。
温度計で作成したプロジェクトは使用出来なくなるので削除する。
完成したCO2 Monitor
OLED及びCo2センサーはホットグルーでケースに固定しました。
ケース内の画像はZ19Cですが、前に作成したCO2モニターと入れ替えてデーターに変化があるか確認した時の物です。



MH-Z19C と MH-Z19E のデーター比較
正確なCO2の値は解らないのでどちらが正確なのかは判断できませんが、双方のデーターの比較は下記のようになりました。

キャリブレーションは屋外で2台並べて行いました。
・ 1000PPM位までは50PPM以内の差でモジュールの誤差範囲内で推移しました。
・ 2000PPMまではZ19Eの方が200PPMほど上昇します。
・ 2000PPMを超えるとだんだん差が開き3000PPMを超えた時点で500PPMほどZ19Eの濃度が高く表示されます。
・ 比較的にZ19CよりZ19EのほうがCO2に敏感に反応する感じがします。




