ESP32-DevKitCによる温湿度測定（Wi-Fi機能の使用）

## はじめに
最近、趣味と勉強のためマイコンボードを使い始めました。
今回は、ESP32-DevKitC（以下ESP32）というマイコンボードでWi-Fi機能を使って温湿度測定を行いました。

## ESP32のWi-Fi機能について
ESP32のWi-Fi機能にはステーション（STA）モードとアクセスポイント（AP）モードがあります。これらは次のように使い分けます。
- STAモード
ESP32を既存のWi-Fiネットワークのアクセスポイントに接続する場合に使います。PC等とESP32を無線LANルータを経由して接続するため、PC等でインターネットに接続しながらESP32に接続できます。
- APモード
ESP32自身をアクセスポイントとして、PCやスマホからアクセスする場合に使います。無線LANルータが無くてもPC等とESP32を接続できます。

## ESP32のWi-Fi機能を使った温湿度測定
温湿度センサDHT11を用いて、Wi-Fi機能のSTAおよびAPモードを使った温湿度の測定を行いました。

### 温湿度センサとESP32の接続
温湿度センサにはDHT11を用いて、DHT11とESP32は以下のように接続しました。
- DHT11のVDDをESP32の5Vへ接続
- DHT11のGNDをESP32のGNDへ接続
- DHT11のSIGをESP32の14ピンへ接続

マイコンボードESP32への温湿度センサDHT11の接続
![20240115_205651.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/88a08ff3-669f-b513-0175-1616013c2c87.jpeg)

センサ裏面に書かれた電極名
![20240115_205854_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/48ec26e0-0400-c3ac-70ab-7c111e1a43a4.jpeg)

作成したArduino IDEのスケッチです。

### STAモード
```
#include <WiFi.h>
#include <DHT.h>

const char* ssid = "Buffalo-G-1028"; //Wi-FiルータのSSID
const char* password = "************"; //Wi-FiルータのPASSWORD

const int PIN_DHT = 14;
DHT dht(PIN_DHT,DHT11);
WiFiServer server(80);

void setup() {
  Serial.begin(115200);
  delay(100);
  WiFi.mode(WIFI_STA);
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  Serial.print("Connecting to ");
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    if (WiFi.status() == WL_CONNECT_FAILED) {
      Serial.println("Can't connect");
    }
  }
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
  dht.begin();
}

void loop() {
  WiFiClient client = server.available();
  if (client) {
    String currentLine = "";
    Serial.println("New Client.");
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        if (c == '\n') {
          if (currentLine.length() == 0) {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html; charset=utf-8;");
            client.println();
            client.println("<!DOCTYPE HTML>");
            client.println("<html>");
            client.println("<head><meta http-equiv=\"refresh\" content=\"5\"></head><body><h1>ESP32とDHT11による温度・湿度の測定</h1><h2>温度 : ");
            client.println(dht.readTemperature(), 1);
            client.println("℃<br>湿度 : ");
            client.println(dht.readHumidity(), 1);
            client.println("%RH</h2></body></html>");
            client.println();
            Serial.println("温度 湿度");
            Serial.println(dht.readTemperature(), 1);
            Serial.println(dht.readHumidity(), 1);
            break;
          } else {
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }
      }               
    }
    client.stop();
    Serial.println("Client Disconnected.");
  }
}
```
### APモード
```
#include <WiFi.h>
#include <DHT.h>

const char *ssid = "ESP32ap"; //任意の名前
const char *password = "12345678"; //任意のパスワード
const IPAddress ip(192,168,30,3);
const IPAddress subnet(255,255,255,0);

const int PIN_DHT = 14;
DHT dht(PIN_DHT,DHT11);
WiFiServer server(80);

void setup() {
  Serial.begin(115200);
  dht.begin();
  WiFi.softAP(ssid, password);
  delay(100);
  WiFi.softAPConfig(ip,ip,subnet);
  IPAddress myIP = WiFi.softAPIP();
  server.begin();
  Serial.print("SSID: ");
  Serial.println(ssid);
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  Serial.println("Server start!");
}

void loop() {
  WiFiClient client = server.available();
  if (client) {
    String currentLine = "";
    Serial.println("New Client.");
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        if (c == '\n') {
          if (currentLine.length() == 0) {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html; charset=utf-8;");
            client.println();
            client.println("<!DOCTYPE HTML>");
            client.println("<html>");
            client.println("<head><meta http-equiv=\"refresh\" content=\"5\"></head><body><h1>ESP32とDHT11による温度・湿度の測定</h1><h2>温度 : "); 
            client.println(dht.readTemperature(), 1);
            client.println("℃<br>湿度 : ");
            client.println(dht.readHumidity(), 1);
            client.println("%RH</h2></body></html>");
            client.println();
            Serial.println("温度 湿度");
            Serial.println(dht.readTemperature(), 1);
            Serial.println(dht.readHumidity(), 1);
            break;
          } else {
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }
      }               
    }
    client.stop();
    Serial.println("Client Disconnected.");
  }
}
```
これら二つのスケッチにおいて、void loop()関数は全く同じです。
各スケッチを実行後、次の操作が必要になります。

- STAモード
Arduino IDEのシリアルモニタにIP adressが表示されるので、そのアドレスをスマホやPCのブラウザに打ち込むと温度と湿度が測定され表示されます。表示は5秒ごとに更新されます。
- APモード
スマホやPCをスケッチのssidで定義したアクセスポイントにWi-Fi接続します。passwordの入力を求められたら、それも入力します。
スケッチで定義したIP adress 「192,168,30,3」をスマホやPCのブラウザに打ち込むと温度と湿度が測定され表示されます（表示は5秒ごとに更新されます）。私のPCでは、APモードでWi-Fi接続すると次のような表示になりました。
![Wifi.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/705599d0-636d-31a3-9f53-f1af50b5cdb8.jpeg)
ブラウザに温度と湿度が表示されている様子です。
![測定状態.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729073/778d81a8-734e-b0c3-6823-9c33035c070b.jpeg)


## 開発環境
- マイコンボード：ESP32-DevKitC-32E
https://akizukidenshi.com/catalog/g/gM-15673/
- ボード情報：esp32 by Espressif, ver. 2.0.11
- 温湿度センサ：DHT11
https://akizukidenshi.com/catalog/g/gM-15491/
- Ardiono IDE：ver. 2.2.1
- OS：Windows11

## 終わりに
何かのご参考になれば幸いです。

## 参考記事
- M5StackでWifiをAPとSTAとで使い分ける

https://qiita.com/nnn112358/items/fbb4f24505c6ef8082cd

- WIFI環境でESP32を使ったサーバーを立ててみよう！

https://qiita.com/northVil/items/f5cfee1cfd38ece59bb5
- ESP32 Arduino: ウェブサーバ上で温湿度センサの情報表示

https://web.is.tokushima-u.ac.jp/wp/blog/2018/05/16/esp32-arduino-%E3%82%A6%E3%82%A7%E3%83%96%E3%82%B5%E3%83%BC%E3%83%90%E4%B8%8A%E3%81%A7%E6%B8%A9%E6%B9%BF%E5%BA%A6%E3%82%BB%E3%83%B3%E3%82%B5%E3%81%AE%E6%83%85%E5%A0%B1%E8%A1%A8%E7%A4%BA/