/* ESP32 HTTP IoT Server Example for Wokwi.com
這個範例展示如何在ESP32上建立一個簡單的HTTP伺服器
並控制LED燈的狀態(開啟或關閉)
https://wokwi.com/projects/320964045035274834
要測試這個範例,您需要使用Wokwi的IoT Gateway,詳細說明請見:
https://docs.wokwi.com/guides/esp32-wifi#the-private-gateway
啟動模擬後,可以在另一個瀏覽器標籤中開啟 http://localhost:9080
注意:使用IoT Gateway需要Wokwi Club訂閱
訂閱Wokwi Club請前往 https://wokwi.com/club
*/
#include <WiFi.h> // 引入WiFi函式庫,用於ESP32的WiFi功能
#include <WiFiClient.h> // 引入WiFi客戶端函式庫,用於TCP連線
#include <WebServer.h> // 引入WebServer函式庫,用於建立HTTP伺服器
#include <uri/UriBraces.h> // 引入UriBraces,用於處理帶有參數的URI
#define WIFI_SSID "Wokwi-GUEST" // 定義WiFi網路名稱
#define WIFI_PASSWORD "" // 定義WiFi密碼(此處為空字串)
#define WIFI_CHANNEL 6 // 定義WiFi通道,加快連線速度
WebServer server(80); // 建立一個HTTP伺服器,監聽80埠
const int LED1 = 26; // 定義LED1的控制腳位為GPIO 26
const int LED2 = 27; // 定義LED2的控制腳位為GPIO 27
bool led1State = false; // 用於記錄LED1的狀態(開或關)
bool led2State = false; // 用於記錄LED2的狀態(開或關)
// 發送HTML網頁給客戶端的函式
void sendHtml() {
String response = R"(
<!DOCTYPE html><html>
<head>
<title>ESP32 Web Server Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html { font-family: sans-serif; text-align: center; }
body { display: inline-flex; flex-direction: column; }
h1 { margin-bottom: 1.2em; }
h2 { margin: 0; }
div { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: auto auto; grid-auto-flow: column; grid-gap: 1em; }
.btn { background-color: #5B5; border: none; color: #fff; padding: 0.5em 1em;
font-size: 2em; text-decoration: none }
.btn.OFF { background-color: #333; }
</style>
</head>
<body>
<h1>ESP32 Web Server</h1>
<div>
<h2>LED 1</h2>
<a href="/toggle/1" class="btn LED1_TEXT">LED1_TEXT</a>
<h2>LED 2</h2>
<a href="/toggle/2" class="btn LED2_TEXT">LED2_TEXT</a>
</div>
</body>
</html>
)";
response.replace("LED1_TEXT", led1State ? "ON" : "OFF"); // 將LED1的狀態替換為"ON"或"OFF"
response.replace("LED2_TEXT", led2State ? "ON" : "OFF"); // 將LED2的狀態替換為"ON"或"OFF"
server.send(200, "text/html", response); // 回應HTTP狀態200和HTML內容
}
void setup(void) {
Serial.begin(115200); // 初始化序列通訊,波特率為115200
pinMode(LED1, OUTPUT); // 設定LED1腳位為輸出
pinMode(LED2, OUTPUT); // 設定LED2腳位為輸出
WiFi.begin(WIFI_SSID, WIFI_PASSWORD, WIFI_CHANNEL); // 開始連接WiFi
Serial.print("Connecting to WiFi ");
Serial.print(WIFI_SSID);
// 等待WiFi連接完成
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println(" Connected!"); // WiFi連接成功
Serial.print("IP address: ");
Serial.println(WiFi.localIP()); // 顯示ESP32的IP地址
server.on("/", sendHtml); // 設定HTTP伺服器的根路徑請求處理函式
// 設定處理/toggle/{number}路徑的請求,用來切換LED的狀態
server.on(UriBraces("/toggle/{}"), []() {
String led = server.pathArg(0); // 取得路徑中的參數(LED編號)
Serial.print("Toggle LED #");
Serial.println(led);
switch (led.toInt()) { // 依據LED編號切換對應LED的狀態
case 1:
led1State = !led1State; // 切換LED1的狀態
digitalWrite(LED1, led1State); // 設定LED1的輸出狀態
break;
case 2:
led2State = !led2State; // 切換LED2的狀態
digitalWrite(LED2, led2State); // 設定LED2的輸出狀態
break;
}
sendHtml(); // 回傳更新後的HTML頁面
});
server.begin(); // 啟動HTTP伺服器
Serial.println("HTTP server started"); // 顯示伺服器啟動訊息
}
void loop(void) {
server.handleClient(); // 處理客戶端的請求
delay(2); // 延遲2毫秒,避免CPU過度占用
}