首页 > 未分类 > 带存储和重置功能的 WiFiConFig
2022
05-14

带存储和重置功能的 WiFiConFig

带存储和重置功能的 WiFiConFig

现在,让我们为这个示例添加更多功能,使其变得更加可靠。

在这个项目中,我们会将接收到的 Wi-Fi 凭据存储在 EEPROM/闪存中。因此,我们不需要每次都配置 ESP。

接下来,我们将添加一个小检查,例如 ESP 打开时;它将检索存储的 Wi-Fi 凭据并连接到 Wi-Fi 网络。
如果连接成功,则跳过进入 SmartConfig 模式。

此外,我们将使用启动按钮作为重置按钮。它将清除存储的 Wi-Fi 凭据并重新启动 ESP 以进行新配置。
需要长按开机键3秒以上再松开,重置配置成功。

这是完整的项目代码。

/*
  Date: 11-08-21
  Code is written by: Dharmik
  Configure ESP32 Wi-Fi parameters using SmartConfig
  Find more on www.TechTOnions.com
*/
#include "WiFi.h"
#include "EEPROM.h"
#define LENGTH(x) (strlen(x) + 1)   // length of char string
#define EEPROM_SIZE 200             // EEPROM size
#define WiFi_rst 0                  //WiFi credential reset pin (Boot button on ESP32)
String ssid;                        //string variable to store ssid
String pss;                         //string variable to store password
unsigned long rst_millis;

void setup() {
  Serial.begin(115200);             //Init serial
  pinMode(WiFi_rst, INPUT);
  if (!EEPROM.begin(EEPROM_SIZE)) { //Init EEPROM
    Serial.println("failed to init EEPROM");
    delay(1000);
  }
  else
  {
    ssid = readStringFromFlash(0); // Read SSID stored at address 0
    Serial.print("SSID = ");
    Serial.println(ssid);
    pss = readStringFromFlash(40); // Read Password stored at address 40
    Serial.print("psss = ");
    Serial.println(pss);
  }

  WiFi.begin(ssid.c_str(), pss.c_str());

  delay(3500);   // Wait for a while till ESP connects to WiFi

  if (WiFi.status() != WL_CONNECTED) // if WiFi is not connected
  {
    //Init WiFi as Station, start SmartConfig
    WiFi.mode(WIFI_AP_STA);
    WiFi.beginSmartConfig();

    //Wait for SmartConfig packet from mobile
    Serial.println("Waiting for SmartConfig.");
    while (!WiFi.smartConfigDone()) {
      delay(500);
      Serial.print(".");
    }

    Serial.println("");
    Serial.println("SmartConfig received.");

    //Wait for WiFi to connect to AP
    Serial.println("Waiting for WiFi");
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }

    Serial.println("WiFi Connected.");

    Serial.print("IP Address: ");
    Serial.println(WiFi.localIP());

    // read the connected WiFi SSID and password
    ssid = WiFi.SSID();
    pss = WiFi.psk();
    Serial.print("SSID:");
    Serial.println(ssid);
    Serial.print("PSS:");
    Serial.println(pss);
    Serial.println("Store SSID & PSS in Flash");
    writeStringToFlash(ssid.c_str(), 0); // storing ssid at address 0
    writeStringToFlash(pss.c_str(), 40); // storing pss at address 40
  }
  else
  {
    Serial.println("WiFi Connected");
  }
}

void loop() {
  // put your main code here, to run repeatedly:
  rst_millis = millis();
  while (digitalRead(WiFi_rst) == LOW)
  {
    // Wait till boot button is pressed 
  }
  // check the button press time if it is greater than 3sec clear wifi cred and restart ESP 
  if (millis() - rst_millis >= 3000)
  {
    Serial.println("Reseting the WiFi credentials");
    writeStringToFlash("", 0); // Reset the SSID
    writeStringToFlash("", 40); // Reset the Password
    Serial.println("Wifi credentials erased");
    Serial.println("Restarting the ESP");
    delay(500);
    ESP.restart();            // Restart ESP
  }
}


void writeStringToFlash(const char* toStore, int startAddr) {
  int i = 0;
  for (; i < LENGTH(toStore); i++) {
    EEPROM.write(startAddr + i, toStore[i]);
  }
  EEPROM.write(startAddr + i, '\0');
  EEPROM.commit();
}


String readStringFromFlash(int startAddr) {
  char in[128]; // char array of size 128 for reading the stored data 
  int i = 0;
  for (; i < 128; i++) {
    in[i] = EEPROM.read(startAddr + i);
  }
  return String(in);
}

 

代码如何工作

首先,我们将包含该项目所需的所有库。

  • WiFi.h 库将处理所有与 wifi 相关的任务,例如连接到您的 Wi-Fi 和 SmartConfig。
  • EEPROM.h 库需要将数据存储到 ESP32 的 EEPROM/闪存中。

#include “WiFi.h”
#include “EEPROM.h”

定义自定义函数 LENGTH(x) 将为我们提供一个增量为 char 字符串的长度。稍后我们将使用此功能。

并将所需的 EEPROM 大小定义为 EEPROM_SIZE

#define LENGTH(x) (strlen(x) + 1) // length of char string
#define EEPROM_SIZE 200 // EEPROM size

我们正在使用 ESP32 板的启动按钮来重置 Wi-Fi 凭据设置。ESP32 板上的开机按钮与 GPIO0 引脚相连,并带有上拉电阻。

因此,我们将 WiFi_rst 定义为 0。如果您使用任何其他引脚作为重置按钮,则需要将该 GPIO 编号添加到 WiFi_rst 变量中。

#define WiFi_rst 0 //WiFi credential reset pin (Boot button on ESP32)

我们正在定义用于检索 SSID 和密码的字符串变量。

此外,我们将使用 rst_millis 变量来计算按下重置按钮的时间。

String ssid; //string variable to store ssid
String pss; //string variable to store password
unsigned long rst_millis;

设置()

我们将使用所需的波特率初始化串行通信。

Serial.begin(115200); //Init serial

将 WiFi_rst 引脚设置为输入引脚。

pinMode(WiFi_rst, INPUT);
现在,使用预定义的 EEPROM_SIZE 初始化 EEPROM。

初始化后,我们将分别在地址 0 和 40 处将存储的 SSID 和密码读取为字符串。

我们使用名为 readStringFromFlash() 的用户定义函数从 EEPROM/闪存中读取字符串。

if (!EEPROM.begin(EEPROM_SIZE)) { //Init EEPROM
Serial.println(“failed to init EEPROM”);
delay(1000);
}
else
{
ssid = readStringFromFlash(0); // Read SSID stored at address 0
Serial.print(“SSID = “);
Serial.println(ssid);
pss = readStringFromFlash(40); // Read Password stored at address 40
Serial.print(“psss = “);
Serial.println(pss);
}

使用 Wi-Fi.begin 功能连接到 Wi-Fi 网络。我们将 Wi-Fi 凭据作为字符串变量传递;因此,我们将需要使用 c_str(),它将返回一个指向以空字符结尾的字符串的 const char*。

我们将添加一点延迟,以便 ESP 可以连接到 Wi-Fi 网络。

WiFi.begin(ssid.c_str(), pss.c_str());

delay(3500);   // Wait for a while till ESP connects to WiFi

延迟之后,我们将检查 ESP32 是否连接到 Wi-Fi。

如果 ESP 连接到 Wi-Fi,那么我们将跳过 if 条件中的 SmartConfig 代码。

如果它与 Wi-Fi 连接失败,我们将启动 Wi-Fi Station 模式和 SmartConfig,与前面的示例类似。

if (WiFi.status() != WL_CONNECTED) // if WiFi is not connected
  {
    //Init WiFi as Station, start SmartConfig
    WiFi.mode(WIFI_AP_STA);
    WiFi.beginSmartConfig();

使用while 循环等待 SmartConfig 数据到达 。网络凭据到达后,它将尝试连接到该 Wi-Fi 网络。

//Wait for SmartConfig packet from mobile
Serial.println(“Waiting for SmartConfig.”);
while (!WiFi.smartConfigDone()) {
delay(500);
Serial.print(“.”);
}

Serial.println(“”);
Serial.println(“SmartConfig received.”);

//Wait for WiFi to connect to AP
Serial.println(“Waiting for WiFi”);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(“.”);
}

Serial.println(“WiFi Connected.”);
Serial.print(“IP Address: “);
Serial.println(WiFi.localIP());

连接 Wi-Fi 后,我们将通过以下函数读取连接的 Wi-Fi SSID 和密码。

ssid = WiFi.SSID();
pss = WiFi.psk();
Serial.print(“SSID:”);
Serial.println(ssid);
Serial.print(“PSS:”);
Serial.println(pss);
我们将使用另一个用户定义的函数 writeStringToFlash() 来存储新凭据。 我们只需要传递字符串数据和地址。

Serial.println(“Store SSID & PSS in Flash”);
writeStringToFlash(ssid.c_str(), 0); // storing ssid at address 0
writeStringToFlash(pss.c_str(), 40); // storing pss at address 40

环形()

在循环函数内部,我们将当前的millis()值存储在 rst_millis 变量中,因为当有人按下 Wi-Fi 重置按钮时,我们将使用该值作为开始时间。

rst_millis = millis();

当我们按下 Boot 按钮时, while 循环 条件就满足了。因此,代码被困在循环中,直到按钮被释放。

while (digitalRead(WiFi_rst) == LOW)
{
// Wait till boot button is pressed
}

当按钮立即松开时,我们将检查我们按下按钮的时间,如果时间大于 3000mS, 则满足if 条件 。

if (millis() – rst_millis >= 3000)
现在我们将通过将空白值传递给 writeStringToFlash() 函数来擦除地址 0 和 40 处存储的 Wi-Fi 凭据。

Serial.println(“Reseting the WiFi credentials”);
writeStringToFlash(“”, 0); // Reset the SSID
writeStringToFlash(“”, 40); // Reset the Password
Serial.println(“Wifi credentials erased”);

最后,我们将使用以下命令触发对 ESP32 的软件复位。

Serial.println(“Restarting the ESP”);
delay(500);
ESP.restart(); // Restart ESP

writeStringToFlash(const char* toStore, int startAddr)

该用户自定义函数将字符串或字符数组指针存储在 ESP32 的 EEPROM/Flash 存储器中。

我们需要将其存储在非易失性存储器中;因此即使电源关闭,存储的数据也不会被删除。

如果我们仔细看这个函数的代码,它只是一个 for 循环。 它根据 LENGTH() 函数输入执行,如前所述,它将提供字符串的长度。

我们将使用 EEPROM.write() 函数将字符串的每个字节存储到传递的特定地址,并且地址保持递增。

一旦 执行了 for 循环 ,我们将保存一个 ‘\0’ 作为字符串终止符。并将提交更改,以便将它们全部存储在内存中。

void writeStringToFlash(const char* toStore, int startAddr) {
int i = 0;
for (; i < LENGTH(toStore); i++) {
EEPROM.write(startAddr + i, toStore[i]);
}
EEPROM.write(startAddr + i, ‘\0’);
EEPROM.commit();
}

字符串 readStringFromFlash(int startAddr)

此用户定义函数从 EEPROM/闪存中的所需地址读取存储的字符串。

这里我们将char数组名初始化为 in[128] ,它的大小为128,这意味着它只能处理小于128的字符串长度。如果需要处理更大的字符串,可以增加大小。

与存储函数类似,它也适用于 for 循环。它将从startAddr (起始地址)开始 一个接一个地读取所有字符 。

最后,我们将以字符串的形式返回它。

String readStringFromFlash(int startAddr) {
char in[128]; // char array of size 128 for reading the stored data
int i = 0;
for (; i < 128; i++) {
in[i] = EEPROM.read(startAddr + i);
}
return String(in);
}

包起来

我们已经看到 SmartConfig 是在我们基于 ESP32 的物联网项目或设备中配置网络凭据的一种非常有效且直接的方法。

对于配置,ESP32 不需要 Wi-Fi 管理器所需的任何连接的 Wi-Fi 网络。

我们已经使用标准 Wi-Fi 路由器测试了 SmartConfig,它的工作原理非常棒。



最后编辑:
作者:卡萨布兰卡
这个作者貌似有点懒,什么都没有留下。

留下一个回复

你的email不会被公开。