但也有一個很麻煩的地方在於,只要 NodeMCU 斷電之後,又要重新開起手機的 APP 再連線一次
故我們希望,如果可以將 Wifi 的帳號密碼儲存於 Flash 之中,並且調用出來呢?
註 :
沒錯,將帳號密碼從 Flash 中讀取出來再讓 NodeMCU 連上網路
跟 "把 WIFi 帳密寫死在程式內 " 可以說是一模一樣的行為
但這個只是一個練習而已,只要結合前一篇文章中的 Flash 資料寫入
我們就可以串接起來,讓 NodeMCU 可以在初次連接 WiFi 的時候使用手機 APP 設定,並且將 WiFi 帳號密碼寫入 Flash 中。
當 NodeMCU 斷電重啟後,可以自動從 Flash 中抓出 WiFi 帳號密碼
#include "ESP8266WiFi.h"
bool connectWiFi(const char* ssid, const char* pass, int tryNumber);
bool combine();
void smartConfig();
const uint32_t Base_address = 0x3FA000;
char Name_buff[64];
char pass_buff[64];
uint32_t Count;
static int n = 0;
static int RemJ = 0;
int _SSID = 404;
void setup() {
Serial.begin(115200);
pinMode(D4, OUTPUT);
if ( combine() ) Serial.println("Success");
else Serial.println("False");
if ( !ESP.flashRead( Base_address + 2*RemJ*64, (uint32_t*)pass_buff, 64 ) ) {
} else Serial.printf( "%2d: addr: %p value [%s] \n", 1, Base_address + 2*64, pass_buff );
connectWiFi(Name_buff,pass_buff,20);
if ( WiFi.status() != WL_CONNECTED ) smartConfig();
}
void loop() {
// put your main code here, to run repeatedly:
}
bool connectWiFi(const char* ssid, const char* pass, int tryNumber){
int _try = 0;
WiFi.mode(WIFI_STA);
delay(500);
WiFi.begin(ssid,pass);
Serial.print("Connecting to ");
Serial.println(ssid);
while( WiFi.status() != WL_CONNECTED ){
if( _try <= tryNumber){
delay(500);
_try++;
Serial.print(_try);
}
else {Serial.println("\nConnected Failed"); return false; }
}
Serial.println("\nConnected success");
return true;
}
void smartConfig(){
Serial.println("\r\nWait for Smartconfig");
WiFi.beginSmartConfig();
pinMode(D4,OUTPUT);
while (WiFi.status() != WL_CONNECTED) {
delay(500); //勿刪
digitalWrite(D4, !digitalRead(D4) ); // ESP8266 上的藍色指示燈閃爍
Serial.print(".");
if ( WiFi.smartConfigDone() )
{
Serial.println("\nSmartConfig Success");
Serial.printf("SSID : %s\r\n", WiFi.SSID().c_str() );
Serial.printf("PassWord : %s\r\n", WiFi.psk().c_str() );
break;
}
}
Serial.println("WiFi connected");
digitalWrite(D4, LOW);
}
bool combine(){
// 搜尋週邊 wifi ,可由 WiFi.SSID(i) 讀取出,回傳搜尋到的 wifi 數量
WiFi.mode(WIFI_STA);
WiFi.disconnect();
n = WiFi.scanNetworks(); //回傳找到的 wifi 數量
if (n == 0){
Serial.println("No networks found !");
}
else
{
Serial.print(n);
Serial.println(" networks found\n");
for (int i = 0; i < n; ++i)
{
Serial.printf("%d. ", i);
Serial.println(WiFi.SSID(i));
delay(10);
}
}
Serial.println("");
if ( !ESP.flashRead( Base_address, (uint32_t*)&Count, 32 ) ) {;}
else Serial.printf( "addr: %p Count : %d \n\n", Base_address, Count ); // 讀取 Flash 中被記憶過的 Wifi 名稱
Serial.printf("n = %d\n", n);
for ( int i = 0; i < n ; i++){
for ( int j = 1; j <= (Count*2) -1 ; j = j + 2){
if ( !ESP.flashRead( Base_address + j*64, (uint32_t*)Name_buff, 64 )){
}//else Serial.printf( "addr: %p SSID : %s \n", Base_address + j*64, Name_buff ); // 列印 Flash 中被記憶過的 Wifi 名稱
if ( !(strcmp(WiFi.SSID(i).c_str(),Name_buff)) ) { _SSID = i; RemJ = j; Serial.printf("SSID Match, RemJ = %d\n",RemJ); break;}
else Serial.printf("%s is NOT in the FLASH \n",WiFi.SSID(i).c_str());
}
if ( _SSID != 404 ) { break; }
}
if ( _SSID == 404 ) { Serial.println("\nNot found"); return false; }
else {
Serial.printf("\nFind SSID : %s\r\n", WiFi.SSID(_SSID).c_str() );
return true;
}
}
註:已事先在 0x3fa040 及 0x3fa080 寫入 WIFI 帳號以及密碼(見前一章的補充),並且故意將 WiFi 來源關閉
開啟 WiFi 分享的話會是以下結果