Una forma sencilla de enviar información de y a un microcontrolador es centralizándola en un servidor web. Si bien no es un método tan eficiente como, por ejemplo, acceder directamente a una base de datos, sí que es lo suficientemente eficaz, especialmente si se considera un proyecto basado en un microcontrolador, y se añade las ventajas de la ubicuidad (datos en la nube) y la simplicidad (puede manejarse como texto información y órdenes) El envío de información usando este sistema puede consistir en hacer peticiones HTTP POST y la recepción en analizar el contenido de la respuesta a una petición HTTP GET.
El módulo WiFi ESP8266 es una opción muy económica, con un rendimiento muy adecuado para su uso con microcontroladores y muy sencillo de usar trabajando con órdenes AT.
Para sistematizar su uso con peticiones HTTP he desarrollado una pequeña librería que da soporte a las necesidades de mi proyecto de dispositivo gestor de sueño (que he llamado SleepManager) ya que basa su infraestructura en un servidor web que permite extenderlo a un objeto IoT como servicio en la nube. No es difícil agregar a la librería otros servicios como peticiones UDP, por ejemplo, para sincronización horaria por NTP aunque, como explico en el texto enlazado, no es crítico para mis necesidades y puedo resolverlo aceptablemente con una petición HTTP a una página web preparada a ese efecto como muestro en un ejemplo de uso de esta librería.
El funcionamiento de la librería se basa en el envío de órdenes AT cuando el dispositivo está disponible y la repetición (con un pequeño retraso) en caso de error, que se interpreta como no disponibilidad (con éxito, por las pruebas) por ejemplo del punto de acceso WiFi o del servidor al que se consulta.
La librería aprovecha el hecho de que el módulo WiFi ESP8266 devuelva un código +IPD como aviso de la recepción de datos para ir rellenando un pequeño buffer con la información devuelta por el servidor. Para el proyecto de dispositivo gestor del sueño necesito analizar muy pocos datos devueltos desde el servidor por lo que, para economizar, el buffer y el puntero que lo recorren son especialmente pequeños; esta será una de las primeras cosas que deberás cambiar para reutilizar la librería para procesar un volumen de datos mayor.
Las funciones que se exponen como públicas permiten (1) saber el estado del módulo: si está conectado o no, si hay datos en el buffer y cuántos y si el módulo ESP8266 ha terminado la operación que se le ha solicitado; (2) conectar a un punto de acceso WiFi en una red con un servidor DHCP y (3) hacer peticiones HTTP de tipo GET y POST aunque, como verás, el código está diseñado pensando en que sea muy sencillo añadir otras.
En cuanto al funcionamiento interno, en primer lugar se construyen dos matrices, una con las órdenes AT y otra con las respuestas esperadas para éxito y error; luego, el programa que usa la librería, debe ir llamando cada cierto tiempo a la función
que se encargará de mandar las órdenes al módulo si hay disponibles y no está ocupado y a la función que procesará las respuestas del módulo ESP8266 (y del servidor HTTP a través de él si procede)Como cabe la posibilidad de que el módulo se desconecte por pérdida de señal, el programa principal puede comprobar si el módulo ESP8266 está conectado al punto de acceso WiFi (con la función
) y tratar de conectar en caso contrario (con la función )Para saber si la operación que se ha solicitado ha terminado, el programa puede usar la función
y en tal caso enviar otra o utilizar los datos resultantes para lo que se utiliza la función , que devuelve el contenido del buffer que se ha ido rellenando con los datos que llegaban al módulo ESP8266 hasta completar la operación, y la función que informa de la cantidad de esos datos que el servidor ha avisado de que iban a ser enviados (con lo que poder descontar la información del propio módulo)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 |
//ESP8266.cpp #if defined(ARDUINO) && ARDUINO>=100 #include "Arduino.h" #else #include "WProgram.h" #endif // Para monitorizar (CONSOLA) a la vez que se comunica con el módulo por el puerto serie hace falta una placa Arduino con varios puertos (como Mega o Leonardo) en caso contrario hay que cambiar a MODULO_WIFI Serial y desactivar la depuración // No se inicializan las comunicaciones serie, es necesario inicializarlas desde el programa que usa la librería #define CONSOLA Serial #define MODULO_WIFI Serial1 #include "ESP8266.h" ESP8266::ESP8266(boolean depuracion) { constructor(depuracion); } ESP8266::ESP8266() { constructor(false); } ESP8266::~ESP8266() { } void ESP8266::constructor(boolean depuracion) { mostrar_salida=false; // Sin depuración para Arduino Uno //mostrar_salida=depuracion; estado_orden=ORDEN_OK; indicador_operacion_terminada=&ESP8266_operacion_terminada; *indicador_operacion_terminada=true; reiniciar_buffer(); mensaje_buscado[ORDEN_RECIBIENDO]=CODIGO_INICIO_RECEPCION; } void ESP8266::conectar_wifi ( String ssid, String clave, String ip, byte timeout ) { estado_orden=ORDEN_OK; pasos_operacion=0; paso_operacion=255; //Para poder incrementar al principio del proceso y que empiece en cero ESP8266_conectado=false; indicador_operacion_terminada=&ESP8266_conectado; *indicador_operacion_terminada=false; respuesta[pasos_operacion][ORDEN_KO]=""; //reiniciar para descartar la configuración anterior que es desconocida respuesta[pasos_operacion][ORDEN_OK]="ready"; comando[pasos_operacion++]="AT+RST"; //reiniciar para descartar la configuración anterior que es desconocida //respuesta[pasos_operacion][ORDEN_KO]="ERROR"; //Consultar el firmware //respuesta[pasos_operacion][ORDEN_OK]="OK"; //comando[pasos_operacion++]="AT+GMR"; //Consultar el firmware respuesta[pasos_operacion][ORDEN_KO]=""; //Modo Sta (1|3) respuesta[pasos_operacion][ORDEN_OK]=""; comando[pasos_operacion++]="AT+CWMODE=1"; //Modo Sta = 1 (también es posible con 3, mixto) //respuesta[pasos_operacion][ORDEN_KO]=""; //Listado de puntos de acceso //respuesta[pasos_operacion][ORDEN_OK]=""; //comando[pasos_operacion++]="AT+CWLAP"; //Listado de puntos de acceso respuesta[pasos_operacion][ORDEN_KO]=""; respuesta[pasos_operacion][ORDEN_OK]=""; comando[pasos_operacion++]="ATE0"; //Desactivar el eco antes de mandar la clave respuesta[pasos_operacion][ORDEN_KO]="FAIL"; //En el firmware original era "Error" respuesta[pasos_operacion][ORDEN_OK]="OK"; comando[pasos_operacion++]="AT+CWJAP=\""+ssid+"\",\""+clave+"\""; //SSID y clave respuesta[pasos_operacion][ORDEN_KO]=""; respuesta[pasos_operacion][ORDEN_OK]=""; comando[pasos_operacion++]="ATE1"; //Activar el eco antes de seguir respuesta[pasos_operacion][ORDEN_KO]=""; respuesta[pasos_operacion][ORDEN_OK]="\""+ssid+"\""; comando[pasos_operacion++]="AT+CWJAP?"; //Comprobar que se ha conectado respuesta[pasos_operacion][ORDEN_KO]="ERROR"; respuesta[pasos_operacion][ORDEN_OK]=ip.substring(0,ip.lastIndexOf('.')+1); comando[pasos_operacion++]="AT+CIFSR"; //Consultar la dirección IP respuesta[pasos_operacion][ORDEN_KO]="ERROR"; respuesta[pasos_operacion][ORDEN_OK]="AT+CIPMUX=0\r\r\n\r\nOK"; comando[pasos_operacion++]="AT+CIPMUX=0"; //Conenexión simple } void ESP8266::http ( byte tipo_consulta_http, String direccion_servidor, unsigned int puerto, String nombre_servidor, String agente, String pagina, String texto_consulta, String respuesta_ko, String respuesta_ok ) { String consulta=""; estado_orden=ORDEN_OK; pasos_operacion=0; paso_operacion=255; //Para poder incrementar al principio del proceso y que empiece en cero consultando_http=true; reiniciar_buffer(); indicador_operacion_terminada=&consultando_http; *indicador_operacion_terminada=false; switch(tipo_consulta_http) { case HTTP_GET: consulta+="GET"; if(texto_consulta!="") { pagina+="?"+texto_consulta; } break; case HTTP_POST: consulta+="POST"; break; } consulta+=" /"+pagina+" HTTP/1.1"+"\r\n"; consulta+="User-Agent: "+agente+"\r\n"; consulta+="Host: "+nombre_servidor+"\r\n"; if(tipo_consulta_http==HTTP_POST) { consulta+="Content-Type: application/x-www-form-urlencoded\r\n"; consulta+="Content-Length: "+String(texto_consulta.length(),DEC)+"\r\n"; consulta+="\r\n"; consulta+=texto_consulta; } consulta+="\r\n"; respuesta[pasos_operacion][ORDEN_KO]="ERROR"; //en el firmware anterior era "Error" respuesta[pasos_operacion][ORDEN_OK]="OK"; //en el firmware anterior era "Linked" comando[pasos_operacion++]="AT+CIPSTART=\"TCP\",\""+direccion_servidor+"\","+String(puerto,DEC); respuesta[pasos_operacion][ORDEN_KO]="Error"; respuesta[pasos_operacion][ORDEN_OK]=">"; comando[pasos_operacion++]="AT+CIPSEND="+String(consulta.length(),DEC); respuesta[pasos_operacion][ORDEN_KO]=respuesta_ko; respuesta[pasos_operacion][ORDEN_OK]=respuesta_ok; //respuesta[pasos_operacion][ORDEN_OK]="CLOSED"; //en el firmware anterior era "Unlink" comando[pasos_operacion++]=consulta; /* respuesta[pasos_operacion][ORDEN_KO]=""; respuesta[pasos_operacion][ORDEN_OK]="OK"; comando[pasos_operacion++]="AT+CIPCLOSE"; */ } void ESP8266::enviar() { if(!*indicador_operacion_terminada) { switch(estado_orden) { case ORDEN_OK: paso_operacion++; if(paso_operacion<pasos_operacion) { enviar_comando ( comando[paso_operacion], respuesta[paso_operacion][ORDEN_KO], respuesta[paso_operacion][ORDEN_OK] ); } else { *indicador_operacion_terminada=true; } break; case ORDEN_KO: paso_operacion--; estado_orden=ORDEN_OK; delay(ESPERA_REINTENTO); break; /* case ORDEN_RECIBIENDO: break; case ORDEN_ACTIVA: break; */ } } } //integrar en enviar void ESP8266::enviar_comando(String comando,String respuesta_ko,String respuesta_ok) { /* //Monitorizar las ordenes que se envian if(mostrar_salida) { CONSOLA.print("\n"); CONSOLA.print("("+String(millis(),DEC)+")"); //CONSOLA.print("\n"); CONSOLA.print(String(paso_operacion+1,DEC)+"/"+String(pasos_operacion,DEC)+"> "); CONSOLA.print(comando); CONSOLA.print(" ["+respuesta_ko+"|"+respuesta_ok+"]"); CONSOLA.print("\n"); } */ MODULO_WIFI.println(comando); mensaje_buscado[ORDEN_KO]=respuesta_ko; mensaje_buscado[ORDEN_OK]=respuesta_ok; if(respuesta_ok=="") { estado_orden=ORDEN_OK; delay(ESPERA_ORDEN); } else { estado_orden=ORDEN_ACTIVA; reiniciar_busqueda_mensaje(); } } void ESP8266::reiniciar_buffer() { puntero_buffer=0; buffer_activo=false; longitud_ipd=0; } void ESP8266::reiniciar_busqueda_mensaje() { byte contador; buscando_mensaje=true; //estados=sizeof(mensaje_buscado)/sizeof(String); //Es posible generalizar calculando los estados for(contador=0;contador<ESTADOS_COMUNICACION;contador++) { puntero_mensaje[contador]=0; longitud_mensaje[contador]=mensaje_buscado[contador].length(); } } void ESP8266::recibir() { char lectura; while(MODULO_WIFI.available()>0) { lectura=MODULO_WIFI.read(); if(mostrar_salida) { CONSOLA.print(lectura); } if(buffer_activo) { if(longitud_ipd==0&&lectura==CODIGO_FIN_RECEPCION) { ESP8266_buffer[puntero_buffer]=0; longitud_ipd=atoi(ESP8266_buffer); puntero_buffer=0; } else { ESP8266_buffer[puntero_buffer++]=lectura; } } if(estado_orden==ORDEN_ACTIVA||estado_orden==ORDEN_RECIBIENDO) { estado_orden=buscar_mensaje(lectura,mensaje_buscado); if(estado_orden==ORDEN_RECIBIENDO) { buffer_activo=true; estado_orden=ORDEN_ACTIVA; buscando_mensaje=true; } } } } byte ESP8266::buscar_mensaje(char lectura,String *mensaje) { byte contador; byte numero_de_estado=0; while(numero_de_estado<ESTADOS_COMUNICACION-buffer_activo&&buscando_mensaje) { if(longitud_mensaje[numero_de_estado]) { if(lectura==mensaje[numero_de_estado].charAt(puntero_mensaje[numero_de_estado])) { puntero_mensaje[numero_de_estado]++; if(puntero_mensaje[numero_de_estado]==longitud_mensaje[numero_de_estado]) { buscando_mensaje=false; for(contador=0;contador<ESTADOS_COMUNICACION-buffer_activo;contador++) { puntero_mensaje[contador]=0; } } } else { puntero_mensaje[numero_de_estado]=0; } } numero_de_estado=numero_de_estado+buscando_mensaje; } if(buscando_mensaje) { return ORDEN_ACTIVA; } else { return numero_de_estado; } } char *ESP8266::leer_buffer() { reiniciar_buffer(); return ESP8266_buffer; } byte ESP8266::longitud_buffer() { return longitud_ipd; } boolean ESP8266::conectado() { return ESP8266_conectado; } boolean ESP8266::desconectado() { return ESP8266_conectado; } boolean ESP8266::consulta_ok() { return estado_orden==ORDEN_OK; } boolean ESP8266::operacion_terminada() { return *indicador_operacion_terminada; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
//ESP8266.h #if defined(ARDUINO) && ARDUINO>=100 #include "Arduino.h" #else #include "WProgram.h" #endif #define HTTP_CONNECT 0 //Codigos HTTP (en uso + reservados) #define HTTP_DELETE 1 #define HTTP_GET 2 #define HTTP_HEAD 3 #define HTTP_OPTIONS 4 #define HTTP_PATCH 5 #define HTTP_POST 6 #define HTTP_PUT 7 #define HTTP_TRACE 8 #define PASOS_HTTP 4 #define MAXIMO_PASOS_OPERACION 8 //+listar puntos de acceso +verificar firmware #define ESTADOS_COMUNICACION 3 //Estados que contienen mensajes que hay que atender #define ORDEN_KO 0 #define ORDEN_OK 1 #define ORDEN_RECIBIENDO 2 //debe ser el último de los estados para desactivarlo cuando se este rellenando el buffer #define ORDEN_ACTIVA 3 //debe ser igual a ESTADOS_COMUNICACION (uno más que el último estado) #define ESPERA_ORDEN 3000 //milisegundos despues de una orden AT sin respuesta #define ESPERA_REINTENTO 5000 //milisegundos antes de reintentar una orden AT #define MAX_BUFFER 256 //cambiar también el tipo de puntero_buffer si aumenta #define CODIGO_INICIO_RECEPCION "+IPD," #define CODIGO_FIN_RECEPCION ':' class ESP8266 { private: boolean ESP8266_conectado; boolean consultando_http; boolean ESP8266_operacion_terminada; boolean *indicador_operacion_terminada; boolean mostrar_salida; boolean datos_recibidos; byte paso_operacion; byte pasos_operacion; //boolean estado_operacion; String comando[MAXIMO_PASOS_OPERACION]; String respuesta[MAXIMO_PASOS_OPERACION][ESTADOS_COMUNICACION]; String mensaje_buscado[MAXIMO_PASOS_OPERACION]; byte puntero_mensaje[ESTADOS_COMUNICACION]; //ORDEN_KO->error (0/false), ORDEN_OK->acierto (1/true) byte longitud_mensaje[ESTADOS_COMUNICACION]; //longitudes la cadena de error y de la de acierto boolean buscando_mensaje; byte estado_orden; //boolean error_de_conexion; byte buscar_mensaje(char lectura,String *mensaje); void reiniciar_busqueda_mensaje(); char ESP8266_buffer[MAX_BUFFER]; boolean buffer_activo; byte puntero_buffer; byte longitud_ipd; void enviar_comando ( String comando, String respuesta_ok, String respuesta_ko ); protected: public: ESP8266(); ESP8266(boolean depuracion); ~ESP8266(); void conectar_wifi ( String ssid, String clave, String ip, byte timeout ); void constructor(boolean depuracion); void http ( byte tipo_consulta_http, String direccion_servidor, unsigned int puerto, String nombre_servidor, String agente, String pagina, String texto_consulta, String respuesta_ko, String respuesta_ok ); void reiniciar_buffer(); char *leer_buffer(); byte longitud_buffer(); void enviar(); void recibir(); boolean conectado(); boolean desconectado(); boolean consulta_ok(); boolean operacion_terminada(); }; |
El ejemplo de más abajo usa la librería de consultas HTTP con el módulo WiFi ESP8266 para enviar datos al servidor (un porcentaje obtenido de la lectura de una entrada analógica) cada cierto intervalo de tiempo. Como no espera recibir ninguna respuesta no hace uso del buffer y le basta que la operación se complete correctamente. Este sistema es el que utilizo en mi proyecto de dispositivo gestor del sueño para ir almacenando los resultados de las lecturas de los sensores en el servidor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
#include "ESP8266.h" #define MODO_DEPURACION true #define PIN_LED_CONEXION 13 #define WIFI_VELOCIDAD 115200 #define WIFI_SSID "SleepManager" #define WIFI_CLAVE "****" #define CONSOLA_VELOCIDAD 115200 #define SERVIDOR_DIRECCION "192.168.1.22" #define SERVIDOR_PUERTO 80 #define SERVIDOR_PROTOCOLO "HTTP/1.1" #define SERVIDOR_NOMBRE "" #define SERVIDOR_AGENTE "sleepmanager-clinic-wifi" #define PAGINA_PRUEBA "pruebas/lectura_porcentaje.php" #define PARAMETRO_PRUEBA "porcentaje" #define CONSULTA_KO "" #define CONSULTA_OK "porcentaje recibido correctamente" #define TIMEOUT_CONEXION 30000 #define INTERVALO_LECTURAS_SENSOR 60000 float valor_sensor_analogico; String texto_consulta; unsigned long cronometro_lectura=0; ESP8266 conexion_wifi_servidor(MODO_DEPURACION); void setup() { Serial.begin(CONSOLA_VELOCIDAD); // Cambiar para que el puerto serie corresponda con el de la consola Serial1.begin(WIFI_VELOCIDAD); // Cambiar para que el puerto serie corresponda con el del módulo WiFi delay(5000); //Unos segundos para que el humano active la consola conexion_wifi_servidor.conectar_wifi ( WIFI_SSID, WIFI_CLAVE, SERVIDOR_DIRECCION, TIMEOUT_CONEXION ); } void loop() { if(conexion_wifi_servidor.operacion_terminada()) { if(conexion_wifi_servidor.conectado()) { digitalWrite(PIN_LED_CONEXION,HIGH); if(cronometro_lectura<millis()) { valor_sensor_analogico=analogRead(A0)*100.0/1023.0; texto_consulta=String(PARAMETRO_PRUEBA)+"="+String(valor_sensor_analogico,DEC); cronometro_lectura=millis()+INTERVALO_LECTURAS_SENSOR; conexion_wifi_servidor.http ( HTTP_POST, SERVIDOR_DIRECCION, SERVIDOR_PUERTO, SERVIDOR_NOMBRE, SERVIDOR_AGENTE, PAGINA_PRUEBA, texto_consulta, CONSULTA_KO, CONSULTA_OK ); } } else { digitalWrite(PIN_LED_CONEXION,LOW); conexion_wifi_servidor.conectar_wifi ( WIFI_SSID, WIFI_CLAVE, SERVIDOR_DIRECCION, TIMEOUT_CONEXION ); } } else { conexion_wifi_servidor.enviar(); } conexion_wifi_servidor.recibir(); } |
El siguiente ejemplo usa una consulta HTTP GET para consultar la hora del servidor y sincronizarla con la del dispositivo microcontrolado añadiéndole el tiempo estimado de respuesta; en realidad, añade entre 4 y 6 segundos más para asegurar que la hora del dispositivo es mayor que la del servidor y poder comprobar fácilmente si la hora del reloj en tiempo real que forma parte del dispositivo es correcta o se ha perdido por descarga de la batería.
Después de muchas pruebas he verificado que este sistema de sincronización horaria con el módulo WiFi ESP8266 es lo bastante precisa para mis necesidades; en el peor caso con un error de menos de 10 segundos que es algo irrelevante en mi caso.
Como puede verse en el código, es necesario consultar primero la longitud del buffer ya que la lectura lo reinicia para que esté disponible para almacenar nuevos datos.
Una vez leído el contenido del buffer, en este ejemplo se procesa para obtener la hora. En primer lugar se selecciona el texto que queda entre las llaves (el servidor responde usando la orden PHP ) lo transforma en un "objeto tiempo" y de él obtiene en formato humano la fecha y la hora.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
#include <Time.h> #include "ESP8266.h" #define MODO_DEPURACION true #define PIN_LED_CONEXION 13 #define WIFI_VELOCIDAD 115200 #define WIFI_SSID "SleepManager" #define WIFI_CLAVE "****" #define CONSOLA_VELOCIDAD 115200 #define SERVIDOR_DIRECCION "192.168.1.22" #define SERVIDOR_PUERTO 80 #define SERVIDOR_PROTOCOLO "HTTP/1.1" #define SERVIDOR_NOMBRE "" #define SERVIDOR_AGENTE "sleepmanager-clinic-wifi" #define PAGINA_PRUEBA "pruebas/hora_servidor.php" #define CONSULTA_KO "" #define CONSULTA_OK "CLOSED" // Cuando se desconecte el servidor pasado el timeout #define TIMEOUT_CONEXION 3000 #define INTERVALO_LECTURAS_HORA 60000 String texto_consulta; unsigned long cronometro_lectura=0; ESP8266 conexion_wifi_servidor(MODO_DEPURACION); byte longitud_buffer; byte inicio_fecha; byte fin_fecha; char *buffer; time_t fecha_hora; void setup() { Serial.begin(CONSOLA_VELOCIDAD); // Cambiar para que el puerto serie corresponda con el de la consola Serial1.begin(WIFI_VELOCIDAD); // Cambiar para que el puerto serie corresponda con el del módulo WiFi delay(5000); //Unos segundos para que el humano active la consola conexion_wifi_servidor.conectar_wifi ( WIFI_SSID, WIFI_CLAVE, SERVIDOR_DIRECCION, TIMEOUT_CONEXION ); texto_consulta=""; //no se envía información, solo se lee la pagina } void loop() { if(conexion_wifi_servidor.operacion_terminada()) { if(conexion_wifi_servidor.conectado()) { digitalWrite(PIN_LED_CONEXION,HIGH); if(cronometro_lectura<millis()) { cronometro_lectura=millis()+INTERVALO_LECTURAS_HORA; conexion_wifi_servidor.http ( HTTP_GET, SERVIDOR_DIRECCION, SERVIDOR_PUERTO, SERVIDOR_NOMBRE, SERVIDOR_AGENTE, PAGINA_PRUEBA, texto_consulta, CONSULTA_KO, CONSULTA_OK ); } else { longitud_buffer=conexion_wifi_servidor.longitud_buffer(); if(longitud_buffer) { buffer=conexion_wifi_servidor.leer_buffer(); inicio_fecha=String(buffer).indexOf('{'); if(inicio_fecha<255) { fin_fecha=String(buffer).indexOf('}'); if(fin_fecha>0) { fecha_hora=String(buffer).substring(inicio_fecha+1,fin_fecha).toInt()+10; Serial.println ( "Fecha: "+ String(day(fecha_hora),DEC)+"/"+ String(month(fecha_hora),DEC)+"/"+ String(year(fecha_hora),DEC)+" "+ "Hora: "+ String(hour(fecha_hora),DEC)+":"+ String(minute(fecha_hora),DEC)+":"+ String(second(fecha_hora),DEC) ); } } } } } else { digitalWrite(PIN_LED_CONEXION,LOW); conexion_wifi_servidor.conectar_wifi ( WIFI_SSID, WIFI_CLAVE, SERVIDOR_DIRECCION, TIMEOUT_CONEXION ); } } else { conexion_wifi_servidor.enviar(); } conexion_wifi_servidor.recibir(); } |
El siguiente programa de ejemplo, inspirado en la consulta de un usuario, sirve para buscar la dirección IP pública usando el servicio CheckIP de AWS (Amazon Web Services) cada cinco minutos.
Como en los ejemplos anteriores, se hacen una serie de presunciones que habrá que cambiar conforme a la configuración de la red que se use (192.168.1.X, en el ejemplo) el SSID y la clave del WiFi… La forma de encontrar la dirección IP no es muy elegante, supone que es la última línea de la respuesta a la petición HTTP GET aunque puede que exista una API para hacerlo de manera más ortodoxa.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
#include "ESP8266.h" #define MODO_DEPURACION true #define PIN_LED_CONEXION 13 #define WIFI_VELOCIDAD 115200 #define WIFI_SSID "SleepManager" #define WIFI_CLAVE "****" #define CONSOLA_VELOCIDAD 115200 #define RED_DIRECCION "192.168.1.X" #define SERVIDOR_DIRECCION "23.23.144.23" // ¡¡Mucho cuidado, puede cambiar la dirección IP!! (buscarla antes de usar el programa, por ejemplo, con ping checkip.amazonaws.com) #define SERVIDOR_PUERTO 80 #define SERVIDOR_PROTOCOLO "HTTP/1.1" #define SERVIDOR_NOMBRE "checkip.amazonaws.com" #define SERVIDOR_AGENTE "buscadordeipes" #define PAGINA_IP "" #define CONSULTA_KO "Error" #define CONSULTA_OK "\n\r\nOK" #define TIMEOUT_CONEXION 3000 #define INTERVALO_LECTURAS_IP 300000 //Leer la IP publica cada 5 minutos String texto_consulta; unsigned long cronometro_lectura=0; ESP8266 conexion_wifi_servidor(MODO_DEPURACION); byte longitud_buffer; byte inicio_ip; byte fin_ip; char *buffer; void setup() { Serial.begin(CONSOLA_VELOCIDAD); // Cambiar para que el puerto serie corresponda con el de la consola Serial1.begin(WIFI_VELOCIDAD); // Cambiar para que el puerto serie corresponda con el del módulo WiFi pinMode(PIN_LED_CONEXION,OUTPUT); digitalWrite(PIN_LED_CONEXION,LOW); delay(5000); //Unos segundos para que el humano active la consola conexion_wifi_servidor.conectar_wifi ( WIFI_SSID, WIFI_CLAVE, RED_DIRECCION, TIMEOUT_CONEXION ); texto_consulta=""; //no se envia informacion, solo se lee la pagina } void loop() { if(conexion_wifi_servidor.operacion_terminada()) { if(conexion_wifi_servidor.conectado()) { digitalWrite(PIN_LED_CONEXION,HIGH); if(cronometro_lectura<millis()) { cronometro_lectura=millis()+INTERVALO_LECTURAS_IP; conexion_wifi_servidor.http ( HTTP_GET, SERVIDOR_DIRECCION, SERVIDOR_PUERTO, SERVIDOR_NOMBRE, SERVIDOR_AGENTE, PAGINA_IP, texto_consulta, CONSULTA_KO, CONSULTA_OK ); } else { longitud_buffer=conexion_wifi_servidor.longitud_buffer(); if(longitud_buffer) { buffer=conexion_wifi_servidor.leer_buffer(); inicio_ip=String(buffer).indexOf("\r\n\r\n")+4; fin_ip=String(buffer).indexOf("\r\n",inicio_ip)-1; Serial.println("IP ["+String(buffer).substring(inicio_ip,fin_ip)+"]"); } } } else { digitalWrite(PIN_LED_CONEXION,LOW); conexion_wifi_servidor.conectar_wifi ( WIFI_SSID, WIFI_CLAVE, SERVIDOR_DIRECCION, TIMEOUT_CONEXION ); } } else { conexion_wifi_servidor.enviar(); } conexion_wifi_servidor.recibir(); } |
Aquí puedes descargar la librería ESP8266 para consultas HTTP con Arduino Uno (sin consola) y desde aquí puedes descargar la librería ESP8266 de consultas HTTP para Arduino que usa consola, es decir que necesita implementar un puerto serie por software o usar como hardware, por ejemplo, una placa Arduino Mega o Arduino Leonardo.
jorge
Donde puedo descargar la librería para hacer envios http Post
Víctor Ventura
Hola, Jorge.
Aquí puedes descargar la librería ESP8266 para consultas HTTP con Arduino
¡Hasta pronto!
ALEXANDER
HOLA DISCULPEN ME PODRIAN AYUDAR EMPECE A TRABAJAR CON ESP8266 TENGO UN MODULO ESP8266 01 Y UN ESP8266 05 PERO LA VERDAD NO TENGO NI IDEA COMO FUNCIONAN ME PODRIA AYUDAR ALGIEN
rgbyflar
Super trabajo exelente..
Víctor Ventura
No es para tanto, pero muchas, muchas gracias 🙄
ANDERSON CIFUENTES DUARTE
hola buenas he descargado la librería y diseccionado la informacion necesaria para que se ajuste a mi servidor local para realizar dicha prueba pero hasta el momento no tengo resultados. me gustaría saber cual es procedimiento adecuado o que paso debo seguir pues hasta el momento no me ha funcionado.
Víctor Ventura
Hola, Anderson.
Para hacer funcionar la librería debes utilizar los valores de conexión de tu WiFi en lugar de los de los ejemplos (el SSID, la clave, indicar la dirección de tu red…)
Puedes empezar probando el ejemplo más sencillo, que es el que busca la IP pública de tu conexión a Internet en los servicios web de Amazon. Debes cambiar las constantes WIFI_SSID, WIFI_CLAVE y RED_DIRECCION
En tu servidor web local deben existir los script PHP que gestionen las consultas (por ejemplo graben en una base de datos los valores que le pasas) y las aplicaciones Arduino que usen la librería deben enviar la información conforme hayas previsto en dichos script (en formato JSON, por ejemplo)
Espero haberte ayudado con esto.
Un saludo.
Miguel
Hola buen dia, soy nuevo en esto, mi duda es de como sería la conexion del modulo esp8266 con la placa arduino uno. Saludos
Víctor Ventura
Hola, Miguel.
Supongo que te refieres a un módulo que contiene el ESP8266 y en ese caso depende de qué módulo se trate. El más común (y barato) es el que se muestra en las fotos de la portada de las entradas Conexión WiFi con un módulo ESP8266 y Sincronización horaria con un módulo ESP8266 del blog, en tal caso las patillas que hay que conectar son las llamadas UTXD del módulo a la RX de Arduino, URXD del módulo a TX de Arduino, VCC y CHPD del módulo a 3.3V de Arduino y GND del módulo a GND de Arduino.
Mirando el módulo desde la cara de las patillas con la antena hacia arriba, VCC queda abajo a la izquierda, GND arriba a la derecha, UTXD bajo GND, URXD sobre VCC y CHPD justo a la izquierda de UTXD (el siguiente es RST antes de VCC)
Hay una salvedad, aunque si lo conectas sin más seguramente no lo rompas, el ESP8266 funciona a 3,3 V y no soporta 5 V por lo que no es una buena idea que URXD conecte directamente a TX, deberías regular la tensión. Para eso te puede servir un sencillo divisor de tensión (un par de resistencias) o puedes usar un diodo y una resistencia, un regulador «casero» para pruebas como el que aparece en el artículo cómo poner pines a un componente de montaje superficial o, lo que te recomiendo, un módulo que cambie de nivel la tensión entre URXD y TX. Si usas un módulo con varios canales para convertir la tensión también te recomiendo que no sólo conectes URXD (que es lo menos que debes hacer) sino también UTXD.
No tengas problema en preguntar más si no ha quedado claro.
Saludos.
Edgar
Muy buena labor. Estoy trabajando con un sensor IMU conectado a un Arduino Pro Mini (programando y recibiendo datos por medio de un UNO) y quiero enviar esos datos del sensor a un servidor utilizando también el ESP8266. Leí tu trabajo y quisiera que me explicaras un poco mejor lo de las alternativas de la librería para uso Con y Sin consola que no me queda bien claro. Agradezco la ayuda.
Víctor Ventura
Hola, Edgar.
La diferencia es que la librería sin consola funciona sin más en las placas Arduino que sólo tienen un puerto serie (como Arduino Uno) mientras que la otra librería necesita una placa Arduino con más de un puerto serie, como ocurre con Arduino Leonardo o Arduino Mega.
En los ejemplos de la librería el otro puerto serie (el que no comunica con el módulo ESP8266) sólo se usa para mostrar mensajes de depuración pero en producción también puede ser necesario, por ejemplo, para comunicar con un tercer dispositivo, que puede ser (a lo mejor es tu caso) precisamente otro Arduino.
Puedes sustituir el puerto serie hardware de Arduino por uno software (gestionar por software las comunicaciones) pero aparte de que pudiera ser que el rendimiento se viera afectado, depende del proyecto, lo que es seguro es que tendrás que medir con cuidado el uso de memoria; el inconveniente de los comandos AT es que necesitan bastante memoria.
Muchas gracias por participar en el blog.
aNDRES
Hola
Como hago una conexión directa del ESP8266 y servidor web como hostinger, para que capture los datos y los envié a una base de datos.
Gracias
Víctor Ventura
Hola, Andrés.
Echa un vistazo al tutorial para almacenar datos de dispositivos IoT con un servidor web que creo que te puede orientar y ayudarte a empezar.
Gracias por visitar polaridad.es
Wilson
Estimado tienes de casualidad algun ejemplo para utilizar esta libreria?
Víctor Ventura
Hola, Wilson
En el texto de esta misma entrada puedes econtrar un ejemplo para enviar datos a un servidor realizando una consulta HTTP GET con el módulo WiFi ESP8266 y Arduino
También hay otro ejemplo para averiguar la fecha y la hora de un servidor desde Arduino con un módulo WiFi ESP8266 Por cierto, si quieres más información sobre este tema, puedes consultar la entrada del blog sobre cómo sincronizar fecha y hora con el módulo WiFi ESP8266 desde Arduino
Y por último, también en esta misma entrada, puedes ver el ejemplo para consultar la dirección IP pública con el módulo WiFi ESP8266 y una placa Arduino que añadí a los otros porque parece que era un uso habitual de los lectores de polaridad.es
Espero que esto te ayude.
Gracias por visitar polaridad.es ¡Hasta pronto!
Guille
Hola gracias por compartir.
Estoy trabajando en un proyecto en el que necesito que un sensor añadido a una placa ardruino mande una señal a una app a través de la web. Es posible resolverlo con este modulo? cuando el ardruino tenga información del sensor la envía a una base de datos y a través de ahí con consultas php la app determina si enviar una notificación al usuario o no. Este sería una solución viable? gracias.
Víctor Ventura
Hola, Guille.
Sí, por lo que dices, podrías resolver el proyecto con un módulo ESP8266 y una pequeña infraestructura de servidor web.
En este artículo tienes bastantes pistas sobre cómo hacer la parte del ESP8266 y en la serie de artículos sobre cómo almacenar los datos obtenidos por los dispositivos de la Internet de las cosas (IoT) puedes encontrar información sobre la parte de la infraestructura de base de datos y web.
Suerte con tu proyecto.
Hector Ricardo
Muy buen trabajo soy principiante en esto de arduino y he intentado hacer funcionar el esp8266 con el modulo board y es un verdadero dolor de cabeza al menos para mi de hecho nunca logre hacerlo funcionar tu libreria se ve increiblemente facil de usar la pregunta es, como la implementaria en un mega haciendola funcionar como un server rest api por ejemplo implementandola con la libreria arest es muy flexible en cuanto a comunicacion desde una app o un website a traves de este metodo. muchas gracias por tan buen articulo y porfavor digame que piensa al respeco de mi pequeño proyecto tenga un excelente dia
Víctor Ventura
Hola, Hector.
La librería de este artículo está pensada para hacer consultas, es decir, para funcionar como cliente. Por lo que dices de tu proyecto, lo que tratas de hacer es usar una placa Arduino Mega como servidor. Desde luego, un proyecto así es viable pero debes considerar que un sistema así (Arduino Mega + ESP8266) podrá atender pocas peticiones cada vez. Si necesitas atender un número considerable de consultas debes plantearte usar un servidor web mayor, algo como Apache, al menos; incluso, si necesitas mucha disponibilidad, implementarlo usando Node.js En ambos casos necesitarás también más recursos hardware, como mínimo una placa tipo Raspberry Pi.
En la serie de artículos sobre el almacenamiento de los datos obtenidos por los dispositivos de la Internet de las cosas (IoT) tienes algunas pistas sobre cómo funcionaría un servidor así (Apache, PHP y MySQL) que puede servirte como punto de partida para implementarlo.
Espero haber sido de ayuda ¡Suerte con tu proyecto!
Hexa
En realidad no necesitas ni un Arduino, con un módulo ESP8266 y su SDK puedes programar un servidor web
Víctor Ventura
Hola, Hexa.
En efecto, se puede programar directamente el ESP8266, con su SDK o con el IDE de Arduino, pero este artículo trata de cómo usarlo con órdenes AT desde Arduino y el problema de Hector en cualquier caso seguiría siendo el mismo: un sistema muy pequeño como para atender muchas peticiones a la vez.
Gracias por participar en polaridad.es 🙂
angel
Para solamente cargar una pagina web, como si fuera un navegador, cuando cumpla una condicion como seria?
Víctor Ventura
Hola, Ángel.
El último ejemplo te puede servir más o menos de referencia. Tendrías que cambiar la condición en la línea 60, la línea 62 ya no sería necesaria (lo que hace es reiniciar el cronómetro) y la carga útil después de leer la página está entre las líneas 82 y 84, que es donde tendrías que poner tu código, lo que sea que quieres hacer con la página cargada.
Espero que eso te ayude. Gracias por visitar polaridad.es 🙂
Alejandro
Actualmente estamos desarrollando un proyecto escolar que consiste en un invernadero donde se realiza un DataLog de ciertos valores que se toman mediante sensores (temperatura, humedad y luminosidad) y se va a implementar un modulo ESP8266, para la comunicación con un ordenador.
La problemática que nos ha surgido es que la conexión a Internet en el lugar, es muy mala, y en algunas ocasiones el sistema podría estar desconectado durante dos horas aproximadamente(es por eso que decidimos realizar el Data Log).
Se planea que desde el arranque del sistema, se comience a registrar el estado del sistema, y en cuanto reciba conexión a Internet, envie los datos recabados durante el tiempo fuera de linea, al terminar, cierre el enlace, siga con las mediciones y nuevamente al conectarse envíe un nuevo archivo, y así sucesivamente. De los tiempos de transmisión y lectura de los valores ya se encargaran los microcontroladores, pero lo que no logro encontrar, es el como enviar los archivos del Log directamente al ordenador.
De antemano agradezco por tu atención y te envío un cordial saludo
Víctor Ventura
Hola, Alejandro.
Enviar los archivos del log directamente al servidor, aunque posible, no me parece la opción más eficaz. Lo que yo haría sería ir leyendo del log los datos monitorizados en cada entrada (temperatura, humedad y luminosidad), mandar cada entrada al servidor y para saber las que ya se han enviado, almacenar el código de tiempo del último registro enviado al servidor, por ejemplo.
El resto de la lógica sería la que describes: ir monitorizando desde que se inicia el sistema e ir almacenando los datos promediados, con registro de tiempo, cada cierto intervalo. Con un periodo de tiempo mayor que el de almacenamiento de datos (podría ser un múltiplo, para simplificar las cosas) verificaría que hay conexión a Internet y si la hay enviaría al servidor los datos (registro a registro). Si termina correctamente, empezaría un nuevo documento (log) y repetiría el proceso.
Si te quedas sin conexión mientras mandas los datos puedes volver a intentar conectar cuando pase el periodo que hayas prefijado y si lo consigues, envías solamente los datos que tengan un registro de tiempo mayor que el del instante en el que se produjo el error. Como el proceso no terminó si se cortó la conexión a Internet, el documento es el mismo (se siguen almacenando los datos en el documento a medio leer) y solamente usaría un documento nuevo si el envío de datos termina correctamente.
No sé cómo de concreto está ya tu código (no dices, por ejemplo, cómo envías los datos al servidor) y por tanto el nivel de detalle que necesitas para terminarlo. En cualquier caso, en polaridad.es puedes encontrar información sobre cómo leer y grabar en una tarjeta SD con Arduino o sobre cómo conectar una tarjeta SD a Arduino usando el bus SPI, por si estás más atrás en el proceso. Hay un comentario en el que muestro un ejemplo sobre cómo hacer un log de datos de un sensor de ultravioleta (muy interesante, por cierto, para un invernadero). En este mismo artículo tienes información (del lado del cliente) sobre cómo enviar los datos al servidor y también hay una serie de artículos sobre cómo almacenar en Internet (en un servidor) los datos monitorizados que explican cómo preparar la infraestructura del servidor y el proceso de recepción y almacenamiento de la información. En esos artículos (y otros) también puedes hacer consultas de algo más concreto si lo necesitas o contarnos cómo va vuestro proyecto de invernadero.
Espero que esto te resulte útil. Gracias por participar en polaridad.es.
Abraham
Victor que tal, un saludo.
Que arduino utilizaste en los ejemplos?, es posible hacer peticiones a un servidor por medio de HTTPS & ssl ??? quiero mandar datos médicos desde un arduino a una pagina web, muchas gracias
Víctor Ventura
Hola, Abraham.
Suelo hacer las pruebas de lo que publico en el blog con placas pequeñas, como Arduino Uno o Arduino Leonardo.
Utilizar HTTPS con el módulo ESP8266 es posible, pero no desde Arduino mediante comandos AT, como se muestra en este artículo. Necesitarás un firmware para el módulo Wifi que soporte SSL; con ese firmware no necesitarás Arduino y podrás programar sobre el propio módulo, aunque la forma de hacerlo es completamente diferente (usando el SDK del ESP8266) a cómo lo haces con órdenes AT.
En la web del fabricante, Espressif, hay algún ejemplo sobre cómo usar SSL. Ya te adelanto que, principalmente por los certificados, SSL necesita mucha memoria y tendrás que trabajar siempre con esa circunstancia en mente.
Gracias por participar en polaridad.es
Hexa
Ni lo intentes. ESP8266+SSL=PROBLEMAS
Si no puedes utilizar un IC WiFi de gama alta, el ESP8266 es de gama baja, mejor monta un servidor local con una RaspberryPi o algo así y manda cada tanto los datos al servidor de verdad.
El ESP8266 va muy bien para cosas pequeñas pero como trates de hacer cosas más exigentes, como HTTPS, todo son inconvenientes, por lo menos en mi experiencia.
Joel Leal
Buen día. Muchas gracias por el apoyo y los conocimientos compartidos. Pudiera ayudarme por favor.
Tengo un arduino Mega que monitorea unos sensores, junto con el modulo ESP8266. Por ejemplo, tengo el sensor de temperatura y establecí un valor minimo y un valor maximo, como puedo enviar un correo de alerta cuando se sale del rango por medio del modulo ESP8266?
Víctor Ventura
Hola, Joel.
Para enviar un correo debes acceder a tu servidor de envío de correo (algo como smtp.tuservidor.com) y utilizar el protocolo SMTP para comunicarte. Con la excepción de la autentificación (que la mayoría de servidores exigen) el proceso es muy sencillo, basta con indicar el remitente después del texto
MAIL FROM:
, el destinatario después deRCPT TO:
y los datos del correo (incluyendo el asunto) después deDATA
. Para cerrar la conexión con el servidor se envían dos líneas en blanco. Normalmente, entre los datos del correo se incluyen, además del asunto (conSubject:
) otra vez el remitente (From:
) y el destinatario (To:
) delante del cuerpo del mensaje.El protocolo también permite formatear el mensaje en HTML así como incluir imágenes. Creo que sería largo de explicar todo aquí en respuesta a un comentario así que estudiaré si es interesante como para desarrollar un artículo sobre el tema… Tendrás que seguir pendiente de polaridad.es 🙂
¡Gracias por participar en el blog!
rssg
Estimado Victor, antes que todo gracias por:
Compartir, tu amabilidad para responder y por el Español que nos permite a todos los hispano parlantes tener una fuente mas clara, llegue a tu blog buscando informacion sobre arduino uno y el modulo esp8266 ya que estoy en un proyecto para el cual e implementado un sistema web en php y MYSQL, donde con arduino + sensor infrarrojo sharp efectuo la contabilidad de objetos dato que envio a mysql via LAN arduinol, hasta hay todo bien pero hay una zona en donde no tengo cableado pero si wifi y es donde quiero usar el esp8266 y si me lo permites tu ejemplo get para lo cual te solicito si tienes a bien indicar las conexiones usadas entre arduino uno y sp8266
Víctor Ventura
La conexión entre Arduino y un ESP8266 depende del tipo de módulo wifi ESP8266 que hayas elegido y también del tipo de Arduino, es difícil darte los número de patilla de cada uno de ellos sin saberlo.
Lo que sí es seguro es que tendrás que alimentar el módulo ESP8266 a 3V3 (puedes hacer pruebas a 5 V pero no utilices ese voltaje para producción o es posible dañarlo) así que ya tienes el destino de VCC y GND del ESP8266.
Para comunicar el módulo ESP8266 con Arduino debe conectarse RX de uno con TX del otro (RX de Arduino a TX del ESP8266 y TX de Arduino a RX del ESP8266) Como te decía antes, el ESP8266 funciona a 3V3, así que tendrás que utilizar un conversor de nivel si tu Arduino funciona a 5 V.
El pin RESET del ESP8266 debe estar a nivel alto (VCC a 3V3) para que no se reinicie a la mínima alteración electromagnética.
Para terminar, la patilla de activación del ESP8266 (Chip enable o CH_PD) debe estar también a nivel alto (VCC a 3V3) para que el módulo wifi funcione.
Como el módulo ESP8266 que más se utiliza es el ESP-01, a lo mejor este diagrama de las patillas (pinout) te puede resultar útil.
Espero que esto te ayude. Gracias por participar en polaridad.es
rssg
Hola Victor, muchas gracias por tu comunicacion, bueno te comento que estoy trabajando con la placa Arduino uno y el modulo SP8266-01, sobre las conexiones indicadas para los pines ax y tx las mia son paralelas, el pin reset no lo estoy ocupando y el dato sobre la alteración electromagnética no lo tenia considerado, como dispongo de rectificador para los 3.3 volts no sera problema energizarlo, ademas te comento que el modulo wifi lo tengo programado con comandos AT y su conexion es inmediata, me puedes explicar a que te refieres con:
#define SERVIDOR_AGENTE y se puede omitir #define SERVIDOR_DIRECCION pues el envio GET seria sobre #define SERVIDOR_NOMBRE que esta en un hosting.
Víctor Ventura
He usado
SERVIDOR_AGENTE
para el nombre (agente) con el que se identifica el cliente. En la mayoría de los servidores es opcional, seguramente puedas omitirlo.Si puedes resolver la dirección IP del servidor utilizando el nombre del dominio (usando un DNS, cosa que depende de la red a la que te conectes) puedes omitir
SERVIDOR_DIRECCION
e indicarle al módulo ESP8266 la IP a la que te conectas con el nombre del servidor.En cambio, el nombre del dominio
SERVIDOR_NOMBRE
seguramente no podrás omitirlo, dependerá del servidor. Cuando en una misma máquina se alojan varios dominios virtuales compartiéndola (esto es muy común en alojamientos pequeños) es necesario indicar el nombre del dominio al conectar, dado que en la misma dirección IP (indicada expresamente o resuelta con DNS por medio del nombre del servidor) escucharán peticiones de varios dominios diferentes y será necesario saber al que se refiere la petición.Espero que esto te ayude 🙂
Sergio Alberto Mozo Pacheco
Hola, soy nuevo en esto y quisiera saber que debo modificar para poder usar la libreria con la placa arduino UNO, de antemano gracias
Víctor Ventura
Hola, Sergio Alberto.
En principio, no hace falta que modifiques nada para usar la librería en una placa Arduino Uno, solamente tendrás que descargar la versión de la librería para consultas HTTP usando el módulo wifi ESP8266 que NO usa la consola. Podrás usar un sniffer, pero no la consola (y lo que eso implica), porque el puerto serie se usa para conectar con el módulo wifi ESP8266 (podrías usar comunicaciones serie software, pero ese es otro tema).
Sí que tendrás que atender a los aspectos configurables: ① la macro
MODULO_WIFI
debe asignarse aSerial
y ② dependiendo del código en el que se use (la carga de proceso) puede que debas utilizar velocidades menores para comunicar con el módulo wifi ESP8266 porque el MCU de Arduino Uno a lo peor no soporta 115200 baudios si el resto del programa lo mantiene muy ocupado.Gracias por participar en polaridad.es.
Francuqo
Consulta ! … ¿Cómo logro decodificar un mensaje escrito en el navegador, para que arduino pueda interpretarlo ??
Saludos Cordiales
Víctor Ventura
Hola, Francuqo.
Tendrás que dar más información, no sé a qué te refieres 🙁
Saludos.
Monica García
Hola Víctor Ventura, me parece excelente tu articulo
Me llamo mucho la atención lo que publicas, me parece muy bueno, te comento que yo soy estudiante de 2 semestre en la carrera de informática en México y te quiero preguntar si este proyecto lo podemos implementar en una Esp8266 D1, he analizado y creo que sí, además quisiera implementarle algunas cosillas como algunas órdenes para apagar y encender focos
Saludos y felicidades por tu excelente trabajo
Víctor Ventura
Hola, Mónica.
Gracias por tus halagos 🙂
La librería puede que funcione en una placa basada en el ESP8266 pero no te lo puedo asegurar porque no lo he probado 🙁
Acabo de publicar un artículo sobre el manejo básico (y genérico) del ESP8266 que te puede dar pistas sobre cómo explotarlo sin usar una librería y, por el enfoque genérico, aunque está pensado para usarlo desde una placa Arduino, puede ayudarte a trasponer a tu placa el código.
Ahora estoy preparando otro artículo sobre el ESP8266, cuando lo termine lo probaré en una placa basada en este MCU, que los usuarios lo demandan, y podré decirte qué cambios serían necesarios (¡no te pierdas polaridad.es!). Por desgracia no te puedo garantizar que eso coincida con los plazos de tu universidad.
Gracias por participar en polaridad.es
alejandro franco
hola victor muy bueno tu post pero tube unos problemitas quisiera saber si me podrias dar una mano ,uchas gracias 🙂
wifi_http__prueba_.ino:33:1: error: ‘time_t’ does not name a type
wifi_http__prueba_.ino: In function ‘void setup()’:
wifi_http__prueba_.ino:39:3: error: expected initializer before ‘Serial’
wifi_http__prueba_.ino: In function ‘void loop()’:
wifi_http__prueba_.ino:93:15: error: ‘fecha_hora’ was not declared in this scope
wifi_http__prueba_.ino:97:38: error: ‘day’ was not declared in this scope
wifi_http__prueba_.ino:98:40: error: ‘month’ was not declared in this scope
wifi_http__prueba_.ino:99:39: error: ‘year’ was not declared in this scope
wifi_http__prueba_.ino:101:39: error: ‘hour’ was not declared in this scope
wifi_http__prueba_.ino:102:41: error: ‘minute’ was not declared in this scope
wifi_http__prueba_.ino:103:41: error: ‘second’ was not declared in this scope
Víctor Ventura
Hola, Alejandro.
Así, sin ver el código que produce esos errores no te voy a poder ayudar mucho 🙁
Tiene pinta de que se te haya olvidado incluir la librería Time con
#include <Time.h>
, pero no puedo decirte mucho más.¿Estás usando el ejemplo de la sincronización horaria? ¿Para qué placa Arduino lo compilas (por si tienes el puerto
Serial1
)?Gracias por participar en polaridad.es
Fredy
Que tal Victor, muy buen aporte.
Estoy programando un ESP8266 NODEMCU, y quisiera saber si hay alguna libreria o comando para poder determinar la IP de un sitio web.
Lo quiero hacer es por ejemplo: decirle a ESP8266 que consulte http://www.google.com y me devuelva la IP.
No se si se pueda.
Saludos y gracias por tus conocimientos.
martin
hola victor, mi pregunta es si se puede mandar datos con un teclado matricial, que en cada case# mande cierto dato a una ip
Mary
Hola!
Disculpe me podría ayudar a mandar instrucciones por medio del modulo wifi, utilizando una aplicación móvil para encender Led. Y así mismo que el arduino por medio del modulo mande datos a la aplicación…
Gracias