0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【ESP32入門】CO2モニターを作る #5 Webサーバー編

0
Posted at

はじめに

前回(#4 LCD表示編)でLCDにCO2濃度を表示できるようになりました。

今回はESP32でWebサーバーを立てて、ブラウザで CO2濃度をグラフ表示 します。


なぜWebサーバー・グラフをつけるのか

LCDでは「今の数値」しかわかりません。

CO2濃度が時間とともにどう変化したかをグラフで見られれば、分析がしやすくなると考えました。

例えば「何時頃に濃度が上がるのか」「換気でどれくらい下がるのか」が一目でわかります。


仕組み

ESP32自身がWebサーバーになり、ブラウザからアクセスするとグラフページを返します。

1. [ブラウザ] からESP32にアクセス
2. [ESP32] がCO2データ付きHTMLを返す
3. [ブラウザ] がグラフを表示

グラフの描画には Chart.js という無料のライブラリを使います。


使用ライブラリ

  • WiFi(ESP32標準)
  • WebServer(ESP32標準)

Chart.jsはインターネットから読み込むのでインストール不要です。


コード

#include <HardwareSerial.h>
#include <MHZ19.h>
#include <WiFi.h>
#include <WebServer.h>
#include "secrets.h"

MHZ19 myMHZ19;
HardwareSerial mySerial(2);
int co2Value = 0;
int co2History[20] = {0};
int historyIndex = 0;
unsigned long lastTime = 0;

const char* ssid = SECRET_SSID;
const char* password = SECRET_PASSWORD;

WebServer server(80);

void handleRoot() {
  String dataPoints = "";
  for (int i = 0; i < 20; i++) {
    int index = (historyIndex + i) % 20;
    dataPoints += String(co2History[index]);
    if (i < 19) dataPoints += ",";
  }

  String html = "<!DOCTYPE html><html>";
  html += "<head><meta charset='UTF-8'>";
  html += "<script src='https://cdn.jsdelivr.net/npm/chart.js'></script>";
  html += "</head><body>";
  html += "<h1>CO2 Monitor</h1>";
  html += "<p>現在のCO2: " + String(co2Value) + "ppm</p>";
  html += "<canvas id='chart'></canvas>";
  html += "<script>";
  html += "var ctx = document.getElementById('chart').getContext('2d');";
  html += "var chart = new Chart(ctx, {";
  html += "type: 'line',";
  html += "data: { labels: Array.from({length: 20}, (_, i) => i + 1),";
  html += "datasets: [{ label: 'CO2 (ppm)', data: [" + dataPoints + "],";
  html += "borderColor: 'rgb(75, 192, 192)', tension: 0.1}] },";
  html += "options: { scales: { y: {beginAtZero: false } } }";
  html += "});";
  html += "setInterval(function() { window.location.reload(); }, 5000);";
  html += "</script>";
  html += "</body></html>";
  server.send(200, "text/html", html);
}

void setup() {
  Serial.begin(115200);
  mySerial.begin(9600, SERIAL_8N1, 13, 14);
  myMHZ19.begin(mySerial);
  myMHZ19.autoCalibration(false);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("Wi-Fi接続成功!");
  Serial.print("IPアドレス:");
  Serial.println(WiFi.localIP());

  server.on("/", handleRoot);
  server.begin();
}

void loop() {
  server.handleClient();

  unsigned long currentTime = millis();
  if (currentTime - lastTime >= 5000) {
    lastTime = currentTime;
    co2Value = myMHZ19.getCO2();
    co2History[historyIndex] = co2Value;
    historyIndex = (historyIndex + 1) % 20;
    Serial.print("CO2: ");
    Serial.println(co2Value);
  }
}

使い方

  1. 書き込んだらSerial Monitorを開く
  2. 表示されたIPアドレス(例:192.168.1.50)を確認
  3. 同じWi-FiのスマホやpcのブラウザでそのIPアドレスにアクセス

グラフが表示されます。


一番ハマったポイント

ずっとリロードされてグラフが表示されない

最初、ブラウザがずっと再読み込みを繰り返すだけで、グラフがいつまでも表示されませんでした。

原因は loop() の中で delay(5000) を使っていたことでした。

delay() の間、ESP32は完全に停止します。その間ブラウザからのアクセスに応答できず、ページが正しく返せていなかったのです。


解決方法:delay()をやめてmillis()を使う

// 悪い例:delay()で5秒止まる
delay(5000);

// 良い例:millis()で時間を測る
unsigned long currentTime = millis();
if (currentTime - lastTime >= 5000) {
  lastTime = currentTime;
  // 5秒ごとの処理
}

millis() はESP32が起動してからの時間をミリ秒で返します。

これを使えばESP32を止めずに「5秒経ったか」を判定できるので、その間もブラウザに応答し続けられます。

この修正でグラフが無事表示されました。


コードのポイント

① 過去のデータを配列に保存

int co2History[20] = {0};

過去20件のCO2データを配列に保存し、グラフに表示しています。

② リング状にデータを保存

historyIndex = (historyIndex + 1) % 20;

% 20 で、20件を超えたら古いデータから上書きしていきます。


まとめ

  • ESP32でWebサーバーを立てた
  • Chart.jsでCO2をグラフ表示できた
  • delay()をやめてmillis()にしたらリロード問題が解決した

delay() の落とし穴は初心者がハマりやすいポイントだと思います。同じ問題で困っている人の参考になれば嬉しいです。

次回はNTPで時刻を取得してグラフのX軸に表示します!


#6 NTP時刻編へ続く


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?