Esp8266 使用可配置式 WiFi

最近在使用 WeMos D1 mini 制作一个局域网开机模块,需要将 WiFi 信息设置为可配置,网上搜索良久都未发现满意的解决方案,最终在一个台湾上人的博客上,发现了一个相对比较友好的程序,博客原链接如下http://nhs-tw.blogspot.com/2015/11/step-by-step-esp8266-12-with-arduino_27.html,我将它整理了一下,并修改添加了部分注释。


代码

//声明
#include 
#include 
#include 
#include 

int EPPROM_Address = 512;

// WiFi,可以写入在这里预先输入自己最常用的 WiFi 信息,也可以设置为空字符串
String WiFi_SSID = "";
String WiFi_Password = "";

//Ap 设置热点信息
const char* AP_Host = "esp8266";
const char* AP_SSID = "Esp8266AP";
const char* AP_Password = "12345678";

// web
String webContent;
int webStatusCode;
String wifiScanContent;

ESP8266WebServer WebServer(80);

void DebugMessage(String str)
{
  Serial.println(str);
}

void setup() {
  Serial.begin(115200);
  DebugMessage("The program startup...");

  EEPROM.begin(EPPROM_Address);
  readWiFiInfoFromEEPROM();

  bool connectStatus = tryToConnectToWiFi();
  if (connectStatus)
  {
    DebugMessage("WiFi connected, IP address: " + WiFi.localIP());
    createConnectedWeb();
  }
  else
  {
    DebugMessage("Connect timed out, ESP8266 change to AP mode");
    ScanNetwork();
    SetupToAPMode();
    connectStatus = tryToConnectToWiFi();
  }

  WebServer.begin();
  delay(100);
}


void loop() {
  WebServer.handleClient();
}


/********* 从存储器中读取 WiFi 信息 ***************/
void readWiFiInfoFromEEPROM()
{
  //--- 从 EEPROM 中读取 WiFi 的 SSID 和密码
  DebugMessage("--- Reading EEPROM SSID & PASSWORD");

  //--- 读取 wifi ssid
  WiFi_SSID = "";
  for (int i = 0; i < 32; ++i)
  {
    WiFi_SSID += char(EEPROM.read(i));
  }
  delay(100);

  //--- 读取 wifi 密码
  WiFi_Password = "";
  for (int i = 32; i < 96; ++i)
  {
    WiFi_Password += char(EEPROM.read(i));
  }
  delay(100);

  //--- 打印 EEPROM 中存储的 WiFi 信息
  DebugMessage("SSID NAME : " + WiFi_SSID);
  DebugMessage("PASSWORD NAME : " + WiFi_Password);
  DebugMessage("essid.length = " + WiFi_SSID.length());
}

/********* 尝试连接 WiFi ***************/
bool tryToConnectToWiFi()
{
  DebugMessage("--- try to connect to ssid: " + WiFi_SSID + " with password: " + WiFi_Password);

  WiFi.mode(WIFI_STA);
  WiFi.begin(WiFi_SSID.c_str(), WiFi_Password.c_str());
  delay(100);

  // WiFi 连接需要时间,因此这里相当于持续检测 10 秒
  int times = 0;
  while ( times < 10 ) {
    if (WiFi.status() == WL_CONNECTED) {
      return true;
    }
    delay(1000);
    times++;
  }
  return false;
}

/********* 设置为 AP 模式 ***************/
void SetupToAPMode() {
  DebugMessage("--- Setup Ap Model");

  WiFi.mode(WIFI_AP);
  WiFi.softAP(AP_SSID, AP_Password, 6, 0);
  createApModeWeb();

  //貌似 dns 不生效
  if (MDNS.begin(AP_Host))
  {
    MDNS.addService("http", "tcp", 80);
    DebugMessage("MDNS responder started");
    DebugMessage("You can now connect to http://" + String(AP_Host) + ".local");
  }
}

/********* 创建 AP 模式网页 ***************/
void createApModeWeb()
{
  //加载网页
  WebServer.on("/", []() {
    IPAddress ip = WiFi.softAPIP();
    webContent = "";
    webContent += "";
    webContent += "WiFi 信息设置";
    webContent += "";
    webContent +=  "

请输入 WiFi 信息

"; webContent += wifiScanContent; // 代表插入一个空格, 重复5个就是插入5个空格 webContent += "
"; webContent += "
"; webContent += ""; webContent += "
"; // webContent += ""; webContent += "      
"; WebServer.send(200, "text/html", webContent); //200代表服务器状态码为 OK, text/html代表用html网页类型, 不加这个会找不到网页 }); WebServer.on("/setting", []() { WiFi_SSID = WebServer.arg("ssid"); WiFi_Password = WebServer.arg("pass"); if (WiFi_SSID.length() > 0 && WiFi_Password.length() > 0) { if (WiFi_SSID.length() <= 32 && WiFi_Password.length() <= 64) { DebugMessage("clearing eeprom"); for (int i = 0; i < 96; ++i) { EEPROM.write(i, 0); } DebugMessage("SSID To Write: " + WiFi_SSID + " Password To Write: " + WiFi_Password); for (int i = 0; i < WiFi_SSID.length(); ++i) { EEPROM.write(i, WiFi_SSID[i]); } for (int i = 0; i < WiFi_Password.length(); ++i) { EEPROM.write(32 + i, WiFi_Password[i]); } EEPROM.commit(); //EEPROM.write 并不会马上写入 EEPROM, 而是要执行 EEPROM.commit()才会实际的写入EEPROM delay(50); webContent = "存储成功, 请按 RESET 键重新开机!"; webStatusCode = 200; } else { webContent = "

输入错误!!! SSID 允许的最大长度为 32,PASSWORD 允许的最大长度为 64, 按上一页重新输入

"; webContent += ""; webStatusCode = 404; DebugMessage("SSID length OR Password length too long"); } } else { webContent = "

输入错误!!! SSID 和 PASSWORD 都不允许为空, 按上一页重新输入

"; webContent += ""; webStatusCode = 404; DebugMessage("SSID length Password length is empty"); } WebServer.send(webStatusCode, "text/html", webContent); }); } /********* 扫描无线网络 ***************/ void ScanNetwork() { DebugMessage("--- Scan WiFi"); WiFi.disconnect(); WiFi.mode(WIFI_STA); delay(100); int wifiCount = WiFi.scanNetworks(); if (wifiCount == 0) DebugMessage("Scan Network Done...and No Any Networks Found!"); else { DebugMessage("Scan Network Done...and " + String(wifiCount) + " Networks Found!"); for (int i = 0; i < wifiCount; ++i) { // Print SSID and RSSI for each network found DebugMessage(String(i + 1) + ": " + WiFi.SSID(i) + " (" + WiFi.RSSI(i) + ") Encryption Type:" + getEncryptionTypeString(WiFi.encryptionType(i))) ; delay(100); } } // 将 WiFi 信息构造成 html 格式 wifiScanContent = "
    "; for (int i = 0; i < wifiCount; ++i) { // Print SSID and RSSI for each network found wifiScanContent += ""; } wifiScanContent += "
    "; wifiScanContent += String(i + 1) + ". "; wifiScanContent += WiFi.SSID(i); wifiScanContent += " ("; wifiScanContent += WiFi.RSSI(i); wifiScanContent += ")"; wifiScanContent += ""; byte encryption = WiFi.encryptionType(i); wifiScanContent += getEncryptionTypeString(encryption); wifiScanContent += "

    "; } String getEncryptionTypeString(byte type) { String str = ""; switch (type) { case 2: str = "TKIP(WPA)"; break; case 5: str = "WEP"; break; case 4: str = "CCMP(WPA)"; break; case 7: str = "NONE"; break; case 8: str = "AUTO(WPA or WPA2)"; break; default: str = ""; } return str; } void createConnectedWeb() { WebServer.on("/", []() { webContent = ""; webContent += ""; webContent += "WiFi 信息"; webContent += ""; webContent += "

    当前 WiFi 信息

    "; // webContent += wifiScanContent; // 代表插入一个空格, 重复5个就是插入5个空格 webContent += "
    "; webContent += ""; webContent += ""; webContent += ""; webContent += "
    "; webContent += ""; WebServer.send(200, "text/html", webContent); }); }

你可能感兴趣的:(Esp8266 使用可配置式 WiFi)