天天看點

ESP8266動态網頁設定網絡連接配接一、DNS動态配網二、ESP8266 三、燒錄四、網頁設定連接配接網絡自動跳出網頁 樣例1五、 序列槽監視日志

一、DNS動态配網

ESP8266動态網頁設定網絡連接配接一、DNS動态配網二、ESP8266 三、燒錄四、網頁設定連接配接網絡自動跳出網頁 樣例1五、 序列槽監視日志

二、ESP8266

1、樣例1

#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>

const char* AP_NAME = "ESP8266_WIFI_CONFIG";//wifi名字
//暫時存儲wifi賬号密碼
char sta_ssid[32] = {0};
char sta_password[64] = {0};
//配網頁面代碼
const char* page_html = "\
<!DOCTYPE html>\r\n\
<html >\r\n\
<head>\r\n\
  <meta charset='UTF-8'>\r\n\
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>\r\n\
  <title>Document</title>\r\n\
</head>\r\n\
<body>\r\n\
  <form name='input' action='/' method='POST'>\r\n\
        wifi名稱: <br>\r\n\
        <input type='text' name='ssid'><br>\r\n\
        wifi密碼:<br>\r\n\
        <input type='text' name='password'><br>\r\n\
        <input type='submit' value='儲存'>\r\n\
    </form>\r\n\
</body>\r\n\
</html>\r\n\
";

const byte DNS_PORT = 53;//DNS端口号
IPAddress apIP(192, 168, 4, 1);//esp8266-AP-IP位址
DNSServer dnsServer;//建立dnsServer執行個體
ESP8266WebServer server(80);//建立WebServer

void handleRoot() {//通路首頁回調函數
  server.send(200, "text/html", page_html);
}

void handleRootPost() {//Post回調函數
  Serial.println("handleRootPost");
  if (server.hasArg("ssid")) {//判斷是否有賬号參數
    Serial.print("got ssid:");
    strcpy(sta_ssid, server.arg("ssid").c_str());//将賬号參數拷貝到sta_ssid中
    Serial.println(sta_ssid);
  } else {//沒有參數
    Serial.println("error, not found ssid");
    server.send(200, "text/html", "<meta charset='UTF-8'>error, not found ssid");//傳回錯誤頁面
    return;
  }
  //密碼與賬号同理
  if (server.hasArg("password")) {
    Serial.print("got password:");
    strcpy(sta_password, server.arg("password").c_str());
    Serial.println(sta_password);
  } else {
    Serial.println("error, not found password");
    server.send(200, "text/html", "<meta charset='UTF-8'>error, not found password");
    return;
  }

  server.send(200, "text/html", "<meta charset='UTF-8'>儲存成功");//傳回儲存成功頁面
  delay(2000);
  //連接配接wifi
  connectNewWifi();
}

void initBasic(void){//初始化基礎
  Serial.begin(115200);
  WiFi.hostname("Smart-ESP8266");//設定ESP8266裝置名
}

void initSoftAP(void){//初始化AP模式
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  if(WiFi.softAP(AP_NAME)){
    Serial.println("ESP8266 SoftAP is right");
  }
}

void initWebServer(void){//初始化WebServer
  Serial.println("初始化WebServer!");
  //server.on("/",handleRoot);
  //上面那行必須以下面這種格式去寫否則無法強制門戶
  server.on("/", HTTP_GET, handleRoot);//設定首頁回調函數
  server.onNotFound(handleRoot);//設定無法響應的http請求的回調函數
  server.on("/", HTTP_POST, handleRootPost);//設定Post請求回調函數
  server.begin();//啟動WebServer
  Serial.println("WebServer started!");
}

void initDNS(void){//初始化DNS伺服器
  if(dnsServer.start(DNS_PORT, "*", apIP)){//判斷将所有位址映射到esp8266的ip上是否成功
    Serial.println("start dnsserver success.");
  }
  else Serial.println("start dnsserver failed.");
}

void connectNewWifi(void){
  WiFi.mode(WIFI_STA);//切換為STA模式
  WiFi.setAutoConnect(true);//設定自動連接配接
  WiFi.begin();//連接配接上一次連接配接成功的wifi
  Serial.println("");
  Serial.print("Connect to wifi");
  int count = 0;
   while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    count++;
    if(count > 10){//如果5秒内沒有連上,就開啟Web配網 可适當調整這個時間
      initSoftAP();
      initWebServer();
      initDNS();
      break;//跳出 防止無限初始化
    }
    Serial.print(".");
  }
  Serial.println("");
  if(WiFi.status() == WL_CONNECTED){//如果連接配接上 就輸出IP資訊 防止未連接配接上break後會誤輸出
    Serial.println("WIFI Connected!");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());//列印esp8266的IP位址
    server.stop();
  }
}

void setup() {
  initBasic();
  connectNewWifi();
}

void loop() {
  server.handleClient();
  dnsServer.processNextRequest();
}
           

樣例2

#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266WiFi.h>

//配網頁面代碼
const char *page_html = "\
<!DOCTYPE html>\r\n\
<html >\r\n\
 <head>\r\n\
    <meta charset='UTF-8'>\r\n\
    <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'>\r\n\
    <title>配置WIFI</title>\r\n\
    <style>*{margin:0;padding:0}body{font-size:16px;margin:0 15px;z-index:0}.flexcenter{display:flex;align-content:center;align-items:center}.button{width:40%;border-radius:5px;height:40px;background:none;border:1px solid green;font-size:20px;justify-content:space-evenly;color:green}.button:active{background:#ccc}.wifititle{display:flex;margin:0 15px;justify-content:space-between;font-size:22px;color:#333}.wifilist{display:flex;flex-direction:column;align-items:center;justify-content:space-between;font-size:25px;color:#ccc}divw{height:30px;border-bottom:1px solid#ccc;width:100%;background:none;margin-top:5px}divw:active{background:#50bfff}.title{justify-content:center;height:10%;font-size:35px;color:#725af3;letter-spacing:5px;text-shadow:0px 12px 10px#9d91bf}.content-input{height:20%;max-height:20%;display:flex;flex-direction:column}.input-text{display:flex;flex-direction:row;align-items:flex-end;justify-content:space-evenly;font-size:20px;color:#ccc}.input{width:76%;line-height:30px;font-size:25px;margin-top:15px;border-top:0;border-left:0;border-right:0;border-bottom:1px solid#ccc}.context-button{margin-top:15px;margin-bottom:15px;justify-content:space-around}.loading-svg-container{width:50px;height:50px}.path{stroke:#409eff;stroke-width:2;stroke-dasharray:95,126;stroke-dashoffset:0;animation:loading-dash 1.5s ease-in-out infinite}@keyframes loading-dash{0%{stroke-dasharray:1,126;stroke-dashoffset:0}50%{stroke-dasharray:95,126;stroke-dashoffset:-31px}to{stroke-dasharray:6,120;stroke-dashoffset:-120px}}.loading{width:40%;height:15%;position:absolute;background:#fff;display:flex;align-items:center;justify-content:space-around;top:30%;left:30%;flex-direction:column;color:#F4606C;border-radius:20px;overflow:hidden;font-size:14px;z-index:999}.box{width:100%;height:100%;position:fixed;background:#cccccc;opacity:0.8;margin-left:-15px;display:none}</style>\r\n\
  </head>\r\n\
  <body οnlοad='initData()'>\r\n\
    <div class='box'>\r\n\
      <div class='loading'>\r\n\
        <svg viewBox='0 0 50 50' class='loading-svg-container'>\r\n\
          <circle cx='25' cy='25' r='20' fill='none' class='path'></circle>\r\n\
        </svg>\r\n\
        <span id='tip'></span>\r\n\
      </div>\r\n\
    </div>\r\n\
    <div class='flexcenter title'>歡迎使用配置WIFI</div>\r\n\
    <div class='content-input'>\r\n\
      <div class='input-text'>SSID:\r\n\
        <input class='input' id='ssid' name='ssid' type='text' value='' />\r\n\
      </div>\r\n\
      <div class='input-text'>密碼:\r\n\
        <input class='input' id='pwd' name='password' type='password' value='' />\r\n\
      </div>\r\n\
    </div>\r\n\
    <div class='flexcenter context-button'>\r\n\
      <input class='flexcenter button' onclick='connwifi()' type='button' value='提&nbsp;&nbsp;交'/>\r\n\
      <input class='flexcenter button' onclick='reset()' type='button' value='重&nbsp;&nbsp;置'/>\r\n\
    </div>\r\n\
    <div class='wifititle'>\r\n\
      <span>wifi清單</span>\r\n\
      <a style='color: blue' onclick='getWifiList()'>重新整理</a>\r\n\
    </div>\r\n\
    <div class='wifilist' id='wifilist'></div>\r\n\
  </body>\r\n\
  <script>\r\n\
    function initData() {\r\n\
      setTimeout(function() {\r\n\
        getWifiList()\r\n\
      }, 1000)\r\n\
    }\r\n\
    function showloading(msg) {\r\n\
      document.getElementsByClassName('box')[0].style.display = 'table';\r\n\
      document.getElementById('tip').innerHTML = msg;\r\n\
    }\r\n\
    function hideloading() {\r\n\
      document.getElementsByClassName('box')[0].style.display = 'none';\r\n\
      document.getElementById('tip').innerHTML = '';\r\n\
    }\r\n\
    function getWifiList() {\r\n\
      debugger;\r\n\
      document.getElementById('tip').innerText = '';\r\n\
      showloading('搜尋wifi中...');\r\n\
      doget('/wifilist', function(result) {\r\n\
        if (result.indexOf('.nodata') !== -1) {\r\n\
          showloading('找不到有效wifi資訊');\r\n\
          setTimeout(function() {\r\n\
            hideloading()\r\n\
          }, 2000);\r\n\
          return;\r\n\
        }\r\n\
        hideloading();\r\n\
        var arr = result.split(',');\r\n\
        var html = '';\r\n\
        for (item of arr) {\r\n\
          if (item === '') {\r\n\
            continue;\r\n\
          }\r\n\
          html += '<divw οnclick=\"setSsid(event)\">' + item + '</divw>';\r\n\
        }\r\n\
        document.getElementById('wifilist')\r\n\
          .innerHTML = html;\r\n\
      });\r\n\
    }\r\n\
    function setSsid(event) {\r\n\
      debugger;\r\n\
      document.getElementById('tip').innerText = '';\r\n\
      document.getElementById('ssid').value = event.currentTarget.innerText;\r\n\
    }\r\n\
    function reset() {\r\n\
      debugger;\r\n\
      document.getElementById('tip').innerText = '';\r\n\
      document.getElementById('ssid').value = '';\r\n\
      document.getElementById('pwd').value = '';\r\n\
    }\r\n\
    function connwifi() {\r\n\
      var ssid = document.getElementById('ssid').value;\r\n\
      if (ssid === '' || ssid === null || typeof(ssid) === 'undefined') {\r\n\
        showloading('SSID不能為空');\r\n\
        setTimeout(function() {\r\n\
          hideloading();\r\n\
        }, 1000);\r\n\
        return;\r\n\
      }\r\n\
      var pwd = document.getElementById('pwd').value;\r\n\
      var url = '/configwifi?ssid=' + ssid + '&pwd=' + pwd;\r\n\
      //showloading('網絡配置中...');\r\n\
      console.info('網絡配置中...');\r\n\
      doget(url, function(result) {\r\n\
        console.info('1'+result);\r\n\
       // showloading(result);\r\n\
        //setTimeout(function() {\r\n\
          //hideloading();\r\n\
        //}, 20000);\r\n\
      })\r\n\
    }\r\n\
    function doget(url, callback) {\r\n\
      var ajax = new XMLHttpRequest();\r\n\
      ajax.open('POST', url);\r\n\
      ajax.send();\r\n\
      ajax.onreadystatechange = function() {\r\n\
        debugger;\r\n\
        callback(ajax.response);\r\n\
        console.info('2'+ajax.response);\r\n\
      }\r\n\
    }\r\n\
  </script>\r\n\
</html>\r\n\
";

const char *AP_NAME = "esp8266-config"; // wifi名字
const byte DNS_PORT = 53;//DNS端口号
IPAddress apIP(192, 168, 4, 1);        // esp8266-AP-IP位址
DNSServer dnsServer;                   //建立dnsServer執行個體
ESP8266WebServer server(80);           //建立WebServer

/**
   @brief 通路首頁回調函數

*/
void handleRoot()
{
  server.send(200, "text/html", page_html);
}

/**
   @brief Post回調函數

*/
void handleConfigWifi()
{
  Serial.println("EXE handleConfigWifi:");   
  server.send(200, "text/html", "<!DOCTYPE html><html ><head><meta charset='UTF-8'><meta name='viewport'content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'><title>配置WIFI</title></head><body><a style='color: blue'>連接配接成功!</a></body></html>");
  WiFi.setAutoConnect(true);                                         // 設定自動連接配接
  WiFi.begin(server.arg("ssid").c_str(), server.arg("pwd").c_str()); // 使用配網擷取的wifi資訊
  Serial.print("擷取 ssid:");   
  Serial.println(server.arg("ssid").c_str());   
  Serial.print("擷取 pwdid:");   
  Serial.println(server.arg("pwd").c_str());   
  int count = 0;
  Serial.println(WiFi.status()); 
  Serial.println(WL_CONNECTED);  
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    count++;
    Serial.print("while count:"); 
    Serial.println(count);  
    
    if (count > 50)
    { //如果5秒内沒有連上,就開啟Web配網 可适當調整這個時間
      Serial.println("wifi連接配接失敗,請檢查密碼後重試。"); 
      //server.send(200, "text/html", "wifi連接配接失敗,請檢查密碼後重試。"); //傳回儲存成功頁面
      server.send(200, "text/html", "<meta charset='UTF-8'>wifi連接配接失敗,請檢查密碼後重試");//傳回儲存成功頁面
      break;                                                            //跳出 防止無限初始化
    }
    Serial.print(".");
  }
  if (WiFi.status() == WL_CONNECTED) //如果連接配接上 就輸出IP資訊 防止未連接配接上break後會誤輸出
  {
    Serial.print("wifi連接配接成功: ");                               //列印esp8266的IP位址
    Serial.println(WiFi.localIP());                                //列印esp8266的IP位址
    server.send(200, "text/html", "wifi連接配接成功,即将重新開機裝置。"); //傳回儲存成功頁面
    //server.send(200, "text/html", "<!DOCTYPE html><html ><head><meta charset='UTF-8'><meta name='viewport'content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'><title>配置WIFI</title></head><body><a style='color: blue'>連接配接成功!</a></body></html>");//傳回儲存成功頁面
    delay(20000);
    server.stop();
  }else{
    Serial.println("wifi連接配接失敗,請檢查密碼後重試。"); 
    server.send(200, "text/html", "<meta charset='UTF-8'>wifi連接配接失敗");//傳回儲存成功頁面
    return;
  }
}

/**
   @brief 擷取wifi清單回電函數

*/
void handleWifiList()
{

  int n = WiFi.scanNetworks(); //開始同步掃描,将傳回值存放在變量n中
  if (n > 0)
  {
    char wifilist[640] = {0}; // 傳回給網頁的資料
    Serial.println("sacn wifi.");
    for (int i = 0; i < 20; ++i) //開始逐個列印掃描到的
    {
      sprintf(wifilist, "%s%s%s", wifilist, WiFi.SSID(i).c_str(), ","); // 組裝資訊傳回給接口
    }
    Serial.print(wifilist);                  // 列印一下日志
    server.send(200, "text/html", wifilist); //傳回儲存成功頁面
    return;                                  // 結束這裡的操作
  }
  Serial.println("no any wifi.");           // 列印沒有任何wifi日志
  server.send(200, "text/html", ".nodata"); //傳回儲存成功頁面
}

/**
   @brief 初始化WebServer

*/
void initWebServer(void)
{
  WiFi.mode(WIFI_AP);                                         //初始化AP模式
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0)); //初始化AP模式
  //WiFi.softAP(AP_NAME);                                   //初始化AP模式
  if(WiFi.softAP(AP_NAME)){
    Serial.println("ESP8266 SoftAP is right");
  }
  Serial.println("初始化WebServer!");
  server.on("/", HTTP_GET, handleRoot);                 //設定首頁回調函數
  server.onNotFound(handleRoot);                        //設定無法響應的http請求的回調函數
  server.on("/configwifi", HTTP_POST, handleConfigWifi); //設定Post請求回調函數
  server.on("/wifilist", HTTP_GET, handleWifiList);     // 設定擷取wifi清單回調函數
  server.begin();                                       //啟動WebServer
  Serial.println("WebServer started!");
}

void initDNS(void){//初始化DNS伺服器
  if(dnsServer.start(DNS_PORT, "*", apIP)){//判斷将所有位址映射到esp8266的ip上是否成功
    Serial.println("start dnsserver success.");
  }
  else Serial.println("start dnsserver failed.");
}


void connectNewWifi(void)
{
  WiFi.mode(WIFI_STA);       //切換為STA模式
  WiFi.setAutoConnect(true); //設定自動連接配接
  WiFi.begin();              //連接配接上一次連接配接成功的wifi
  Serial.println("");
  Serial.print("Connect to wifi");
  int count = 0;
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    count++;
    if (count > 100)
    {
      initWebServer(); //如果5秒内沒有連上,就開啟Web配網 可适當調整這個時間
      initDNS();
      break;           //跳出 防止無限初始化
    }
    Serial.print(".");
  }
  Serial.println("");
  if (WiFi.status() == WL_CONNECTED) //如果連接配接上 就輸出IP資訊 防止未連接配接上break後會誤輸出
  {
    Serial.print("WIFI Connected!"); //列印esp8266的IP位址
    Serial.println(WiFi.localIP());  //列印esp8266的IP位址
  }
}

void setup()
{
  Serial.begin(115200);           //初始化基礎
  WiFi.hostname("Smart-ESP8266"); //設定ESP8266裝置名
  connectNewWifi();
}

void loop()
{
  server.handleClient();
  dnsServer.processNextRequest();
}
           

 三、燒錄

ESP8266動态網頁設定網絡連接配接一、DNS動态配網二、ESP8266 三、燒錄四、網頁設定連接配接網絡自動跳出網頁 樣例1五、 序列槽監視日志

四、網頁設定

ESP8266動态網頁設定網絡連接配接一、DNS動态配網二、ESP8266 三、燒錄四、網頁設定連接配接網絡自動跳出網頁 樣例1五、 序列槽監視日志

連接配接網絡自動跳出網頁 樣例1

ESP8266動态網頁設定網絡連接配接一、DNS動态配網二、ESP8266 三、燒錄四、網頁設定連接配接網絡自動跳出網頁 樣例1五、 序列槽監視日志
ESP8266動态網頁設定網絡連接配接一、DNS動态配網二、ESP8266 三、燒錄四、網頁設定連接配接網絡自動跳出網頁 樣例1五、 序列槽監視日志

樣例2

ESP8266動态網頁設定網絡連接配接一、DNS動态配網二、ESP8266 三、燒錄四、網頁設定連接配接網絡自動跳出網頁 樣例1五、 序列槽監視日志
ESP8266動态網頁設定網絡連接配接一、DNS動态配網二、ESP8266 三、燒錄四、網頁設定連接配接網絡自動跳出網頁 樣例1五、 序列槽監視日志

五、 序列槽監視日志

ESP8266動态網頁設定網絡連接配接一、DNS動态配網二、ESP8266 三、燒錄四、網頁設定連接配接網絡自動跳出網頁 樣例1五、 序列槽監視日志

繼續閱讀