今後のために、偶然家に眠っていたESP32を使って、LAN環境で簡単なレスポンスを行うサーバーを作ってみようと思います。ESP32への書き込みはArduino IDEを使用します。
Arduino IDEでのESP32用セットアップ
①まずArduino IDEを開き、「ファイル」の「環境設定」を選択します。
②環境設定の画面下部にある追加のボードマネージャのURLに以下のURLを入力し、「OK」を押します。
https://dl.espressif.com/dl/package_esp32_index.json
③メイン画面に戻り、「ツール」の「ボード」タグから「ボードマネージャ」を選択します。
④検索画面で「esp32」と検索し、一番上に出てきたものをインストール。
⑤メイン画面に戻り、「ツール」の「ボード」タグ「ESP32 Arduino」から「ESP32 Dev Module」が選択できるようになっていれば完了です。
ESP32のサーバー用ライブラリのインストール
このGitHubにアクセスして、zipファイルをダウンロードしてください。
Arduino IDEの画面から「スケッチ」の「ライブラリをインクルード」タグから「.ZIP形式のライブラリをインストール」を選択し、先ほどダウンロードしたZIPファイルを選択するだけです。
ESP32①何もしないサーバ
#include <WiFi.h>
#include <WebServer.h>
const char *ssid = "Buffalo-A-aaaa"; // WifiのSSIDの定義と代入
const char *pass = "abcdefghijklm"; // Wifiのパスワードの定義と代入
WebServer Server(80); // ポート番号(HTTP)
// メインプログラム
void setup() {
// シリアルモニタ(動作ログ)
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.begin(); // ウェブサーバ開始
}
void loop() {
Server.handleClient();
}
ssidとpassには自分の環境のものを入力してください。ただし、ESP32は5GHzに対応していないことに注意してください。そのため、WifiのSSIDを入力する際には2.4GHzのアクセスポイントを使用しないとエラーが出ます。
①のコードの内容と結果
①を実行し、シリアルモニタを見ると以下のようなログが出力されていると思います。
最後の行で出力されているIPアドレスに、chromeで接続するとこのような結果になっていることが確認できます。
返すものがないためNot found
となっていますが、このようになっていればサーバが正しく稼働している状態です。
WiFi.mode(WIFI_STA)
この関数はWifiの動作モードを設定する関数です。設定結果が成功の場合true
、失敗の場合false
を返します。WIFI_STA
とはWifiをステーションモードで使用するということです。ステーションモードで使用すると、ESP32が設定したWifiの子機として使用されるため、クライアント側は同じWifi環境であればアクセスポイントを変更せずにそのまま接続できます。
WiFi.begin(ssid, pass)
Wifiのアクセスポイントの接続する関数です。このssid
とpass
にはchar型
のポインタで定義したWifiの設定がそのまま引数として入っています。
while (WiFi.status() != WL_CONNECTED)
WiFi.status()
が現在のWifiの接続状態をenum型
で返します。WL_CONNECTED
はWiFi.status()
がWifiに接続完了したときに返す値です。つまり、このwhile
はWifiに接続されるまで繰り返すということです。
if (WiFi.status() == WL_CONNECT_FAILED)
先ほどのwhile
の中にあるこのif
は、Wifi接続失敗を意味するWL_CONNECT_FAILED
がWiFi.status()
から返されたときに行う処理です。
Server.begin()
上記までの内容で、Wifiには接続されている状態であるため、Server.begin()
を使ってServerを開始します。
WiFi.localIP()
現在割り当てられているIPアドレスを返します。
Server.handleClient()
Server.handleClient()
は登録した情報に従ってクライアントからのリクエストを処理する関数です。loop
内で呼び出します。
ESP32②テキストを返すサーバ
#include <WiFi.h>
#include <WebServer.h>
const char *ssid = "Buffalo-A-aaaa"; // WifiのSSID
const char *pass = "abcdefghijklm"; // Wifiのパスワード
WebServer Server(80); // ポート番号(HTTP)
// メインプログラム
void setup() {
// シリアルモニタ(動作ログ)
Serial.begin(115200); // ESP 標準の通信速度 115200
delay(100);
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.onNotFound(SendeNotFound);
Server.begin(); // ウェブサーバ開始
}
void SendMessage() {
Serial.println("SendMessage");
String message = "Thank you for visiting my server";
Server.send(200, "text/plain", message); // 値をクライアントに返す
}
void SendeNotFound() {
Serial.println("SendNotFound");
Server.send(404, "text/plain", "404 not found");
}
void loop() {
Server.handleClient();
}
②のコードの内容と結果
①と同じく出力されたIPアドレスに接続するとこのようになります。
①と違ったテキストが表示されていると思います。また、同じIPアドレスの適当なパスに接続してみるとこのようになります。
①の結果と似ていますが、少し違うことが分かります。
Server.on("/", SendMessage)
Server.on
関数は第一引数のパスにクライアントからアクセスがあった際、第二引数の関数を呼び出すというものです。ここでは、パスは設定せずIPアドレスにアクセスされるとSendMessage
関数を実行するという内容になっています。
Server.onNotFound(SendeNotFound)
Server.onNotFound
関数はServer.on
関数で設定されていないパスにアクセスがあった際に呼び出される関数です。呼び出された際には引数に指定した関数が実行されます。
Server.send(200, "text/plain", message)
Server.send
関数はクライアントにレスポンスを送信する関数です。第一引数にHTTPステータスコード
、第二引数にコンテンツタイプ
、第三引数にコンテンツ
をとります。この関数はSendMessage
の内部で呼び出されている関数であるため、成功レスポンスである200を返しています。クライアントに送信する変数のmessage
はテキストであるためコンテンツタイプはtext/plain
となります。
コンテンツタイプの種類はたくさんあります。
https://qiita.com/AkihiroTakamura/items/b93fbe511465f52bffaa
Server.send(404, "text/plain", "404 not found")
上記と同じ関数、Server.onNotFound
のときに呼び出される関数のでのレスポンスなので、クライアントエラーレスポンスの404を返します。コンテンツタイプ、コンテンツについては同じです。
ESP32③HTMLを返す動的なサーバ
#include <WiFi.h>
#include <WebServer.h>
const char *ssid = "Buffalo-A-aaaa"; // WifiのSSID
const char *pass = "abcdefghijklm"; // Wifiのパスワード
WebServer Server(80); // ポート番号(HTTP)
int Counter = 0; // カウンタ
void SendMessage() {
// レスポンス文字列の生成('\n' は改行; '\' は行継続)
Counter++;
Serial.println("SendMessage");
String message = "\
<html lang=\"ja\">\n\
<meta charset=\"utf-8\">\n\
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\
<head>\n\
<title>HTML</title>\n\
</head>\n\
<body style=\"font-family: sans-serif; background-color: #008080;\" >\n\
<h1>North Vilによるウェブサーバー</h1>\n\
<h3>あなたはこのサーバの "
+ String(Counter)
+ "人目のお客さまです!</h3>\n\
</body>\n\
</html>\n";
String celebrate = "\
<html lang=\"ja\">\n\
<meta charset=\"utf-8\">\n\
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n\
<head>\n\
<title>HTML</title>\n\
</head>\n\
<body style=\"font-family: sans-serif; background-color: #008080;\" >\n\
<h1>North Vilによるウェブサーバー</h1>\n\
<h2>あなたはこのサーバの記念すべき "
+ String(Counter)
+ "人目のお客さまです!!!!!</h2>\n\
</body>\n\
</html>\n";
// クライアントにレスポンスを返す
if (Counter % 10 != 0) {
Server.send(200, "text/html", message);
} else {
Server.send(200, "text/html", celebrate);
}
}
void SendNotFound() {
Serial.println("SendNotFound");
Server.send(404, "text/plain", "404 not found...");
}
// メインプログラム
void setup() {
// シリアルモニタ(動作ログ)
Serial.begin(115200); // ESP 標準の通信速度 115200
delay(100);
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.onNotFound(SendNotFound); // 不正アクセス時の応答
Server.begin(); // ウェブサーバ開始
}
void loop() {
Server.handleClient();
}
③のコードの内容と結果
HTMLを返すことで、やっと少しだけウェブサイトっぽい見た目になりました。Counter変数でクライアントがリクエストするたびに人数が増えていくように設定しており、Server.send
にif
を追加して、10人単位でのみHTMLが専用のものに切り替わります。また、②のようなテキストのみでは日本語を表示させることはできませんが、HTMLを使用することで日本語も使用できます。
Server.send(200, "text/html", message)
②のコードとは違い、レスポンスがHTMLなのでコンテンツタイプをtext/html
と変更しています。
終わり
ESP32は買ったはいいものの、当初の自分には難しく持て余していたので多少なりとも使ってあげられてよかったと思います。
初めてのQiita投稿なので至らぬ点等あったと思いますが、最後まで見ていただきありがとうございました。
参考URL
WebServerライブラリリファレンス
https://garretlab.web.fc2.com/arduino/esp32/reference/libraries/WebServer/
ESP32ライブラリリファレンス
https://garretlab.web.fc2.com/arduino/esp32/reference/libraries/WiFi/
Content-Typeの一覧
https://qiita.com/AkihiroTakamura/items/b93fbe511465f52bffaa
M5StackでWifiをAPとSTAとで使い分ける
https://qiita.com/nnn112358/items/fbb4f24505c6ef8082cd
HTTP レスポンスステータスコード
https://developer.mozilla.org/ja/docs/Web/HTTP/Status
ESP32をWebサーバーにして応答させてみる
https://labo.mycabin.net/electronics/arduino-esp32/466/
ESP-WROOM-32をHTTPで制御する
https://ideal-reality.com/computer/arduino/esp32-http-server/
こじ研 トンペイーノを WiFi につないでみる
https://www.ei.tohoku.ac.jp/xkozima/lab/espTutorial0wifi.html