ESP01s 智慧插座專案,請依照上課講師步驟執行唷
- 這段程式使用ESP8266搭建一個簡單的Web伺服器,並且控制LED的開關。
- 用戶透過瀏覽器訪問ESP8266提供的Wi-Fi熱點,並可透過網頁控制LED的開關。
- 程式中定義了四個主要路由:根路由(/),開啟LED的路由(/ledon),關閉LED的路由(/ledoff),以及未找到頁面的處理(/notfound)。
- 當用戶點擊網頁上的"ON"或"OFF"按鈕時,會發送HTTP請求來控制LED的開關,並且更新網頁顯示的狀態。
#include <ESP8266WiFi.h> // 引入ESP8266 WiFi庫
#include <ESP8266WebServer.h> // 引入ESP8266 Web Server庫
/* Put your SSID & Password */
const char* ssid = "cda1031"; // 設定Wi-Fi名稱 (SSID)
const char* password = "123456789"; // 設定Wi-Fi密碼
ESP8266WebServer server(80); // 建立一個Web Server物件,使用端口80
bool LEDstatus = LOW; // 定義LED的狀態,初始為LOW (關閉)
void setup() {
Serial.begin(9600); // 啟動Serial監控,設定波特率為9600
pinMode(0, OUTPUT); // 設定D0腳位為輸出模式
pinMode(2, OUTPUT); // 設定D2腳位為輸出模式
digitalWrite(2, LOW); // 設定D2腳位初始狀態為LOW (關閉)
WiFi.softAP(ssid, password); // 啟動ESP8266作為Access Point,並設定SSID和密碼
IPAddress myIP = WiFi.softAPIP(); // 取得ESP8266的IP地址
Serial.print("Access Point IP:"); // 顯示 "Access Point IP:"
Serial.println(myIP); // 顯示ESP8266的IP地址
// 設定Web伺服器的處理路由,當路由被訪問時呼叫對應的處理函數
server.on("/", handle_OnConnect); // 根路由 ("/") 呼叫 handle_OnConnect 函數
server.on("/ledon", handle_ledon); // 訪問 "/ledon" 呼叫 handle_ledon 函數
server.on("/ledoff", handle_ledoff); // 訪問 "/ledoff" 呼叫 handle_ledoff 函數
server.onNotFound(handle_NotFound); // 訪問其他未定義的路由,呼叫 handle_NotFound 函數
server.begin(); // 啟動Web伺服器
//Serial.println("HTTP Server Started"); // 可選,顯示伺服器已啟動
}
void loop() {
server.handleClient(); // 處理來自客戶端的請求
// 根據LEDstatus變數,控制D0腳位的電平 (開/關LED)
if(LEDstatus)
{
digitalWrite(0, HIGH); // 如果LEDstatus為HIGH,則設置D0腳位為HIGH (開啟LED)
}
else
{
digitalWrite(0, LOW); // 如果LEDstatus為LOW,則設置D0腳位為LOW (關閉LED)
}
}
// 根路由 ("/") 的處理函數
void handle_OnConnect() {
LEDstatus = LOW; // 設置LED為關閉狀態
Serial.println("LED: OFF"); // 輸出 "LED: OFF" 到Serial監控
server.send(200, "text/html", updateWebpage(LEDstatus)); // 回應HTTP請求,傳送HTML頁面
}
// 訪問"/ledon"的處理函數
void handle_ledon() {
LEDstatus = HIGH; // 設置LED為開啟狀態
Serial.println("LED: ON"); // 輸出 "LED: ON" 到Serial監控
server.send(200, "text/html", updateWebpage(LEDstatus)); // 回應HTTP請求,傳送更新的HTML頁面
}
// 訪問"/ledoff"的處理函數
void handle_ledoff() {
LEDstatus = LOW; // 設置LED為關閉狀態
Serial.println("LED: OFF"); // 輸出 "LED: OFF" 到Serial監控
server.send(200, "text/html", updateWebpage(LEDstatus)); // 回應HTTP請求,傳送更新的HTML頁面
}
// 處理未定義的路由,顯示 404 頁面
void handle_NotFound(){
server.send(404, "text/plain", "Not found"); // 回應HTTP請求,傳送 404 Not Found
}
// 更新HTML頁面的內容,根據LED狀態顯示不同的內容
String updateWebpage(uint8_t LEDstatus){
String ptr = "<!DOCTYPE html> <html>\n"; // 開始編寫HTML頁面
ptr += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n"; // 設置視窗縮放屬性
ptr += "<title>LED Control</title>\n"; // 設置頁面標題
ptr += "<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n"; // CSS樣式設置
ptr += "body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;} h3 {color: #444444;margin-bottom: 50px;}\n";
ptr += ".button {display: block;width: 80px;background-color: #1abc9c;border: none;color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}\n";
ptr += ".button-on {background-color: #3498db;}\n";
ptr += ".button-on:active {background-color: #3498db;}\n";
ptr += ".button-off {background-color: #34495e;}\n";
ptr += ".button-off:active {background-color: #2c3e50;}\n";
ptr += "p {font-size: 14px;color: #888;margin-bottom: 10px;}\n";
ptr += "</style>\n"; // 結束CSS樣式
ptr += "</head>\n"; // 結束HTML的頭部
ptr += "<body>\n"; // 開始HTML的主體部分
ptr += "<h1>Smart Switch Project</h1>\n"; // 頁面標題顯示
ptr += "<h3>2024 DV107 @ 202</h3>\n"; // 顯示小標題
ptr += "<h3>smf.ntc.im</h3>\n"; // 顯示網站名
// 根據LED的狀態,顯示不同的按鈕和信息
if(LEDstatus){
ptr += "<p>Power: ON</p><a class=\"button button-off\" href=\"/ledoff\">OFF</a>\n"; // LED開啟時,顯示"Power: ON"和"OFF"按鈕
} else {
ptr += "<p>Power: OFF</p><a class=\"button button-on\" href=\"/ledon\">ON</a>\n"; // LED關閉時,顯示"Power: OFF"和"ON"按鈕
}
ptr += "</body>\n"; // 結束HTML主體
ptr += "</html>\n"; // 結束HTML頁面
return ptr; // 返回生成的HTML頁面
}