bclose

Servidor Web con WIFI ESP8266

Programando el ESP8266 para montar un servidor Web
tienda online prometec

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 superior  Arduino DUE o MEGA.
ProtoboardUna Protoboard .
conexionesAlgunos cables de protoboard, preferiblemente Dupont macho/hembra.
Vista frontal Un módulo WIFI ESP8266
Fuente para protoboard Una fuente de alimentación externa de 3.3V

 

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í:   
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.

 
 

 

 

 

 

(203) Comments

    • Milton

    me gustaría con que comando, o como puedo hacer puedo vincular paginas internas en el mismo dispositivo, y tambien como puedo subir imagenes no muy pesadas al dispositivo (LOGO)

    • Hola Milton,

      No he dedicado mucho tiempo al esp8266 con servidores web mas alla de unas pocas pruebas sencillas, pero hay mucha documentacion por internet que puede servirte

  • Usado: /Users/leondev/Documents/Arduino/libraries/WiFi
    No usado: /Applications/Arduino.app/Contents/Java/libraries/WiFi
    exit status 1
    ‘GetLineWIFI’ was not declared in this scope

    Ayuda me sale este error.

    • Hola Luis, GetLineWifi es una pequeña funcion que escribimos para leer un puerto serie y que no s eporque no aparece en este listado pero que aqui tienes:
      String GetLineWIFI()
      { String S = “” ;
      if (Serial3.available())
      { char c = Serial3.read(); ;
      while ( c != ‘\n’ ) //Hasta que el caracter sea intro
      { S = S + c ;
      delay(25) ;
      c = Serial3.read();
      }
      return( S ) ;
      }
      }

      De todas formas puedes descargar el programa completo en el enlace que ahí en la sesión. Un saludo.

  • Buen día
    ¿No hacen tutoriales de arduino-esp8266-appinventor? …
    Me gustaría saber mas acerca de como enviar datos desde el arduino al esp8266 y de ahí a alguna pagina (viceversa de lo que hacen con PuTTY)

    • Hola Felipe, pues es uno de los temas que nos gustaría abordar, pero de momento andamos escasos de tiempo…

Give a Reply

WordPress Anti-Spam by WP-SpamShield