Servidor Web con WIFI ESP8266

Objetivos

 

  • Programar el módulo WIFI ESP8266 desde el arranque de Arduino. con un programa que le vuelque comandos AT.
  • Probar la comunicación a 115.200 baudios con el módulo ESP8266.
  • Montar un programa de ejemplo, para usar el ESP8266 como servidor web desde Arduino.
  •  

    Material requerido.

     

    Vista principal
    Vista frontal
    Power Supply

    Alternativamente puedes usar un Nodemcu V2 o un ESP32

    Mas sobre WIFI y ESP8266

     

    En las dos últimas sesiones hemos estado jugando con el módulo WIFI ESP8266. Le he encontrado muy simpático y capaz, especialmente dado su bajo precio.

    Le hemos probado primero alimentado directamente desde el Arduino, lo que no es muy aconsejable dado que, especialmente en el arranque, puede demandar más intensidad de la que el pin de 3V puede proporcionar. Aunque al final se consigue que arranque, no suele ser sin varios intentos lo que resulta molesto y poco fiable.

    En la siguiente sesión usamos una fuente de alimentación de protoboard para garantizar la alimentación correcta del módulo, lo que nos llevó a un arranque falible al 100% (Menos mal).

    Pero aun así, seguíamos usando las señales de transmisión de Arduino a 5V sin adaptar a los 3,3 V que el fabricante recomienda. La experiencia es que resulta fiable y funciona bastante bien, con una molesta tendencia a colgarse con ciertos comandos, especialmente cuando se los volcábamos por programa.

    Así que la solución definitiva pasaba por probar con todas las señales a 3.3V y la alimentación correcta del módulo (No veo otra solución que le vamos a hacer), y como por otro lado llevaba ya un tiempo queriendo probar mi flamante Arduino DUE y no encontraba excusa, mira por donde voy a matar dos pájaros de un tiro.

    Como el DUE funciona nativo a 3.3V, nos viene de perlas porque, además, dispone de 3 puertas hardware de comunicaciones que  pueden funcionar a 115200 baudios y así podemos probar el modulo con una velocidad de verdad.

    Pues eso, que vamos a ver qué pasa, aquí tenéis el diagrama de conexión al DUE.

    Esxquema de protoboard

  • Por favor que no se os ocurra olvidaros de conectar la masa común entre la protoboard ( O el regulador que uséis) y la masa GND de Arduino. Ignorar esto puede ser muy perjudicial para la buena salud de vuestra electrónica.
  • Recordad que unir las masas, es lo único que nos garantiza un nivel cero de referencia, común. Si lo omitís, las diferencias de tensión entre el alimentador de vuestro Arduino y el de la protoboard, pueden ser más que suficientes para daros una sorpresa y chamuscar algo.
  • El programa de control

     

    La idea es volcar por programa los comandos necesarios al DUE para programarlo desde el arranque. Ya en la sesión previa vimos la parte interesante de este programa y no creo que sea necesario insistir más en ello. Aquí tenemos el programa Prog_76_1

    Hemos convertido el programa de volcado de comandos en una función, que incluye un array con las órdenes a enviar:

    void SetUpWIFI()
       {  String ordenes[]=
           {  //"AT+RST",
              "AT+CWMODE=3",
              //"AT+CWQAP", 
              //"AT"AT+CWLAP",
              "AT+CWJAP=\"charly\",\"contrase\"",
              "AT+CIFSR" ,
              "AT+CIPMUX=1",
              "AT+CIPSERVER=1,80",
              "END"          // Para reconocer el fin de los comandos AT
           };
    
          int index = 0;
          while(ordenes[index] != "END")
            {  Serial3.println(ordenes[index++]);
               while ( true)
                  {   String s = GetLineWIFI();
                      if ( s!= "") Serial.println(s);
                      if ( s.startsWith("no change"))  
                           break;
                     if ( s.startsWith("OK"))   
                           break;
                     if ( s.startsWith("ready"))  
                           break;
                  }
              Serial.println("....................");
            }  
       }

     

  • Un comentario importante: Esta función no puede enviar la orden AT+RST, porque su salida es más o menos así:  [/fancy-ul] [/three-fourth]
  • Comunicacion con WIFI ESP8266

     

  • Podéis ver que el resultado incluye “OK” y “ready”, lo que es mortífero para nuestra función que busca solo una de las dos terminaciones, pero no las dos. O bien hay que sofisticar más el programa o enviar esta orden con un println directo y luego esperar un par de segundos.
  • El Arduino DUE dispone de tres puertas hardware de comunicaciones que soportan sin problemas los 115.200 baudios y  para ello no necesitamos ninguna librería. Por eso las inicializamos directamente, con Serial y Serial3:

    void setup()
       {   Serial.begin(19200);
           Serial3.begin(19200);
           delay(1500);          // Para darnos tiempo a abrir la consola
           SetUpWIFI() ;         // Envia los comandos AT
       }

    Inicialmente las programamos a 19.200, que es la velocidad a la que está actualmente el módulo WIFI (y si ponemos aquí los 115200 baudios, va a ser difícil comunicar con el)

    Creo que el resto del programa no tendrá ninguna dificultad para vosotros (Si estáis leyendo esto seguro que ya sois usuarios avanzados).

    Ahora podemos volcar este programa Prog_76_1 y una finalizada, abrimos la consola Arduino para reprogramar la velocidad. Comprobad que os escucha y enviar la orden.

    AT+CIOBAUD

    AT+CIOBAUD=?
    At+CIOBAUD?
    AT+CIOBAUD=115200

    Si todo va bien perderemos la comunicación con el modulo, porque adaptará su velocidad a 115200 y nosotros debemos reprogramar el Arduino de modo acorde, igual que la velocidad de la consola.

    Cambiad en el programa

    Serial.begin(19200);
    Serial3.begin(19200);

    Por esto otro

    Serial.begin(115200);
    Serial3.begin(115200);

    Y volcad el nuevo programa a Arduino. Cuando finalice, cambiad a 115.200 baudios la velocidad de la consola y ya está. Ejecutad de nuevo el programa para ver el resultado.

    El resumen es que mejoran bastante los problemas de comunicación,  pero sigo recibiendo bastantes interferencias en forma de basura en la puerta serie y además aunque mejora, no se elimina del todo la tendencia a colgarse con los comandos CWLAP y CWJAP,al volcarlos por programa,  pero la verdad es que el DUE va como una seda.

    No necesitamos cargar librerías, tenemos 3 puertas hardware de comunicaciones, un procesador de verdad a 32 bits y cantidad de memoria para nuestros programas. Casi me da pena volver al venerable Arduino UNO para los tutoriales.

    Un servidor Web con el WIFI ESP8266

     

    Vamos con el plato fuerte de la sesión. Voy a usar un Arduino DUE para este ejemplo pero sería de lo más sencillo convertirlo a un UNO. Bastaría con usar la librería SotwareSerial que usamos en las dos sesiones previas referentes al WIFI ESP8266. En un Mega, debería correr sin modificar, ya que es pin a pin compatible con el DUE.

    Vamos a montar un pequeño ejemplo en el que nuestro Arduino DUE o Mega, presenten una página Web con las lecturas de las puertas analógicas.

    Usaremos para ello el mismo montaje que en el ejemplo anterior y que repetimos aquí por comodidad de los más vagos (Entre los que me cuento sin rubor).

    Esxquema de protoboard

    El programa de servidor WEB con WIFI ESP8266

     

    Os dejo aquí el programa completo Prog_76_2 y pasamos a describir las partes más oscuras.

    En primer lugar y como vimos en la sesión anterior, definimos un array de comandos para programar el modulo:

    String ordenes[]=
       {  //“AT+CWJAP=”redwifi”,”Contraseña”       // A mi esto me da problemas
          "AT+CWMODE=3",
          "AT+CIFSR" ,
          "AT+CIPMUX=1",
          "AT+CIPSERVER=1,80",
          "END"                // Para reconocer el fin de los comandos AT
       };

    En el setup programamos las puertas Serie y Serie3 a 115.200 baudios y después volcamos los comandos de la matriz, con un programa similar al anterior pero desde el setup.

    void setup()
       {   Serial3.begin(115200);
           Serial.begin(115200);
           delay (1000);       // Para tener tiempo de arrancar la consola
           int index = 0;
           while(ordenes[index] != "END")
             {  Serial3.println(ordenes[index++]);
                while ( true)
                  {   String s = GetLineWIFI();
                      if ( s!= "") Serial.println(s);
                      if ( s.startsWith("no change")) break;
                      if ( s.startsWith("OK")) break;
                      if ( s.startsWith("ready")) break;
                  }
                Serial.println("....................");
             }
      }

    Usaremos una versión modificada de GetLine() para leer el Serial3, llamada GetLineWIFI ()y que simplemente lee de esta puerta para recibir líneas completas.

    Para poder enviar las líneas HTTP que conforman la página de presentación de datos, vamos a necesitar enviar varias líneas de texto, que como ya vimos antes deben hacerse con AT+CIPSEND que espera que le demos la longitud del texto, por lo que va a ser necesaria una función:

    void http(String output)
      {  Serial3.print("AT+CIPSEND=0,");   // AT+CIPSEND=0, num
         Serial3.println(output.length());
         if (Serial3.find(">"))            // Si recibimos la peticion del mensaje
            { Serial.println(output);
              Serial3.println(output);     //Aqui va el string
              delay(10);
              while( Serial3.available() > 0)    // Busca el OK en la respuesta 
                { if (  Serial3.find("SEND OK")  )  break;
                }
             }
      }

    Como veréis, esta función http(), recibe un String y calcula su longitud para después mandar un comando CIPSEND con ella.  Después busca recibir un carácter ‘>’ que nos devuelve el modulo para indicar que espera la recepción del String.

    Si lo encuentra, le envía el String recibido a la puerta serie y al serial3 hacia el WIFI. Cuando termina busca el “SEND OK” y termina al recibirlo.

    Para enviar la página web, hemos montado una pequeña función con los textos necesarios:

    void webserver(void)
       {  http("<!DOCTYPE HTML>");
          http("<html>");
          http("<head><title>LECTURAS ANALOGICAS.</title>");
          http("<meta http-equiv=\"refresh\" content=\"15\"></head>"); // Refresco
          http("<body><h1> Situacion Ambiente</h1>");
    
          for (int analogChannel = 0; analogChannel < 6; analogChannel++)
              {    int sensorReading = analogRead(analogChannel);
                   http("    analog input ");
                   http( String(analogChannel));
                   http(" is ");
                   http(String(sensorReading));
                   http("<br />");
              }
          http("<p><em> La pagina se actualiza cada 15 segundos.</em></p></body></html>");
          delay(1);
          Serial3.println("AT+CIPCLOSE=0");
       }

    Envía en primer lugar un típico encabezado HTML, con una instrucción para que se refresque cada 15 segundos y luego envía los textos que corresponden a las lecturas de las puertas analógicas con un bucle for.

    Las últimas líneas son para cerrar la sesión IP con el navegador y dejarlo libre al servidor para una nueva conexión.

    Y por último, el loop busca conexiones a través de la puerta WIFI (Serial3) y cuando las encuentra, invoca webserver().
     

    Aquí os dejo un mini vídeo con el resultado:

    Resumen de la sesión

     

  • Probamos el programa de volcado de comandos AT y vimos que tiene una cierta tendencia a colgarse con ciertos comandos.
  • Hemos probado la comunicación a 115.200 baudios entre el módulo WIFI y el Arduino DUE con plena satisfacción.
  • Montamos un ejemplo de servidor Web, apoyándonos en el módulo WIFI y vimos cómo usar los comandos AT desde programa para gestionar el servidor.
  • En definitiva tengo una muy buena opinión del módulo ESP8266. Tiene sus manías, pero nos permite conectar vía WIFI nuestros Arduinos de forma más que satisfactoria y con un poco de cuidado, nos abre unas puertas de los más interesantes por una precio ridículo.
  •  

    Deja una respuesta