admin管理员组

文章数量:1619281

ESP32C3 的配网方式有好多种,这里主要使用AP配网方式。在 ESP32C3 上建立热点AP,使用手机连接上后在浏览器打开配置网页,输入WIFI信息,完成配网。这种方式很可靠,而且允许在电脑端完成配网。
配网流程

yes no 获取SSID yes no WIFI连接 连接成功? 连接成功 配置AP 用SSID连接WIFI 连接成功?

AP配网(Soft AP)
ESP32C3配置为AP模式
手机or电脑连接ESP32热点,发送WiFi和密码
ESP32设置为STA模式,连接WIFI。

手机登录页面

手机连接到"ESP32-C3-1"

登录“ESP32-C3-1”

配网用到的
ConfigWiFi.h

#ifndef __CONFIGWIFI_H__
#define __CONFIGWIFI_H__
 
#include <WiFi.h>
#include <DNSServer.h>
#include <WebServer.h>
#include <ESPmDNS.h>      //用于设备域名 MDNS.begin("esp32")
#include <esp_wifi.h>     //用于esp_wifi_restore() 删除保存的wifi信息
 
#define ROOT_HTML  "<!DOCTYPE html><html><head><title>设置WIFI</title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"></head><style type=\"text/css\">.input{display: block; margin-top: 10px;}.input span{width: 200px; float: left; float: left; height: 36px; line-height: 36px;}.input input{height: 30px;width: 200px;}.btn{width: 150px; height: 35px; background-color: #3CBC8D; border:0px; color:#000000; margin-top:15px; }</style><body><h3>设置 WIFI</h3><form method=\"POST\" action=\"configwifi\"><table><tr><td><label class=\"input\"><span>WiFi SSID</span></label></td></tr><ty><td><label><input type=\"text\" name=\"ssid\" value=\"\"></label></td></tr><tr><td><label class=\"input\"><span>WiFi PASS</span></label></td></tr><tr><td><label> <input type=\"text\"  name=\"pass\"></label></td></tr><tr><td><label><input class=\"btn\" type=\"submit\" name=\"submit\" value=\"确  定\"></label></td></tr><tr><td> <h3> 附  近 wifi:</h3></td></tr></table></form>"


#define DNS_PORT  53                    //设置DNS端口号
#define webPort   80                    //设置Web端口号
#define HOST_NAME  "MY_ESP32"           //设置设备名

//==============================================
class ConfigWifi{
    public:
        ConfigWifi(  char *aAP_ssid="AutoConnectAP");
        // ConfigWifi( char *aAP_ssid, char *aAP_pass);

    void connectToWiFi(int timeOut_s);    //连接WiFi
    void checkConnect(bool reConnect);    //检测wifi是否已经连接请求
    void restoreWiFi();                   //删除保存的wifi信息

    static void handleRoot();                    //处理网站根目录的访问请求
    static void handleConfigWifi() ;             //提交数据后的提示页面
    static void handleNotFound();                //处理404情况的函数'handleNotFound'
    void initSoftAP();                    //进入AP模式
    void initDNS();                       //开启DNS服务器
    void initWebServer();                 //初始化WebServer
    bool scanWiFi();                      //扫描附近的WiFi,为了显示在配网界面
  
    char* iAP_ssid  = "AutoConnectAP";    //设置AP热点名称
    // char* iAP_pass = "";                  //设置AP热点密码
};
#endif

ConfigWiFi.cpp

#include "ConfigWifi.h"

String scanNetworksID = "";                 //用于储存扫描到的WiFi ID
String iWifi_ssid = "";                      //暂时存储wifi账号密码
String iWifi_pass = "";                      //暂时存储wifi账号密码

IPAddress AP_IP(192, 168, 4, 1);             //设置AP的IP地址
DNSServer dnsServer;                        //创建dnsServer实例
WebServer server(webPort);                  //开启web服务, 创建TCP SERVER,参数: 端口号,最大连接数

ConfigWifi::ConfigWifi(char *aAP_ssid){
    iAP_ssid = aAP_ssid;
 }

// ConfigWifi::ConfigWifi(char *aAP_ssid,char *aAP_pass){
//     iAP_ssid = aAP_ssid;
//     iAP_pass = aAP_pass;
// }

void ConfigWifi::connectToWiFi(int timeOut_s){
    WiFi.hostname(HOST_NAME);                //设置设备名
    Serial.println("进入connectToWiFi()函数");
    WiFi.mode(WIFI_STA);                     //设置为STA模式并连接WIFI
    WiFi.setAutoConnect(true);               //设置自动连接    
    
    Serial.println("用nvs保存的信息连接.");
    WiFi.begin();                            //begin()不传入参数,默认连接上一次连接成功的wifi

    int Connect_time = 0;                    //用于连接计时,如果长时间连接不成功,复位设备
    while ((WiFi.status() != WL_CONNECTED)&(Connect_time <= 2 * timeOut_s)) {      //等待WIFI连接成功
        Serial.print(".");                   //一共打印30个点点
        delay(500);
        Connect_time ++;
    }
    
    while(WiFi.status() != WL_CONNECTED){
        initSoftAP();   
        initDNS();        
        initWebServer();  
        scanWiFi(); 
        
        while(iWifi_ssid == ""){
            dnsServer.processNextRequest();   //检查客户端DNS请求
            server.handleClient();            //检查客户端(浏览器)http请求

        }

        delay(2000);
        WiFi.softAPdisconnect(true);     //参数设置为true,设备将直接关闭接入点模式,即关闭设备所建立的WiFi网络。
        server.close();                  //关闭web服务
        WiFi.softAPdisconnect();         //在不输入参数的情况下调用该函数,将关闭接入点模式,并将当前配置的AP热点网络名和密码设置为空值.
        Serial.println("WiFi Connect SSID:" + iWifi_ssid + "  PASS:" + iWifi_pass);

        WiFi.hostname(HOST_NAME);                     //设置设备名
        WiFi.mode(WIFI_STA);                          //设置为STA模式并连接WIFI
        WiFi.setAutoConnect(true);                    //设置自动连接    
        Serial.println("用web配置信息连接.");
        WiFi.begin(iWifi_ssid.c_str(),iWifi_pass.c_str()); //连接wifi
        iWifi_ssid = "";
        iWifi_pass = "";
        int Connect_time = 0;                       //用于连接计时,如果长时间连接不成功,复位设备
        while ((WiFi.status() != WL_CONNECTED)&(Connect_time <= 2 * timeOut_s)) {      //等待WIFI连接成功
            Serial.print(".");                        //一共打印30个点点
            delay(500);
            Connect_time ++;
        }
    }
    if (WiFi.status() == WL_CONNECTED){
        Serial.println("WIFI连接成功.");      
    }    
    
}

void ConfigWifi:: checkConnect(bool reConnect){
    if (WiFi.status() != WL_CONNECTED) {          //wifi连接失败
        if (reConnect == true && WiFi.getMode() != WIFI_AP && WiFi.getMode() != WIFI_AP_STA ) {
            Serial.println("WIFI未连接.");
            Serial.println("WiFi Mode:");
            Serial.println(WiFi.getMode());
            Serial.println("正在连接WiFi...");
            WiFi.begin();                   //连接wifi 
            delay(30000);                      
        }
        if (WiFi.status() == WL_CONNECTED){
            Serial.println("WIFI连接成功.");      
        }

    }
}
void ConfigWifi:: restoreWiFi(){
    delay(500);
    esp_wifi_restore();  //删除保存的wifi信息
    Serial.println("连接信息已清空,准备重启设备..");
    delay(10);

}

void ConfigWifi::  handleRoot() {
    if (server.hasArg("selectSSID")) {
        server.send(200, "text/html", ROOT_HTML + scanNetworksID + "</body></html>");   //scanNetWprksID是扫描到的wifi
    } else {
        server.send(200, "text/html", ROOT_HTML + scanNetworksID + "</body></html>");   
    }

}

void ConfigWifi:: handleConfigWifi(){
    if (server.hasArg("ssid")) {          //判断是否有账号参数
        Serial.print("got ssid:");
        iWifi_ssid = server.arg("ssid");   //获取html表单输入框name名为"ssid"的内容
        Serial.println(iWifi_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("pass")) {
        Serial.print("got password:");
        iWifi_pass = server.arg("pass");  //获取html表单输入框name名为"pwd"的内容
        Serial.println(iWifi_pass);
    } 
    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'><h2>SSID:" + iWifi_ssid + "<br />password:" + iWifi_pass + "<br />已取得WiFi信息,正在尝试连接,请手动关闭此页面。</h2>"); //返回保存成功页面
    
}

void ConfigWifi:: handleNotFound(){            // 当浏览器请求的网络资源无法在服务器找到时通过此自定义函数处理
    handleRoot();                 //访问不存在目录则返回配置页面
  //   server.send(404, "text/plain", "404: Not found");
}

void ConfigWifi::initSoftAP(){
    WiFi.mode(WIFI_AP);                                           //配置为AP模式
    WiFi.softAPConfig(AP_IP, AP_IP, IPAddress(255, 255, 255, 0));   //设置AP热点IP和子网掩码
    if (WiFi.softAP(iAP_ssid/*,iAP_pass*/))                         //开启AP热点,如需要密码则添加第二个参数
    {                           
    //打印相关信息
        Serial.println("ESP-32S SoftAP is right.");
        Serial.print("Soft-AP IP address = ");
        Serial.println(WiFi.softAPIP());                                                //接入点ip
        Serial.println(String("MAC address = ")  + WiFi.softAPmacAddress().c_str());    //接入点mac
    } 
    else {                                                //开启AP热点失败
        Serial.println("WiFiAP Failed");
        delay(1000);
        Serial.println("restart now...");
        ESP.restart();                                      //重启复位esp32
    }

}

void ConfigWifi:: initDNS(){
    if (dnsServer.start(DNS_PORT, "*", AP_IP)) {  //判断将所有地址映射到esp32的ip上是否成功
        Serial.println("start dnsserver success.");
    } 
    else {
        Serial.println("start dnsserver failed.");
    }

}

void ConfigWifi:: initWebServer(){
    if (MDNS.begin("esp32")) {     //给设备设定域名esp32,完整的域名是esp32.local
        Serial.println("MDNS responder started");
    }
  //必须添加第二个参数HTTP_GET,以下面这种格式去写,否则无法强制门户
    server.on("/", HTTP_GET, handleRoot);                      // 当浏览器请求服务器根目录(网站首页)时调用自定义函数handleRoot处理,设置主页回调函数,必须添加第二个参数HTTP_GET,否则无法强制门户
    server.on("/configwifi", HTTP_POST, handleConfigWifi);     // 当浏览器请求服务器/configwifi(表单字段)目录时调用自定义函数handleConfigWifi处理
    server.onNotFound(handleNotFound);                         //当浏览器请求的网络资源无法在服务器找到时调用自定义函数handleNotFound处理
    server.begin();                                            //启动TCP SERVER
    Serial.println("WebServer started!");
   
}

bool ConfigWifi:: scanWiFi(){
    Serial.println("scan start");
    Serial.println("--------->");
    // 扫描附近WiFi
    int n = WiFi.scanNetworks();
    Serial.println("scan done");
    if (n == 0) {
        Serial.println("no networks found");
        scanNetworksID = "no networks found";
        return false;
    } else {
        Serial.print(n);
        Serial.println(" networks found");
        for (int i = 0; i < n; ++i) {
        // Print SSID and RSSI for each network found
        Serial.print(i + 1);
        Serial.print(": ");
        Serial.print(WiFi.SSID(i));
        Serial.print(" (");
        Serial.print(WiFi.RSSI(i));
        Serial.print(")");
        Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*");
        scanNetworksID += "<P>" + WiFi.SSID(i) + "</P>";
        delay(10);
        }
        return true;

    }
}

示例


#include "Arduino.h"
#include "ConfigWifi.h"

ConfigWifi configwifi("ESP32-C3-1");    //创建实例,AP热点名:ESP32-C3-1

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
    
  configwifi.connectToWiFi(30);  //连接配网,30秒超时。
  
  /*调试WIFI配网时用,可删除WIFI保存的SSID和PASS,通过串口监视器操作*/
  // Serial.println("删除WIFI信息?:");
  // char temp[1];
  // while(temp[0] !='y' && temp[0]!='n' ){
  //   if (Serial.available())
  //   {
  //       temp[0] = Serial.read();
  //   }    
  // }
  // if( temp[0] == 'y' ){
  //     configwifi.restoreWiFi(); 
  //     ESP.restart();              //重启复位esp32
  // }
//==================END=================================

}

void loop() {
  // put your main code here, to run repeatedly:
  configwifi.checkConnect(true); // 检查是否断网,断网自动连接。 
}


本文标签: 配网ConfigWiFi