天天看点

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五、 串口监视日志

继续阅读