ESP-WROOM32でCO2を計測してみる

ESP-WROOM32

はじめに

ESP-WROOM32を使ってCO2濃度を計測してみます。

CO2センサーは、MH-Z19を使います。

Amazon.co.jp: LaDicha MH-Z19 0-5000PPM CO2室内空気質モニタ用赤外線CO2センサUART / PWM : 産業・研究開発用品
Amazon.co.jp: LaDicha MH-Z19 0-5000PPM CO2室内空気質モニタ用赤外線CO2センサUART / PWM : 産業・研究開発用品

CO2濃度データは、ESP-WROOM32からWi-Fiで飛ばして、パソコンから参照できるようにします。

ここでは、ESP-WROOM32をアクセスポイントとして使います。

ESP-WROOM32には、 技術適合基準(技適) マークがついているので、問題なく無線通信ができます。

技適マークがないと電波法違反の可能性がありますので、注意が必要です。

総務省 電波利用ホームページ|電波監視|技適マーク、無線機の購入・使用に関すること

CO2センサーMH-Z19のライブラリのダウンロード

CO2の計測プログラムには、こちらのライブラリを利用させていただきました。

WifWaf/MH-Z19
For Arduino Boards (&ESP32). Additional Examples/Commands., Hardware/Software Serial - WifWaf/MH-Z19

回路を接続する

MH-Z19の出力は、UARTとPWMがありますが、ここでは、UARTを使います。

ESP-WROOM32側は16Pin,17Pinを使用して通信することにします。

MH-Z19ESP-WROOM32
TxdGPIO16
RxdGPIO17
V+5V
V-GND

プログラムをつくる

スケッチ例のWiFiAccessPointをベースとして作ります。

まず、Arduino IDEの[ファイル]-[スケッチ例]-[WiFi]からWiFiAccessPointを選択します。

このプログラムにMH-Z19のライブラリMHZ19.hをインクルードします。

#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>
#include <Arduino.h>
#include "MHZ19.h"
#define RX_PIN 16 // Rx pin which the MHZ19 Tx pin is attached to
#define TX_PIN 17 // Tx pin which the MHZ19 Rx pin is attached to
#define BAUDRATE 9600 // Device to MH-Z19 Serial baudrate (should not be changed)
#define LED_BUILTIN 2 // Set the GPIO pin where you connected your test LED or comment this line out if your dev board has a built-in LED
//prototype
void co2SensorModule(void);
MHZ19 myMHZ19; // Constructor for library
HardwareSerial mySerial(2); // (ESP32 Example) create device to MH-Z19 serial
unsigned long getDataTimer = 0;
int CO2;
int8_t Temp;
// Set these to your desired credentials.
const char* ssid = "tsunelab";
const char* password = "tsunelabpass";
WiFiServer server(80);
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
Serial.println();
Serial.println("Configuring access point...");
//CO2 sensor setup
mySerial.begin(BAUDRATE, SERIAL_8N1, RX_PIN, TX_PIN); // (ESP32 Example) device to MH-Z19 serial start
myMHZ19.begin(mySerial); // *Serial(Stream) refence must be passed to library begin().
myMHZ19.autoCalibration(); // Turn auto calibration ON (OFF autoCalibration(false))
// You can remove the password parameter if you want the AP to be open.
WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.begin();
Serial.println("Server started");
}
void loop() {
//CO2 Sensor Module
co2SensorModule();
WiFiClient client = server.available(); // listen for incoming clients
if (client) { // if you get a client,
Serial.println("New Client."); // print a message out the serial port
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected()) { // loop while the client's connected
if (client.available()) { // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
Serial.write(c); // print it out the serial monitor
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
// the content of the HTTP response follows the header:
client.print(String("CO2[ppm]:") +CO2+"<br>");
// The HTTP response ends with another blank line:
client.println();
// break out of the while loop:
break;
} else { // if you got a newline, then clear currentLine:
currentLine = "";
}
} else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
}
}
// close the connection:
client.stop();
Serial.println("Client Disconnected.");
}
}
void co2SensorModule(void)
{
if (millis() - getDataTimer >= 2000)
{
/* 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) */
CO2 = myMHZ19.getCO2(); // Request CO2 (as ppm)
Temp = myMHZ19.getTemperature(); // Request Temperature (as Celsius)
getDataTimer = millis();
}
}
view raw esp-wroom32_co2.c hosted with ❤ by GitHub

計測してみる

プログラムをコンパイルして実行してみます。

シリアルモニタに出力されるAPのIPアドレスをメモしておいて、パソコンのWi-FI一覧を見てみます。

設定したSSIDの名前が表示されているはずです。ここでは、「tsunelab」でプログラムを作成しているので、tsunelabに接続します。パスワードは、tsunelabpassです。

接続が完了したら、ブラウザを立ち上げて、メモしておいたIPアドレスを入力します。

ESP-WROOM32から送信されたCO2データが表示されます。

CO2濃度のレベルです。

CO2濃度[ppm]レベル
350~450外気レベル
450~700室内レベル
700~1000不快レベル
1000~2000眠気レベル

計測時は、不快レベルでした。

このセンサーは、仕様にPreheat time3分とあるので、電源投入から安定するまで3分程度は必要です。電源投入時は、濃度値が大きく出ますが、徐々に下がっていって安定します。

まとめ

ESP-WROOM32のWi-Fiアクセスポイントを使ってMH-Z19センサーからCO2濃度値を取得して、パソコンからデータを参照してみました。

窓を開けて計測すると濃度値が下がっていくので、換気度合いの見える化ができそうです。

コメント

タイトルとURLをコピーしました