Código Fuente:
#include <ESP8266WiFi.h> #include <ESP8266WebServer.h> #include <EEPROM.h> //-------------------VARIABLES GLOBALES-------------------------- int contconexion = 0; unsigned long previousMillis = 0; char ssid[50]; char pass[50]; const char *ssidConf = "tutorial"; const char *passConf = "12345678"; String mensaje = ""; //-----------CODIGO HTML PAGINA DE CONFIGURACION--------------- String pagina = "<!DOCTYPE html>" "<html>" "<head>" "<title>Tutorial Eeprom</title>" "<meta charset='UTF-8'>" "</head>" "<body>" "</form>" "<form action='guardar_conf' method='get'>" "SSID:<br><br>" "<input class='input1' name='ssid' type='text'><br>" "PASSWORD:<br><br>" "<input class='input1' name='pass' type='password'><br><br>" "<input class='boton' type='submit' value='GUARDAR'/><br><br>" "</form>" "<a href='escanear'><button class='boton'>ESCANEAR</button></a><br><br>"; String paginafin = "</body>" "</html>"; //------------------------SETUP WIFI----------------------------- void setup_wifi() { // Conexión WIFI WiFi.mode(WIFI_STA); //para que no inicie el SoftAP en el modo normal WiFi.begin(ssid, pass); while (WiFi.status() != WL_CONNECTED and contconexion <50) { //Cuenta hasta 50 si no se puede conectar lo cancela ++contconexion; delay(250); Serial.print("."); digitalWrite(13, HIGH); delay(250); digitalWrite(13, LOW); } if (contconexion <50) { Serial.println(""); Serial.println("WiFi conectado"); Serial.println(WiFi.localIP()); digitalWrite(13, HIGH); } else { Serial.println(""); Serial.println("Error de conexion"); digitalWrite(13, LOW); } } //-------------------------------------------------------------- WiFiClient espClient; ESP8266WebServer server(80); //-------------------------------------------------------------- //-------------------PAGINA DE CONFIGURACION-------------------- void paginaconf() { server.send(200, "text/html", pagina + mensaje + paginafin); } //--------------------MODO_CONFIGURACION------------------------ void modoconf() { delay(100); digitalWrite(13, HIGH); delay(100); digitalWrite(13, LOW); delay(100); digitalWrite(13, HIGH); delay(100); digitalWrite(13, LOW); WiFi.softAP(ssidConf, passConf); IPAddress myIP = WiFi.softAPIP(); Serial.print("IP del acces point: "); Serial.println(myIP); Serial.println("WebServer iniciado..."); server.on("/", paginaconf); //esta es la pagina de configuracion server.on("/guardar_conf", guardar_conf); //Graba en la eeprom la configuracion server.on("/escanear", escanear); //Escanean las redes wifi disponibles server.begin(); while (true) { server.handleClient(); } } //---------------------GUARDAR CONFIGURACION------------------------- void guardar_conf() { Serial.println(server.arg("ssid"));//Recibimos los valores que envia por GET el formulario web grabar(0,server.arg("ssid")); Serial.println(server.arg("pass")); grabar(50,server.arg("pass")); mensaje = "Configuracion Guardada..."; paginaconf(); } //----------------Función para grabar en la EEPROM------------------- void grabar(int addr, String a) { int tamano = a.length(); char inchar[50]; a.toCharArray(inchar, tamano+1); for (int i = 0; i < tamano; i++) { EEPROM.write(addr+i, inchar[i]); } for (int i = tamano; i < 50; i++) { EEPROM.write(addr+i, 255); } EEPROM.commit(); } //-----------------Función para leer la EEPROM------------------------ String leer(int addr) { byte lectura; String strlectura; for (int i = addr; i < addr+50; i++) { lectura = EEPROM.read(i); if (lectura != 255) { strlectura += (char)lectura; } } return strlectura; } //---------------------------ESCANEAR---------------------------- void escanear() { int n = WiFi.scanNetworks(); //devuelve el número de redes encontradas Serial.println("escaneo terminado"); if (n == 0) { //si no encuentra ninguna red Serial.println("no se encontraron redes"); mensaje = "no se encontraron redes"; } else { Serial.print(n); Serial.println(" redes encontradas"); mensaje = ""; for (int i = 0; i < n; ++i) { // agrega al STRING "mensaje" la información de las redes encontradas mensaje = (mensaje) + "<p>" + String(i + 1) + ": " + WiFi.SSID(i) + " (" + WiFi.RSSI(i) + ") Ch: " + WiFi.channel(i) + " Enc: " + WiFi.encryptionType(i) + " </p>\r\n"; //WiFi.encryptionType 5:WEP 2:WPA/PSK 4:WPA2/PSK 7:open network 8:WPA/WPA2/PSK delay(10); } Serial.println(mensaje); paginaconf(); } } //------------------------SETUP----------------------------- void setup() { pinMode(13, OUTPUT); // D7 // Inicia Serial Serial.begin(115200); Serial.println(""); EEPROM.begin(512); pinMode(14, INPUT); //D5 if (digitalRead(14) == 0) { modoconf(); } leer(0).toCharArray(ssid, 50); leer(50).toCharArray(pass, 50); setup_wifi(); } //--------------------------LOOP-------------------------------- void loop() { unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= 5000) { //envia la temperatura cada 5 segundos previousMillis = currentMillis; Serial.println("Funcionado..."); } }
Genial! esta muy bueno el tutorial.. Es muy util... Te quiero hacer una consulta... A esto le quiero agregar el codigo que uso normalmente para recibir comandos http pero no me permite
ResponderEliminarWiFiClient client = server.available();
if (!client) {
return;
}
Serial.println("new client"); // Wait until the client sends some data
while(!client.available()){
delay(1);
}
String req = client.readStringUntil('\r'); // Read the first line of the request
Serial.println(req);
client.flush();
if (req.indexOf("/D3/0") != -1) // Match the request
val1 = 0;
else if (req.indexOf("/D3/1") != -1)
val1 = 1;
ese es el codigo que quiero agregar en el loop... pero me sale el siguiente error...
C:\Users\xxx\Documents\Arduino\Tecla___config_wifi\Tecla___config_wifi.ino: In function 'void loop()':
Tecla___config_wifi:260: error: 'class ESP8266WebServer' has no member named 'available'
WiFiClient client = server.available();
^
exit status 1
'class ESP8266WebServer' has no member named 'available'
Podras darme una mano? Gracias
Tendría que ver todo el código para estar seguro: pero me parece que te falta declarar: ESP8266WebServer server(80);
EliminarO eliminar la línea: WiFiClient espClient;
Lo que quiero hacer es agregar al codigo la posibilidad de prender y apagar un led una vez realizada la configuracion. Si llegas a tener idea de como hacerlo te agradeceria muchisimo
EliminarLo agregas al final de la función: void guardar_conf()
EliminarTe recomiendo el tutorial 8, usar SPIFFS es mejor que usar la EEPROM
El problema no parece estar en esa parte. Está en la linea 260. Saludos.
EliminarHola buenas, muy bueno el tutorial, yo estoy intentando hacer lo mismo que el amigo ian carrasco, y tengo el mismo error que el, y quisiera saber si pudieron solucionar el problema? Muchísimas gracias, saludos
EliminarTambién estoy intentando lo mismo, si alguien ya dio con la solución podrían por favor compartirlo.
EliminarBuenas tardes, super bueno el tutorial, una pregunta porque es mejor spiffs que la eeprom
ResponderEliminarPara mi gusto es mejor SPIFFS, fijate que hice un tutorial al respecto. Saludos.
ResponderEliminarBuenas tardes, si no se disponer de un interruptor... ¿seria posible disponer del web server que permite introducir el SSID y de loop normal?, seria algo asi como una alternativa puramente software...
ResponderEliminarSi, tenés que iniciar tanto en modo softAP como station es decir: WIFI_AP_STA. Pero no te lo recomiendo, para mi es mejor no usar el modo softAP al menos que se lo necesite, para que sea más estable y consuma menos energía.
EliminarPero, se puede mantener el server iniciado mientra en el bucle loop normal, se ejecutan otra acciones? por mas que lo pienso no encuentro manera
EliminarSi se puede, eso correr en otro hilo.Tenés que poner dentro del loop:
Eliminarserver.handleClient();
Buenas tardes, como hago para agregarle la conexión a un servidor remoto para actualizar datos en una base de datos? He intentado de mil formas pero no lo he logrado.
ResponderEliminarAgradecería mucho tu ayuda! Gracias
Hice un tutorail al respecto, espero que te sirva. http://www.sinaptec.alomar.com.ar/2017/07/tutorial-9-esp8266-mysql-php-en.html
EliminarBuena tarde, muchas gracias por el código, funciona perfectamente, solo le hice un pequeño cambio para evitar el uso del pulsador, y que mejor revise si está vacía la ssid (si falla la conexión después de los 50 segundos limpia la EEPROM), en este caso se pone automáticamente en modo SoftAP. Pero me queda una duda, habrá forma de reiniciar el dispositivo por código una vez configurada la red?? Saludos!!
ResponderEliminarsi entendi bien, respecto a la adaptación a modo automático suprimiendo el pulsador y vaciado de EEPROM, si por alguna razón tenes que apagar el router o el AP al cual se conecta se perdería la configuración del modulo y si tenes varios tendrías que volver a configurar en cada uno el ssid y pass manualmente?
EliminarMuchas gracias! en base a este código y algunas adiciones tengo mi proyecto.
ResponderEliminarEn modo configuración grabo en la eeprom (Ssid, Pass y le asigno un nombre al host) como mi router le asigna ip por dhcp es dinamica pero siempre puedo acceder al modulo por el nombre.
Desde la pc le puedo hacer "ping esp8266" y responde bien, desde el navegador "http://esp8266" o simplemente "esp8266/" y muestra el html, pero no asi desde android (solo se puede por la ip) al parecer android no trata los DNS y lo delega directamente a google.
- Tanto las pc's como el modulo están en la misma red local
- El modulo es el esp8266-12e y esta como ServerWeb (no AP)
Ya probe varias opciones entre ellas mDNS pero sigo sin resolverlo. Si a alguien le sucedió lo mismo y pudo solucionarlo se agradece la ayuda! Saludos
Este comentario ha sido eliminado por el autor.
EliminarTengo el mismo problema, pudiste resolverlo? Cómo asigno el nombre de Host al dispositivo?
EliminarDesde ya Gracias.
Buenas tardes, quisiera hacer algo parecido a fredi, al iniciar que que ejecute el servidor y espere por un tiempo una conexión , si no la hay , que salda e inicie como cliente. no se como hacerlo, desde ya muchas gracias.
EliminarHola Ale, te envidio todo lo que sabes!
ResponderEliminarestuve probando esto y es genial, lo unico que no se como hacer es para cambier estas lineas:
const char *ssidConf = "tutorial";
const char *passConf = "12345678";
las cambien 1.000.000 de veces y me sigue tirando tutorial y la pass 12345678.
me gustaria cambiarlas pero no me da ni pelota, no se si queda grabada en la eeprom o donde?
reflashee el nodemcu mas de 10 veces y sigue quedando esas lineas
y el ssdi y password de mi modem guardados.
si podes ayudarme genial!
Soy Pablo
Hola, proba borrando la eeprom y después volve a cargar tu código.
Eliminar#include
void setup ( ) {
for (int i = 0 ; i < EEPROM.length() ; i++) {
EEPROM.write(i, 0);
}
}
void loop ( ) { }
void WiFiServidor () {
ResponderEliminarString User;
String Pass;
String message = "{\"mensaje\" = \"";
message += "Credenciales";
message += "\"}";
server.send(200, "text/html",message);
Serial.println("Configuring connection to server...");
if (EEPROM.read(100) == '\0') {
if (server.arg(0).length() != 0 ) {
User = server.arg(0);
UserServ = const_cast(User.c_str());
Pass = server.arg(1);
PassServ = const_cast(Pass.c_str());
server.send(200, "text/html",message);
Serial.println("Leyo credenciales");
WiFiServerConnect ();
Serial.println("Despues de WiFiServerConnect");
} else {
Serial.println("Esperando credenciales");
}
} else {
Serial.println("entro a leer credenciales guardadas");
server.send(200, "text/html",message);
leer(100).toCharArray(UserServ, 50);
leer(150).toCharArray(PassServ, 50);
WiFiServerConnect ();
}
return;
}
void WiFiAP () {
if (EEPROM.read(100) == '\0') {
Serial.print("Configuring access point...");
Serial.println();
if (EEPROM.read(50) != '\0') {
leer(50).toCharArray(APpass, 50);
WiFi.disconnect();
WiFi.softAP(ssid,APpass);
Serial.println("wifi AP con contrasena seteado");
} else {
WiFi.disconnect();
WiFi.softAP(ssid);
RSTButtom = 1;
Serial.println("wifi AP sin contrasena seteado");
}
IPAddress myIP = WiFi.softAPIP();
Serial.print("Server MAC address: ");
Serial.println(WiFi.softAPmacAddress());
Serial.print("AP IP address: ");
Serial.println(myIP);
server.begin();
Serial.println("HTTP server started");
} else {
Serial.println("hay algo guardado en user server");
WiFiServidor ();
}
}
Alguien podria ayudarme, no se porque se va a wdt reset al terminar la funcion WiFiServidor, intente varias maneras pero todas terminaron con el mismo resultado, Ademas de que cuando entra a esta parte leer(100).toCharArray(UserServ, 50);
leer(150).toCharArray(PassServ, 50); no logra leer correctamente
Hola buenas tardes, muchas gracias por el tutorial esta perfecto y muy claro, habia estado buscando informacion al respecto pero estoy es lo mas claro que he encontrado.
ResponderEliminarTe comento, lo estoy implemmentando con un D1 de WEMOS, en este momento no tengo protoboard y me esta constando acceder al SETUP por el tema del pulsador. ya conecte uno al GPIO14 y a 3.3V, presione y al mismo tiempo reinicie el D1 pero no consigo accesar, tienes alguna idea de como pudeo hacer que funcione con el D1?
te lo agradecere mucho
Buenas, gracias por compartir!!
ResponderEliminartengo el mismo problema que "Pescadito".
al cambiar el valor de las siguientes variables:
const char *ssidConf = "tutorial";
const char *passConf = "12345678";
y cargar el sketch en modo:
erase flash "Sketch + Wifi Sentinngs"
Al reiniciar el ESP8266 el nombre del servidor wifi me cambia a
"ESP_0B0B03" y sin Pass alguno
He borrado EEPROM, SPiFFS, Y Restaurado de fábrica antes de cargar de nuevo el Sketch, pero no lo consigo.
Gracias de nuevo
Hola saludos, alguien ha podido evitar colocar el pulsador para entrar en modo AP. Gracias de antemano por cualquier colaboración para hacer los cambios en el código actual.
ResponderEliminarhola Saludos, excelente tutorial!!, me gustaría poder modificar la ip del NODEMCU, desde una pagina web, no sólo por DHCP, muchas gracias.
ResponderEliminarbuenas tardes: me pareció excelente este tutorial ya que es exactamente lo que estaba buscando, de paso me suscribí al canal y me ví unos cuantos videos.
ResponderEliminarMe gustaría que subas algún video sobre como utilizar los pines rx y tx del ESP8266 01 como entradas/salidas digitales y de ser posible si tenes info de alimentar este mismo ESP con una o dos pilas cr2032. Te pido esto ya que estoy armando un proyecto donde el tamaño reducido es muy importante.
Muchas gracias y saludos!
EXCELENTES TUS TUTORIALES, FELICITACIONES AMIGO. SALUDOS DESDE PERU.
ResponderEliminarMuchas gracias. Saludos.
EliminarMuy bueno e interesante tu tutorial. Te felicito!!.
ResponderEliminarSaludos,
Pedro de Chile
Muchas gracias. Saludos desde Buenos Aires.
EliminarEstimado, puedo usar este mismo concepto, para que ademas de el usuario y contraseña del wifi, me guarde una serie de otros valores? Por ejemplo necesito definir temperatura normal, diferencia de temperatura, distancia (en cm) que signifique de debo rellenar agua, pero configurarlos una vez (por el usuario) y que luego los pueda usar dentro del codigo del software.
ResponderEliminarSera posible, hacer esto del softap y el webserver, pero sin boton, sino que detecte si ya estan las configuraciones?
Todo lo que decís es posible. Pero te recomiendo usar el SPIFFS. http://www.sinaptec.alomar.com.ar/2017/06/tutorial-8-esp8266-spiffs-json.html
EliminarEl botón te recomiendo usarlo,¿sino como vas a hacer para volver a configurarlo?
Saludos.
Hola, ¿cómo hago una aplicación de teléfono para conectar el módulo esp a internet?
ResponderEliminar'guardar_conf' was not declared in this scope
ResponderEliminar¿Se puede usar un ESP8266-01?
ResponderEliminarSi claro. Saludos.
EliminarMuy pero muy buen aporte, te agradezco el compartir tus conocimientos, he usado tu ejemplo añadiendo en el código botón la función reset(para no hacerlo manual con el botón del esp o pulsando dos botones como el ejemplo) pero antes uso spiffs para almacenar valores y al reiniciar el esp lea los valores y de este modo sepa el esp de que modo iniciar, quizás suene algo enredado pero es útil simplificar cosas para un usuario final, en fin, un enorme saludo desde México y de nuevo gracias por estos aportes que hasta hoy siguen vigentes, saludos.
ResponderEliminarHola eres un capo... muy bueno el tutorial, tengo una duda...
ResponderEliminarcuando entramos el modo configuración, el MCU actúa como un access point verdad, entonces, la ip que nos muestra en el puerto serial se mantiene constante cada vez que entramos al modo configuración o va cambiando? por que si nos tendríamos que conectarnos con USB cada vez que entremos a dicho modo para visualizar la IP, ya que no seria constante, una ayuda en esa parte por favor.
Buenas tardes, muchas gracias por compartir los conocimientos con nosotros!! y con el mundo.
ResponderEliminarUsted sabe que sigo todos los pasos y anda todo muy bien, configuro la red wifi pero luego al reiniciar la placa no logro conectarme, sabe que puede ser?
hola excelente tutorial soy nuevo programando en arduino estoy haciendo un proyecto con un esp8266 y un receptor RF433MHZ estoy ocupando tu codigo quiero guardar los valores del control que en su ejempo serial 8854245 y quiero agregar una descripcion al control como 22d guardarlos en la eeprom y despues cuando active el control ver si se encuentra guardado y me arroje el valor 22d me podrias apoyar con la duda
ResponderEliminarExcelente, muy útil. Con muy poco esfuerzo le agregue para guardar el mqtt broker, port user, password, etc.
ResponderEliminarPrimero me mori probando con las librerias wifimanager y el uso de spiffs que en mi caso no se justifica porque solamente lo voy a usar para inyectar a todos el mismo codigo y configurarlos una sola vez en toda la vida del producto.
Si algun principiante lee esto ni lo dude en usar este método.
Este comentario ha sido eliminado por el autor.
ResponderEliminar