在上一節的《四、2 使用超連結(href)的方式控制單一輸出》中,已示範過如何使用標準的網頁html語法中的超連結(href)元素去控制ESP32開發模組板上內建LED的亮滅,接下來就讓我們使用同樣的語法但是把控制的輸出數目擴充,在本小節中將以控制三個輸出點的方式來示範,當然更多的輸出點也不是問題,只要依樣照做就可以;為了方便測試,這三個點分別接到不同的LED燈上,也就是以LED的亮(1)滅(0)來代表輸出的狀態。
◎ 範例程式功能與動作說明:
1、以ESP32建立一無線WiFi AP存取點,此AP存取點SSID名稱為 『ESP32_softAP01』,而且不使用密碼,該AP存取點內建伺服器的IP位址為:[ 192.168.4.1 ]。
圖四、3-1 客戶端瀏覽器連線系統後啟動首頁網頁畫面
3、當使用者點選上圖中選標記2上方的「”點亮”」這個超連結選項時,系統會回應下面【圖四、3-2】的網頁畫面給客戶端,畫面中標記1的『[LED點亮]』回應訊息文字部分的顏色會變為紅色。
圖四、3-2 點選”點亮”超連結選項後客戶端瀏覽器畫面
◎電路圖:
圖四、3-3 使用ESP32開發板控制三顆LED亮滅電路
圖四、3-4 實際使用的WeMos D1/R32 ESP32開發板控制三顆LED亮滅電路
本實習使用ESP32開發板(類似NodeMcu)控制三顆LED燈,如【圖四、3-3】所示,當輸出High時會令接在這些腳上的LED點亮;這三隻腳分別是GPIO25、26、27,當然改用其他的接腳也是可以,但是不能使用GPIO34、35、36、39這四隻,因為這四隻腳在ESP32上只能作為輸入用!
為了方便燒錄程式與接線,本範例程式實際測試時使用的是如【圖四、3-4】所示,類似Arduino Uno的WeMos D1/R32開發板。
◎程式列表與說明:
以下是這個範例的完整程式列表內容:
/*
ESP32 soft AP 範例四 : 四、3 使用超連結(href)的方式控制多重輸出之一
*/
#include <WiFi.h>
#include "index.h"
const char* ssid = "ESP32_softAP01";
const char* password = "12345678";
const int LED1=27,LED2=26,LED3=25;
String LED1_Status="<font color=blue>LED1 熄滅</font>" ,
LED2_Status="<font color=blue>LED2 熄滅</font>" ,
LED3_Status="<font color=blue>LED3 熄滅</font>";
unsigned long connectTime = 0;
const long timeoutTime = 3000;
WiFiServer server(80);
// 初始化設定程式開始:
void setup()
{
Serial.begin(115200);
pinMode(LED1, OUTPUT); // set the LED pin mode
pinMode(LED2, OUTPUT); // set the LED pin mode
pinMode(LED3, OUTPUT); // set the LED pin mode
delay(10);
// We start by connecting to a WiFi network
WiFi.softAP(ssid);
Serial.println("Setting softAP ...");
Serial.println();
Serial.print("Your softAP is : ");
Serial.println(ssid);
Serial.println("IP address: ");
Serial.println(WiFi.softAPIP());
server.begin();
} // 初始化設定程式結束.
// 主迴圈程式開始:
void loop(){
WiFiClient client = server.available(); // listen for incoming clients
// wait for a client (web browser) to connect
if (client)
{
connectTime = millis();
Serial.println("\n[Client connected]");
while (client.connected() && (millis() - connectTime <= timeoutTime))
{
// read line by line what the client (web browser) is requesting
if (client.available())
{
String line = client.readStringUntil('\r');
// Serial.print(line);
// Check to see if the client request was "GET /H" or "GET /L":
if (line.indexOf("GET /ON1") >= 0) {
Serial.println(line);
digitalWrite(LED1, HIGH); // GET /H turns the LED on
LED1_Status="<font color=red>LED1 點亮</font>";
}
if (line.indexOf("GET /OFF1") >= 0) {
Serial.println(line);
digitalWrite(LED1, LOW); // GET /L turns the LED off
LED1_Status="<font color=blue>LED1 熄滅</font>";
}
if (line.indexOf("GET /ON2") >= 0) {
Serial.println(line);
digitalWrite(LED2, HIGH); // GET /H turns the LED on
LED2_Status="<font color=red>LED2 點亮</font>";
}
if (line.indexOf("GET /OFF2") >= 0) {
Serial.println(line);
digitalWrite(LED2, LOW); // GET /L turns the LED off
LED2_Status="<font color=blue>LED2 熄滅</font>";
}
if (line.indexOf("GET /ON3") >= 0) {
Serial.println(line);
digitalWrite(LED3, HIGH); // GET /H turns the LED on
LED3_Status="<font color=red>LED3 點亮</font>";
}
if (line.indexOf("GET /OFF3") >= 0) {
Serial.println(line);
digitalWrite(LED3, LOW); // GET /L turns the LED off
LED3_Status="<font color=blue>LED3 熄滅</font>";
}
// wait for end of client's request, that is marked with an empty line
if (line.length() == 1 && line[0] == '\n')
{
String tmpString = MAIN_page; // 取出html網頁回應程式
tmpString.replace("%LED1_Status%", LED1_Status ); 帶入LED顯
示狀態至回應網頁
tmpString.replace("%LED2_Status%", LED2_Status );
tmpString.replace("%LED3_Status%", LED3_Status );
client.println( tmpString );
break;
}
}
}
delay(1); // give the web browser time to receive the data
// close the connection:
client.stop();
Serial.println("[Client disonnected]");
}
} // 主迴圈程式結束.
// 以下部分為「index.h」標籤頁面的內容:
const char MAIN_page[] PROGMEM = R"=====(
HTTP/1.1 200 OK
Content-Type:text/html
Connection: close
<!DOCTYPE html>
<html>
<head>
<meta name='viewport' content='width=device-width, initial-scale=1.0'/>
<meta charset='utf-8'>
<meta http-equiv='refresh' content='%rTime%'>
<style>
body {font-size:100%;}
#main {display: table; margin: auto; padding: 0 10px 0 10px; }
</style>
<title>Soft AP模式-使用超連結(href)控制多重輸出實習</title>
</head>
<body>
<div id='main'>
<h2><center>[Soft AP模式] <br>
使用超連結(href)控制多重輸出實習<br><br>
[ %LED1_Status% ]<br>
請按這裡 <a href='ON1'> 點亮 </a> LED1.<br>
請按這裡 <a href='OFF1'> 熄滅 </a> LED1.<br><br>
[ %LED2_Status% ]<br>
請按這裡 <a href='ON2'> 點亮 </a> LED2.<br>
請按這裡 <a href='OFF2'> 熄滅 </a> LED2.<br><br>
[ %LED3_Status% ]<br>
請按這裡 <a href='ON3'> 點亮 </a> LED3.<br>
請按這裡 <a href='OFF3'> 熄滅 </a> LED3.<br>
</center>
</h3>
</div>
</body>
</html>
)=====";
程式名稱:ESP32_softAP42_3Href.ino
為了配合實際的電路,在此定義了所使用的三隻輸出腳位(第10行),此外也將回應給客戶端的動態回應訊息增加為三個字串變數:
10. const int LED1=27,LED2=26,LED3=25;
11. String LED1_Status="<font color=blue>LED1 熄滅</font>" ,
12. LED2_Status="<font color=blue>LED2 熄滅</font>" ,
13. LED3_Status="<font color=blue>LED3 熄滅</font>";
這三個字串變數都是使用了html語法中的「font」元素,好讓『LED熄滅』這個回應訊息的文字顏色為藍色。至於初始化程式(setup())部分(29~39行),則是多了三行用來設定腳位輸出模式的指令:
pinMode(LED1, OUTPUT); // set the LED pin mode
pinMode(LED2, OUTPUT); // set the LED pin mode
pinMode(LED3, OUTPUT); // set the LED pin mode
而在主迴圈(loop())的部分(42~108行)和之前一樣,都是在不停的監聽是否有客戶端連線到本系統,假如有的話便使用”while()”(51~101行)這種流程控制方式去接收客戶端所傳送來的訊息,並在測試URI請求的內容後,執行對應的動作即依客戶端的請求,輸出高或低態信號至指定的輸出腳。59~68行在判斷客戶端所傳來的URI是代表點亮LED1的字串『"GET /ON1"』﹖還是熄滅LED1的『"GET /OFF1"』﹖再依照測試結果控制LED1的亮滅,並把訊息顯示在Arduino IDE的監控式窗;然後把兩種不同的回應訊息依測試結果放到字串變數「LED1_Status」上,在此『LED1點亮』這個回應訊息的文字顏色會設定成紅色,以便和表示LED熄滅時的藍色有所區別。
59. if (line.indexOf("GET /ON1") >= 0) {
60. Serial.println(line);
61. digitalWrite(LED1, HIGH); // GET /H turns the LED on
62. LED1_Status="<font color=red>LED1 點亮</font>";
63. }
64. if (line.indexOf("GET /OFF1") >= 0) {
65. Serial.println(line);
66. digitalWrite(LED1, LOW); // GET /L turns the LED off
67. LED1_Status="<font color=blue>LED1 熄滅</font>";
68. }
至於輸出2或是說LED2及輸出3,則分別由69~78行與79~88行負責。
再來就是回傳到網頁部分的字串變數改為「LED1_Status」~「LED3_Status」:
93. tmpString.replace("%LED1_Status%", LED1_Status ); 帶入LED顯
94. 示狀態至回應網頁
95. tmpString.replace("%LED2_Status%", LED2_Status );
96. tmpString.replace("%LED3_Status%", LED3_Status );
後面的111~151行是「index.h」這個頁面的內容,是一個完整的html網頁程式,在此也是使用C++語言中稱為原始字串 (Raw String) 的語法;其中的131、132行會實現【圖四、3-1】畫面上方的『[Soft AP模式] 使用超連結(href)控制多重輸出實習』的提示訊息,而134~144行則會將前面迴圈主程式所傳來的「LED1_Status」~「LED3_Status」字串變數帶入這個html網頁程式中,將最後的輸出結果回應給客戶端的使用者。
◎ 執行結果:
在程式執行之後,開啟手機/平板/筆電的WiFi功能,在看到”ESP32_softAP01”這個AP存取點後點選它,接著啟動瀏覽器,並在網址輸入欄中輸入[ 192.168.4.1 ]這個IP位址並前往。如果連線正常將會看到【圖四、3-5】的畫面,最左邊是客戶端連線上系統內建伺服器的首頁畫面,同時也是三組控制超連接都點選「”熄滅”」這個選項時顯示的網頁頁面,此時電路上所有的LED是熄滅狀態。而畫面右邊則是全部點選「”點亮”」這個超連結選項時,客戶端所看到的網頁畫面,同時也會點亮所有的LED。
圖四、3-5 客戶端瀏覽器各種輸出控制畫面
圖四、3-6 ESP32開發板電路各種輸出控制對應狀況畫面
至於【圖四、3-6】照片的內容,則是對應【圖四、3-5】四種客戶端瀏覽器畫面的實際電路輸出狀況。
沒有留言:
張貼留言