IOT再びーーーESP32編(2)

前回,とりあえず,諸兄のスケッチ動かしみました。
このスケッチのhtml部分を書き換え,下記ようにして,スケッチの方で,それぞれのLの帯を順次消していけ
ば,目的を達成できるかなと考えました。

ただ,これでは,問題があるようで,サーバー側で,新しい情報をクライアントの方に送っても,クライア
ント側で更新を行わないと,画面が新しくならないみたいなので,このままでは,つかえないかなとおもい
ました。

いろいろあさってると,「非同期処理」が必要だとのHPを見つけました。これを改変すれば,目的が達成でき
そうな気がしてきました。
このHPのスケッチをDLして,自分の環境に合わせて,動かしてみました。温度センサーは以前買った,
Sensor Kit for Aruduinoというセット

に入ってた物をつかいました。
写真の下にあるのが,写真のものを動かしている諸兄のHPにあった,スケッチです。
もっともここよりも諸兄のHPに全文がのっていますので,そちらからDLした方がいいでし
ょうか。


/*
 * File:      WiFiMeasureAsync.ino
 * Function:  計測デバイスを非同期Webサーバーにして、クライアント画面に計測値を更新表示
 *            させる。
 * Date:      2020/02/12
 * Author:    M.Ono
 * 
 * Hardware   MCU:  ESP32 (DOIT ESP32 DEVKIT V1 Board)
 *            ブレッドボードに上記開発ボードと温湿度センサー、プッシュボタン、LEDを配線
 *            温湿度センサーはDHT11 
 *            ※今回はプッシュボタンとLEDは使用しない。
 */
 
#include <arduino.h>
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <DHT.h>                    // DHTセンサー用


/* Function Prototype */
String getTemperature();
String getHumidity();
String processor(const String&);
void doInitialize();
void connectToWifi();

// ルーター接続情報
#define WIFI_SSID "aterm-e4b126-g"
#define WIFI_PASSWORD "3d259dac2f80e"

/* 基本属性定義  */
#define SPI_SPEED   115200          // SPI通信速度
#define DHTTYPE     DHT11           // DHTセンサーの型式

// Webサーバーオブジェクト
#define HTTP_PORT 80
AsyncWebServer server(HTTP_PORT);

/* DHTセンサー*/
const int DHTPin = 14;                  // DHTセンサーの接続ピン
DHT   dht(DHTPin, DHTTYPE);             // DHTクラスの生成(初期化?)

/* HTMLページ */
const char* strHtml = R"rawliteral(
 <!DOCTYPE HTML>
 <html>
 <head>
 <meta charset="utf-8">
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <style>
html { font-family: Helvetica; display: inline-block; margin: 0px auto;text-align: center;}
h1 {font-size:28px;}
body {text-align: center;}
table { border-collapse: collapse; margin-left:auto; margin-right:auto;}
th { padding: 12px; background-color: #0000cd; color: white; border: solid 2px #c0c0c0;}
tr { border: solid 2px #c0c0c0; padding: 12px;}
td { border: solid 2px #c0c0c0; padding: 12px;}
.value { color:blue; font-weight: bold; padding: 1px;}
 </style>
 </head>
 <body>
 <h1>Asynchronous Server </h1>
 <p style='color:brown; font-weight: bold'>計測値は 10 秒ごとに自動更新されます! </p>
 <p> <table>
 <tr> <th>ELEMENT </th> <th>VALUE </th> </tr>
 <tr> <td>Temperature </td> <td> <span id="temperature" class="value">%TEMPERATURE%
 </span> <tr> <td>Humidity </td> <td> <span id="humidity" class="value">%HUMIDITY% </span>
 </td> </tr>
 </table> </p>
 </body>
 <script>
var getTemperature = function () {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("temperature").innerHTML = this.responseText;
}
};
xhr.open("GET", "/temperature", true);
xhr.send(null);
}
var getHumidity = function () {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("humidity").innerHTML = this.responseText;
}
};
xhr.open("GET", "/humidity", true);
xhr.send(null);
}
setInterval(getTemperature, 10000);
setInterval(getHumidity, 10000);
 </script>
 </html>)rawliteral";

/*****************************************************************************
 *                          Predetermined Sequence                           *
 *****************************************************************************/
void setup(){
    doInitialize();             // 初期化処理をして
    connectToWifi();            // Wi-Fiルーターに接続する

    // GETリクエストに対するハンドラーを登録して
    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
        request->send_P(200, "text/html", strHtml, editPlaceHolder);
    });
    server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
        request->send_P(200, "text/plain", getTemperature().c_str());
    });
    server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
        request->send_P(200, "text/plain", getHumidity().c_str());
    });
    // サーバーを開始する
    server.begin();
}
 
void loop(){
}

/* 計測処理ロジック */
String getTemperature() {
    float t = dht.readTemperature();
    if (isnan(t)) {    
        Serial.println("Failed to get temperature!");
        return "--";
    }
    else {
        Serial.println(t);
        return String(t) + " ℃";
    }
}

String getHumidity() {
    float h = dht.readHumidity();
    if (isnan(h)) {
        Serial.println("Failed to get humidity!");
        return "--";
    }
    else {
        Serial.println(h);
        return String(h) + " %";
    }
}

/* プレースホルダー処理 */
String editPlaceHolder(const String& var){
    if(var == "TEMPERATURE"){
        return getTemperature();
    }
    else if(var == "HUMIDITY"){
        return getHumidity();
    }
    return "??";
}

/* 初期化処理 */
void doInitialize() {
    Serial.begin(SPI_SPEED);
    dht.begin();                       // DHTセンサーを起動
}

/****************************< Connect functions >****************************/
/* Wi-Fiルーターに接続する */
void connectToWifi() {
    Serial.print("Connecting to Wi-Fi ");
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    // モニターにローカル IPアドレスを表示する
    Serial.println("WiFi connected.");
    Serial.print("  *IP address: ");
    Serial.println(WiFi.localIP());
    server.begin();
}

  }
}