2020年11月7日 星期六

四、3 使用超連結(href)的方式控制多重輸出之一


在上一節的《四、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開發板。


程式列表與說明

以下是這個範例的完整程式列表內容:



  1. /*

  2.   ESP32 soft AP 範例四 : 四、3  使用超連結(href)的方式控制多重輸出之一

  3.  */

  4.  

  5. #include <WiFi.h>

  6. #include  "index.h"

  7.  

  8. const char* ssid     = "ESP32_softAP01";

  9. const char* password = "12345678";

  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>";

  14.  

  15. unsigned long connectTime = 0; 

  16. const long timeoutTime = 3000;

  17.  

  18. WiFiServer server(80);

  19.  

  20. // 初始化設定程式開始:

  21. void setup()

  22. {

  23.     Serial.begin(115200);

  24.     pinMode(LED1, OUTPUT);      // set the LED pin mode

  25.     pinMode(LED2, OUTPUT);      // set the LED pin mode

  26.     pinMode(LED3, OUTPUT);      // set the LED pin mode

  27.  

  28.     delay(10);

  29.  

  30.     // We start by connecting to a WiFi network

  31.     WiFi.softAP(ssid);

  32.     Serial.println("Setting softAP ...");

  33.     Serial.println();

  34.     Serial.print("Your softAP is : ");

  35.     Serial.println(ssid);

  36.     Serial.println("IP address: ");

  37.     Serial.println(WiFi.softAPIP());

  38.     

  39.     server.begin();

  40. }   // 初始化設定程式結束.

  41.  

  42. // 主迴圈程式開始:

  43. void loop(){

  44.  

  45.   WiFiClient client = server.available();   // listen for incoming clients

  46.   // wait for a client (web browser) to connect

  47.   if (client)

  48.   {

  49.     connectTime = millis();

  50.     Serial.println("\n[Client connected]");

  51.     while (client.connected() && (millis() - connectTime <= timeoutTime))

  52.     {

  53.       // read line by line what the client (web browser) is requesting

  54.       if (client.available())

  55.       {

  56.         String line = client.readStringUntil('\r');

  57. //        Serial.print(line);

  58.         // Check to see if the client request was "GET /H" or "GET /L":

  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.         }

  69.         if (line.indexOf("GET /ON2") >= 0) {

  70.           Serial.println(line);

  71.           digitalWrite(LED2, HIGH);      // GET /H turns the LED on

  72.           LED2_Status="<font color=red>LED2 點亮</font>";

  73.         }

  74.         if (line.indexOf("GET /OFF2") >= 0) {

  75.           Serial.println(line);

  76.           digitalWrite(LED2, LOW);        // GET /L turns the LED off

  77.           LED2_Status="<font color=blue>LED2 熄滅</font>";

  78.         }

  79.         if (line.indexOf("GET /ON3") >= 0) {

  80.           Serial.println(line);

  81.           digitalWrite(LED3, HIGH);        // GET /H turns the LED on

  82.           LED3_Status="<font color=red>LED3 點亮</font>";

  83.         }

  84.         if (line.indexOf("GET /OFF3") >= 0) {

  85.           Serial.println(line);

  86.           digitalWrite(LED3, LOW);         // GET /L turns the LED off

  87.           LED3_Status="<font color=blue>LED3 熄滅</font>";

  88.         }

  89.         // wait for end of client's request, that is marked with an empty line

  90.         if (line.length() == 1 && line[0] == '\n')

  91.         {

  92.      String tmpString = MAIN_page;    // 取出html網頁回應程式

  93.      tmpString.replace("%LED1_Status%", LED1_Status ); 帶入LED顯

  94. 示狀態至回應網頁

  95.      tmpString.replace("%LED2_Status%", LED2_Status );

  96.        tmpString.replace("%LED3_Status%", LED3_Status );

  97.      client.println( tmpString );

  98.            break;

  99.         }

  100.       }

  101.     }

  102.     delay(1); // give the web browser time to receive the data

  103.  

  104.     // close the connection:

  105.     client.stop();

  106.     Serial.println("[Client disonnected]");

  107.   }

  108. }   // 主迴圈程式結束.

  109.  

  110. // 以下部分為「index.h」標籤頁面的內容:

  111. const char MAIN_page[] PROGMEM = R"=====(

  112. HTTP/1.1 200 OK

  113. Content-Type:text/html

  114. Connection: close

  115.  

  116. <!DOCTYPE html>

  117. <html>

  118.  <head>

  119.   <meta name='viewport' content='width=device-width, initial-scale=1.0'/>

  120.   <meta charset='utf-8'>

  121.  <meta http-equiv='refresh' content='%rTime%'>

  122.   <style>

  123.     body {font-size:100%;} 

  124.     #main {display: table; margin: auto;  padding: 0 10px 0 10px; } 

  125.   </style>

  126.   <title>Soft AP模式-使用超連結(href)控制多重輸出實習</title>

  127.  </head>

  128.  

  129.  <body> 

  130.    <div id='main'>

  131.      <h2><center>[Soft AP模式] <br>

  132.          使用超連結(href)控制多重輸出實習<br><br>

  133.  

  134.          [ %LED1_Status% ]<br>

  135.          請按這裡 <a href='ON1'> 點亮 </a> LED1.<br>

  136.          請按這裡 <a href='OFF1'> 熄滅 </a> LED1.<br><br>

  137.          

  138.          [ %LED2_Status% ]<br>

  139.          請按這裡 <a href='ON2'> 點亮 </a> LED2.<br>

  140.          請按這裡 <a href='OFF2'> 熄滅 </a> LED2.<br><br>

  141.          

  142.          [ %LED3_Status% ]<br>

  143.          請按這裡 <a href='ON3'> 點亮 </a> LED3.<br>

  144.          請按這裡 <a href='OFF3'> 熄滅 </a> LED3.<br>

  145.          </center>

  146.      </h3>

  147.    </div> 

  148.  </body>

  149. </html>

  150.  

  151. )=====";

程式名稱: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】四種客戶端瀏覽器畫面的實際電路輸出狀況


沒有留言:

張貼留言

三、使用Line Notify傳送照片之安全監控系統之二---低功耗篇

在前一個章節中 , 我們建構了一個標準照片擷取 、 傳送與儲存的按全監控裝置 , 不過假如我們使用的場域中有許多的地方都必須按裝這類的裝置時 , 例如在一個有許多門 、 窗的家庭或辦公室 , 由於我們的系統使用無線WiFi作為信號傳輸之用 , 所以信號的傳輸除非裝置離WiFi分享...