2020年8月13日 星期四

七.2-1.3 使用表單(Form)的方式控制單一輸出

接著這個小節是在修改在前一章ESP8266單機模式的【六、5-1.3 使用表單(Form)的方式控制】小節的範例並配合上一節中【七.1-4】小節的方法與WiFi分享器連線以協助使用者了解系統的連線狀況。在前一個範例使用所謂的超連結(href)html語法去控制單一LED的亮滅,讓使用者操作起來比較方便,可是要用兩組超連結文字去實現,感覺起來不夠精簡因此接下來我們改用html語法中的表單(form)標籤架構,來達到更精簡的的控制方式與介面。

下面的html程式(“softAP_6_5_1Led4_href.html”)當我們用電腦的瀏覽器開啟它時,可看到【圖七、2-1.3_1】的畫面其中標記1用紅色線框起來的部分是一個屬性為按鈕(button)的輸入(input)元素,此按鈕中的文字為點亮LED」代表是用來控制點亮LED之用而標記2的「LED 目前狀態:熄滅」這段文字則是顯示目前ESP8266上LED燈的狀態

<!DOCTYPE html>

<html>

  <head>

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

    <meta charset='utf-8'>

    <style>body {font-size:140%;} #main {display:table; margin:auto;

      padding:0 10px 0 10px;} h3,{text-align:center;} h4,{text-align:center;} 

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

      .button2 {padding:10px 10px 10px 10px; width:100%; background-color: yellowgreen; font-size:120%;} 

    </style>

  </head>

  <body>

    <div id='main'>

      <h4>單一LED亮滅使用Form示範 1</h4>

<h3>LED目前狀態 : 熄滅</h3><br>

<form action='LedOn'>  <input class='button'  type='submit' value='點亮LED'>

</form><br>

    </div>

  </body>

</html>



程式名稱softAP_6_5_1Led4_form.html


圖六_21

圖七、2-1.3_1softAP_6_5_1Led4_form.html》於電腦瀏覽器執行結果


如果我們將softAP_6_5_1Led4_form.html》這個程式的16~19行改寫成下面的內容


16      <h4>單一LED亮滅使用Form示範 1</h4>

17 <h3>LED目前狀態 : 點亮</h3><br>

18 <form action='LedOff'>  <input class='button2'  type='submit' value='熄滅LED'>

19 </form><br>


當重新在電腦的瀏覽器上執行時螢幕上出現的會是圖七、2-1.3_2】的畫面,此時標記1的按鈕背景顏色(草綠色)跟提示文字(熄滅LED)都改變了而標記2的文字也換成「LED 目前狀態:點亮」這樣的內容這時如果我們按下這個提交按鈕就會向網頁伺服器送出’LedOff”這樣的URI請求因此如果結合這兩個動作我們便可以用同一個按鈕去控制LED的亮滅並收到操作結果的回應訊息

圖六_21b

圖七、2-1.3_2softAP_6_5_1Led4b_form.html》於電腦瀏覽器執行結果


範例程式功能與動作說明

1、本範例與上一小節大致相同會令ESP8266以站點(Station)腳色連接上無線WiFi分享器,並且由使用者自行選定WiFi分享器,時主要的差別是當使用者連線上時以表單(form)的提交按鈕方式控制ESP8266上LED的亮滅。

2、當連接上無線WiFi分享器後會在OLED顯示器上顯示由WiFi分享器所分配到的本地IP位址其畫面和上一小節的【圖七、2-1.1_1】相同

3、使用者以行動通信裝置連上同一個WiFi分享器並開啟瀏覽器後(不必管OS的種類),在網址輸入欄輸入所分配到的IP位址,如果是系統剛開機第一次被使用者連線上則系統會回應【圖七、2-1.3_3】的網頁畫面給使用者的瀏覽器此時LED狀態是熄滅狀態假如已經有使用者連線及使用過則系統會依最後一次的狀態顯示對應的頁面。

圖七、2-1.3_3 系統開機後使用者第一次連線畫面


4、當使用者按下其中的標記文字為「點亮LED」的按鈕時除了會令ESP8266這個模組上內建的LED會點亮之外還會使系統的OLED顯示器及手機瀏覽器會分別顯示【圖七、2-1.3_4】的畫面。

圖七、2-1.3_4


5、如果使用者按下【圖七、2-1.3_4】中的標記文字為「熄滅LED」的按鈕時則會令ESP8266這個模組上內建的LED熄滅並使系統的OLED顯示器及手機瀏覽器則會切換到【圖七、2-1.3_5】的畫面。

圖七、2-1.3_5


電路圖

本此範例的電路圖與上一節完全相同,不必更改。


程式列表與說明



 

#include "WiFiConnect.h" //include before SSD1306.h if using custom fonts

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

#include "image.h"

#include "index.h"

 

 

WiFiServer  server(80);

WiFiClient  client;

 

//String  html_end="</body></html>";

String Uri;

 

WiFiConnect wc;     // 宣告一WiFiConnect類別物件變數

 

#define SCREEN_WIDTH 128 // OLED display width, in pixels

#define SCREEN_HEIGHT 64 // OLED display height, in pixels

 

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

 

String softSsidChip = "ESP"+String(ESP.getChipId());

 

const byte  indLED=2;               // ESP系列模組郵票板指示用LED腳位

const byte ledOn=0,ledOff=1;

boolean LEDstate=false;

 

String  html_LedOn="<form action='LedOn'><input class='button' type='submit' value='點亮LED'></form><br>";

String  html_LedOff="<form action='LedOff'><input class='button2' type='submit' value='熄滅LED'></form><br>";

String  html_end="</div></body></html>";

String  html_Echo="";

 

 

// 連線設定回應副程式:

void configModeCallback(WiFiConnect *mWiFiConnect) {

  Serial.println("Entering Access Point!");

  Serial.println("進入 AP 存取點模式!");

}

 

// WiFi連線副程式 :

void startWiFi(boolean showParams = false) {

 

  wc.setDebug(true);

  // 設定連線回應副程式 

  wc.setAPCallback(configModeCallback);

 

    /*

       AP_NONE = Continue executing code   --> 繼續往下執行

       AP_LOOP = Trap in a continuous loop --> 進入無窮AP設定迴圈莊太

       AP_RESET = Restart the chip         --> 啟動晶片重置動作

    */

  // ESP系列模組進入存取點(Access Point)模式畫面:

    if ( !wc.autoConnect()) { // try to connect to wifi

      // 測試ESPXX系列晶片有沒有再自動連上WiFi分享器

      LED_Blink(5,300);

      wc.startConfigurationPortal(AP_LOOP);//if not connected show the configuration portal

    }

}   // WiFi連線副程式結束

 

//  setuo()初始化程式開始:

void setup() {

  Serial.begin(115200);

  pinMode(indLED,OUTPUT);

  digitalWrite(indLED,1);

  Serial.println();

  Serial.println("Program Start!");

  Serial.println("程式開始!");

  // initialize with the I2C addr 0x3C

  if(display.begin(SSD1306_SWITCHCAPVCC, 0x3C))  // Address 0x3D for 128x64

  {

    Serial.println("SSD1036 OLED allocation Successed!");

    Serial.println("SSD1306 初始化成功!");

  }

  else  {

    Serial.println("SSD1306 allocation failed!");

    Serial.println("SSD1306 初始化失敗");

    for(;;);

  }

  

  // Draw bitmap on the screen

  display.clearDisplay();  

  display.setTextSize(2);

  display.setTextColor(WHITE);

  display.setCursor(0,0);

  display.println("");

  display.println(" Program ");

  display.println("  Start!");

  display.display();

  delay(2000);

  Serial.printf("\nAnalog in = %d\n",analogRead(A0));

  // 啟動WiFi連線參數清除

  //  wc.resetSettings(); //helper to remove the stored wifi connection, comment out after first upload and re upload

  // 在螢幕上畫出WiFi圖片

  display.clearDisplay();  

      display.drawBitmap(30, 0, WiFiMap2, 70, 40, WHITE);

      display.setTextSize(1);

      display.setTextColor(WHITE);

      display.setCursor(0,46);

      display.println(" Waiting for");

      display.println(" Connection...");

      display.display();

 

   // 啟動WiFi連線副程式

    startWiFi();

    Serial.print("Cnnect to : ");

    Serial.println(WiFi.SSID());

    Serial.print("ESP已連接至:");

    Serial.println(WiFi.SSID());

      display.clearDisplay();  

  // Draw bitmap on the screen

      display.drawBitmap(30, 0, WiFiMap2, 70, 40, WHITE);

      display.setTextSize(1);

      display.setTextColor(WHITE);

      display.setCursor(0,40);

      display.println("ESP Connect to :");

      display.print("    ");

      display.println(WiFi.SSID());

      display.print(" IP:");

      display.println(WiFi.localIP());

      display.display();

  // WiFi連線成功 :

  delay(3000);

  Serial.println();

  Serial.print("WiFi Connected, IP address: ");

  Serial.println(WiFi.localIP());

  Serial.print("連線成功, 本地WiFi的IP位址為 : ");

  Serial.println(WiFi.localIP());

  Serial.println();

  LED_Blink(5,400);

  delay(1000);

  

  server.begin();

 

  display.clearDisplay();  

  display.setTextSize(2);

  display.setCursor(0,16);

  display.println("  System");

  display.println("  Ready!");

  display.display();

}   // setup()初始化程式結束

 

//  loop()主迴圈程式開始:

void loop() {

 

  client=server.available();

  if(!client) 

    return;

 

  String request="",requests="";

  while(client.connected())

  {

      request=client.readStringUntil('\r');

      requests+=request;

      if(request=="\n")

            break;

  }

  client.flush();

 

  Serial.println("Request end!");

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

  Uri.trim();

  Serial.print("Uri = '");

  Serial.print(Uri);

  Serial.println("'");

  String URI=Uri;

  Serial.println(URI);

  if(URI=="/")

  {

    if(LEDstate)

      LedOn();

    else

      LedOff();

  }

  else if(URI.indexOf("/LedOn")==0)

  {

    LEDstate=true;

      LedOn();

  }

  else if (URI.indexOf("/LedOff")==0)

  {

    LEDstate=false;

      LedOff();

  }

  else

    handleNotFound();

 

  delay(5);

} //  loop()主迴圈程式結束

 

void LedOn() {

 

  html_Echo="<h3>LED目前狀態 : 點亮</h3><br>";

  String s=MAIN_page;

//  String s=html_1;

  s+=html_Echo;

  s+=html_LedOff;

  s+=html_end;

  client.println(s);

  Serial.println("LED is On!");

  Serial.println();

  digitalWrite(indLED,ledOn);

  OLEDshowMessage();

}

 

void LedOff() {

 

  html_Echo="<h3>LED目前狀態 : 熄滅</h3><br>";

  String s=MAIN_page;

//  String s=html_1;

  s+=html_Echo;

  s+=html_LedOn;

  s+=html_end;

  client.println(s);

  digitalWrite(indLED,ledOff);

  Serial.println("LED is Off!");

  Serial.println();

  OLEDshowMessage();

}

 

void handleNotFound(){

 

  String s=MAIN_page;

  s+="<h3>動作錯誤! ==> ";

  s+=Uri;

  s+="</h3><br>";

  s+=html_end;

  client.println(s);

  Serial.print("URI not found -->");

  Serial.println(Uri);

  Serial.println();

}

 

// OLED顯示器輸出狀態顯示:

void OLEDshowMessage()

{

  display.clearDisplay();  

  display.setTextSize(2);

  if(LEDstate) {

    display.drawBitmap(40, 0, LED_ON, 48, 48, WHITE);

    display.setCursor(0,50);

    display.println("  LED On!");

  }

  else  {

    display.drawBitmap(35, 0, LED_OFF, 55, 48, WHITE);

    display.setCursor(0,50);

    display.println("  LED Off!");

  }

  display.display();

}

 

// 讓指示LED快閃count次,亮滅時間為dTime秒

void LED_Blink(int count,int dTime)

{

  for(int i=0;i<count;i++)        

  {

    digitalWrite(indLED,ledOn);

    delay(dTime);

    digitalWrite(indLED,ledOff);

    delay(200);

  }  

}

 

// '319-3192981_free-wifi-svg-png-icon-free-download-free', 70x40px

const unsigned char WiFiMap2 [] PROGMEM = {

  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 

  0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x7f, 

  0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x01, 0xff, 0xe0, 0x00, 0x1f, 0xff, 0x00, 0x00, 0x00, 

  0x0f, 0xfc, 0x00, 0x00, 0x00, 0xff, 0xc0, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x1f, 0xf0, 

  0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfc, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x00, 

  0x00, 0xfe, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x0f, 0xc0, 0x00, 0x1f, 

  0xff, 0xf0, 0x00, 0x0f, 0xc0, 0x1f, 0x80, 0x01, 0xff, 0xff, 0xfe, 0x00, 0x07, 0xe0, 0x3f, 0x00, 

  0x0f, 0xff, 0xff, 0xff, 0xc0, 0x01, 0xf0, 0x3c, 0x00, 0x3f, 0xf8, 0x00, 0x3f, 0xf0, 0x00, 0xf0, 

  0x18, 0x00, 0xff, 0x80, 0x00, 0x07, 0xfc, 0x00, 0x60, 0x00, 0x03, 0xfc, 0x00, 0x00, 0x00, 0xff, 

  0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 

  0x00, 0x0f, 0xc0, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x3e, 0x00, 

  0x07, 0xff, 0x80, 0x01, 0xf0, 0x00, 0x00, 0x1c, 0x00, 0x3f, 0xff, 0xf0, 0x00, 0xe0, 0x00, 0x00, 

  0x00, 0x00, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0x01, 0xff, 0x00, 0x00, 

  0x00, 0x00, 0x00, 0x07, 0xf0, 0x00, 0x3f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x0f, 

  0xc0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 

  0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 

  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

  0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x00, 0x00, 

  0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 

  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

  0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 

  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

};

 

// 'WiFi_AP4', 55x35px

const unsigned char WiFi_AP4 [] PROGMEM = {

  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 

  0xff, 0xfe, 0x7f, 0xff, 0x9e, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0x8e, 0xff, 0xff, 0xff, 0xf8, 

  0xe7, 0xf9, 0xc6, 0xff, 0xff, 0xff, 0xf9, 0xc7, 0xf8, 0xe6, 0xff, 0xff, 0xff, 0xf1, 0xcf, 0x3c, 

  0xe6, 0xff, 0xff, 0xff, 0xf3, 0x8e, 0x0c, 0x62, 0xff, 0xff, 0xff, 0xf3, 0x8e, 0x0e, 0x62, 0xff, 

  0xff, 0xff, 0xf1, 0xce, 0x1c, 0xe2, 0xff, 0xff, 0xff, 0xf9, 0xcf, 0x3c, 0xe6, 0xff, 0xff, 0xff, 

  0xf9, 0xe7, 0x39, 0xc6, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x3f, 0xce, 0xff, 0xff, 0xff, 0xfe, 0x7f, 

  0x3f, 0x9e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfe, 

  0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 

  0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xff, 

  0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 

  0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe6, 0x8f, 

  0xff, 0xff, 0xff, 0xff, 0xff, 0xe6, 0x8f, 0xff, 0xff, 0xf9, 0xf3, 0xf3, 0xe6, 0x8f, 0xff, 0xff, 

  0xe0, 0xe0, 0xc1, 0xe6, 0x8e, 0x00, 0x01, 0xe0, 0xe4, 0xc0, 0xe6, 0x8f, 0xff, 0xff, 0xf0, 0xf1, 

  0xe1, 0xe6, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe6, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe6, 

  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 

  0xff, 0xff, 0xff, 0xff, 0xfe

};

 

// 'led-light-bulb-diode-512', 48x48px

const unsigned char LED_ON [] PROGMEM = {

  0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 

  0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 

  0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xfc, 0x7f, 

  0xfe, 0x1f, 0xff, 0xff, 0xf8, 0x3f, 0xfe, 0x0f, 0xff, 0xff, 0xf8, 0x7f, 0xff, 0x0f, 0xff, 0xff, 

  0xf0, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xff, 

  0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0x07, 0xe0, 0xff, 0xff, 

  0xff, 0xfe, 0x1f, 0xf8, 0x7f, 0xff, 0xff, 0xfc, 0x3f, 0xfc, 0x3f, 0xff, 0xff, 0xf8, 0x7f, 0xfe, 

  0x1f, 0xff, 0xff, 0xf8, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xf8, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xf1, 

  0xff, 0xff, 0x8f, 0xff, 0x03, 0xf1, 0xff, 0xff, 0x8f, 0xc0, 0x03, 0xf1, 0xff, 0xff, 0x8f, 0xc0, 

  0x03, 0xf1, 0xff, 0xff, 0x8f, 0xc0, 0x03, 0xf1, 0xff, 0xff, 0x8f, 0xc0, 0xff, 0xf1, 0xff, 0xff, 

  0x8f, 0xff, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xf1, 

  0xff, 0xff, 0x8f, 0xff, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 

  0xff, 0xf1, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x03, 0xff, 0xff, 0x80, 0x00, 0x00, 

  0x01, 0xff, 0xff, 0x80, 0x00, 0x00, 0x01, 0xff, 0xff, 0xfe, 0x3f, 0xfc, 0x7f, 0xff, 0xff, 0xfe, 

  0x3f, 0xfc, 0x7f, 0xff, 0xff, 0xfe, 0x3f, 0xfc, 0x7f, 0xff, 0xff, 0xfe, 0x3f, 0xfc, 0x7f, 0xff, 

  0xff, 0xfe, 0x3f, 0xfc, 0x7f, 0xff, 0xff, 0xfe, 0x3f, 0xfc, 0x7f, 0xff, 0xff, 0xfe, 0x3f, 0xfc, 

  0x7f, 0xff, 0xff, 0xfe, 0x3f, 0xfc, 0x7f, 0xff, 0xff, 0xfe, 0x3f, 0xfc, 0x7f, 0xff, 0xff, 0xfe, 

  0x3f, 0xfc, 0x7f, 0xff, 0xff, 0xfe, 0x3f, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0x3f, 0xfe, 0x7f, 0xff

};

 

// 'led-variant-off2', 55x48px

const unsigned char LED_OFF [] PROGMEM = {

  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xfe, 0xff, 0xff, 

  0xff, 0x00, 0x07, 0xff, 0xfe, 0xff, 0xff, 0xfc, 0x00, 0x03, 0xff, 0xfe, 0xe3, 0xff, 0xf8, 0x00, 

  0x01, 0xff, 0xfe, 0xc1, 0xff, 0xf0, 0x00, 0x00, 0xff, 0xfe, 0x80, 0xff, 0xf0, 0x00, 0x00, 0x7f, 

  0xfe, 0xc0, 0x3f, 0xe0, 0x00, 0x00, 0x7f, 0xfe, 0xe0, 0x1f, 0xe0, 0x00, 0x00, 0x3f, 0xfe, 0xf8, 

  0x0f, 0xe0, 0x00, 0x00, 0x3f, 0xfe, 0xfc, 0x07, 0xf8, 0x00, 0x00, 0x3f, 0xfe, 0xfe, 0x03, 0xfc, 

  0x00, 0x00, 0x3f, 0xfe, 0xff, 0x00, 0xfe, 0x00, 0x00, 0x3f, 0xfe, 0xff, 0x80, 0x7f, 0x00, 0x00, 

  0x3f, 0xfe, 0xff, 0xe0, 0x3f, 0x80, 0x00, 0x3f, 0xfe, 0xff, 0xf0, 0x1f, 0xe0, 0x00, 0x3f, 0xfe, 

  0xff, 0xf8, 0x0f, 0xf0, 0x00, 0x3f, 0xfe, 0xff, 0xfc, 0x03, 0xf8, 0x00, 0x3f, 0xfe, 0xff, 0xfe, 

  0x01, 0xfc, 0x00, 0x3f, 0xfe, 0xff, 0xff, 0x80, 0xff, 0x00, 0x3f, 0xfe, 0xff, 0xff, 0xc0, 0x7f, 

  0x80, 0x3f, 0xfe, 0xff, 0xff, 0xe0, 0x3f, 0xc0, 0x3f, 0xfe, 0xff, 0xff, 0xe0, 0x0f, 0xe0, 0x3f, 

  0xfe, 0xff, 0xff, 0xe0, 0x07, 0xf0, 0x3f, 0xfe, 0xff, 0xff, 0xe0, 0x03, 0xfc, 0x3f, 0xfe, 0xff, 

  0xf8, 0x00, 0x01, 0xfe, 0x00, 0xfe, 0xff, 0xf8, 0x00, 0x00, 0xff, 0x00, 0xfe, 0xff, 0xf8, 0x00, 

  0x00, 0x3f, 0x80, 0xfe, 0xff, 0xf8, 0x00, 0x00, 0x1f, 0xc0, 0xfe, 0xff, 0xf8, 0x00, 0x00, 0x0f, 

  0xf0, 0xfe, 0xff, 0xff, 0xf8, 0x1c, 0x07, 0xff, 0xfe, 0xff, 0xff, 0xf8, 0x1e, 0x03, 0xff, 0xfe, 

  0xff, 0xff, 0xf8, 0x1f, 0x00, 0xff, 0xfe, 0xff, 0xff, 0xf8, 0x1f, 0x80, 0x7f, 0xfe, 0xff, 0xff, 

  0xf8, 0x1f, 0x80, 0x3f, 0xfe, 0xff, 0xff, 0xf8, 0x1f, 0x80, 0x1f, 0xfe, 0xff, 0xff, 0xf8, 0x1f, 

  0x80, 0x0f, 0xfe, 0xff, 0xff, 0xf8, 0x1f, 0x80, 0x03, 0xfe, 0xff, 0xff, 0xf8, 0x1f, 0x80, 0x01, 

  0xfe, 0xff, 0xff, 0xf8, 0x1f, 0x81, 0x80, 0xfe, 0xff, 0xff, 0xf8, 0x1f, 0x81, 0xc0, 0x7e, 0xff, 

  0xff, 0xf8, 0x1f, 0x81, 0xe0, 0x3e, 0xff, 0xff, 0xf8, 0x1f, 0x81, 0xf0, 0x0e, 0xff, 0xff, 0xf8, 

  0x1f, 0x81, 0xf8, 0x06, 0xff, 0xff, 0xfc, 0x1f, 0x81, 0xfe, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 

  0xff, 0x0e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe

};

 

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:140%;} #main {display:table; margin:auto;

      padding:0 10px 0 10px;} h3,{text-align:center;} h4,{text-align:center;} 

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

      .button2 {padding:10px 10px 10px 10px; width:100%; background-color:yellowgreen; font-size:120%;}    

    </style>

  </head>

  <body>

    <div id='main'>

      <h4>以Form方式控制單一LED亮滅</h4>

)=====";



程式名稱ESP_CH7_2_3_but1.ino


本範例程式和上一個非常類似主要是修改了網頁部分的html程式而已基本上就是把前一章的「softAP_6_5_1Led6_but.ino」這個範例程式與上一節的「ESP_CH7_AutoConnectOLED20.ino」兩個程式組合而成為了節省篇幅在此僅就新增及不同的部分加以說明如果有不了解的請自行回到之前的文章去研讀一下。

從第1行開始到初始化(setup())程式結束(第143行)為止跟上一個範例程式來比較主要是多了下面的布林變數(LEDstate)跟組成完整網頁用的html字串變數


26.  boolean LEDstate=false;

27.

28. String  html_LedOn="<form action='LedOn'><input class='button' type='submit' value='點亮29. LED'></form><br>";

30. String  html_LedOff="<form action='LedOff'><input class='button2' type='submit' value='熄滅31. LED'></form><br>";

32. String  html_end="</div></body></html>";

33. String  html_Echo="";


一般系統在開機時都會把所有的輸出腳設定為不動作的狀態,在此也就是讓LED熄滅;當使用者連線上我們的系統時,也就是進入網站的首頁,如果是剛開機的情形下,當然LED應該是在熄滅的狀態,由於我們使用一個按鈕(Button)來控制LED的亮滅兩種狀態,如果使用者在離線之後又連上線,但是之前已經點亮過LED,這時還是看到首頁LED熄滅的UI介面,就會產生錯誤,而且這種問題在控制更多輸出時會更嚴重!

為了避免這種現象產生,因此使用了「LEDstate」這個代表LED亮滅狀態的變數以作為標示,這樣一來除了開機之外,不管使用者是第幾次再連線系統,都會真實呈現出之前LED亮滅的實際狀態,這也是前面功能與動作說明第3項所代表的意義。

至於主迴圈程式(loop())區和上一個範例的差別,是在170~188行的客戶端傳送來的URI內容判斷部分,當指令為首頁(“/”)時不再使用之前建構的首頁專用副程式「handleRoot()」,而是依照「LEDstate」這個變數決定顯示的畫面,也就是說已經沒有「handleRoot()」這個副程式了!此外還新增了一個OLED顯示器LED狀態顯示的副程式「OLEDshowMessage()」(236~252行):


// OLED顯示器輸出狀態顯示:

void OLEDshowMessage()

{

  display.clearDisplay();  

  display.setTextSize(2);

  if(LEDstate) {

    display.drawBitmap(40, 0, LED_ON, 48, 48, WHITE);

    display.setCursor(0,50);

    display.println("  LED On!");

  }

  else  {

    display.drawBitmap(35, 0, LED_OFF, 55, 48, WHITE);

    display.setCursor(0,50);

    display.println("  LED Off!");

  }

  display.display();

}


這個副程式會依照「LEDstate」這個變數決定顯示的畫面而「LEDstate」這個變數的內容則是由瀏覽器所送來的URI決定

至於後面幾個副程式的內容,包括「LedOn()」「LedOn()」「handleNotFound()」等也只有和網頁html部分的程式稍作修改而已,也就是把原來使用超連結(href)的語法改成了表單(form)的語法而已,如果還是不清楚,請回到前一章的六、5-1.3 使用表單(Form)的方式控制】小節去研讀一下softAP_6_5_1Led6_but.ino》這個副程式應該就可以了解


執行結果:

前面的【圖七、2-1.3_3】至【圖七、2-1.3_5】即為本範例程式執行的結果,其中包括了手機端瀏覽器與ESP8266模組端OLED顯示器畫面的截圖,至於下面的影片則是完整的啟動與操作過程

https://youtu.be/Q3HzKG4jRvQ


沒有留言:

張貼留言