前回作ったサーバは文字をページ表示させることとWifi
ライブラリの使い方を学ぶことがメインでした。今回はIoTに活用していくために、Webサーバにボタンを配置し、ボタンからESP32を操作することを目的とします。
ボタン操作でLチカ
Arduino IDEでESP32環境を作った際にスケッチ例として自動的インストールされるSimpleWiFiServer
というものもありますが、個人的にはこちらの方が分かりやすいと思ったのでこちらを参考にさせていただきました。細かいところを変更しオリジナルを加えたものがLED.ino
になります。
ESP32のピン配置はこのサイトが見やすかったです。
https://ht-deko.com/arduino/esp-wroom-32.html
#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サーバにアクセスしたときのブラウザ画面とシリアルモニタ
ONボタンを押したときブラウザ画面とシリアルモニタ
OFFボタンを押したときブラウザ画面とシリアルモニタ
プログラムの内容
基本的な中身は前回とほとんど同じです。変更しているのは、クライアントへ返す変数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_Sensor
とBME280
という専用ライブラリが用意されているので簡単に操作できます。
#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サーバにアクセスしたときのブラウザ画面とシリアルモニタ
プログラムの内容
レスポンスする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