ESP32活用① ESP32とブラウザでお話しする(5)LEDのON/OFFとI2Cの温度センサの測定結果をまとめて表示

 次に示すWebブラウザの画面は、ESP32に接続された温度センサから気温を測定し表示しています。
 この表示は、次のページの記事で作成解説したプログラム「esp32lcdwifi010.ins」をESP32 WROOM 32Dの開発ボードに書き込み、PCのブラウザでアクセスして表示された気温のデータです。

https://www.denshi.club/cookbook/arduino/esp32/esp32-9-web.html
 ESP32入門 通信機能が標準搭載されたマイコン・ボード (9)
 測定した温度をWebに表示
 ①ESP32活用① ESP32とブラウザでお話しする


 このプログラムと、次に示すLEDのON/OFFを行うプログラムとを一緒にします。ON/OFFプログラムは、次のページで作成解説しています。

https://www.denshi.club/cookbook/arduino/esp32/esp32-esp324.html
 ESP32活用① ESP32とブラウザでお話しする(4)
 センタリング、ボタンを作ってみる


 二つのプログラムを統合して作ったプログラムをESP32 WROOM 32Dの開発ボードに書き込むと、次に示す表示となりました。

統合したプログラムの内容

 A********で囲まれた部分は、温度測定のプログラムesp32lcdwifi010.insからコピーした部分です。B*******で囲まれた部分は、LEDのON/OFFを行うプログラムesp32lcdwifi1050.insをコピーした部分です。それぞれ若干の修正を加えた部分もあり、それぞれ説明を加えています。

各種のライブラリを利用するための準備

 I2Cインターフェースの処理のためのWire.lib、I2CインターフェースのLCDモジュール用に筆者が作成したi2clcd.lib、Wi-Fiの処理に対応するArduinoの標準ライブラリWiFi.libを利用するための、それぞれのヘッダ・ファイルの読み込みを指定しています。

A********
#include <Wire.h>
#include <i2clcd.h>
#include <WiFi.h>
#include <WebServer.h>
const char ssid[] = "Buffalo-G-2C6E";
const char password[] = "passwordxxxxxxx";

 SSIDとキーはそれぞれの環境に合わせた値を設定します。

LEDのON/OFFに合わせて変更する色を定数として設定

 LEDのON/OFFに合わせて表示文字の色を変更します。ONのときの色をCOLOR1に、OFFのときの色をCOLOR2にセットしています。

B************
String COLOR1= "red";
String COLOR2 = "blue";

WebServer、各種の変数などの設定

A*******
WebServer server(80);
IPAddress ipadr;
int n = 0;
int bp = 0;
unsigned char tmp2_adr = 0x48;
i2clcd qlcd(0x3E, 3, 0x20); // 具体的な処理を行うためのオブジェクトを作る

tmp102温度センサから気温を読み取る関数

float get_tmp102(unsigned char tmp0_adr) {  // 温度センサを読み取る関数
    Wire.requestFrom(tmp0_adr, 2);
    while (Wire.available() < 2) {
    }
    int tmpin = Wire.read() * 16;
    tmpin = tmpin + (Wire.read() >> 4);
    return 0.0625 * tmpin;
}

Webサーバにアクセスがあったときの応答処理

B************
void handleRoot() {
    handleRootmsg(COLOR2, COLOR2);
}
void handleon() {
    digitalWrite(5, HIGH); // GET /H turns the LED on
    handleRootmsg(COLOR1, COLOR1);
}
void handleoff() {
    digitalWrite(5, LOW); // GET /L turns the LED off
    handleRootmsg(COLOR2, COLOR2);
}

メイン・ページの作成

 メインのページ、IPアドレス/ でアクセスした場合にブラウザに表示される画面のデータを、HTMLとCSSを利用して作成しています。
 温度の測定は、経過時間の確認の後センサにアクセスし気温を測定し実数tvalueにセットします。経過時間、気温は snprintf()関数で次のような処理を行います。
 "<html>\ から </html>"までの間で設定されたフォーマットに経過時間、気温を組み込み、文字列データとして文字列tempaにセットします。処理できる文字数は、ここでは最大400文字までと設定されています。snprintf()関数はオブジェクトの文字列は対象とならないので、文字型の配列の文字列を対象としています。
 フォーマットの設定では、途中に改行コードを入れることができません。そのため改行コードの前に\(バックスラッシュ)を挿入してあります。この¥があるためにコンパイルなどの処理を行うまえに¥と次に続く改行コードは削除され、改行のない連続した文字列と解釈されます。

A********
void handleRootmsg( String cr1, String cr2) {
    String temp = “”;
    char tempa[400];
    int sec = millis() / 1000;
    int min = sec / 60;
    int hr = min / 60;
    float tvalue = get_tmp102(tmp2_adr);
    snprintf(tempa, 400,
                 "<html>\
    <head>\
    <meta http-equiv='refresh' content='5'/>\
    <div style=\"background-color:#00ac0f\";\"backgroun-size 100px 400px\">\
    <title>Denshi Club ESP32 test</title>\
    </head>\
        <body style=\"text-align:center\">\
        <h1>Temperature from ESP32</h1>\
            <p>Uptime: %2d:%2d:%2d</p>\         // 時分秒の表示形式
            <p>Temperature: %8.2f</p>\          // 気温の表示形式
        </body>\
        </div>\
</html>",
           hr, min % 60, sec % 60,          // 経過時間 時間、分、秒
           tvalue                           // 気温の測定結果
           );

LEDのON/OFFはオブジェクトの文字列を利用する

 LEDのON/OFF処理の文字列はオブジェクトでしたので、最初にtemp = tempa;で初期化し、新しいフォーマットを追加します。

B*******
    temp = tempa;
    temp += "<div style=\"background-color:#f5ac0f\";\"backgroun-size 100px 400px\">";
    temp += "<p>Click <a href=\"/H\">here</a> to turn ";
    temp += "<span style=\"color:";
    temp += cr1 + "\">the LED </span>on pin 5 on.</p>";
    temp += "<p>Click <a href=\"/L\">here</a> to turn <span style=\"color:";
    temp += cr2 + "\">the LED </span> on pin 5 off.</p>";
    temp += "<button type=\"button\" ><a href=\"/H\" style=\"color:" + cr1 + ";line-height:2.5\">LED ON.</a></button><br>";
    temp += "<button type=\"button\" ><a href=\"/L\" style=\"color:" + cr2 + ";line-height:2.5\">LED OFF</a></button>";
    temp += "</div>";
    temp += "</body>";
    temp += "</html>",
        server.send(200, "text/html", temp);
}

 それぞれのバックグラウンド・カラーの設定は、<div>タグの中にstyle属性を利用して設定しています。サイズの指定は未設定です。

アドレスが見つからなかった場合の処理

 クライアントからのアクセスの要求に対して、アドレスが見つからなかった場合の処理をこの関数で行います。

void handleNotFound() {
    String message = "File Not Found\n\n";
    message += "URI: ";
    message += server.uri();
    message += "\nMethod: ";
    message += (server.method() == HTTP_GET) ? "GET" : "POST";
    message += "\nArguments: ";
    message += server.args();
    message += "\n";
    for (uint8_t i = 0; i < server.args(); i++) {
        message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
    }
    server.send(404, "text/HTML", message);
}

初期化処理の関数

 LCDモジュールの初期化、Wi-Fiの接続、IPアドレス取得、IPアドレスはLCDモジュールへの表示と合わせてシリアル・モニタへも送信表示できるようになっています。コピー元がLCDモジュールを利用するものなので、LEDのON/OFFを行うディジタル・ポートの出力設定、LEDのONの応答の設定、LEDのOFFの応答の設定が行われていません。そのため、次の項目を追加します。

        pinMode(5,OUTPUT);  // ディジタル・ポート5を出力に設定
        server.on("/H", handleon);  // LED ONの応答
        server.on("/L", handleoff);  // LED OFFの応答

 以上が追加した項目です。

A********
void setup(void) {
    qlcd.init_lcd();  // LCDモジュールの初期化処理
    qlcd.i2cprint("start:");
    pinMode(5,OUTPUT);  // ディジタル・ポート5を出力に設定 追加分
    Serial.begin(115200);
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    Serial.println("");
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.print("Connected to ");
    Serial.println(ssid);
    Serial.print("IP address: ");
    ipadr = WiFi.localIP();
    Serial.println(ipadr);
    qlcd.lcdcu_set(0, 1);
    qlcd.i2cprint(String(ipadr[0]) + "." + String(ipadr[1]) + ".");
    qlcd.i2cprint(String(ipadr[2]) + "." + String(ipadr[3]));
    server.on("/", handleRoot);
    server.on("/H", handleon);  // LED ONの応答 追加分
    server.on("/L", handleoff);  // LED OFFの応答 追加分
    server.onNotFound(handleNotFound);
    server.begin();
    Serial.println("HTTP server started");
}

メイン関数(loop())による処理

 クライアントのブラウザからの問い合わせには、server.handleClient();ですべて処理されます。その他の処理は1秒ごとに気温の測定を行い。LCDモジュールの表示を更新しています。元のプログラムをmillis()を1000で割った余りが0になることで1秒の経過を確認する方法に変更しました。

void loop(void) {
    server.handleClient();
    if (0== (millis() % 1000)) {
        bp = bp + 1;
        qlcd.lcdcu_set(0, 0); // LCDモジュールのカーソルを先頭に
        n = n + 1;
        qlcd.i2cprint(String(n)); // カウンタの値をLCDへ表示
        qlcd.i2cprint(":");
        qlcd.i2cprint("temp2="); // 見出しをLCDへ表示
        qlcd.i2cprint(String(get_tmp102(tmp2_adr))); //測定温度を表示
        }
}

Arduino IDEでマイコン・ボードに書き込み

 ボードの設定をDOIT ESP32 DEVKIT V1を選択し、シリアルポートを適切な値に設定し、プログラムをボードに書き込みます。

IPアドレスにアクセスすると

 LCDモジュールにIPアドレスが表示されるので、PCのブラウザからアクセスするとブラウザは次の表示になります。


 次回は、気温の測定データをリング・バッファにセットし、ブラウザにはテーブルで表示する検討を行ってみます。

(2019/6/30 V1.0)

<神崎康宏>

前へ

感震センサで揺れを記録する M5Stack編 (4) 設定変更

次へ

回すだけ (1) ブラシレス・モータ・キット