Wifi con ESP8266
El módulo ESP8266 nos permite añadir conexión Wifi a nuestro Arduino por unos 3€. Ello nos posibilita el control inalámbrico en un entorno de bastantes metros y sin cables, bien a través de nuestra red local o (si configuramos el Router y tenemos IP fija) vía Internet desde cualquier parte con un ordenador o un móvil. ¡¡Guai!!.
El módulo mide 1,5x2,5 cm y solo necesita dos hilos para funcionar, ya que se comunica vía serie con el Arduino. No hay una autentica comunicación Wifi, solo es serie, pero es más que suficiente para recibir datos o enviar comandos a cualquiera de los pines del Arduino.
Al contrario que con el módulo HLK-RM04 que dispone de una página Web para configuración , el ESP8266 se configura por medio de comandos AT.
Funciona a 3,3V y a veces consume bastante. Con una fuente de alimentación y limitando la salida a 100mA, no es capaz de arrancar. Aunque después baja el consumo. Los que no tengan fuente con 3,3V, pueden usar las salidas de ese voltaje de una fuente de PC o incluso dos pilas de 1,5V en serie.
Así pues, con este módulo y un Arduino mini podemos por unos 6€ controlar los pines, tanto mandando datos como recibiendos.
Los módulos mas recientes, vienen con un firmware habilitado para comunicación a 9600. Tenia también mas antiguos con firmware a 115200. Se cambia el firm y listo. Toda esta información y los comandos AT están en http://www.electrodragon.com/w/Wi07c
A la derecha vemos una secuencia de comandos:
-AT: Nos contesta OK
-AT+CWMODE=3: Nos dice "no change" porque ya habia sido configurado en otra ocasión.
-AT+CWLAP: Lista los puntos de acceso en las proximidades.
-AT+CWJAP="Jopapa","pepitogrillo": Mandamos nuestro usuario y clave para conectar con nuestro router.
-AT+CIFSR: Nos dice que IP nos asigna el router por DHCP. Esta IP se conserva aunque el modulo se quede sin tensión. También puede forzarse en el router, asociando una IP a la MAC del módulo.
-AT+CIPMUX: Habilita múltiples conexiones.
-AT+CIPSERVER=1,4040: Habilita modo SERVER en el puerto 4040.
Ahora podemos escribir en nuestro navegador 192.168.1.xx:4040 y tendremos respuesta en Termite.
Si por ejemplo ponemos 192.168.1.xx:4040/EncenderLED, recibiremos esta última cadena en la salida serie, lo que nos permite conectándolo a la entrada serie de un microprocesador detectar la cadena y realizar la accion correspondiente.
Para comunicar con el ESP8266 he usado una placa USB/UART y el programa Termite. Es importante en su configuración, aparte de la velocidad y el puerto, poner que mande tras cada comando AT un CR/LF.
Aunque algunos USB/UART pueden proporcionar 3,3v, he preferido alimentar el ESP8266 con una fuente externa. Hasta ahora y tras múltiples pruebas, tanto con el USB/UART como con Arduinos a 5v he conectado los TX y RX sin ninguna protección y no ha pasado nada.
Programa para controlar un LED
//Joaquin Paredes. 2014. http://www.jopapa.me
//Pruebas hechas con un Arduino Mega
//192.168.1.XX:8266/LED
#define SSID "Jopapa" //El ssid de tu router
#define PASS "pepitogrillo" //Tu clave Wifi
void setup() {
// Open serial communications for WiFi module:
Serial1.begin(9600);
Serial.begin(9600); //can't be faster than 19200 for softserial
Serial1.println("AT+RST");
if(Serial1.find("ready")){
Serial.println("Modulo preparado");
delay(1000);
//connect to the wifi
boolean connected=false;
for(int i=0;i<5;i++){
if(connectWiFi()){
connected = true;
break;}
}
if (!connected){
while(1);}
delay(5000);
// single connection mode
Serial1.println("AT+CIPMUX=1"); //Aceptar multiples conexiones
delay(1000);
Serial.print("IP:");
Serial1.println("AT+CIFSR");
delay(100);
while ( Serial1.available() ) {
Serial.write(Serial1.read());
}
Serial.println("Comenzando Server TCP");
Serial1.println("AT+CIPSERVER=1,8266"); //Actuar como Server en puerto 8266
}
else{
Serial.println("Modulo no responde");}
Serial.println("Esperando conexion...");
pinMode(13, OUTPUT);
}
void loop() {
if (Serial1.available()>0){
if(Serial1.find("LED")) {
digitalWrite(13, HIGH);
Serial.println("LED encendido");}
if(Serial1.find("APA")) {
digitalWrite(13, LOW);
Serial.println("LED apagado");}
}
}
boolean connectWiFi(){
Serial1.println("AT+CWMODE=1");
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
Serial.println(cmd);
Serial1.println(cmd);
delay(2000);
if(Serial1.find("OK")){
Serial.println("Conectado a WiFi");
return true;}
else{
Serial.println("No puede conectar a WiFi");
return false;}
}
Programa para recibir datos de A0 y A1
//Joaquín Paredes. 2014. http://www.jopapa.me
//Conexión a ESP8266 con Arduino Mega
//Lectura de analógicas 0 y 1
#define SSID "Jopapa" //Tu SSDI
#define PASS "xxxxxxxxx" //Tu clave
void setup(){
Serial1.begin(9600);
Serial.begin(9600);
Serial1.println("AT");
if ( Serial1.find("OK") ) {
Serial.println("AT-->OK ");}
delay(500);
Serial1.println("AT+CWMODE=1");
delay(1000);
// conectar al router
boolean connected=false;
for(int i=0;i<5;i++){
if(connectWiFi()){
connected = true;
break;}
}
/*Serial.println("AT+CWJAP=\"Jopapa\",\"ximopardo\"");
Serial1.println("AT+CWJAP=\"Jopapa\",\"ximopardo\"");
delay(2000);
while (!Serial1.find("OK")){
Serial.println("Conectando a Wifi");
Serial1.println("AT+CWJAP=\"Jopapa\",\"ximopardo\"");
delay(2000);}
Serial.println("Modulo conectado a Wifi");
delay(1000);*/
Serial.println();
//multiple connection mode
Serial1.println("AT+CIPMUX=1"); delay(100);
while ( Serial1.available() ) {
Serial.write(Serial1.read());}
Serial.println();
Serial1.println("AT+CIPSERVER=1,80"); delay(100);
while ( Serial1.available() ) {
Serial.write(Serial1.read());}
Serial.println();
//La ip
Serial.print("IP:");
Serial1.println("AT+CIFSR");
delay(100);
while ( Serial1.available() ) {
Serial.write(Serial1.read());
}
Serial.println();
Serial.println( "Start Webserver" );
}
void loop() {
while (Serial1.available() >0 ){
char c = Serial1.read();
if (c == 71) {
Serial.println("Enviada Web Request");
webserver();
delay(500);}
}}
void http(String output){
Serial1.print("AT+CIPSEND=0,");
Serial1.println(output.length());
if (Serial1.find(">")){
Serial.println(output);
Serial1.println(output); delay(10);
while ( Serial1.available() > 0 ) {
if ( Serial1.find("SEND OK") ) {
Serial.println("SEND OK");
break; }
}}}
void webserver(void) {
char temp1[10];
dtostrf(analogRead(A0),1,2,temp1);
http("<H4>Value A0 = "+ String(temp1) +"</H4>\n");
dtostrf(analogRead(A1),1,2,temp1);
http("<H4>Value A1 = "+ String(temp1) +"</H4>\n");
Serial1.println("AT+CIPCLOSE=0");
delay(500);
while ( Serial1.available() > 0 ) {
if ( Serial1.find("") ) {
Serial.println("");
break;
} } }
boolean connectWiFi(){
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
Serial.println(cmd);
Serial1.println(cmd);
delay(2000);
if(Serial1.find("OK")){
Serial.println("Conectado a WiFi");
return true;}
else{
Serial.println("No puede conectar a WiFi");
return false;}
}
Otra maravilla es que el ESP8266 puede funcionar sin necesidad de ningún Arduino, pueden activarse las dos salidas GPIO por TCP desde el ordenador, Internet o con telefonia de datos.