我正在构建一个基于ESP8266的小型传感器。为了设置wifi,我主持一个小型网络服务器,用户可以在其中输入凭据。
在设置例程中,我加载凭据并尝试连接到wifi。如果连接失败,esp将创建一个AP,用户可以输入新凭据。
我有一些奇怪的行为。因为当我删除凭据时,esp仍然成功连接到wifi。但'serial.print()'不显示任何凭据。
可能是EEPROM或FLASH的问题我不知道。我可以在几个ESP上重现这种行为。
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>
ESP8266WebServer server(80);
const char *soft_ap_ssid = "Connect Sensor to MCU";
const char *soft_ap_password = "MySensor";
char ssid[32] = "";
char password[32] = "";
bool wifi_status;
void setup()
{
Serial.begin(115200);
Serial.println();
delay(10);
load_credentials();
wifi_status = setup_wifi(5);
if (!wifi_status)
{
setup_soft_ap();
setup_server();
}
}
void loop()
{
if (!wifi_status)
{
server.handleClient();
}
else
{
Serial.println("Doing Sensor stuff");
delay(2000);
// Remove exsting credentials
for( int i = 0; i < sizeof(ssid); i++ ){
ssid[i] = (char)0;
password[i] = (char)0;
}
save_credentials();
}
}
/*
############## Gernerische Code ########### TODO LIB
*/
bool setup_wifi(int timeout)
{
int timeout_ctr = 0;
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password); //Connect to the WiFi network
while ((WiFi.status() != WL_CONNECTED) && (timeout_ctr < timeout))
{
delay(500);
Serial.println("...");
timeout_ctr++;
}
if (WiFi.status())
{
Serial.print("IP address: ");
Serial.println(WiFi.localIP()); //Print the local IP
}
else
{
Serial.println("Connection to MCU failed, setting up AP.");
}
return (WiFi.status() == WL_CONNECTED);
}
void setup_soft_ap()
{
Serial.println();
Serial.println("Creating WiFi AP...");
WiFi.softAP(soft_ap_ssid, soft_ap_password);
Serial.print("AP \"");
Serial.print(soft_ap_ssid);
Serial.println("\" is online.");
Serial.print("IP address: ");
Serial.println(WiFi.softAPIP());
Serial.println();
}
void setup_server()
{
server.on("/", handle_root); //Associate the landingpage function to the path
server.on("/submit", handle_submit); //Associate the handler function to the path
server.begin(); //Start the server
Serial.println("Server listening");
}
void handle_root()
{
const char *landingpage = "<html><head> <title>ESP8266 Demo</title> <style></style></head><body> <h1>Sensor einrichten</h1> <p> Eingabe der Wifi Daten </p><form action='/submit' method='post'> <input type='text' name='ssid' placeholder='Wifi SSID'> <input type='text' name='pw' placeholder='Wifi Password'> <input type='submit' value='Submit'> </form></body></html>";
server.send(200, "text/html", landingpage);
}
void handle_submit()
{
if (server.args() > 0)
{
Serial.println("POST:");
Serial.println(server.arg("ssid"));
Serial.println(server.arg("pw"));
server.arg("ssid").toCharArray(ssid, sizeof(ssid) - 1);
server.arg("pw").toCharArray(password, sizeof(password) - 1);
Serial.println("credentials:");
Serial.println(ssid);
Serial.println(password);
save_credentials();
}
server.sendHeader("Location", String("/"), true);
server.send(302, "text/plain", "");
}
void load_credentials()
{
EEPROM.begin(512);
EEPROM.get(0, ssid);
EEPROM.get(0 + sizeof(ssid), password);
char ok[2 + 1];
EEPROM.get(0 + sizeof(ssid) + sizeof(password), ok);
EEPROM.end();
if (String(ok) != String("OK"))
{
ssid[0] = 0;
password[0] = 0;
}
Serial.println("Recovered credentials:");
Serial.println(ssid);
Serial.println(password);
}
/** Store WLAN credentials to EEPROM */
void save_credentials()
{
EEPROM.begin(512);
EEPROM.put(0, ssid);
EEPROM.put(0 + sizeof(ssid), password);
char ok[2 + 1] = "OK";
EEPROM.put(0 + sizeof(ssid) + sizeof(password), ok);
EEPROM.commit();
EEPROM.end();
}
答案 0 :(得分:1)
默认情况下,ESP8266 Arduino SDK将其wifi配置保存在闪存中。
这是documented,但没有明确说出来。
您需要致电Wifi.persistent()
让ESP无法保存凭据。在我看过的很多ESP Arduino Core的文章中似乎都没有清楚地说明这一点。
试试这个:
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.persistent(false);
WiFi.begin(ssid, password); //Connect to the WiFi network
while ((WiFi.status() != WL_CONNECTED) && (timeout_ctr < timeout))
您可能希望在更新代码之前将一组错误的凭据写入闪存,以告知SDK停止保存它们,否则我认为它将继续使用上次保存的设置。另一种方法是擦除存储凭证的ESP上的闪存扇区,这是一项更多的工作。
WiFi.persistent()
here上有一些文档 - appears to be incorrect - 我认为此调用的操作方式与我描述的方式相同(传递false只是根本不存储凭据)。
如果你的项目要经常重启(比如经常深入睡眠),我肯定会使用WiFi.persistent(false)
来避免在闪光灯上磨损。