2020年6月6日 星期六

ESP8266應用篇:手機WiFi遙控密碼鎖



前言

在之前的範例的中,我們曾設計一個以手機WiFi直接遙控一個使用ESP-01模組的繼電器板,然後再去控制一些較大電力的開關或是燈具等家電的例子,而這些設備的特性就是比較不需要考慮到隱密性或安全性的問題,如果要提高使用的安全性,只要把ESP8266的AP上加上一組比較長或者難記的連線密碼就應該可了!

如果我們想要把這個系統拿來控制公司單位或者公寓大樓的出入門戶或者是常見的置物櫃及電鎖等設備時安全性就不太夠了因此本單元打算把之前的手機遙控開關裝置進階為具有密碼功能的控制系統這樣一來就可以使用在一些需要比較高安全性的場合了

由於我們使用的是所謂乾接點的繼電器去控制其他電子裝置因此可以不受該裝置所使用的電源種類與消耗功率的限制只要更改該裝置的種類便可應用在許多不同的場所;例如接上電磁鎖便可以使用在公寓大廈或者建築物的門禁管制上或是公用的保管箱、置物櫃等。接下來就讓我們看看這個裝置具有的功能與動作內容。


系統功能與動作說明

1、本系統使用ESP6266/ESP-01繼電器模組板設計一具密碼功能的無線WiFi遙控開關裝置,此裝置鎖使用的密碼可為數字或英文字母且長度不限制。

2、使用者可使用任何一款具有無線WiFi介面的手機平板電腦或筆記型電腦作為控制的裝置,只要該裝置內建有網頁瀏覽器即可不必考慮該裝置的作業系統為何

3、本裝置設計為一網頁的伺服器當使用者連接上本裝置內建的網頁伺服器首頁時在密碼輸入欄位鍵入正確的密碼後按下一【開啟(On)】按鈕,便可啟動繼電器動作一段特定的時間然後再回復原來關閉的狀態此繼電器動作的時間可依所驅動裝置的不同由設計者改變且動作的結果會回傳到連線裝置瀏覽器的螢幕上讓使用者知道。


本次製作所使用的零件是目前市面上很流行的ESP8266/ESP-01繼電器WiFi模組],它的外觀如下面的【圖一】所示

ESP-01_Relay

圖一、 ESP8266/ESP-01 WiFi繼電器模組外觀


在圖中左上方的是ESP8266/ESP-01 WiFi繼電器模組完整外觀而右上方的照片是拿掉ESP-01後的零件上視圖其中用紅線框起來標記1的部分是LED動作的指示LED燈也是ESP-01這塊模組上的GP00腳從照片中可看出模組上的繼電器接點可以承受10Amp的電流,其工作電壓交流可到250VAC,當使用在一般家庭的125VAC電源也可以控制到1250Watt的功率,這麼大的功率對一般的應用來說應該是很夠了

至於模組左上方標記2黃色8Pin的插座,是供ESP-01模組連接用的插座,如果參考下方的底視圖可得知,中間標記3綠色2Pin的接線栓是這塊模組的電源輸入腳,工作電壓是5V。至於右邊標記4綠色3Pin的接線栓則是模組上的繼電器輸出控制腳這個繼電器是所謂的單刀雙擲(SPDT)型繼電器其中的”COM”是共同腳”NC”是常閉接點而”NO”則是常開接點至於要如何使用就依個人的需要了一般來說是使用”COM”與”NO”腳也就是不動作(Off)時兩個點是開路的當按下開(ON)或啟動時才會連接在一起

ESP-01s

圖二、 ESP-01S WiFi模組外觀與接腳名稱


【圖二】是ESP-01S WiFi模組的外觀與接腳名稱,ESP-01這個系列的模組板,可說是ESP8266這個WiFi單晶片的起家模組,由於便宜又容易使用,早就被許多業餘玩家或專業人士所廣泛使用;目前最新的版本是ESP-01S,不過接腳數目與功能還是跟以前一樣,其接腳編號與功能名稱如下:


  1. GND :ESP-01電源接地腳

  2. U0TXD/GPIO1 :非同步串列傳輸埠(UART)0的發送腳

  3. GPIO2/U1TXD :主要功能為輸出/入腳GPIO02

  4. CH_PD/Chip_EN :晶片致能腳燒錄時須接到VCC

  5. GPIO00 :輸出/入腳GPIO00燒錄時須接地

  6. EXT_RSTB :晶片重置腳

  7. U0RXD/GPIO3 :非同步串列傳輸埠(UART)0的接收腳

  8. VCC/3.3V :ESP-01電源的+輸入腳電壓為3.3V過高會燒毀


【圖二】左邊ESP-01S模組板右下方用紅線框起來的地方,是併接在「GPIO2/U1TXD」腳的一顆LED顯示器,當燒錄程式時這顆LED會隨之閃爍,等燒錄完成後便可以拿來當成輸出/入腳使用。在燒錄ESP-01時,除了要接上與電腦連接的U0TXD (Pin2)與U0RXD(Pin7)之外,在接上電源之前CH_PD(Pin4)與GPIO00(Pin5)還必須分別接到VCC(Pin8/3.3V)及GND電位,否則會無法正常燒錄!由於ESP-01系列模組並不具有與電腦連接的介面,所以大多是使用USB轉UART/RS232模組來燒錄(如【圖三】所示)


ESP-01燒錄接線圖2

圖三 使用USB轉UART模組燒錄ESP-01


不過對初學者來說還是經常會弄錯腳位甚至接到5V的電源以致於將ESP-01模組燒毀為了一勞永逸建議使用圖四】所示的ESP-01專用USB轉UART燒錄模組這樣既方便使用又不必擔心把ESP-01燒壞了


USB2ESP01

圖四、 常見USB轉ESP-01 UART燒錄模組


在之前面的章節介紹過的ESP-202實驗模組板,也可以拿來燒錄ESP-01下面的圖五】介紹了ESP-202 WiFi模組板外觀接腳名稱與連接ESP-01方法。如果把ESP-202當成ESP-01燒錄器使用和原來作為實驗板的差別有兩點一是標記1所示的兩個跳線接頭的位置如果兩個接頭都在左邊是作為實驗板之用此時程式會直接燒錄在板子上面的ESP8266郵票板如果要拿來燒錄外接的ESP-01,那麼兩個跳線接頭都必須移到在右邊不過此時標記2的兩個指撥開關的位置就必須撥在1下(OFF)2上(ON)的地方這剛好和當成試驗板用時相反

ESP-202_ESP-01

圖五、 ESP-202 WiFi模組板外觀接腳名稱與連接ESP-01方法


由於我們的系統裝置是使用瀏覽器來操作的所以可以先寫一段html的網頁程式在PC電腦上演練驗證無誤後再移植到ESP8266上下面的《WiFi_Locker.html》程式便是此測試及驗證用的html程式



 

1. <!DOCTYPE html>

2. <html>

3. <head>

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

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

6.    <link rel='icon' href='data:,\'>

7.    <style>body {font-size:140%;} #main {display:table; margin:auto;padding:0 10px 0 10px;}

8.       h3,{text-align:center;} h4,{text-align:center;} 

9.    .button {padding:10px 10px 10px 10px; width:40%; background-color: pink;font-size:100%;}

10.      .text1 {padding:5px 5px 5px 5px; width:40%; font-size:100%;}    

11.      .password {padding:5px 5px 5px 5px; width:60%; font-size:70%;}    

12.    </style>

13.  </head>

14.  <body>

15.     <center>

16.      <h3>[ 手機WiFi遙控密碼鎖:]<br><br>

17. 密碼鎖目前狀態 : 關閉(Off)<br></h3>

18.

19.  <form ><h4>請輸入密碼 : <input class='text1' type='text' name='password' size='30'value=''>

20.   <br><br>

21.   <input class='button'  type='submit' value='開啟(On)'></h4>

22. </form>

23.    </center>

24.  </body>

25. </html>



程式名稱WiFi_Locker.html


在這個程式中我們使用html語法中的表單(form)標籤架構,來完成使用者的人機控制UI介面。所謂表單(form)是html語法中一種可以提供輸入的介面,可讓使用者輸入資料,然後將資料回傳給網路伺服器的一種元素元件表單的建立包含兩個部份:


  1. 先使用<form>……</form>和<input>這兩個標籤元素建立我們所要的操作表單介面。

  2. 設計表單傳回資料的後端處理程式。


前面的html程式(“WiFi_Locker.html”)便是用來實現表單的第一個部份,當我們用電腦的瀏覽器開啟它時,可看到【圖六a】的畫面其中標記1用紅色線框起來的部分是一個類別(class)為文字(text)的輸入(input)元素,在此可以輸入啟動繼電器用的密碼。而下方標記2文字為「開啟(On)」的按鈕一看就可知道是控制繼電器啟動之用是一個類別(class)為提交(submit)的元素在被按下之後會把上面標記1中所輸入的文數字傳送到由ESP8266所建構的網頁伺服器上而標記3的「密碼鎖目前狀態 : 關閉(Off)」這段文字則是顯示目前ESP8266/ESP-01 WiFi繼電器模組上繼電器的狀態


圖六a 、 《WiFi_Locker.html》程式於電腦瀏覽器執行結果


要實現這樣一個網頁畫面,首先我們在程式的7~12行撰寫了一段CSS語法,用來定義送出(submit)用的按鈕(button) (第9行)與輸入用的文字(text1)元素(第10行)的外觀,其中按鈕”button”的顏色是粉紅色(pink)。至於第11行的「password」則是專為輸入密碼用的元素會令使用者輸入的密碼值以《*》符號取代以達到提高隱密性的要求為方便測試與驗證在此暫我們不使用這個元素



9.    .button {padding:10px 10px 10px 10px; width:40%; background-color: pink;font-size:100%;}

10.      .text1 {padding:5px 5px 5px 5px; width:40%; font-size:100%;}    

11.      .password {padding:5px 5px 5px 5px; width:60%; font-size:70%;}     


【圖六a】畫面中所呈現的內容共有四個部分是由程式16~22行所構成最上面的一行是不會變動的提示文字[ 手機WiFi遙控密碼鎖:](第16行)第二行標記3的「密碼鎖目前狀態 : 關閉(Off)」文字(第17行)是用來顯示密碼鎖目前的狀態這部分的內容會隨著密碼鎖(繼電器)當下實際的狀態而改變第三行則是標記2的按鈕(button)在此是用來送出密碼以啟動密碼鎖(繼電器)由於這個密碼鎖只有單一的啟動動作所以這個按鈕的提示文字與顏色在使用的過程中不需要做任何改變

接著的19~22行是<form>這個標籤的內容必須以</form>結束夾在中間的是<input>這個元素<input>的種類有很多,例如”text””password””radio””submit”…..等等;在19行我們使用「text」這個元素作為密碼輸入之而且也給這個元素設定了”password”這樣的變數名稱(不是前面提到的「password」元素)至於21行則是定義了一個”submit”按鈕元素也就是所謂的送出提交按鈕,。


16.      <h3>[ 手機WiFi遙控密碼鎖:]<br><br>

17. 密碼鎖目前狀態 : 關閉(Off)<br></h3>

18.

19.  <form ><h4>請輸入密碼 : <input class='text1' type='text' name='password' size='30'value=''>

20.   <br><br>

21.   <input class='button'  type='submit' value='開啟(On)'></h4>

22. </form>


下面這段html語法程式的意思是設定按鈕種類作為提交(type=’submit’)之用,按鈕上的提示文字(value)為【開啟(On)】,而按鈕的外觀長相(class)就是前面提到的CSS所定義底色是粉紅的’button’。

<input class='button'  type='submit' value='開啟(On)'>

這個按鈕被按下時會把第19行文字欄(“text”)所輸入的密碼內容提交回傳給我們的ESP8266網頁伺服器而且它的變數名稱(即”password”)也會一併被送出這樣一來由ESP8266所構成的表單傳回資料的後端處理程式便可辨識出這筆資料是使用者所輸入的密碼

當手機實際連接上ESP8266所構成的伺服器時,首先會看前面的【圖六a】這個螢幕畫面當使用者輸入密碼(標記1)並按下【開啟(On)】按鈕將密碼送出後如果密碼錯誤將會看到【圖六b】的密碼輸入錯誤回應畫面其中標記2的「輸入密碼錯誤!」文字訊息就是用來告知使用者輸入的密碼不正確。假如密碼是正確的,則會出現【圖六c】的畫面,和【圖六a】畫面來比較差別只有標記1的訊息變成「密碼鎖目前狀態 : 開啟(On)」而已。由於一般門禁或櫥櫃之類的裝置使用的都是所謂的電磁鎖它們共通的特點就是在作動時只會啟動一段短暫的時間因此我們的系統的繼電器也必須設計成只動作一段短暫的時間所以畫面看到密碼鎖已經開啟的訊息並不代表繼電器還在啟動


圖六b 密碼輸入錯誤回應畫面


圖六c、 密碼正確電鎖啟動畫面


程式列表與說明


  1.  #include  <ESP8266WiFi.h>

  2.  

  3. //----------------------------------------------

  4. // 將我們的HTML 網頁程式內容直接建構在program memory內:

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

  6. HTTP/1.1 200 OK

  7. Content-Type:text/html

  8. Connection: close

  9.  

  10. <!DOCTYPE html>

  11. <html>

  12.   <head>

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

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

  15.     <link rel='icon' href='data:,\'>

  16.     <style>body {font-size:140%;} #main {display:table; margin:auto;padding:0 10px 0 10px;}

  17.        h3,{text-align:center;} h4,{text-align:center;} 

  18.       .button {padding:10px 10px 10px 10px; width:40%; background-color: pink; font-size:100%;}

  19.       .text1 {padding:5px 5px 5px 5px; width:40%; font-size:100%;}    

  20.       .password {padding:5px 5px 5px 5px; width:60%; font-size:70%;}    

  21.     </style>

  22.   </head>

  23.   <body>

  24.      <center>

  25.       <h3>[ 手機WiFi遙控密碼鎖:]<br><br>

  26. )=====";

  27. //---------------------------------------------------

  28.  

  29. const char* softSsid = "ESP_softAP002";

  30. const char* password = "12345678";

  31. const byte LED_Pin=2;     

  32. String  URI;

  33. int lockOnTime=1000;

  34. String  lockerPW="123321";

  35.  

  36. String  html_Echo="";

  37. String  lockOff="密碼鎖目前狀態 : 關閉(Off)<br><h3/>";

  38. String  lockOn="密碼鎖目前狀態 : 開啟(On)<br><h3/>";

  39. String  passwordError="密碼輸入錯誤!!";

  40. String  formStart="<form ><h3>請輸入密  碼 : <input class='text1' type='text' name='password' size='30' value=''><br><br>";

  41. String  pageEnd="<input class='button'  type='submit' value='開啟(On)'></h4></form></center></body></html>";

  42.  

  43. WiFiServer  server(80);

  44. WiFiClient  client;

  45.  

  46. void setup() {

  47.   // put your setup code here, to run once:

  48.   pinMode(LED_Pin,OUTPUT);

  49.   digitalWrite(LED_Pin,1);

  50.   Serial.begin(115200);

  51.   

  52.   Serial.println();

  53.   Serial.print("Setting soft-AP with configuratin... ");

  54. //  WiFi.softAPConfig(local_IP,gateway,subnet);

  55.   boolean result=WiFi.softAP(softSsid,password);

  56.   if(!result)

  57.   {

  58.     Serial.println("soft-AP failed");

  59.     for(;;)

  60.     {

  61.       digitalWrite(LED_Pin,0);

  62.       delay(200);

  63.       digitalWrite(LED_Pin,1);

  64.       delay(200);

  65.     }

  66.   }  

  67.     Serial.println("soft-AP ready!");

  68.     Serial.print("softAP = ");

  69.     Serial.println(softSsid);

  70.     Serial.print("softIP = ");

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

  72.   server.begin();

  73. }

  74.  

  75. void loop() {

  76.   client=server.available();

  77.   if(!client) 

  78.     return;

  79.  

  80.   URI=Get_URI();   // 取得客戶端GET請求內容全部轉成大寫

  81.  

  82.   Serial.println("Request end!");

  83.   Serial.print("Uri = ");

  84.   Serial.println(URI);

  85.   if(URI.indexOf("PASSWORD")>0)

  86.       checkPassword();

  87.   else

  88.       handleRoot();

  89.   delay(50);

  90. }

  91.  

  92. // 網頁首頁副程式:

  93. void handleRoot(){

  94.   String s=MAIN_page;

  95.   s+=lockOff;

  96.   s+=formStart;

  97.   s+=pageEnd;

  98.   client.println(s);

  99.   client.println();

  100.   Serial.println("Client is connected!");

  101.   Serial.println();

  102. } // 網頁首頁副程式結束

  103.  

  104. //  密碼檢查比對副程式:

  105. void checkPassword() {

  106.   

  107.     String pwWiFi=URI.substring(URI.indexOf("PASSWORD")+9);

  108.     pwWiFi.trim();                    // 將密碼後的空格去除

  109.     Serial.print("密碼值為 : [");

  110.     Serial.print(pwWiFi);

  111.     Serial.println("]");

  112.  

  113.   String s=MAIN_page;

  114.     if(pwWiFi.equals(lockerPW))

  115.     {

  116.       s+=lockOn;

  117.     }

  118.     else

  119.     {

  120.       s+=passwordError;

  121.       Serial.println("密碼錯誤!");

  122.     }

  123.   s+=formStart;

  124.   s+=pageEnd;

  125.   client.println(s);

  126.   client.println();

  127.     if(pwWiFi.equals(lockerPW))

  128.     {

  129.       digitalWrite(LED_Pin,0);

  130.       delay(lockOnTime);

  131.       digitalWrite(LED_Pin,1);

  132.     }

  133.   Serial.println("密碼處理完成");

  134.   Serial.println();

  135. }

  136.  

  137. // URI接收副程式:

  138. String Get_URI()

  139. {

  140. //  WiFiClient client;

  141.   String request="",Uri="";

  142.   while(client.connected())

  143.   {   // 等待第一行"GET"請求結束

  144.       Uri=client.readStringUntil('\r');

  145. //  Serial.println(Uri);

  146.       request+=Uri;

  147.       if(Uri=="\n")

  148.          break;         // 第一行"GET"請求結束,結束while等待迴圈

  149.   }

  150.     client.flush();

  151.   request.toUpperCase();   // 將GET請求內容全部轉成大寫

  152.   Uri=request.substring(request.indexOf("/"),request.indexOf("HTTP/"));

  153.   Serial.println("客戶端發送結束!");

  154.   Serial.print("URI內容-->[ ");

  155.   Serial.print(Uri);

  156.   Serial.println("]");

  157.   Serial.println();

  158.   return Uri;

  159. }   // Get_Uri()副程式結束



程式名稱softAP_6_5_1Led6_RY0.ino


程式說明

為了程式相容性的問題在這個製作的範例程式中我們只引用了<ESP8266WiFi.h>這個最基礎的函式庫而已;接著的5~28行是在實作《WiFi_Locker.html》這個html網頁程式的前半段(1~16行),由於整個螢幕畫面實際上只有回應訊息會變動所以我們把密碼電鎖回應訊息的html語言部分以下面“lockOn””lockOff”及”passwordError”這三個html語法的字串變數來取代


37. String  lockOff="密碼鎖目前狀態 : 關閉(Off)<br><h3/>";

38. String  lockOn="密碼鎖目前狀態 : 開啟(On)<br><h3/>";

39. String  passwordError="密碼輸入錯誤!!";


程式的29~34行定義了一些系統使用到的變數其中”lockOnTime”用來決定電鎖動作的時間使用者可依所採用的電鎖種類去修改而”lockerPW”這個變數則是密碼鎖的啟動密碼在程式中是使用了六位數的數字但由於它是字串型的變數所以不管是文字或數字都可以使用而且長度也沒有限制只要能使用者能記得就好不過一般來說超過六位數就不容易記住


29. const char* softSsid = "ESP_softAP002"; // 軟體SSID名稱

30. const char* password = "12345678"; // SSID密碼

31. const byte LED_Pin=0;     // 繼電器輸出控制腳位

32. String  URI;

33. int lockOnTime=1000; // 電鎖動作時間

34. String  lockerPW="123321"; // 密碼鎖密碼


至於《WiFi_Locker.html》這個html網頁程式的後半段(19~25行)則由” formStart”和” pageEnd這兩個字串變數負責完成。


40. String  formStart="<form ><h3>請輸入密  碼 : <input class='text1' type='text'

name='password' size='30' value=''><br><br>";

41. String  pageEnd="<input class='button'  type='submit' value='開啟(On)'></h4></form>

            </center></body></html>";


至於初始化程式setup()(46~73行)部分和之前使用ESP-01繼電器的製作範例幾乎是一模一樣請自行參考之前的文章在此就不贅言不過就像前面說過因為是密碼鎖控制應該要有比較高的安全性所以在此我們就為ESP8266的AP分享點加上了連線密碼(即常數變數password=“12345678”)使用者可依自己的喜好更改;除此之外,在實際的應用時,有些ESP8266模組如果自行設定本地的IP位址,有時會出現連線不穩定的狀況,因此本範例將原來的指令註解掉(53行),這樣一來當系統啟動時,會使用ESP8266原來預設的『192.168.4.1』IP位址。


53. //  WiFi.softAPConfig(local_IP,gateway,subnet);

54.   boolean result=WiFi.softAP(softSsid,password);


主迴圈loop()程式部分(75~90行)只有短短不到20行而已,之所以會這麼精簡,主要是筆者把相關的動作寫成了三個副程式這樣一來不管是在閱讀上或是維護上都會很容易;由於迴圈部分的程式已經很簡單了所以就留給讀者自行閱覽以便把說明重點放在這三個副程式上。

在之前的【六、3-1 GET請求的解析】一文中,曾經把一般手機瀏覽器在連上由ESP8266所建構的網頁伺服器時,會送出那些訊息或指令動作做了詳細的說明;在瀏覽器所傳來落落長的資料中(如圖七】所示),我們其實大多只有取用最前面一行的「GET」請求而已。可是由於無線WiFi網路傳輸的速度並不會每次都一樣,所以有時我們主要的動作都做完了,可是瀏覽器傳送的資料還沒完成,這些後續還傳送來的資料都會被我們的程式視為錯誤的指令,雖然說我們的系統不會錯誤的動作,可是這樣一來使用者的手機瀏覽器畫面便會一直看到指令錯誤的回應訊息!為了避免這種困擾,本範例特別設計一個副程式(即Get_URI())去接收瀏覽器完整的傳送資訊然後再取出其中的「GET」請求內容

softAP3_webServer1

圖七、 瀏覽器連線後傳送資料內容


Get_URI()』(138~159行)是一個型別為字串(String)的副程式在程式142~149行的while迴圈中在每次接收完一行(由“URI”這個變數接收)資料後除了會把這些資料合併在一起(即變數”request”)外還會去測試該行是否為代表瀏覽器資料傳送結束的空行(即整行內容只有一個換行碼”\n”)如果是便會結束這個while迴圈!


142.  while(client.connected())

143.  {   // 等待第一行"GET"請求結束

144.      Uri=client.readStringUntil('\r');

145. //  Serial.println(Uri);

146.      request+=Uri;

147.      if(Uri=="\n") // 測試是否已經傳送完畢,即內容為空行

148.         break;         // 第一行"GET"請求結束,結束while等待迴圈

149.  }


接著下面程式的前兩行會先把接收到的瀏覽器訊息內容全部改成大寫然後再取出第一行的「GET」請求(放在變數”Uri”上),並且在副程式的最後一行返回時回傳給呼叫者。


151.  request.toUpperCase();   // 將GET請求內容全部轉成大寫

152.  Uri=request.substring(request.indexOf("/"),request.indexOf("HTTP/"));

      …………….

158.  return Uri;


在主迴圈(loop())程式的第80行呼叫Get_URI()』副程式取得瀏覽器的「GET」請求內容後,接著85~88行會依傳來的內容決定是呼叫網頁首頁副程式「handleRoot()」﹖還是密碼檢查副程式「checkPassword()」!


85.  if(URI.indexOf("PASSWORD")>0)

86.      checkPassword();

87.  else

88.      handleRoot();


「handleRoot()」這個副程式的主要功能就是實作出前面提到在PC上作為驗證用的WiFi_Locker.html》網頁程式並送回給提出請求的客戶端裝置(也就是手機的瀏覽器);實作的方式就是把”MAIN_page””lockOff””formStart””pageEnd”這幾個字串變數接合在一起(即字串變數“s”)便可得到和WiFi_Locker.html》這個網頁程式一樣的內容剩下的工作就是使用”client.println(s)”指令把它送回給客戶端了


94.   String s=MAIN_page;

95.   s+=lockOff;

96.  s+=formStart;

97.  s+=pageEnd;

98.  client.println(s);

99.  client.println();


在說明密碼檢查副程式「checkPassword()」之前我們先來看一下從使用者開始連線到輸入密碼並按下[開啟(On)]按鍵後我們的系統會收到什麼樣的內容【圖八】是程式將相關的訊息顯示在電腦串列通訊埠的畫面其中的標記1是系統的AP名稱(“ESP_softAP02”)及本地伺服器的IP網址([ 192.168.4.1 ])而標記2是瀏覽器連上系統網頁首頁所送來的”/”請求碼至於標記3則是按下[開啟(On)]按鍵時所傳來的內容其中包括密碼輸入元素”text”的名稱”password”和密碼值本身(即”123321”)

圖八、 手機瀏覽器與密碼鎖伺服器傳輸內容顯示在序列通訊埠畫面


所以密碼檢查副程式「checkPassword()」一開始的前兩行會將密碼值也就是字串”PASSWORD=”之後的內容取出來放到變數”pwWiFi”內並且把密碼後面可能多打的空格去掉


107.    String pwWiFi=URI.substring(URI.indexOf("PASSWORD")+9);

108.    pwWiFi.trim();                    // 將密碼後的空格去除


接著的114~122行程式則會把取出的密碼("pwWiFi")和系統內定的密碼(“lockerPW”)作比對如果完全正確會回傳代表密碼正確的"lockOn"字串訊息否則回傳密碼錯誤的”passwordError”字串不管是那一種結果最後都必須和”MAIN_page””formStart””pageEnd”這幾個字串變數接合在一起才能完整的回傳給提出需求的客戶端(client)

當然還有一件最重要的事要做就是啟動電鎖這個繼電器模組是使用ESP8266的GPIO00做為控制輸出腳而且是以低態輸出來驅動繼電器由於不同的應用場合可能使用不同種類的電鎖而不同的電鎖作動時間也不一定相同所以在程式中我們作動的時間是由”lockOnTime”這個系統變數來決定設計者可依自己的需要去更改


127.    if(pwWiFi.equals(lockerPW))

128.    {

129.      digitalWrite(LED_Pin,0);

130.      delay(lockOnTime);

131.      digitalWrite(LED_Pin,1);

132.    }



◎ 執行結果:

【圖九】是手機瀏覽器連線密碼鎖後的螢幕畫面,畫面中的最上面一行是『手機遙WiFi遙控密碼鎖』的提示訊息;因為是剛連上網頁的首頁,所以會看到標記1的網址輸入欄位列的內容是[ 192.168.4.1 ],而第二行的提示訊息為密碼鎖目前狀態:關閉(Off),至於控制用的按鈕上的提示文字則是[開啟(On)]這和我們前面的規劃的【圖六a】畫面是一樣的。


圖九、 手機瀏覽器連線ESP8266/ESP-01 WiFi密碼鎖畫面


【圖十】是輸入密碼正確後的瀏覽器畫面標記1的網址輸入欄位列的內容會變成[ 192.168.4.1 /?pasword],而第二行標記2的提示訊息則改為密碼鎖目前狀態:開啟(On),至於控制用的按鈕上的提示文字還是保持在「開啟(On)」。


圖十、 輸入密碼正確瀏覽器畫面與電鎖狀態


【圖十一】則是輸入密碼錯誤的瀏覽器畫面只有第二行標記2的提示訊息改為密碼輸入錯誤!』而已。由於顧慮到這個密碼鎖可能會有許多人在使用因此沒有加上密碼輸入錯誤達一定次數後停止使用的功能以免因為一個人的失誤而把系統鎖起來造成其他人無法使用的問題!


圖十一、 輸入密碼輸入錯誤瀏覽器畫面


有時千言萬語不如一段影片後面的影片是利用手機所拍攝的系統使用與操作過程內容看起來好像很陽春不過應該很簡單使用吧!有興趣的朋友不妨去看一看


https://youtu.be/k-ls2Ial20g


沒有留言:

張貼留言