在上一節的《四、4 使用超連結(href)的方式控制多重輸出之二》中,已經把控制的輸出數目擴充了,並且也把操作的連接文字縮減為一行,讓畫面看起更精簡一些,但是這種使用文字的超連結形式看起來還是不夠美觀與方便,接下來我們就把輸出控制的介面再修改成按鈕的形式,好讓使用者更容易使用於操作,而且畫面看起來更簡潔與美觀。
◎ 範例程式功能與動作說明:
1、以ESP32建立一無線WiFi AP存取點,此AP存取點SSID名稱為 『ESP32_softAP01』,而且不使用密碼,該AP存取點內建伺服器的IP位址為:[ 192.168.4.1 ]。
2、當客戶端裝置連線上ESP32內建伺服器首頁時(也就是只鍵入IP網址[ 192.168.4.1 ]),系統會回應下面【圖四、5-1】的首頁網頁畫面給客戶端。畫面中下方共有三組按鈕型的超連結輸出控制,在每一組控制輸出的上方,即標記1處的輸出提示訊息為『[GPIO25:LOW 🡪 LED1熄滅]』,一眼即可看出目前該輸出腳的編號與狀態,及接在這根輸出腳的LED亮滅情形;而位於標記2文字為「”點亮(On)”」的按鈕式超連結選控制項,則是代表按下此鍵的功能,也就是讓對應的輸出腳輸出高態好讓LED點亮;這個網頁程式一開啟時所有的輸出都是低態,所以其輸出提示訊息的文字顏色都是藍色,而超連結選控制按鈕的底色則為粉紅色。
圖四、5-1 系統首頁網頁連線啟動後客戶端瀏覽器畫面
3、當使用者點選上圖中標記2的「”點亮”」這個超連結選項時,系統會回應下面【圖四、5-2】的網頁畫面給客戶端,除了畫面中標記1的『[GPIO25:LOW 🡪 LED1點亮]』回應訊息文字部分的顏色會變為紅色之外,上圖中標記2的「”點亮”」超連結選項會改成「”熄滅(Off)”」。如果使用者點選下面【圖四、5-2】的標記2的「”熄滅(Off)”」超連結選項時,整個LED狀態回應訊息與超連結控制的文字部分又會回到上面的【圖四、5-1】畫面,也就是說輸出狀態的切換控制只用一個按鈕式的超連結點就可以了。
圖四、5-2 點選”點亮”超連結選項後客戶端瀏覽器畫面
◎電路圖:
圖四、5-3 使用ESP32開發板控制三顆LED亮滅電路
本實習和上一小節一樣,使用ESP32開發板(類似NodeMcu)控制三顆LED燈,同樣是採用GPIO25、26、27這三隻接腳。
◎程式列表與說明:
/*
ESP32 soft AP 範例四 : 四、5 使用超連結(href)方式控制多重輸出之三—
採用按鈕介面形式
*/
#include <WiFi.h>
#include "index.h"
const char* ssid = "ESP32_softAP01";
const char* password = "12345678";
const int LED1=25,LED2=26,LED3=27;
String LED1_Status="<font color=blue>GPIO25:Low --> LED1 熄滅</font>",
LED2_Status="<font color=blue>GPIO26:Low --> LED2 熄滅</font>",
LED3_Status="<font color=blue>GPIO27:Low --> LED3 熄滅</font>";
String buttonOn="ON'> <button class='button'>點亮(On)</button> </a>",
buttonOff="OFF'> <button class='button2'>熄滅(Off)</button>";
String LED1_Href="<a href='1"+buttonOn,
LED2_Href="<a href='2"+buttonOn,
LED3_Href="<a href='3"+buttonOn;
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);
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)
{
// currentTime = millis();
connectTime = millis();
Serial.println("\n[Client connected]");
while (client.connected() && millis() - connectTime <= timeoutTime)
{
// currentTime = millis();
// 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 /1ON") >= 0) {
Serial.println(line);
digitalWrite(LED1, HIGH); // GET /H turns the LED on
LED1_Status="<font color=red>GPIO25:High --> LED1 點亮</font>";
LED1_Href="<a href='1"+buttonOff;
}
if (line.indexOf("GET /1OFF") >= 0) {
Serial.println(line);
digitalWrite(LED1, LOW); // GET /L turns the LED off
LED1_Status="<font color=blue>GPIO25:Low --> LED1 熄滅</font>";
LED1_Href="<a href='1"+buttonOn;
}
if (line.indexOf("GET /2ON") >= 0) {
Serial.println(line);
digitalWrite(LED2, HIGH); // GET /H turns the LED on
LED2_Status="<font color=red>GPIO26:High --> LED2 點亮</font>";
LED2_Href="<a href='2"+buttonOff;
}
if (line.indexOf("GET /2OFF") >= 0) {
Serial.println(line);
digitalWrite(LED2, LOW); // GET /L turns the LED off
LED2_Status="<font color=blue>GPIO26:Low --> LED2 熄滅</font>";
LED2_Href="<a href='2"+buttonOn;
}
if (line.indexOf("GET /3ON") >= 0) {
Serial.println(line);
digitalWrite(LED3, HIGH); // GET /H turns the LED on
LED3_Status="<font color=red>GPIO27:High --> LED3 點亮</font>";
LED3_Href="<a href='3"+buttonOff;
}
if (line.indexOf("GET /3OFF") >= 0) {
Serial.println(line);
digitalWrite(LED3, LOW); // GET /L turns the LED off
LED3_Status="<font color=blue>GPIO27:Low --> LED3 熄滅</font>";
LED3_Href="<a href='3"+buttonOn;
}
// 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 ); // 帶入LED1
狀態至回應網頁
tmpString.replace("%LED2_Status%", LED2_Status );
tmpString.replace("%LED3_Status%", LED3_Status );
tmpString.replace("%LED1_Href%", LED1_Href ); // 帶入LED1超連
結狀態至回應網頁
tmpString.replace("%LED2_Href%", LED2_Href );
tmpString.replace("%LED3_Href%", LED3_Href );
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'>
<link rel=\"icon\" href=\"data:,\">
<style>
body {font-size:110%;}
#main {display: table; margin: auto; padding: 0 10px 0 10px; }
.button {padding:10px 10px 10px 10px; width:50%; background-color:pink; font-
size:110%;}
.button2 {padding:10px 10px 10px 10px; width:50%; background-color:yellowgreen;
font-size:110%;}
</style>
<title>Soft AP模式-使用超連結(href)控制多重輸出實習3</title>
</head>
<body>
<div id='main'>
<h3><center>[Soft AP模式] <br>
使用超連結(href)按鈕控制多重輸出實習3<br><br>
[ %LED1_Status% ]<br>
%LED1_Href%<br><br>
[ %LED2_Status% ]<br>
%LED2_Href%<br><br>
[ %LED3_Status% ]<br>
%LED3_Href%<br>
</center>
</h3>
</div>
</body>
</html>
)=====";
程式名稱:ESP32_softAP42_3Href2.ino
在本範例程式中變數定義部分,三個回應給客戶端的訊息字串變數「LED1_Status」~ 「LED1_Status」有稍作修改,以顯示所使用I/O腳位:
11. String LED1_Status="<font color=blue>GPIO25:Low --> LED1 熄滅</font>",
12. LED2_Status="<font color=blue>GPIO26:Low --> LED2 熄滅</font>",
13. LED3_Status="<font color=blue>GPIO27:Low --> LED3 熄滅</font>";
此外為了配合新增的兩種按鈕元件,也增加了兩個不同功能的字串變數:
14. String buttonOn="ON'> <button class='button'>點亮(On)</button> </a>",
15. buttonOff="OFF'> <button class='button2'>熄滅(Off)</button>";
當然三個回應給客戶端的動態超聯結字串變數「LED1_Href」~ 「LED3_Href」也必須跟修改以配合所使用的按鈕元件:
16. String LED1_Href="<a href='1"+buttonOn,
17. LED2_Href="<a href='2"+buttonOn,
18. LED3_Href="<a href='3"+buttonOn;
至於初始化程式(setup())部分(25~43行)和上一個範例完全相同。
而在主迴圈(loop())的部分(46~120行)和上一個範例的差異,主要是在”while()”(54~113行)這個流程控制中測試URI請求的部分,其中61~72行在判斷客戶端所傳來的URI是代表點亮LED1的字串『"GET /ON1"』﹖還是熄滅LED1的『"GET /OFF1"』﹖再依照測試結果控制LED1的亮滅,並把訊息顯示在Arduino IDE的監控式窗,而且也把對應的輸出回應訊息放到字串變數「LED1_Status」上,並把下一次要使用的超連結控制按鈕傳送到字串變數「LED1_Href」,最後再帶入html網頁程式中。
61. if (line.indexOf("GET /1ON") >= 0) {
62. Serial.println(line);
63. digitalWrite(LED1, HIGH); // GET /H turns the LED on
64. LED1_Status="<font color=red>GPIO25:High --> LED1 點亮</font>";
65. LED1_Href="<a href='1"+buttonOff;
66. }
67. if (line.indexOf("GET /1OFF") >= 0) {
68. Serial.println(line);
69. digitalWrite(LED1, LOW); // GET /L turns the LED off
70. LED1_Status="<font color=blue>GPIO25:Low --> LED1 熄滅</font>";
71. LED1_Href="<a href='1"+buttonOn;
72. }
至於輸出2及輸出3部分,則分別由73~84行與85~96行負責。
再來就是回傳到html網頁程式部分(100~109行),和上一個範例完全一樣:
100. String tmpString = MAIN_page; // 取出html網頁回應程式
101. tmpString.replace("%LED1_Status%", LED1_Status ); // 帶入LED1
102. 狀態至回應網頁
103. tmpString.replace("%LED2_Status%", LED2_Status );
104. tmpString.replace("%LED3_Status%", LED3_Status );
105. tmpString.replace("%LED1_Href%", LED1_Href ); // 帶入LED1超連
106. 結狀態至回應網頁
107. tmpString.replace("%LED2_Href%", LED2_Href );
108. tmpString.replace("%LED3_Href%", LED3_Href );
109. client.println( tmpString );
後面的123~164行是「index.h」這個頁面的內容,是回應給發出請求的客戶端的html網頁程式;和之前範例的主要差異之處,是在137~144行的CSS語法區(<style>……</style>)中,多了兩個按鈕外觀的定義:
140. .button {padding:10px 10px 10px 10px; width:50%;
141. background-color:pink; font-size:110%;}
142. .button2 {padding:10px 10px 10px 10px; width:50%;
143. background-color:yellowgreen; font-size:110%;}
接著在146、147行中實現【圖四、5-1】畫面上方的『[Soft AP模式] 使用超連結(href)按鈕控制多重輸出實習3』的提示訊息,而153~160行則會將前面迴圈主程式所傳來的「LED1_Status」~「LED3_Status」與「LED1_Href」~ 「LED3_Href」這兩組字串變數帶入這個html網頁程式中,最後把輸出結果回應給客戶端的瀏覽器。
153. [ %LED1_Status% ]<br>
154. %LED1_Href%<br><br>
155.
156. [ %LED2_Status% ]<br>
157. %LED2_Href%<br><br>
158.
159. [ %LED3_Status% ]<br>
160. %LED3_Href%<br>
◎ 執行結果:
在程式執行之後,開啟手機/平板/筆電的WiFi功能,在看到”ESP32_softAP01”這個AP存取點後點選它,接著啟動瀏覽器,並在網址輸入欄中輸入[ 192.168.4.1 ]這個IP位址並前往。如果連線正常將會看到【圖四、5-1】的畫面,而下面的【圖四、5-4】網頁畫面是客戶端瀏覽器各種輸出控制回應畫面,當上方訊息是LED點亮或輸出腳輸出為High時,下面的超連結選項按鈕文字會呈現「”熄滅”」,反之如果上方訊息是LED熄滅或輸出腳輸出為Low時下面的超連結選項按鈕文字會呈現「”點亮”」。
圖四、5-4 客戶端瀏覽器各種輸出控制回應畫面
沒有留言:
張貼留言