Сохранение и загрузка учетных данных WiFi ESP8266 в EEPROM
Рассматривается способ настройки учетных данных Wi-Fi ESP 8266, без необходимости прописывания учетных данных в скетче, посредством чтения/записи в EEPROM
Сохранение и загрузка учетных данных WiFi ESP8266 в EEPROM
29.02.2024 в 12:28   3352 3
Версия для печати

Сохранение и загрузка учетных данных WiFi ESP8266 в EEPROM

Обзор

В этом руководстве вы узнаете о способе  ручной настройки Wi-Fi ESP 8266, без необходимости прописывания учетных данных в скетче. Таким образом вы сможете подключать ваш ESP8266 к различным сетям WiFi без необходимости его перепрошивки.  Для этих целей будет использована библиотека EEPROM. Альтернативой данному способу является библиотека ESP8266 Wifi-Manager, но здесь мы попробуем написать свою альтернативу, занимающую меньше памяти и подробно рассмотрим алгоритм ее работы.

Все продукты IoT работают по схожему алгоритму. Изначально они запускаются в режиме точки доступа. Затем вам нужно подключить свой телефон или компьютер к ней. После подключения , переходите к определенному IP-адресу (192.168.4.1), а затем вводите учетные данные Wifi, после чего устройство автоматически подключится к домашнему маршрутизатору или Wi-Fi. Таким образом, большинство устройств IoT построены с использованием ESP8266, который позволяет настраивать конфигурацию сети (например, SSID и пароль маршрутизатора WiFi) через форму и сохранять ее в памяти.

ESP8266 Ручная настройка WiFi с помощью EEPROM

Здесь мы создадим IoT устройство , используя ESP8266, которое позволит вам настроить конфигурацию сети (например, SSID и пароль WiFi-маршрутизатора) через форму и сохранить ее в памяти EEPROM. Это немного сложнее сделать, чем на платах Arduino. ESP8266 на самом деле не имеет EEPROM, как у всех настоящих плат Arduino. Вот почему большинству из нас трудно использовать библиотеку EEPROM с  ESP8266.

Используя эту функцию, вам больше не нужно прописывать свои сетевые учетные данные (SSID и пароль) в скетче. Ваш ESP автоматически подключится к известной сети или настроит точку доступа, которую вы можете использовать для настройки сетевых учетных данных. Вот как работает этот процесс:

1. Когда ваш ESP8266 загружается, он настраивается в режиме станции и пытается подключиться к ранее сохраненной точке доступа (известная комбинация SSID и пароля).
2. Если этот процесс завершается неудачей, ESP переводится в режим точки доступа;
3. Используя любое устройство с поддержкой Wi-Fi и браузером, подключитесь к вновь созданной точке доступа.
4. После установления соединения с вновь созданной точкой доступа вы можете перейти на IP-адрес по умолчанию 192.168.4.1, чтобы открыть веб-страницу, которая позволяет настроить ваш SSID и пароль.
5. После установки новых SSID и пароля ESP перезагружается и пытается подключиться.
6. Если соединение установлено, процесс успешно завершен. В противном случае он будет настроен как точка доступа.

Что такое точка доступа?

Точка доступа - это устройство, которое создает беспроводную локальную сеть. Или WLAN, обычно в офисе или большом здании. Иногда точка доступа подключается к проводному маршрутизатору, коммутатору или концентратору через кабель Ethernet и проецирует сигнал Wi-Fi в выделенную область. Он также используется пользователями для настройки IoT устройств  для первого использования или смены пароля.

Разбор программы и описание работы

Для начала  мы рассмотрим, как записывать данные в память ESP8266.

Запись значений, отличных от целых чисел, в память ESP8266 может быть проблематичной. Основная причина заключается в том, что стандартная библиотека EEPROM не работает, потому что ESP8266 не имеет EEPROM. Библиотека, которую мы используем, просто эмулирует EEPROM, но в реальной жизни мы записываем данные во ФЛЭШ-память.


#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>
 
//Variables
int i = 0;
int statusCode;
const char* ssid = "text";
const char* passphrase = "text";
String st;
String content;
 
 
//Function Decalration
bool testWifi(void);
void launchWeb(void);
void setupAP(void);
 
//Establishing Local server at port 80 whenever required
ESP8266WebServer server(80);

Все, что мы записываем в память ESP8266, должно быть строкой, и мы можем записывать их по одному символу за раз. Сначала мы объявляем строковую переменную с именем st и content, а также несколько целых чисел и const char * .

Затем мы объявим три разные функции как:


bool testWifi(void);
void launchWeb(void);
void setupAP(void);

Serial.begin(115200); //Initialising if(DEBUG)Serial Monitor
 Serial.println();
 Serial.println("Disconnecting previously connected WiFi");
 WiFi.disconnect();
 EEPROM.begin(512); //Initialasing EEPROM
 delay(10);
 pinMode(LED_BUILTIN, OUTPUT);
 Serial.println();
 Serial.println();
 Serial.println("Startup");

Сначала запускается функция EEPROM с помощью EEPROM.begin(512) и устанавливается объем памяти в 512 ячеек. Следующий цикл по строковому значению.


String esid;
 for (int i = 0; i < 32; ++i)
 {
 esid += char(EEPROM.read(i));
 }
 Serial.println();
 Serial.print("SSID: ");
 Serial.println(esid);
 Serial.println("Reading EEPROM pass");
 
 String epass = "";
 for (int i = 32; i < 96; ++i)
 {
 epass += char(EEPROM.read(i));
 }
 Serial.print("PASS: ");
 Serial.println(epass);
 
 
 WiFi.begin(esid.c_str(), epass.c_str());
 if (testWifi())
 {
 Serial.println("Succesfully Connected!!!");
 return;
 }
 else
 {
 Serial.println("Turning the HotSpot On");
 launchWeb();
 setupAP();// Setup HotSpot
 }
 
 Serial.println();
 Serial.println("Waiting.");
 
 while ((WiFi.status() != WL_CONNECTED))
 {
 Serial.print(".");
 delay(100);
 server.handleClient();
 }

Изначально ESP8266 настраивается в режиме станции и пытается подключиться к ранее сохраненной точке доступа из памяти EEPROM. Если точка доступа и сеть найдены, он подключится к ней.

Если этот процесс завершается неудачно, ESP8266 переводится в режим точки доступа и создается точка доступа.


void loop() {
 if ((WiFi.status() == WL_CONNECTED))
 {
 
 for (int i = 0; i < 10; i++)
 {
 digitalWrite(LED_BUILTIN, HIGH);
 delay(1000);
 digitalWrite(LED_BUILTIN, LOW);
 delay(1000);
 }
 
 }
 else
 {
 }

В этом разделе вы можете добавить свой собственный код, какое бы действие вы ни хотели выполнить. На данный момент здесь просто мигание светодиодом.


void createWebServer()
{
 {
 server.on("/", []() {
 
 IPAddress ip = WiFi.softAPIP();
 String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
 content = "<!DOCTYPE HTML<\r\n<html<Hello from ESP8266 at ";
 content += "<form action=\"/scan\" method=\"POST\"<<input type=\"submit\" value=\"scan\"<</form<";
 content += ipStr;
 content += "<p<";
 content += st;
 content += "</p<<form method='get' action='setting'<<label<SSID: </label<<input name='ssid' length=32<<input name='pass' length=64<<input type='submit'<</form<";
 content += "</html<";
 server.send(200, "text/html", content);
 });
 server.on("/scan", []() {
 //setupAP();
 IPAddress ip = WiFi.softAPIP();
 String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
 
 content = "<!DOCTYPE HTML<\r\n<html<go back";
 server.send(200, "text/html", content);
 });

Используя любое устройство с поддержкой Wi-Fi и браузером, подключитесь к вновь созданной точке доступа. После установления соединения с вновь созданной точкой доступа вы можете перейти на IP-адрес по умолчанию 192.168.4.1, чтобы открыть веб-страницу, которая позволяет вам настроить свой SSID и пароль.

После установки нового SSID и пароля ESP перезагружается и пытается подключиться. Если он устанавливает соединение, процесс успешно завершен. В противном случае он будет настроен как точка доступа.

Полный код программы

Полный код программы находится здесь. С помощью этого кода ESP8266 Ручная настройка Wi-Fi с помощью EEPROM завершена.

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>
 
//Variables
int i = 0;
int statusCode;
const char* ssid = "text";
const char* passphrase = "text";
String st;
String content;
 
 
//Function Decalration
bool testWifi(void);
void launchWeb(void);
void setupAP(void);
 
//Establishing Local server at port 80 whenever required
ESP8266WebServer server(80);
 
void setup()
{
 
 Serial.begin(115200); //Initialising if(DEBUG)Serial Monitor
 Serial.println();
 Serial.println("Disconnecting previously connected WiFi");
 WiFi.disconnect();
 EEPROM.begin(512); //Initialasing EEPROM
 delay(10);
 pinMode(LED_BUILTIN, OUTPUT);
 Serial.println();
 Serial.println();
 Serial.println("Startup");
 
 //---------------------------------------- Read EEPROM for SSID and pass
 Serial.println("Reading EEPROM ssid");
 
 String esid;
 for (int i = 0; i < 32; ++i)
 {
 esid += char(EEPROM.read(i));
 }
 Serial.println();
 Serial.print("SSID: ");
 Serial.println(esid);
 Serial.println("Reading EEPROM pass");
 
 String epass = "";
 for (int i = 32; i < 96; ++i)
 {
 epass += char(EEPROM.read(i));
 }
 Serial.print("PASS: ");
 Serial.println(epass);
 
 
 WiFi.begin(esid.c_str(), epass.c_str());
 if (testWifi())
 {
 Serial.println("Succesfully Connected!!!");
 return;
 }
 else
 {
 Serial.println("Turning the HotSpot On");
 launchWeb();
 setupAP();// Setup HotSpot
 }
 
 Serial.println();
 Serial.println("Waiting.");
 
 while ((WiFi.status() != WL_CONNECTED))
 {
 Serial.print(".");
 delay(100);
 server.handleClient();
 }
 
}
void loop() {
 if ((WiFi.status() == WL_CONNECTED))
 {
 
 for (int i = 0; i < 10; i++)
 {
 digitalWrite(LED_BUILTIN, HIGH);
 delay(1000);
 digitalWrite(LED_BUILTIN, LOW);
 delay(1000);
 }
 
 }
 else
 {
 }
 
}
 
 
//-------- Fuctions used for WiFi credentials saving and connecting to it which you do not need to change 
bool testWifi(void)
{
 int c = 0;
 Serial.println("Waiting for Wifi to connect");
 while ( c < 20 ) {
 if (WiFi.status() == WL_CONNECTED)
 {
 return true;
 }
 delay(500);
 Serial.print("*");
 c++;
 }
 Serial.println("");
 Serial.println("Connect timed out, opening AP");
 return false;
}
 
void launchWeb()
{
 Serial.println("");
 if (WiFi.status() == WL_CONNECTED)
 Serial.println("WiFi connected");
 Serial.print("Local IP: ");
 Serial.println(WiFi.localIP());
 Serial.print("SoftAP IP: ");
 Serial.println(WiFi.softAPIP());
 createWebServer();
 // Start the server
 server.begin();
 Serial.println("Server started");
}
 
void setupAP(void)
{
 WiFi.mode(WIFI_STA);
 WiFi.disconnect();
 delay(100);
 int n = WiFi.scanNetworks();
 Serial.println("scan done");
 if (n == 0)
 Serial.println("no networks found");
 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) == ENC_TYPE_NONE) ? " " : "*");
 delay(10);
 }
 }
 Serial.println("");
 st = "<ol>";
 for (int i = 0; i < n; ++i)
 {
 // Print SSID and RSSI for each network found
 st += "<li>";
 st += WiFi.SSID(i);
 st += " (";
 st += WiFi.RSSI(i);
 
 st += ")";
 st += "(WiFi.encryptionType(i) == ENC_TYPE_NONE) ? " " : "*";
 st += "</li>";
 }
 st += "</ol>";
 delay(100);
 WiFi.softAP("how2electronics", "");
 Serial.println("softap");
 launchWeb();
 Serial.println("over");
}
 
void createWebServer()
{
 {
 server.on("/", []() {
 
 IPAddress ip = WiFi.softAPIP();
 String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
 content = "<!DOCTYPE HTML>\r\n<html>Hello from ESP8266 at ";
 content += "<form action=\"/scan\" method=\"POST\"><input type=\"submit\" value="scan\"></form>";
 content += ipStr;
 content += "<p>";
 content += st;
 content += "</p><form method='get' action='setting'><label>SSID: </label><input name='ssid' type='text' length=32><input name='pass' type='text' length=64><input type='submit'></form>";
 content += "</html>";
 server.send(200, "text/html", content);
 });
 server.on("/scan", []() {
 //setupAP();
 IPAddress ip = WiFi.softAPIP();
 String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
 
 content = "<!DOCTYPE HTML>\r\n<html>go back";
 server.send(200, "text/html", content);
 });
 
 server.on("/setting", []() {
 String qsid = server.arg("ssid");
 String qpass = server.arg("pass");
 if (qsid.length() > 0 && qpass.length() > 0) {
 Serial.println("clearing eeprom");
 for (int i = 0; i < 96; ++i) {
 EEPROM.write(i, 0);
 }
 Serial.println(qsid);
 Serial.println("");
 Serial.println(qpass);
 Serial.println("");
 
 Serial.println("writing eeprom ssid:");
 for (int i = 0; i < qsid.length(); ++i)
 {
 EEPROM.write(i, qsid[i]);
 Serial.print("Wrote: ");
 Serial.println(qsid[i]);
 }
 Serial.println("writing eeprom pass:");
 for (int i = 0; i < qpass.length(); ++i)
 {
 EEPROM.write(32 + i, qpass[i]);
 Serial.print("Wrote: ");
 Serial.println(qpass[i]);
 }
 EEPROM.commit();
 
 content = "{\"Success\":\"saved to eeprom... reset to boot into new wifi\"}";
 statusCode = 200;
 ESP.reset();
 } else {
 content = "{\"Error\":\"404 not found\"}";
 statusCode = 404;
 Serial.println("Sending 404");
 }
 server.sendHeader("Access-Control-Allow-Origin", "*");
 server.send(statusCode, "application/json", content);
 
 });
 } 
}
Также скетч с программой можно загрузить по ссылке
Материал также доступен на моем канале: Яндекс Дзен и в группе ВК
Категория: Программирование | Добавил: :, (19.12.2022)
Просмотров: 3352 | Комментарии: 3 | Теги: IoT, ESP8266, Arduino IDE, EEPROM | Рейтинг: 0.0/0
Поделиться:
Всего комментариев: 3
avatar
0
burgaevarkadiy • 17:42, 22.12.2022
Добрый вечер,
не собирается пишет ошибки...
content += "<form action=\"/scan\" method=\"POST\"><input type=\"submit\" value="scan\"></form>"; --> stray '\' in program

st += "(WiFi.encryptionType(i) == ENC_TYPE_NONE) ? " " : "*""; -->invalid operands of types 'const char [48]' and 'const char [1]' to binary 'operator*'
avatar
0
ALT • 02:22, 25.12.2022
Здравствуйте. Движок сайта так на вставки html в коде реагирует. В ближайшее время скетч приложу к статье
avatar
0
ALT • 09:31, 25.12.2022
Можете скачать скетч отсюда https://projectalt.3dn.ru/downloads/espeeprom.zip
avatar