Wi-Fi Manager:ESP8266和ESP32開發板的無線網路管理設置介面(一)

佈署物聯網裝置時,經常需要設定Wi-Fi連線到本地的無線路由器(分享器)。例如,假設你購買了一台Wi-Fi攝影監視器,必須先將它連到家裡的Wi-Fi分享器,才能透過網路遠端監看。

Tzapu寫了一個WiFiManager(WiFi管理員),從2.x版開始同時支援ESP8266和ESP32開發板(以下合稱ESP開發板),提供ESP開發板一個方便實用的設置Wi-Fi網路連線的操作介面。底下先介紹它的操作方式和介面外觀。

本文的範例採WEMOS D1 mini開發板,筆者也用ESP32開發板測試過,功能一樣。請在開發板的GPIO 0(D1 mini板的D3腳)連接一個開關,另一腳接地,當作「啟用WiFi設置模式」的按鍵開關。

WEMOS D1 mini開發板

WiFi Manager的無線網路設置介面

燒錄WiFi管理員程式的ESP開發板初次開機時,尚未連到本地無線分享器,它會自動切換到AP模式(無線接入點),其SSID識別名稱預設為“ESP”+MAC位址,筆者將它設成“JarvisAP”。

AP模式

先用手機或電腦的Wi-Fi連接到ESP開發板“JarvisAP”:

連接ESP開發板

然後用瀏覽器開啟IP位址“192.168.4.1”,ESP開發板將傳回如下的設置畫面,網頁底部顯示“尚未設定AP”。

WiFi管理員設置介面

點擊「設置WiFi」,ESP開發板將掃描並列舉周遭的Wi-Fi分享器:

掃描Wi-Fi分享器

點擊Wi-Fi分享器的識別名稱、輸入密碼、按下「儲存」,ESP開發板將傳回底下的訊息頁面:

儲存Wi-Fi設置

ESP開發板將關閉AP模式、切換到STA模式並連接指定的Wi-Fi分享器。此後,手機或電腦便能透過相同的Wi-Fi分享器連接ESP開發板。

STA模式

日後若需要修改ESP板的Wi-Fi分享器的設定,或者要觀看它從Wi-Fi分享器取得的IP位址,請先按一下接在腳0的按鍵開關,ESP將再次啟動AP模式,讓人透過預設的192.168.4.1位址連線到它的設置頁面。

從底下的畫面可看到它已經連線到Wi-Fi分享器並取得IP位址:

Wi-Fi管理員介面

點擊「設置WiFi」可重新設定Wi-Fi分享器連線;點擊「資訊」可看到ESP開發板的韌體版本、晶片ID、運作時脈、快閃記憶體容量、主記憶體的可用空間(heap,堆積)大小…等資訊,若按下其中的「清除WiFi設置」,現有的Wi-Fi連線資料將被清空,需要重新指定Wi-Fi分享器。

清除Wi-Fi設置

替ESP開發板設定連線之後,以本文的範例來說,用瀏覽器開啟它的首頁,將能看到如下的訊息,代表ESP開發板的網站伺服器如預期運作。

ESP開發板首頁

安裝WiFiManager程式庫

選擇Arduino IDE主功能表的「草稿碼→匯入程式庫→管理程式庫」指令,搜尋關鍵字“wifimanager”,即可找到tzapu, tablaronix開發的程式庫。請按下「安裝」鈕安裝它:

安裝WiFiManager程式庫

筆者撰寫本文時,WiFiManager的最新版本是2.0.3-alpha測試版,因此可能有些功能尚未完善。

WiFiManager程式庫1.6版的Wi-Fi設置網頁的HTML原始碼,定義在WiFiManager.h標頭檔的這些字元常數:

const char HTTP_HEADER[] PROGMEM
const char HTTP_STYLE[] PROGMEM
const char HTTP_SCRIPT[] PROGMEM
const char HTTP_HEADER_END[] PROGMEM
const char HTTP_PORTAL_OPTIONS[] PROGMEM
const char HTTP_ITEM[] PROGMEM
const char HTTP_FORM_START[] PROGMEM
const char HTTP_FORM_PARAM[] PROGMEM
const char HTTP_FORM_END[] PROGMEM
const char HTTP_SCAN_LINK[] PROGMEM
const char HTTP_SAVED[] PROGMEM
const char HTTP_END[] PROGMEM

2.0版則是把Wi-Fi設置網頁的HTML碼單獨存放在“strings_en.h”標頭檔。筆者已經把Wi-Fi設置頁面的文字翻譯成中文,有正體(strings_tw.h檔)簡體(strings_cn.h檔)兩個版本,請按此連結下載

除了文字和用詞不同,正體版網頁字體預設成“微軟正黑體”,”黑體-繁”,sans-serif;而簡體版網頁字體則默認為“微软雅黑”,”黑体-简”,sans-serif

下載中文的設置頁面標頭檔,將它解壓縮存入“WiFi管理員”程式庫的所在路徑裡面(亦即,“文件/Arduino/libraries/WiFiManager”):

WiFiManager程式庫

使用文字或程式編輯器開啟此資料夾裡的WiFiManager.h標頭檔,搜尋”strings_en.h“,找到這一行敘述:

#include "strings_en.h"    // 英文設置介面檔

將它改成引用正體或簡體譯本:

#include "strings_tw.h"  // 正體中文版Wi-Fi設置介面

編譯與測試Wi-Fi網路設置功能程式碼

這個程式修改自“WiFi管理員”提供的“OnDemandNonBlocking”範例:

#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
// include MDNS
#ifdef ESP8266                  // 若晶片類型是ESP8266
#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>   // ESP8266網站伺服器程式庫
ESP8266WebServer server(80);    // 建立網站伺服器物件
#elif defined(ESP32)            // 若晶片類型是ESP32
#include <ESPmDNS.h>
#include <WebServer.h>          // ESP32網站伺服器程式庫
WebServer server(80);           // 建立網站伺服器物件
#endif

#define AP_SSID "JarvisAP"      // 自訂的ESP裝置AP名稱
#define AP_PWD  "12345678"      // 自訂的AP密碼
#define TRIGGER_PIN 0           // 啟用「Wi-Fi設置入口」的按鍵接腳

WiFiManager wm;                 // 建立WiFi管理員物件

unsigned int  timeout   = 120; // Wi-Fi管理員的運作秒數
unsigned int  startTime = millis();
bool portalRunning      = false;
bool startAP = true; // 僅啟動網站伺服器,設成true則啟動AP和網站伺服器。

void setup() {
  WiFi.mode(WIFI_STA); // Wi-Fi設置成STA模式;預設模式為STA+AP

  Serial.begin(115200);
  Serial.setDebugOutput(true);
  delay(1000);
  pinMode(TRIGGER_PIN, INPUT_PULLUP);

  wm.setHostname("jarvis");     // 設置ESP的主機名稱
  // wm.setDebugOutput(false);  // 關閉除錯訊息
  wm.autoConnect(AP_SSID, AP_PWD);
  // 確認晶片是否存有Wi-Fi連鍵資料
  if (WiFi.status() == WL_CONNECTED && wm.getWiFiIsSaved()) {
    Serial.println("\n晶片存有Wi-Fi連線資料!");
  } else {
    Serial.println("\n晶片沒有Wi-Fi連線資料…");
  }
  // 設定我們自訂的網站伺服器
  server.on("/", []() {      // 處理”/”路徑的路由
    server.send(200, "text/html; charset=utf-8", "人生最大的風險,<br>就是不願意冒險。");
  });
  server.onNotFound([]() { // 處理「找不到指定資源」的路由
    server.send(404, "text/plain", "File NOT found!");
  });

  server.begin(); // 啟動網站伺服器
}

void loop() {
#ifdef ESP8266
  MDNS.update();
#endif
  doWiFiManager();       // 確認是否啟動Wi-Fi設置介面
  server.handleClient(); // 處理用戶端連線
}

void doWiFiManager() {
  if (portalRunning) {
    wm.process();
    if ((millis() - startTime) > (timeout * 1000)) {
      Serial.println("「Wi-Fi設置入口」操作逾時…");
      portalRunning = false;

      if (startAP) {
        wm.stopConfigPortal();
      } else {
        wm.stopWebPortal();
      }

      server.begin(); // 再次啟動我們的網站伺服器
    }
  }

  // 若啟用「Wi-Fi設置入口」的接腳被按一下…
  if (digitalRead(TRIGGER_PIN) == LOW && (!portalRunning)) {
    server.stop();  // 停止我們自訂的網站伺服器程式

    if (startAP) {
      Serial.println("按鈕被按下了,啟動設置入口。");
      wm.setConfigPortalBlocking(false);
      wm.startConfigPortal(AP_SSID, AP_PWD);
    } else {
      Serial.println("按鈕被按下了,啟動Web入口。");
      wm.startWebPortal();
    }
    portalRunning = true;
    startTime = millis();
  }
}

編譯並上傳程式碼到ESP8266或ESP32開發板,並於腳0連接一個開關,即可依照本文開頭的說明測試連線。WiFi管理員的程式碼解說,參閱下一篇文章。

Posts created 469

8 thoughts on “Wi-Fi Manager:ESP8266和ESP32開發板的無線網路管理設置介面(一)

  1. 昨天有留言簿不能編譯的問題
    後來我把wifimanager版本改成跟你一樣的2.0.3alpha版本後就能正常執行了
    謝謝

  2. D:\C\Documents\Arduino\libraries\WiFiManager/strings_en.h:358:7: error: ‘wifi_country_t’ does not name a type
    const wifi_country_t WM_COUNTRY_US{“US”,1,11,WIFI_COUNTRY_POLICY_AUTO};
    可以請問這類型的錯誤是什麼嗎?

    1. 那個錯誤訊息代表Wi-Fi設置成美國地區時出錯。

      請問你用什麼開發板?我使用ESP32,開發環境是1.0.6版,測試編譯最新的WiFiManager程式沒問題,但是中文翻譯檔不相容。

  3. 老師您好:
    謝謝分享這篇教學文,這樣總算可以不把密碼寫死進程式裡,另外想問esp32一開始是ap模式,供手機等連入無網路的區域熱點(就是他的頁面),輸入其他ap接入點,一旦連上則轉成sta模式,這樣理解有誤嗎?
    因為wifimanager下的範例basic,這邊WiFi.mode是預設是sta模式

  4. 把WiFiManager.h裡的strings_en.h改成strings_tw.h會出現
    開發板 NodeMCU 1.0 (ESP-12E Module) 編譯時出錯

    這要怎麼辦?我好想用中文介面

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top