Administracion de la Red WiFi de la Esp32 con Arduino
Presentación
En el presente proyecto se desarrolla una programación de la placa Esp32 que permita modificar los datos de acceso a la red WiFi domiciliaria a la que la placa se conectara a traves de acceder a la misma mediante una red WiFi STA que crea la propia placa..
Para ello en lugar de colocar el nombre de la red y la clave en la programación de la placa se guardaran los mismos en la memoria EEPROM
Para ello se inicia la placa en los dos modos posibles, AP (Punto de acceso) y STA (Estación)
Primero se inicira en modo STA creando una red de nombre Red_Esp32 y clave 12345678 y luego intentará conectarse a la red cuyos datos se encuentran guardados en la memoria EEPROM
De no haber datos guardados en la memoria o no estar al alcance la red cuyos datos se guardaron la placa quedara funcionando solo em modo STA
En este caso se deberá conectar la pc a la red WiFi Red_Esp32 que será visible y con la clave 12345678, luego de lo cual sse podra ingresar mediante la IP 192.169.4.1 a la pantalla de configuracion
En dicha pantalla se ingresaran los datos de la red WiFi a la que queremos que la placa sse conecte y luego si todo resulto bien al resetear la placa esta se conectara a la red indicada en modo AP
Materiales
Placa Esp32-Cam
Programador Esp32-Cam
Si bien por ser mas cómodo y práctico se ha usado el adaptador el mismo puede ser remplazado por una placa FTDI y el cableado pertinente.
Montaje del proyecto en la placa Esp32
Siendo un proyecto arduino alcanza con cargar el mismo que consta de dos archivos transcriptos mas abajo a la placa y resetear la misma
Codigo
El codigo se ha escrito en dos archivos ADM-red-Esp32.ino y paginas.h.
El archivo ADM-red-Esp32.ino contiene el programa porpiamente dichos.
El archivo paginas.h tiene las paginas html que se utilizan en su funcionamiento.
ADM-red-Esp32.ino
#include <WiFi.h>
#include <EEPROM.h>
#include "paginas.h"
#define EEPROM_SIZE 100
void esc_eeprom(int dir, String dato) {
EEPROM.begin(EEPROM_SIZE);
int longitud = dato.length();
char cadena[50];
dato.toCharArray(cadena, longitud+1);
for (int i = 0; i < longitud; i++) {
EEPROM.write(dir+i, cadena[i]);
}
for (int i = longitud; i < 50; i++) {
EEPROM.write(dir+i, 255);
}
EEPROM.commit();
EEPROM.end();
}
String lee_eeprom(int dir) {
EEPROM.begin(EEPROM_SIZE);
byte lectura;
String cadena;
for (int i = dir; i < dir+50; i++) {
lectura = EEPROM.read(i);
if (lectura != 255) {
cadena += (char)lectura;
}
}
EEPROM.end();
return cadena;
}
const char *red_cam = "Red_Esp32";
const char *clave_cam = "12345678";
const char *red;
const char *clave;
WiFiServer server(80);
void conectar(){
String mired = lee_eeprom(0);
String miclave = lee_eeprom(50);
mired.trim();
miclave.trim();
Serial.println("DATOS RED");
Serial.println("red");
Serial.println(mired);
Serial.println("clave");
Serial.println(miclave);
red = mired.c_str();
clave = miclave.c_str();
Serial.begin(115200);
delay(10);
Serial.println();
WiFi.mode(WIFI_AP_STA);
WiFi.softAP(red_cam, clave_cam);
Serial.print("Conectando con ");
Serial.println(red);
WiFi.begin(red, clave);
unsigned long inicio = millis();
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
if (millis() - inicio > 45000){
Serial.println("");
Serial.println("No se conecto al WiFi.");
break;
}
}
if (WiFi.status() == WL_CONNECTED){
Serial.println("");
Serial.println("Conectado con WiFi.");
}
}
void setup() {
conectar();
// Inicio del Servidor web.
server.begin();
Serial.println("Servidor web iniciado.");
Serial.println();
Serial.print("Red de la Camara: ");
Serial.println(red_cam);
Serial.print("Dirección IP: ");
Serial.println(WiFi.softAPIP());
//*********************
if (WiFi.status() == WL_CONNECTED){
Serial.print("Red de conexion: ");
Serial.println(WiFi.SSID());
Serial.print("Direccion IP: ");
Serial.println(WiFi.localIP());
}
}
void loop() {
// Consulta si se ha conectado algún cliente.
WiFiClient client = server.available();
if (!client) {
return;
}
Serial.print("Nuevo cliente: ");
Serial.println(client.remoteIP());
IPAddress ip = client.remoteIP();
// Espera hasta que el cliente envíe datos.
while(!client.available()){ delay(1); }
String rta = client.readStringUntil('\r');
Serial.println(rta); // Datos enviados por cliente.
if (rta.lastIndexOf("grabar") > 0){
int ini_nombre = rta.indexOf("=") + 1;
int fin_nombre = rta.indexOf("&");
int ini_clave = rta.indexOf("=", fin_nombre) + 1;
int fin_clave = rta.indexOf(" ", ini_clave);
String nueva_red = rta.substring(ini_nombre,fin_nombre);
String nueva_clave = rta.substring(ini_clave,fin_clave);
Serial.println("datos nuevos");
Serial.println(nueva_red);
Serial.println(nueva_clave);
esc_eeprom(0, nueva_red);
esc_eeprom(50, nueva_clave);
client.println(cabecera);
client.println(""); // Importante.
client.println(aviso_html);
}
if (ip[2] == 4 ) {
if (rta.lastIndexOf("grabar") > 0){
}else{
// Página WEB. ///////////////////////////////
client.println(cabecera);
client.println(""); // Importante.
client.println(nueva_clave_html);
}
}else{
// Página WEB. ///////////////////////////////
client.println(cabecera);
client.println(""); // Importante.
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("<head><meta charset=utf-8></head>");
client.println("<body><center><font face='Arial'>");
client.println("<h1>Servidor web con ESP32.</h1>");
client.print("<h3>Connectado a la Red: ");
client.print(WiFi.SSID());
client.println("</h3>");
client.print("<h3>IP : ");
client.print(WiFi.localIP());
client.println("</h3>");
client.println("<br><br>");
client.println("</font></center></body></html>");
}
Serial.print("Cliente desconectado: ");
Serial.println(client.remoteIP());
client.flush();
client.stop();
}
paginas.h
const char cabecera[] PROGMEM = R"rawliteral(
HTTP/1.1 200 OK
Content-Type: text/html
)rawliteral";
const char nueva_clave_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML>
<html>
<head><meta charset=utf-8></head>
<body><center><font face='Arial'>
<h1>Servidor web con ESP32.</h1>
<h3>Configuracion de conexion de red</h3>
<br><br>
<form action='/grabar' method='get'>
<label for='nred'>Nombre Red:</label>
<input type='text' id='nred' name='nred'><br>
<label for='dclave'>Clave acceso:</label>
<input type='text' id='dclave' name='dclave'><br>
<input type='submit' value='Enviar'>
</body>
</html>)rawliteral";
const char aviso_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML>
<html>
<head><meta charset=utf-8></head>
<body><center><font face='Arial'>
<h1>Servidor web con ESP32.</h1>
<h3>Configuracion de conexion de red</h3>
<br><br>
<h3>Se han grabado los nuevos datos de red</h3>
</body>
</html>)rawliteral";