Problemas con nodemcu y modo AP

Hola Chicos,

Estoy intentando hacer un pequeño proyecto personal que a la vez espero que me sirva para aprender. Soy un poco novato con arduino y ESP8266 aunque con arduino ya he hecho algunas cosillas pequeñas.

Mi proyecto de momento lo estoy montando con un nodemcu, he usado como base este ejemplo (http://www.sinaptec.alomar.com.ar/2017/06/tutorial-7-esp8266-guardar-ssid-y.html), el ejemplo me funciona correctamente.

El código base lo he ido modificando para mis requisitos, de momento me compila y lo subo correctamente al nodemcu, pero cuando lo pongo en modo AP, la red Wifi me aparece pero no me puedo conectar y alguna ocasión parce que estoy conectado pero no tengo acceso a 192.168.4.1.

Mi código:

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>

//-------------------VARIABLES GLOBALES--------------------------
struct configuracion_t {
  char hostName[11]="h";
  char ssidName[11]="srrrr";
  char ssid_password[16]="123456789";
  char ap_password[17]="ap";
  boolean dhcp = true; 
  char ip_lan[16]="i";
  char mask_lan[16]="255.255.255.0";
  char gateway_lan[16]="g";
  char api_user[101]="au";
  char api_password[51]="app";
  char api_device_id[33]="S";
  } cfg;


int contconexion = 0;
unsigned long previousMillis = 0;

/*
char ssid[50];      
char pass[50];
*/
char *ssid="ssid";
char *pass="pass";

const char *ssidConf = "SB_";
const char *hostConf = "SBH_";
const char *passConf = "123456789";
const char pVez='1';

String hostName="";
String ssidName="";

String mensaje = "";

char primeraVez;

//-----------CODIGO HTML PAGINA DE CONFIGURACION---------------
String pagina = "<codigo de la página html, esta en el fichero>";

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

      Serial.println("* Nombre:");
      Serial.println(ssid);
      Serial.println("* Password");
      Serial.println(pass);
  
  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 + 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.print("Ssid: " );
  Serial.println(ssidConf);
  Serial.print("Password: " );
  Serial.println(passConf);
  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("name_ssid"));
  Serial.println(server.arg("pass_wifi1"));
  grabar(50,server.arg("pass_wifi1"));

  mensaje = "Configuracion Guardada...";
  paginaconf();
}

void leerConfiguracion(){
  primeraVez = (char)EEPROM.read(0);;
  Serial.print("primeraVez: ");
  Serial.println(primeraVez);

  if (primeraVez != pVez){
       Serial.println("Es la primera vez que se ejecuta, se crea la configuración");
       EEPROM.write(0, pVez);

       //Calculamos el nombre y ssid del dispositivo  
       //y añadimos a la configuración.
       Serial.print("El nombre del ESP es: ");
       Serial.println(WiFi.hostname());
       ssidName=WiFi.hostname().c_str();
       hostName=WiFi.hostname().c_str();

       Serial.print("Lo almacenado en hostname es ");
       Serial.println(hostName);
  
       ssidName.replace("ESP_",ssidConf);
       hostName.replace("ESP_",hostConf);

       Serial.print("El nuevo nombre ssid es");
       Serial.println(ssidName);
       Serial.print("El nuevo nombre del host es");
       Serial.println(hostName);
       
       EEPROM.put(sizeof(pVez)+1,cfg);
       EEPROM.commit();
  } else{
   Serial.println("Ya existe configuración");
  }

  Serial.println(sizeof(pVez));
  EEPROM.get(sizeof(pVez)+1,cfg);  

  Serial.print("ssid Name: ");
  Serial.println(cfg.ssidName);
  Serial.print("Host Name: ");
  Serial.println(cfg.hostName);
  Serial.print("Password ssid: ");
  Serial.println(cfg.ssid_password);
  Serial.print("Mask Network: ");
  Serial.println(cfg.mask_lan);
  Serial.print("DHCP: ");
  Serial.println(cfg.dhcp);

  Serial.println("**HostName: "+WiFi.hostname());
  Serial.println(cfg.ssid_password);
}

void grabarConfiguracion(){
  EEPROM.put(1,cfg);
  EEPROM.commit();  
}

//----------------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 
  pinMode(14, INPUT);  //D5
  
  // Inicia Serial
  Serial.begin(115200);
  Serial.println("");

  //Iniciamos la EEPROM para acceso a ella.
  EEPROM.begin(512);

Serial.println(WiFi.hostname());

  //Cargamos la configuración
  leerConfiguracion();
  
  if (digitalRead(14) == 0) {
    Serial.println("boton pulsado");
    modoconf();
  }

  ssid="hola";
  pass="hola";

  setup_wifi();
}

//--------------------------LOOP--------------------------------
void loop() {

  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= 5000) { //envia la temperatura cada 5 segundos
    previousMillis = currentMillis;
    Serial.println("Funcionado...");
  }
}

¿Que es lo que estoy haciendo mal? He buscado por internet pero no veo o no encuentro nada concreto a mi problema.

P.D.: Perdonar si el código está un poco "sucio". El código completo lo he adjuntado a este post.

firmware.ino (14.5 KB)

Hola, por que por defecto cuando configuras el nodemcu en modo Access Point la ip que asigna es esa (192.178.4.1).

Además, en modo Access Point (AP) hace como un router, es decir, creaa una rede wifi y por tanto, cuando buscar las rededes wifi para conectarte, te sale una nueva para poderte conectar, en este caso sería la del ESP8266.

Un saludo,

Independientemente que por todo internet hay "listillo" y que van de sobrado, puede que no me haya explicado bien, pues al no dominar estas placas, puede que mi exposición del problema no fuese muy precisa, pero mi problema radica cuando esta configurado en modo AP e intento conectarme desde cualquier dispositivo a la wifi que crea el nodemcu, que por cierto, la ip que establece por defecto es la 192.168.4.1 (IP por defecto de cualquier ESP8266), y para que tu sabiduría aumente un poco más, puedes leerte la documentación oficial (Soft Access Point Class — ESP8266 Arduino Core 3.1.1-26-g734defb8 documentation).

Espero que no te canses demasiado leyendo esto, pues temo que no tendrás fuerzas para poderme ayudar.

Un saludo.

P.D.: Sin acritud.

El ejemplo del sitio que has indicado funciona pero el tuyo no. Asi que en el proceso algún error has cometido.
Mi consejo es que vuelvas a tomar el ejemplo base y lo vayas modificando paso a paso dandole la forma que prentendes.

Por cierto, yo me he conectado a _SB con pass 123456789 pero no se ve nada web de esa ip.

Probé con ip/escanear y tampoco

Gracias por tus consejos, precisamente acabo de empezar de nuevo. Con respecto al ejemplo, si lo has visto hace falta un botón conectado a la nodemcu para poder iniciarlo en modo AP.

Un saludo.

Claro que lo he visto pero simplemente lo puse como funcion que se ejecuta y a otra cosa. Pase por el, pude escannear pero no me gusto todo el sketch.
Prefiero la librería WifiManager que hace todo eso de modo mucho mas inteligente y profesional.

Y como es profesional ya guarda los datos en EEPROM y muchas cosas mas, la lista de sus características esta en inglés pero no creo que tengas problemas.

remove dependency on EEPROM library
move HTML Strings to PROGMEM
cleanup and streamline code (although this is ongoing)
if timeout is set, extend it when a page is fetched in AP mode
add ability to configure more parameters than ssid/password
maybe allow setting ip of ESP after reboot
add to Arduino Library Manager
add to PlatformIO
add multiple sets of network credentials
allow users to customize CSS
ESP32 support or instructions
rewrite documentation for simplicity, based on scenarios/goals
rely on the SDK's built in auto connect more than forcing a connect

Gracias por la info. Lo veré con detenimiento.

Un saludo.

Mira los ejemplos son muy buenos y solo tendras que hacer leves cambios.

Hola ArduMyth,

Puede que yo no me haya explicado lo suficientemente bien (Lo siento), pero me ha molestado tu segundo comentario, lo siento si te as ofendido, pero has ido de sobrado. Te recuerdo que estos foros son para ayudar y aclarar temas a los que novatos y los que ya no lo son tantos pero se han encontrado con algún problema que no son capaces de resolver en primera instancia y no para pavonerse con los conocimientos que tiene uno.

Lo único que pretendo es aprender y solucionar mi problema, que seguramente será una tontería, pero no encuentro el motivo y te digo que no es de la IP, sino del AP y la conexión a la Wifi que genera.

No quiero seguir con esta polémica, si te cansas ya sabes, vete y trolea a otro, sino gracias por tu ayuda.

Un abrazo.