El ESP8266 es un modulo que gracias a la comunidad, sus características y un gran precio ha logrado convertirse en uno de los adaptadores Wifi más populares, y es que el chip con el que cuenta alberga gran potencia en un pequeño tamaño. Este modulo Wifi ESP8266 se puede conectar a cualquier microcontrolador a través de UART y de comandos AT.
¿Qué es el ESP8266?
Es un módulo transmisor y receptor Wifi, que puede tener un uso como microcontrolador que puede ser controlado por comandos AT y programado con Arduino, LUA, Raspberry, MicroPython y C/C++. El módulo ESP8266 con el chip ESP-01 cumple con caracteristicas especificas como:
– 96KBytes de RAM de datos
-Soporta hasta 2.4GHz de red.
-Soporta el protocolo 802.11 b/g/n
-64KBytes de RAM de instrucciones
-Los ESP8266 son fabricados por Espressif
-Capacidad para Wi-Fi Direct (P2P), Soft-AP
-Tiene integrado el stack del protocolo TCP/IP
-Su núcleo de arquitectura es RISC 32bits que corre a 80Mhz
-Tiene un núcleo Diamond Standard Core (LX3) hecho por Tensilica
-Los módulos cuentan con una memoria flash SPI Winbond W25Q40BVNIG
-Los módulos que usan este chip son de varios fabricantes y vienen en diferentes formatos.
-Tiene GPIOs, I2C, ADC, SPI, PWM, y más: http://www.esp8266.com/wiki/doku.php?id=feature_set.
Módulos con ESP8266
El ESP8266 está incluido en una gran variedad de módulos de diferentes formas y formatos.
En este tutorial básico vamos a trabajar con el ESP-01, uno de los más conocidos, este módulo cuenta con los componentes necesarios para que solamente alimentes el módulo y lo empieces a utilizar.
Firmware para el ESP8266
El ESP-01 viene inicialmente con el “firmware AT”, con el cual puedes usarlo como un adaptador wifi-serial, usando un microcontrolador externo como un Arduino para controlarlo y comunicarse con la red inalámbrica.
Como cualquier microcontrolador se puede cambiar el firmware del ESP8266 y usar cualquiera de los disponibles, entre los más destacables están, uLUA, microPython, y hasta programas hechos en Arduino.
ESP-01
Partes de la placa
Las partes principales de la placa microcontroladora del ESP-01 son:
– La memoria Flash donde se guardaran los programas que se suban (el chip ESP8266 no tiene memoria al ser un chip)
– Antena Wifi para la conexión con la red
– Leds que van a ser indicadores de si la placa se encuentra encendida o apagada, de la misma manera si recibe y transmite datos en Tx y en Rx
– Pines para conectar la transmisión de programas
– El ESP8266 es el microcontrolador del modulo ESP-01
Pines ESP-01
La conexión es bien sencilla solamente se necesita alimentar el módulo, conectar el pin Rx y Tx serial, y conectar el pin CH_PD a 3.3 para activar el chip.
Uso del módulo
Pines:
1. Conexión a Tierra
2. Entrada de salida, pin digital 2
3. Entrada de salida, pin digital 0
4. Pin que recibirá datos del puerto serial, podría ser un pin digital 3
5. Pin que transmitirá datos del puerto serial, pin digital 1
6. Pin para encender y apagar el chip ESP-01
7. Pin para resetear el chip ESP-01, si se llega a poner en 0V se puede resetear
8. Alimentación para el chip ESP-01 con 3.6V MÁXIMO y corriente mayor que 200mA
Consideraciones:
-El ESP8266 se alimenta con 3.3V, ¡no usar 5V!
-El ESP8266 NO tiene entradas tolerantes a 5V, así que necesitas convertir el nivel de las entradas si quieres comunicarte con dispositivos de 5V
-Durante los periodos de comunicación inalámbrica el ESP8266 puede necesitar hasta 250mA, por lo que sin una buena fuente de alimentación el ESP8266 se puede resetear. Si este es el caso utilizar un capacitor en las entradas de alimentación o una fuente de mayor potencia.
– Si se utilizan capacitores para filtrar los picos de corriente se recomienda que se coloquen de manera paralela con la fuente de alimentación y de un valor de 100uF
Usando el Firmware AT
El firmware AT que viene por defecto en el ESP-01 es el ai-thinker V0.9.2.4.
Utilización de los comandos:
Tipo | Ejemplo | Descripción |
---|---|---|
Prueba | AT+CMD=? | Retorna los posibles valores que puede tomar |
Consulta | AT+CMD? | Retorna el valor actual del parámetro |
Establecer | AT+CMD=Parámetro | Establece el valor del parámetro de usuario |
Ejecutar | AT+CMD | Ejecuta comandos sin parámetros de usuario |
Por defecto se utiliza un baudrate de 9600.
Después de cada comando, el ESP8266 espera los caracteres especiales de nueva línea <CR><LF> para ejecutar el comando.
Lista de comandos:
Comando | Respuesta | Función |
---|---|---|
AT – Probar iniciación correcta | ||
AT | OK | Prueba si el módulo responde correctamente |
AT+RST – Reinicia el módulo | ||
AT+RST | OK | Resetea el módulo |
AT+CWMODE – Modo Wifi | ||
AT+CWMODE=? | +CWMODE:(1-3) OK | Lista los modos validos |
AT+CWMODE? | +CWMODE:modo OK | Pregunta en que modo AP esta actualmente el módulo |
AT+CWMODE=modo | OK | Establece el módulo en el modo dado 1 = Modo estación (cliente) 2 = Modo AP (huésped) 3 = Modo AP + Estación (modo dual) |
AT+CWLAP – Lista APs disponibles | ||
AT+CWLAP | AT+CWLAP:ecn,ssid,rssi,mac OK | Lista los Acess Points disponibles para conectarse. ecn: codificación, puede ser: 0 = Abierto 1 = WEP 2 = WPA PSK 3 = WPA2 PSK 4 = WPA WPA2 PSK ssid: String que contiene el SSID del AP rssi: Fuerza de la señal mac: String que contiene la dirección MAC |
AT+CWLAP=ssid,mac,ch | +CWLAP:ecn,ssid,rssi,mac OK | Busca Acess Points disponibles para conectarse con las condiciones especificadas |
AT+CWJAP – Unirse a un Access Point | ||
AT+CWJAP? | + CWJAP:ssid OK | Imprime el SSID al que el módulo esta conectado |
AT+CWJAP=ssid,pwd | OK | El módulo se conecta al la red con el nombre ssid indicado y la contraseña pwd suministrada |
AT+CWQAP – Desconectarse de una Access Point | ||
AT+CWQAP | OK | Se desconecta de la red que esta actualmente conectado |
AT+CWSAP – Configurar el softAP del módulo | ||
AT+CWSAP? | +CWSAP:ssid,pwd,ch,ecn OK | Pregunta la configuración actual del softAP |
AT+CWSAP=ssid,pwd,ch,ecn | OK | Configura el softAP con ssid: String con el nombre de la red pwd: Contraseña, no mayor a 64 caracteres ch: Canal inalámbrico ecn: Tipo de codificación 1 = Abierto 2 = WPA_PSK 3 = WPA2_PSK 4 = WPA_WPA2_PSK |
AT+CIPSTATUS – Información acerca de la coneción | ||
AT+CIPSTATUS | STATUS:status +CIPSTATUS:id,type,addr,port,tetype OK | status: 2 = Se obtuvo IP 3 = Conectado 4 = Desconectado id: ID de la conexión en caso de multiconexión (1-4) type: Tipo de conexión, “TCP” o “UDP” addr: Dirección IP de la conexión port: Numero del puerto tetype: 0 = El módulo corre como cliente 1 = El módulo corre como servidor |
AT+CIPMUX – Habilitar o deshabilitar multiples conexiones | ||
AT+CIPMUX=mode | OK | mode: 0 = Conexión unica 1 = Múltiples conexiones, hasta 4 |
AT+CIPMUX? | +CIPMUX:mode OK | Imprime el mode, el modo de conexión actual |
AT+CIPSTART – Establece una conexión TCP o registra un puerto UDP e inicia la conexión | ||
AT+CIPSTART=type,addr,port | OK | Empieza una conexión como cliente (en modo conexión única) type: puede ser “TCP” o “UDP” addr: String que contenga la dirección IP remota port: String que contenga el puerto remoto |
AT+CIPSTART=id,type,addr,port | OK | Empieza una conexión como cliente (En modo conexión múltiple) id: ID de la conexión (1-4) |
AT+CIPSTART=? | [+CIPSTART:(id)(“type”),(“ip address”),(port)] OK | Lista los posibles comandos |
AT + CIPCLOSE – Cierra la conexión TCP o UDP | ||
AT+CIPCLOSE=? | OK | |
AT+CIPCLOSE=id | OK | Cierra la conexión TCP o UDP con el ID “id” en modo conexión múltiple |
AT+CIPCLOSE | OK | Cierra la conexión TCP o UDP para modo de conexión única |
AT+CIPSEND – Enviar datos | ||
AT+CIPSEND=? | OK | |
AT+CIPSEND=length | SEND OK | Establece la longitud de datos a enviarse (máximo 2048). Para un envío normal (modo conexión única) |
AT+CIPSEND=id,length | SEND OK | Establece la longitud de datos a enviarse en la conexión número “id”. Para un envío normal (modo conexión múltiple) |
AT+CIPSEND | Envía datos sin adornos cada 20ms. El módulo retorna “>” después ejecutar el comando, si se recibe el comando “+++” se regresa al modo comando. | |
AT+CIFSR – Obtener la dirección IP local | ||
AT+CIFSR=? | OK | |
AT+CIFSR | +CIFSR:ip OK | Retorna la dirección IP local del módulo como cliente. |
AT+CIFSERVER – Configurar como servidor | ||
AT+CIPSERVER=mode[,port] | OK | Configura el módulo como servidor donde el modo: 0 = Borrar servidor 1 = Crear servido puerto: numero del puerto, por defecto es el 333 |
AT+CIOBAUD Cambiar la velocidad de transmisión serial | ||
AT+CIOBAUD=? | +CIOBAUD:(9600-921600) OK | Nos informa que las velocidades de transmisión permitidas están en este rango |
AT+CiOBAUD? | +CIOBAUD:baudrate OK | Nos indica que el módulo está actualmente configurado a ‘baudrate’ |
AT+CIOBAUD=baudrate | OK | Configura la velocidad de transmisión a ‘baudrate’ |
Para la lista completa de comandos visita: at_commands
Pruebas básicas con Arduino
Vamos a realizar unas pruebas en las que el módulo estará conectado a un puerto serial por software del Arduino, el puerto serial por hardware lo utilizaremos para comunicarnos con el Arduino via monitor serial.
Para esta prueba vamos a necesitar un módulo ESP-01, un protoboard, cables dupont, resistencias y un Arduino UNO r3.
Conectamos como se muestra en la imagen:
Ahora cargamos el siguiente código en el arduino.
#include <SoftwareSerial.h> SoftwareSerial ESP(3, 2); // RX | TX void setup() { Serial.begin(9600); ESP.begin(9600); } void loop() { // Repetir lo recibido por el ESP8266 hacia el monitor serial if (ESP.available()) { char c = ESP.read() ; Serial.print(c); } // Repetir lo recibido por el monitor serial hacia el ESP8266 if (Serial.available()) { char c = Serial.read(); ESP.print(c); } }
Ahora vamos a abrir el monitor serial en el IDE del Arduino y configuramos los finales de linea a NL & CR, y el baud rate a 9600 como se muestra en la imagen:
Ahora, para probar que todo funciona correctamente, vamos a resetear el módulo, para esto conectamos el pin RST a tierra y luego lo desconectamos, cuando lo desconectemos lo siguiente debería aparecer.
Los primeros caracteres son parte de un mensaje del bootloader que no vamos a ver por el momento, se muestran así porque están en otro baudrate. La siguiente linea que esta entre ‘[ ]’ es el fabricante y la versión de los códigos AT que está cargada. Cuando el módulo transmita “ready” significa que esta listo para recibir comandos.
Probemos con el comando AT, este modo retorna “OK” si todo está en orden.
Ahora vamos a configurar el módulo para se conecte a una red wifi de nuestra casa y empieze a recibir datos:
El módulo solamente será cliente de una red inalámbrica existente por lo establecemos el modo del módulo a estación (cliente), enviamos el comando:
AT+CWMODE=1
Este comando nos retorna “OK” si todo esta correcto, o “no change” si el módulo ya se encontraba en ese modo. El modo se queda grabado aunque se desenergize el módulo.
Ahora vamos a ver las redes inalambricas disponibles enviando:
AT+CWLAP
Ese comando nos retorna una lista con: el tipo de codificación, el nombre de la red, intensidad de señal, dirección MAC del AP, de la siguiente manera.
+CWLAP:(4,"Naylamp",-55,"0a:18:d6:99:59:47",6)
+CWLAP:(2,"VecinoWifi",-78,"10:fe:ed:7a:a9:42",6)
+CWLAP:(3,"Anonymous-Pro",-92,"c4:17:fe:8a:2d:24",11)
OK
Ahora vamos a conectarnos a una de esas redes, para ello enviamos el siguiente comando con el nombre de red seguido por la contraseña, cada dato tipo String siempre va entre comillas:
AT+CWJAP="Naylamp","hail_hydra"
Si después de unos momentos nos responde con “OK” todo salio bien, sino revisa que hayas puesto bien el nombre y contraseña de la red.
Ahora vamos a iniciar un servidor en el módulo. Primero activamos el modo de multiconexión
AT+CIPMUX=1
Luego que nos responda “OK” iniciamos el servidor y le asignamos el número de servicio 1, este servidor correrá en el puerto 80. Este puerto es el mismo que usan los navegadores al solicitar una página web, por lo que podremos probarlo en el siguiente paso.
AT+CIPSERVER=1,80
Ahora vamos a obtener la dirección IP que tiene asignada el módulo en nuestra red local. Para esto usamos lo siguiente.
AT+CIFSR
El módulo nos responderá con una dirección IP. En mi caso fue la 192.168.88.15 si introducimos esta dirección IP en la barra URL de un navegador web como Google Chrome sucede el navegador le solicita la página web al módulo, para esto envía una serie de datos que vamos a poder ver desde el monitor serial, será algo como esto:
Link
+IPD,0,380:GET / HTTP/1.1
Host: 192.168.88.15
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: es,en-US;q=0.8,en;q=0.6
OK
Link
En el navegador seguira esperando una respuesta (una página web) del módulo, pero como no esta programado para responder no cargará nada. En el monitor serial, el texto de arriba significa que se solicitó información (mediante el método http GET), la dirección a la que va dirigida, tipo de conexión, tipo de archivo que espera recibir, tipo de cliente (navegador) desde el cual se hizo la solicitud e idioma.
Ahora intentemos en el navegador con la siguiente dirección, reemplazando 192.168.88.15 con la dirección que hayas obtenido antes.
192.168.88.15/hola_mundo
En el monitor serial obtendremos:
Link
+IPD,0,380:GET /Hola_mundo HTTP/1.1
Host: 192.168.88.15
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.155 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: es,en-US;q=0.8,en;q=0.6
OK
Link
En el texto recibido de arriba fijate en la línea que contiene +IPD, en ahi se encuentra el texto que enviamos desde el navegador. Ahora podemos pasar información al módulo mediante el navegador web.
Controlando un led desde el navegador
Vamos a implementar un interpretador de comandos en el Arduino para controlar un LED desde el navegador.
Cargamos en el arduino el siguiente programa:
#include <SoftwareSerial.h> // arduino Rx (pin 2) ---- ESP8266 Tx // arduino Tx (pin 3) ---- ESP8266 Rx SoftwareSerial esp8266(3,2);
void setup() { Serial.begin(9600); // monitor serial del arduino esp8266.begin(9600); // baud rate del ESP8255 pinMode(13,OUTPUT); digitalWrite(13,LOW); sendData("AT+RST\r\n",2000); // resetear módulo sendData("AT+CWMODE=1\r\n",1000); // configurar como cliente sendData("AT+CWJAP=\"SSID\",\"PASSWORD\"\r\n",8000); //SSID y contraseña para unirse a red sendData("AT+CIFSR\r\n",1000); // obtener dirección IP sendData("AT+CIPMUX=1\r\n",1000); // configurar para multiples conexiones sendData("AT+CIPSERVER=1,80\r\n",1000); // servidor en el puerto 80 }
void loop() { if(esp8266.available()) // revisar si hay mensaje del ESP8266 { if(esp8266.find("+IPD,")) // revisar si el servidor recibio datos { delay(1500); // esperar que lleguen los datos hacia el buffer int conexionID = esp8266.read()-48; // obtener el ID de la conexión para poder responder esp8266.find("led="); // bucar el texto "led=" int state = (esp8266.read()-48); // Obtener el estado del pin a mostrar digitalWrite(13, state); // Cambiar estado del pin
while(esp8266.available()){ char c = esp8266.read(); Serial.print(c); } //responder y cerrar la conexión para que el navegador no se quede cargando // página web a enviar String webpage = ""; if (state==1) webpage += "<h1>LED_13 = encendido!</h1>"; else { webpage += "<h1>LED_13 = apagado!</h1>";} // comando para enviar página web String comandoWebpage = "AT+CIPSEND="; comandoWebpage+=conexionID; comandoWebpage+=","; comandoWebpage+=webpage.length(); comandoWebpage+="\r\n"; sendData(comandoWebpage,1000); sendData(webpage,1000); // comando para terminar conexión String comandoCerrar = "AT+CIPCLOSE="; comandoCerrar+=conexionID; comandoCerrar+="\r\n"; sendData(comandoCerrar,3000); } } }
/* Enviar comando al esp8266 y verificar la respuesta del módulo, todo esto dentro del tiempo timeout */ void sendData(String comando, const int timeout) { long int time = millis(); // medir el tiempo actual para verificar timeout esp8266.print(comando); // enviar el comando al ESP8266 while( (time+timeout) > millis()) //mientras no haya timeout { while(esp8266.available()) //mientras haya datos por leer { // Leer los datos disponibles char c = esp8266.read(); // leer el siguiente caracter Serial.print(c); } } return; }
Lo que hace el programa es automaticamente conectarse a una red inalambrica de nombre SSID y con contraseña PASSWORD. Luego incia un servidor en el puerto 80. Algo nuevo en este programa es que cuando recibe la solicitud del navegador el módulo le contesta con un pequeño mensaje que se visualiza como pagina web en el navegador, esto lo hace con la funcion AT+CIPSEND.
Podemos verificar la ip asignada al módulo desde el monitor serial del arduino, en mi caso es el 192.168.88.41. Con esta dirección puedo controlar al LED 13 del arduino desde el navegador usando la subdirecciónes
192.168.88.41/led=0 para apagar el LED.
192.168.88.41/led=1 para encender el LED.
Con este tutorial hemos aprendido a usar el Arduino en conjunto con el ESP-01 para hacer un pequeño y simple servidor.
Este fue solo un ejemplo y hay muchas cosas por mejorar como:
-Ejecutar comandos necesarios al inicio, aunque algunos no necesitan ejecutarse cada vez que se inicia el módulo.
Mejorar los tiempos de respuesta para que sea inmediato.
-Añadir funciones adicionales como mostrar los estados de los pines o del ADC en la página web.
-Una interfaz con botones para controlar el Arduino.
En este tutorial solo vimos conectividad wifi en una red local, pero con los mismos principios se puede conectar el módulo a internet y así tener realmente un sistema con internet de las cosas.