3
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ESP32を使った簡単なIoT

Last updated at Posted at 2022-02-24

前回作ったサーバは文字をページ表示させることとWifiライブラリの使い方を学ぶことがメインでした。今回はIoTに活用していくために、Webサーバにボタンを配置し、ボタンからESP32を操作することを目的とします。

ボタン操作でLチカ

 Arduino IDEでESP32環境を作った際にスケッチ例として自動的インストールされるSimpleWiFiServerというものもありますが、個人的にはこちらの方が分かりやすいと思ったのでこちらを参考にさせていただきました。細かいところを変更しオリジナルを加えたものがLED.inoになります。
 ESP32のピン配置はこのサイトが見やすかったです。
https://ht-deko.com/arduino/esp-wroom-32.html

LED.ino
#include <WiFi.h>
#include <WebServer.h>

const char *ssid = "Buffalo-A-aaaa";        // WifiのSSID
const char *pass = "abcdefghijklm";    //  Wifiのパスワード
WebServer Server(80);         //  ポート番号(HTTP)


//  クライアントにウェブページ(HTML)を返す関数
void SendMessage() {
  //  レスポンス文字列の生成('\n' は改行; '\' は行継続)
  Serial.println("SendMessage");
  String message =   "<html lang=\"ja\">\n\
    <meta charset=\"utf-8\">\n\
    <center>\
    <h2>LED制御</h2>\
    <p><button type='button' onclick='location.href=\"/on\"' \
      style='width:200px;height:40px;'>LED-ON</button></p>\
    <p><button type='button' onclick='location.href=\"/off\"' \
      style='width:200px;height:40px;'>LED-OFF</button></p>\
  </center>";
  //  クライアントにレスポンスを返す
  Server.send(200, "text/html", message);
}

void OnSendMessage() {
  Serial.println("OnSendMessage");
  String message =   "<html lang=\"ja\">\n\
    <meta charset=\"utf-8\">\n\
    <center>\
    <h2>LED制御</h2>\
    <p><button type='button' onclick='location.href=\"/off\"' \
      style='width:200px;height:40px;'>LED-OFF</button></p>\
  </center>";
  //  クライアントにレスポンスを返す
  Server.send(200, "text/html", message);
  //LEDをONにする
  digitalWrite(5, HIGH);
}
void OffSendMessage() {
  Serial.println("OffSendMessage");
  String message =   "<html lang=\"ja\">\n\
    <meta charset=\"utf-8\">\n\
    <center>\
    <h2>LED制御</h2>\
    <p><button type='button' onclick='location.href=\"/on\"' \
      style='width:200px;height:40px;'>LED-ON</button></p>\
  </center>";
  //  クライアントにレスポンスを返す
  Server.send(200, "text/html", message);
  //LEDをOFFにする
  digitalWrite(5, LOW);
}
//  クライアントにエラーメッセージを返す関数
void SendNotFound() {
  Serial.println("SendNotFound");
  Server.send(404, "text/plain", "404 not found...");
}

//  メインプログラム
void setup() {
  pinMode(5, OUTPUT);
  //  シリアルモニタ(動作ログ)
  Serial.begin(115200);               //  ESP 標準の通信速度 115200
  delay(100);                         //  100ms ほど待ってからログ出力可
  Serial.println("\n*** Starting ***");
  //  無線 LAN に接続
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);             
  Serial.println("Connecting...");
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    if (WiFi.status() == WL_CONNECT_FAILED) {
      Serial.println("Can't connect");
    }
  }
  Serial.println("Connected");
  Serial.println(WiFi.localIP());     //  ESP 自身の IP アドレスをログ出力
  //  ウェブサーバの設定
  Server.on("/", SendMessage);         //  ルートアクセス時の応答関数を設定
  Server.on("/on", OnSendMessage);
  Server.on("/off", OffSendMessage);
  Server.onNotFound(SendNotFound);  //  不正アクセス時の応答関数を設定
  Server.begin();                     //  ウェブサーバ開始
}
void loop() {
  //  クライアントからの要求を処理する
  Server.handleClient();
}

LED.inoの実行結果

 Webサーバにアクセスしたときのブラウザ画面とシリアルモニタ
スクリーンショット (918).png

 ONボタンを押したときブラウザ画面とシリアルモニタ

スクリーンショット (919).png

 OFFボタンを押したときブラウザ画面とシリアルモニタ

スクリーンショット (920).png

プログラムの内容

 基本的な中身は前回とほとんど同じです。変更しているのは、クライアントへ返す変数messageとボタンに対応したServer.on関数です。ボタンを押した際の動作は上記実行結果の通りで、ONボタンを押したときにはOFFボタンのみが画面に残り、OFFボタンを押したときはONボタンのみが画面に残るようにHTMLを対応させています。
 LEDはIO5番に接続しています。

ボタンの動作

 ボタンはクリックさせることでHTMLで指定したURLにクライアントを移動させることができます。今回はONボタンがクリックされると/onへ、OFFボタンがクリックされると/offへ移動させています。この移動先のURLに合わせたServer.on関数を作成するとそのボタンがクリックされた後Server.onで指定した動作やレスポンスを返すことができます。

ボタン操作でセンサの値を確認する

 それでは先ほどのプログラムLED.inoを応用して、LEDなどの出力ではなくセンサの入力値をサーバから確認できるようにしてみましょう。
 今回使用するセンサは$ I^{2}C $接続で温度、湿度、気圧を測定できるBME280を使用しました。また、Adafruit_SensorBME280という専用ライブラリが用意されているので簡単に操作できます。

BME280.ino
#include <WiFi.h>
#include <WebServer.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
Adafruit_BME280 bme;

float temp;
float pressure;
float humid;

const char *ssid = "Buffalo-A-aaaa";      //  WifiのSSID
const char *pass = "abcdefghijklm";    //  Wifiのパスワード
WebServer Server(80);         //  ポート番号(HTTP)


//  クライアントにウェブページ(HTML)を返す関数
void SendMessage() {
  //  レスポンス文字列の生成('\n' は改行; '\' は行継続)
  Serial.println("SendMessage");
  String message =   "<html lang=\"ja\">\n\
    <meta charset=\"utf-8\">\n\
    <center>\
    <h2>BME280の値</h2>\
    <p><button type='button' onclick='location.href=\"/bme\"' \
      style='width:250px;height:40px;'>気温・湿度・気圧を知る</button></p>\
  </center>";
  //  クライアントにレスポンスを返す
  Server.send(200, "text/html", message);
}

void BmeSendMessage() {
  Serial.println("BmeSendMessage");
  temp = bme.readTemperature();
  humid = bme.readHumidity();
  pressure = bme.readPressure();

  Serial.println("気温 " + String(temp));
  Serial.println("湿度 " + String(humid));
  Serial.println("気圧 " + String(pressure / 100));

  String message =   "<html lang=\"ja\">\n\
    <meta charset=\"utf-8\">\n\
    <center>\
    <h2>BME280の値</h2>\
    <h3>温度: " + String(temp) + "°C, 湿度: " + String(humid) + "%, 気圧: " + String(pressure / 100) + "hPa</h3>\
    <p><button type='button' onclick='location.href=\"/bme\"' \
      style='width:250px;height:40px;'>気温・湿度・気圧を知る</button></p>\
  </center>";
  //  クライアントにレスポンスを返す
  Server.send(200, "text/html", message);
}

//  クライアントにエラーメッセージを返す関数
void SendNotFound() {
  Serial.println("SendNotFound");
  Server.send(404, "text/plain", "404 not found...");
}

//  メインプログラム
void setup() {
  pinMode(5, OUTPUT);
  //  シリアルモニタ(動作ログ)
  Serial.begin(115200);               //  ESP 標準の通信速度 115200
  delay(100);                         //  100ms ほど待ってからログ出力可
  Serial.println("\n*** Starting ***");
  //  無線 LAN に接続
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);            
  Serial.println("Connecting...");
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    if (WiFi.status() == WL_CONNECT_FAILED) {
      Serial.println("Can't connect");
    }
  }
  Serial.println("Connected");
  Serial.println(WiFi.localIP());     //  ESP 自身の IP アドレスをログ出力
  //  ウェブサーバの設定
  Server.on("/", SendMessage);         //  ルートアクセス時の応答関数を設定
  Server.on("/bme", BmeSendMessage);
  Server.onNotFound(SendNotFound);  //  不正アクセス時の応答関数を設定
  Server.begin();                     //  ウェブサーバ開始
  //BME280
  bool status;
  status = bme.begin(0x76);
  while (!status) {
    Serial.println("BME280 sensorが使えません");
    delay(1000);
  }
}
void loop() {
  //  クライアントからの要求を処理する
  Server.handleClient();
}

BME280.inoの実行結果

 Webサーバにアクセスしたときのブラウザ画面とシリアルモニタ
スクリーンショット (923).png
ルートディレクトリ.png

 ボタンをクリックしたときのブラウザ画面とシリアルモニタ
スクリーンショット (924).png
BME.png

プログラムの内容

 レスポンスするHTMLとボタンを変更しています。BME280を使い方はこのサイトを参考にしました。
https://wak-tech.com/archives/1642
 私の使用したBME280はデフォルトで気圧の値が[Pa]単位だったので[hPa]にするためにpressure変数を100で割っています。

まとめ

 WebサーバからESP32を制御できるとIoTとして活用ができるようになります。ただ、結局のところ現段階ではただセンサの値を見たりボタンで制御するだけしかできません。今後他のAPIを組み合わせて、LINEなどと同期できれば、より生活に密着したIoT機器を自作することができると思うので機会があればやってみようと思います。
 最後までご覧いただきありがとうございました。間違い等あるかもしれませんが温かい目で見守っていただけると幸いです。

参考文献

https://qiita.com/northVil/items/f5cfee1cfd38ece59bb5
https://ht-deko.com/arduino/esp-wroom-32.html
https://kit.socinno.com/3_3_r/
https://wak-tech.com/archives/1642

3
6
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
3
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?