Arduino ESP32Web配网
Posted perseverance52
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Arduino ESP32Web配网相关的知识,希望对你有一定的参考价值。
Arduino ESP32Web配网(二)
- 相关篇《Arduino ESP32Web配网》
相对于之前的那篇文章,这篇的配网有不同的地方就是,html页面修饰了一下。
配网操作
1.如果是第一次配网,就可以省略第一步,如果是清空WIFI信息请接下来看这一步。
还是采用的GPIO 0引脚下拉作为清除nvs数据的引脚。我是采用一根导线串联1K的电阻进行与GND短接,如果是串联的是10K的电阻,短接到GND是没有反应的。为什么串电阻短接到地,直接短接到GND不行吗,也可以,为了保护一下引脚。(注意上面的那种板子的GPIO 0引脚是没有引出来的,需要条线进行短接,当然你可以跟换引脚定义也可以,根据个人需求)
- 连接配网wifi
点击连接,即可自动跳转到打浏览器并进入到配网界面
点击保存并连接后,串口打印信息。
3. 配网成功后,只要不主动去清除wifi信息,nvs数据中将永远保存该信息。
4. 主动清空nvs数据操作,非必须项。
从下图可以看出,清空前,
nvs
容量是415
,清空后的容量变大了,变成了421
,清空数据后会重启,自动进入到配网模式。
自动配网源码(采用的VSCode Platform IO进行编译的)
#include <Arduino.h>
#include <WiFi.h>
//#include <WiFiUdp.h>
#include <HTTPClient.h>
#include <Preferences.h>
#include "SetWiFi.h" //Web配网
#include <esp_wifi.h> //用于esp_wifi_restore() 删除保存的wifi信息
String PrefSSID, PrefPassword, cityCode;
//在VSCode Platform IO里面,板子led灯需要注释掉,不然报警告,在ArduinoIDE中需要启用这个宏定义,不然找不到该定义的错误信息产生。
#define LED_BUILTIN (2) //板载led灯
#define NTP1 "ntp1.aliyun.com"
#define NTP2 "ntp2.aliyun.com"
#define NTP3 "ntp3.aliyun.com"
unsigned long wifiTimes = 0;
bool ledState = LOW;
const unsigned long interval = 6000UL; //设置延时时间间隔
unsigned long previousMillis = 0;
//const char* ssid = "MERCURY_D268G";
//const char* password = "pba5ayzk";
//强制门户Web配网
const int resetPin = 0; //设置重置按键引脚,用于删除WiFi信息
bool setWiFi_Flag = false;
String NowTime();
void setWiFi()
initSoftAP();
initWebServer();
initDNS();
while (setWiFi_Flag == false)
server.handleClient();
dnsServer.processNextRequest();
if (WiFi.status() == WL_CONNECTED)
server.stop();
setWiFi_Flag = true;
//删除保存的wifi信息
void DeleteWiFi()
Preferences prefs;
prefs.begin("wifi",false);//为false才能删除键值
Serial.println(prefs.freeEntries());//查询清除前的剩余空间
prefs.remove("ssid"); // 删除当前命名空间中键名为"ssid"的元素
prefs.remove("password"); // 删除当前命名空间中键名为"ssid"的元素
prefs.clear();
delay(500);
Serial.println(prefs.freeEntries());//查询清除后的剩余空间
prefs.end();
esp_wifi_restore(); //删除保存的wifi信息
Serial.println("连接信息已清空,准备重启设备..");
void setup()
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT); //板载led灯作为指示
pinMode(resetPin, INPUT_PULLUP); //按键上拉输入模式(默认高电平输入,按下时下拉接到低电平)
//首次使用自动进入配网模式,读取NVS存储空间内的ssid、password和citycode
Preferences prefs;
prefs.begin("wifi");
if (prefs.isKey("ssid"),"nano")
PrefSSID = prefs.getString("ssid","nano");//如果键值为空,返回0
if (prefs.isKey("password"))
PrefPassword = prefs.getString("password");
if (prefs.isKey("citycode"))
cityCode = prefs.getString("citycode");
prefs.end();//从nvs获取到wifi信息后,关闭Preferences
if (PrefSSID == "nano")
setWiFi();
else
Serial.println(PrefSSID);
Serial.println(PrefPassword);
Serial.println(cityCode);
WiFi.mode(WIFI_STA);//切换为STA模式,进行入网
WiFi.begin(PrefSSID.c_str(), PrefPassword.c_str());
Serial.println("正在连接" + PrefSSID + "...Connecting to WiFi...");
Serial.println("-------------");
byte i = 0;
while (WiFi.status() != WL_CONNECTED)
i++;
Serial.print('.');
delay(500);
if (i > 10)
setWiFi();
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); //板载led灯闪烁
Serial.printf("SSID:%s\\r\\n", WiFi.SSID().c_str());
Serial.printf("PSW:%s\\r\\n", WiFi.psk().c_str());
Serial.println(WiFi.localIP());
configTime(8 * 3600, 0, NTP1, NTP2, NTP3);
void loop()
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval)
ledState = !ledState; //状态翻转
digitalWrite(LED_BUILTIN, ledState);
struct tm timeInfo; //声明一个结构体
if (!getLocalTime(&timeInfo))
//一定要加这个条件判断,否则内存溢出
Serial.println("Failed to obtain time");
Serial.println(&timeInfo, "%F %T %A");
previousMillis = currentMillis;
if(!digitalRead(resetPin))
delay(3000);
if(!digitalRead(resetPin)) //1Kde 下来电阻,10K的拉不动
Serial.println("\\n按键已长按3秒,正在清空NVS保存的信息.");
DeleteWiFi(); //删除保存的wifi信息
ESP.restart(); //重启复位esp32
Serial.println("已重启设备.");
SetWiFi.h
代码
#include <WiFi.h>
#include <DNSServer.h>
#include <WebServer.h>
#include <Preferences.h>
const char* AP_NAME = "ESP32WiFiAP";//Web配网模式下的AP-wifi名字
extern String PrefSSID, PrefPassword,cityCode;
//暂时存储wifi账号密码
char sta_ssid[32] = 0;
char sta_password[64] = 0;
char sta_citycode[32] = 0;
//配网页面代码
String page_html = R"(
<!DOCTYPE html>
<html lang='en'>
<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>ESP32参数配置页面</title>
<style type="text/css">
* margin: 0; padding: 0;
html height: 100%;
h2 text-align: center;color: #fff;line-height: 2.2;
body height: 100%; background-color: #1F6F4A; 50% 50% no-repeat; background-size: cover;
.dowebok position: absolute; left: 50%; top: 30%; width: 380px; height: 500px; margin: -200px 0 0 -200px; border: 3px solid #fff; border-radius: 10px; overflow: hidden;
.form-item position: relative; width: 360px; margin: 0 auto; padding-bottom: 20px;
.form-item input width: 288px; height: 48px; padding-left: 10px; border: 1px solid #fff; border-radius: 25px; font-size: 18px; color: #fff; background-color: transparent; outline: none;
.send_button width: 360px; height: 50px; border: 0; border-radius: 25px; font-size: 18px; color: #1f6f4a; outline: none; cursor: pointer; background-color: #fff;
.tip display: none; position: absolute; left: 20px; top: 52px; font-size: 14px; color: #f50;
.reg-bar width: 360px; margin: 20px auto 0; font-size: 14px; overflow: hidden;
.reg-bar a color: #fff; text-decoration: none;
.reg-bar a:hover text-decoration: underline;
.reg-bar .reg float: left;
.reg-bar .forget float: right;
.dowebok ::-webkit-input-placeholder font-size: 18px; line-height: 1.4; color: #fff;
.dowebok :-moz-placeholder font-size: 18px; line-height: 1.4; color: #fff;
.dowebok ::-moz-placeholder font-size: 18px; line-height: 1.4; color: #fff;
.dowebok :-ms-input-placeholder font-size: 18px; line-height: 1.4; color: #fff;
@media screen and (max-width: 500px)
* box-sizing: border-box;
.dowebok position: static; width: auto; height: auto; margin: 0 30px; border: 0; border-radius: 0;
.logo margin: 50px auto;
.form-item width: auto;
.form-item input, .form-item button, .reg-bar width: 100%;
</style>
</head>
<body>
<div class="dowebok">
<h2>参 数 配 置</h2>
<form style='text-align: center;padding-top: 20px' name='input' action='/' method='POST'>
<div class="form-item">
<input id="username" type="text" name='ssid' autocomplete="off" placeholder="WiFi名称">
</div>
<div class="form-item">
<input id="password" type="password" name='password' autocomplete="off" placeholder="WiFi密码">
</div>
<div class="form-item">
<input id="citycode" type="citycode" name='citycode' autocomplete="off" placeholder="城市代码,留空则自动定位获取">
</div>
<div class="form-item">
<div id="">
<input id="send_button" type='submit' value='保存并连接'>
</div>
</div>
<div class="form-item">
<div class="user_text">
<br>
<p><h3>如何获取cityCode:</h3></p>
<h5>
1、城市代码由9位阿拉伯数字组成,超过位数会导致获取不到数据而无限重启
</h5>
</p>
</div>
</div>
</form>
</div>
</body>
</html>
)";
const byte DNS_PORT = 53;//DNS端口号
IPAddress apIP(192, 168, 4, 1);//esp32-AP-IP地址
DNSServer dnsServer;//创建dnsServer实例
WebServer server(80);//创建WebServer
void handleRoot() //访问主页回调函数
server.send(200, "text/html", page_html);
void initSoftAP(void)//初始化AP模式
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
Serial.println(WiFi.softAPIP());
// Serial.print("本地IP: ");
// Serial.println(WiFi.localIP());
if(WiFi.softAP(AP_NAME))
Serial.println("ESP32 SoftAP is right");
void initDNS(void)//初始化DNS服务器
if(dnsServer.start(DNS_PORT, "*", apIP))//判断将所有地址映射到esp8266的ip上是否成功
Serial.println("start dnsserver success.");
else Serial.println("start dnsserver failed.");
void handleRootPost() //Post回调函数
String wifiid="",wifipass="",cityid="";
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.以上是关于Arduino ESP32Web配网的主要内容,如果未能解决你的问题,请参考以下文章
Arduino ESP32SmartConfig配网+NTP时间获取