Configura la conexión Wifi de tu arduino

Atualización:

Para ver en funcionamiento el programa, consultar la entrada Tutorial Wiflyterm 1.1

Desde el día 4 de Marzo de 2010 se encuentra en la Web de Sparkfun un tutorial llamado WiFly Wireless Talking SpeakJet Server” que incluye una descripcción de la programación del módulo Wifly y programas de terminal (como el mío) y ejemplos.

Post original:

En esta entrada vamos a explicar cómo conectar un microcontrolador a una red wifi cualquiera utilizando una placa de sparkfun llamada Wishield Wifly GSX para arduino que incorpora un módulo de Rovin Networks. Para ello porporcionamos una aplicación que hemos creado (Nueva versión 1.1: wiflyterm1.1 ) que hace de puente entre el PC y dicho módulo, permitiendo acceder a su interfaz de comandos desde nuestro PC a través del puerto USB.

Por fin, WIFI para el arduino fácil (¿?) y a precio aceptable.

Sorprendentemente, por más que he buscado en la red ejemplos de programación de esta tarjeta, no he encontrado nada en absoluto. Solamente preguntas comentarios de la gente a cerca de las ventajas e inconvenientes que pueda tener. La mayoría de los ejemplos que se muestran en videos corresponden a otra placa (también llamada wishield) fabricada por Async_labs (asynclabs.com) que es algo más barata y proporciona unos drivers (¿?) pero contiene un módulo de ZeroG que no se parece mucho al de Rovin Networks, que ya se encarga de todo el tcp/ip stack y no necesita drivers. Esta tarjeta la he comprado en bricogeek (¡gracias por las gorras!) y funciona muy bien.

Wishield de sparkfun

Básicamente la tarjeta (esquema) contiene el módulo de comunicaciones inalámbricas, un puente de SPI a serie, un regulador de tensión de 3.3V y una pequeña zona de taladros para prototipos. Tan solo tenemos que soldarle las tiras de conectores para enchufársela al arduino. El módulo wifi RN-131G se comunica localmente mediante un puerto de comunicaciones serie, pero el arduino (exceptuando el mega) utiliza su único puerto serie (físico) para conectarse con el sistema de desarrollo. Los únicos puertos físicos de comunicaciones que nos quedan son I2C y SPI. El puerto SPI es un puerto serie síncrono más eficiente que el I2C y muy adecuado para esta aplicación, aunque cada fabricante pueda hacer una interpretación un poco diferente del mismo, por lo que esta placa incorpora un puente SPI de phillips (SC16IS750)

El módulo posee una pequeña antena y un conector para poderle poner una antena externa. Posee un modo de espera de ultra-bajo consumo y un reloj de tiempo real que le permiten “despertarse” periódicamente o por eventos externos.

Configuración de la conexión

Una vez accedamos al módulo, ya sea local o remotamente tenemos acceso a la trasmisión de datos (si se encuentra conectado) o al intérprete de comandos (si no se encuentra conectado). Unos leds muestran dicho estado. Podemos entrar en el modo de comandos mediante una combinación de caracteres específica ($$$) segun se describe en la guía de referencia (RN-131G Reference Guide)

Este sistema posee una configuración de fábrica que hace que busque una red inalámbrica sin encriptar con SSID “roving1″ para conectarse. Si no está conectado a dicha red la única forma de acceder a él es mediante su entrada SPI. A unas malas podemos cambiar el nombre de la red de nuestro router y quitarle la encriptación para configurarlo. Lamentablemente, el diseño de la placa no contempla ninguna entrada externa serie que permita acceder localmente mediante un puerto serie ttl desde un PC. Parece que lo mejor es disponer de alguna utilidad que permita su configuración desde el propio arduino, lamentablemente, ninguno de los vendedores proporciona software alguno (al menos hasta ahora).

Una vez configurada la conexión WI-FI, los parámetros se almacenan en la memoria no volátil de la tarjeta, de manera que ya no es necesario configurarla de nuevo y el arduino puede limitarse a enviar y recibir datos mediante su puerto SPI. Incluso tenemos la posibilidad de acceder al intérprete comandos remotamente (desde la red inalámbrica) para cualquier cambio.

Programación: control del SC16IS750

Lo primero es programar el arduino para configure su puerto SPI como tal y sea capaz de enviar y recibir información a través de él. Ésto no supone un problema porque se usa la librería estándar SPI, y las conexiones por defecto coinciden con las de la placa. Descargamos e instalamos la librería en nuestro sistema de desarrollo que no sproporciona una función que lo  mismo vale para transmitir que para recibir datos de 8 bits:

dato_recepcion = SPI.transfer(dato_transmision);

Ahora hace falta que usemos la librería adecuadamente para leer y escribir en los registros del SC16IS750. La hoja de datos parece clara e implementamos las funciones de leer y escribir registros de 8 bits:

byte SPI_Read(byte reg)
{
byte dato;
digitalWrite(SLAVESELECT,LOW);
Spi.transfer(0x80|(reg << 3));
dato=Spi.transfer(0);
digitalWrite(SLAVESELECT,HIGH);
return dato;
}
void SPI_Write(byte reg, byte data)
{
digitalWrite(SLAVESELECT,LOW);
Spi.transfer(reg <<; 3);
Spi.transfer(data);
digitalWrite(SLAVESELECT,HIGH);
}

Una vez hecho ésto necesitamos que el programa principal copie todos los caracteres que reciba del puerto serie (provenientes del PC) en el puerto SPI, y lo que se reciba por el puerto SPI se transmita por el puerto serie hasta la consola del PC:

void loop(void)
{
char c;
if (Serial.available() > 0) { // Si hay datos recibidos por el puerto serie
c=Serial.read();
SPI_Write(THR,c);
}
if (SPI_Read(LSR) & 0x01) { // Si hay datos recibidos por el SPI
c=SPI_Read(RHR);
Serial.write(c);
}
delay(1); // Para no agobiar a los periféricos
}

Y por último (o mejor dicho previamente) sólo queda configurar la velocidad de salida del puente SPI para que coincida con la velocidad de la uart del módulo Wifi. Ésto ha sido lo más complicado porque en la hoja de datos no se explica el procedimiento de uso de los registros. Solo se describen. Por casualidad encontré una nota de aplicación del SC16IS750 con un microcontrolador de otro tipo pero que ayudó un poco, a pesar de los importantes errores que contiene (confusión de los operadores booleanos con los de bits y nombres de registros incorrectos) proporcionó cierta información de utilidad. Confieso que incluso llegué a observar mediante un osciloscopio la velocidad de transmisión del puente en cada caso hasta dar con la combinación y orden de escrituras de registros que funcionó (odio hacer de adivino). Al fin:

void Set_Bauds(long bauds)
{
// Establece la velocidad de comunicación del puente SPI serie
unsigned int divisor = (FREC_OSC_SPI2SER / PREESCALER) / (bauds * 16);
SPI_Write(LCR,0x80); // Habilita el cceso a redistros del divisor
SPI_Write(DLL, divisor & 0xff);   // Escribe LSB del divisor
SPI_Write(DLH, divisor >> 8); // Escribe MSB del divisor
SPI_Write(LCR,0xBF);
SPI_Write(EFR,0x10);
SPI_Write(LCR,0x03);     // N,8,1
SPI_Write(FCR,0x06);
SPI_Write(FCR,0x01);
}

Funcionamiento

Se compila el programa completo. Se carga en el arduino y se abre un emulador de terminal en el ordenador (en mi caso el hyperterminal). Se crea una conexión en el puerto serie adecuado y con velocidad de 9600 baudios. Al iniciarse la sesión se mostrará el mensaje de inicio.
Importante: Hay que establecer el control de flujo a “ninguno”. Con otros valores no se comunicará con el arduino.
Si no estamos conectados estamos en modo de comandos y si no, tecleamos $$$.

Escribimos los siguientes comandos:

set wlan auth 4  (red WPA2)
set wlan channel 0 (búsqueda del canal)
set wlan phrase "clave" (la clave que tenga nuestra red en ascii)
set wlan ssid "nombre de la red" (nombre que tenga nuestra red inalámbrica)
set wlan join 1 (se conecta a la red automáticamente)

para que se conecte hacemos

join ; (nombre de la red a la que le pedimos que se conecte si no lo ha hecho automáticamente)

Y si queremos que estos parámetros se guarden para que cada vez que se enciende el equipo se conecte automáticamente a la red escribimos:

save

Para pasar al modo de comunicación salimos del intérprete con:

exit

Ahora es el momento de abrir una segunda ventana de hyperterminal, pero esta vez en un puerto TCP/IP en la dirección que nuestra red le ha asignado al wifly mediante DHCP (lo pone en la consola anterior al hacer el Join) y en el puerto 2000.

Escibiendo en esa consola, los carateres aparecen en la otra y viceversa. También podemos entrar en modo de comandos remotamente y hacer ciertas cosas.

Conclusiones

Esta aplicación que se proporciona con su código fuente puede servir como base para que cada uno programe su microcontrolador en aplicaciones que requieran comunicarse inalámbricamente con cualquier otro dispositivo de vuestra red local o de internet. Hay que tener en cuenta que para sacar el máximo rendimiento de las comunicaciones hay que modificar las velocidades de comunicación entre el puente SPI y el módulo wifi y aprovechar su sistema de interrupciones, pero eso será en una entrada futura de El Hombre Mecatrónico.

La puerta queda abierta. ¡Las posibilidades son enormes!

Abrazos a todos.

Actualización: Se ha corregido el código para evitar problemas que aparecen esporádicamente debidos a que en determinadas situaciones, la primera instrucción enviada al puente SPI no se efectuaba correctamente. (wiflyterm1.1).

Comparte y disfruta:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay

34 Comments to “Configura la conexión Wifi de tu arduino”

  1. By Oriol, 12 de diciembre de 2012 @ 12:26

    Hola,

    Tengo una placa dfrduino romeo V1.1 y me gustaria poner wifly, pero no se como lo puedo ensamblar en el tipo de placa que tengo… :S
    Alguien me puede echar un cable!!
    Dejo el correo por si alguien puede ayudarme oriolgs25@gmail.com

  2. By Diego, 27 de noviembre de 2012 @ 20:57

    Hola, yo utilizo un módelo similar pero utilizo el puerto serie que en mi opinión es mucho más sencillo de utilizar.
    Te lo dejo por si lo quieres incluir en tu contenido!
    http://www.youtube.com/watch?v=M5ABBw_0hDc

  3. By MANUEL, 10 de agosto de 2012 @ 02:46

    hola que tal me yo estoy intentando hacer un proyecto, pero tengo algunas dudas.
    una ves terminada la configuración y entramos hyperterminal en un puerto TCP/IP en la dirección se le ha asignado al wifly.que podemos realizar por medio de esa ventana. por ejemplo yo quisiera controlar un motor.

  4. By Sergh, 25 de julio de 2012 @ 16:43

    Buenas tardes Jesus, me gusto tu tutorial esta genial! Te felicito! Pero necesito ayuda, soy muy principiante en esto y quisiera mover un servo por medio del Wifly…Como podría hacerlo? Tienes algún tutorial de esto? Muchas gracias! :D

  5. By Ilde, 18 de mayo de 2012 @ 17:52

    Hola

    he realizado un pequeño tutorial que puede complementar al estupendo que acabas de realizar por si a alguien le puede ayudar.

    http://lanavajadelgeek.blogspot.com.es/2012/05/xbee-shield-wifly-rn-xv-arduino-uno.html

    Un saludo

    • By Jesús Gómez, 22 de mayo de 2012 @ 11:38

      Gracias por la aportación.
      En un blog interesantísimo. Me lo apunto en el reader.
      Un saludo.

  6. By gogy, 14 de abril de 2012 @ 22:43

    hola quisiera que me ayudes. Compre arduino wifi shield con todos los componentes adicionales en olimex, subi el scketch que sale en olimex pero no logro que salga la red wlanap.

    • By Jesús Gómez, 16 de abril de 2012 @ 09:39

      Sin problema.
      Necesito que compruebes que el modelo de wifi shield es el mismo.
      Un saludo.

  7. By Emmanuel Azcorra, 27 de febrero de 2012 @ 18:13

    Hola, quisiera saber si me puedes ayudar, quiero mandar datos a un pic con el WiFly GSX desde una red local y posiblemente desde internet con el movil, este dispositivo me puede servir para lo que quiero hacer? y si me podrias explicar de manera muy basica como se conecta
    te lo agradeceria muchisimo

    ATTE:
    Emmanuel Azcorra

    • By Jesús Gómez, 29 de febrero de 2012 @ 09:49

      Hola, Emmanuel,
      Básicamente lo que necesitas es configurar el módulo para que se conecte a la red WIFI que tengas. Si usas DHCP, la IP local puede cambiar, por lo que si quieres implementar un servidor, sería conveniente usar una IP local fija o bien configurar el router para que reserve esa IP para ese dispositivo.
      Desde la red local puedes acceder a él directamente, pero si lo haces desde el exterior debes configurar el router para redirigir el puerto que estés usando al módulo WIFI. Eso ya depende el router que tengas.
      En el módulo que he utilizado, el microcontrolador (auduino en mi caso) lee y envía los datos a través de un puerto SPI.
      Espero que te aclare algo.
      Un saludo.

  8. By Nico, 2 de febrero de 2012 @ 23:55

    Hola, me he bajado wifyterm 1.1 y tengo instaladas las librerias spi y al compilar me sale esto, sabeis de que puede ser?? Gracias

    wiflyterm.cpp:18:17: error: Spi.h: No such file or directory
    wiflyterm.cpp: In function ‘byte SPI_Read(byte)’:
    wiflyterm:42: error: ‘SS_PIN’ was not declared in this scope
    wiflyterm:43: error: ‘Spi’ was not declared in this scope
    wiflyterm.cpp: In function ‘void SPI_Write(byte, byte)’:
    wiflyterm:52: error: ‘SS_PIN’ was not declared in this scope
    wiflyterm:53: error: ‘Spi’ was not declared in this scope
    wiflyterm.cpp: In function ‘void SPI_Write_Block(byte*, int)’:
    wiflyterm:64: error: ‘SS_PIN’ was not declared in this scope
    wiflyterm:65: error: ‘Spi’ was not declared in this scope
    wiflyterm.cpp: In function ‘byte SPI_Read_Block(byte*, int)’:
    wiflyterm:78: error: ‘SS_PIN’ was not declared in this scope
    wiflyterm:79: error: ‘Spi’ was not declared in this scope

    • By Sergh, 16 de agosto de 2012 @ 01:08

      Nico, tengo el mismo problema…de casualidad lo pudiste solucionar?

  9. By zied, 17 de junio de 2010 @ 10:55

    Hi Jesus,

    i used your code for my WiFly and Arduino Duemilanove. I can´t access to the command mode. the result is only initializando and it stops there.

    i tried with enter or with $$$ but any success.

    I looked for this Problem every where but without success. Please give me the solution. I have to configure all the five WiFly Shields for my Bachelor-thesis.

    Thanks a lot.
    Leila

  10. By DustinD, 20 de abril de 2010 @ 04:34

    Hola Jesus,

    ¡Buen trabajo con el codigo! Estoy construyendo un refri para cerveza yo le llamo “kegerator”. Estoy usando “WiFly” para communicion. Con permiso me permite traducir los comentarios en este codigo a ingles y publicarlo en mi sitio red? Gracias!

    • By Jesús Gómez, 20 de abril de 2010 @ 10:36

      Ok, Dustin.
      No problem. But please, include a link to the original article too.
      Good luck.
      And by the way … nice blog!

  11. By Rui Oliveira, 3 de marzo de 2010 @ 20:49

    Hola Desde ya muchas gracias por esta explicación detallada acerca de la Wifly. Soy un principiante en Arduino. He compilado el código y descargar en el Atmega328, cuando me conecto a Tera Term, arrancado, sino un mensaje de error “perro guardián”, también vio el video que el escudo Wifly es alimentado sólo por USB, me pregunto si puedo decir que no y si es posible me ayuda en relación con el error “Watchdog”. Gracias

  12. By George, 1 de febrero de 2010 @ 23:17

    seems to work. thanks!

  13. By tim, 1 de febrero de 2010 @ 04:35

    perfect! thank you so much. I’m learning the arduino language, but this proved difficult to figure out on my own. So thanks for making a good program to start with.

  14. By Jesús Gómez, 31 de enero de 2010 @ 20:40

    Hi, Tim.
    I realized that there was a bug in the program that has been fixed in version 1.1.
    Also I include a video tutorial (in spanish. I’m sorry).

    Please, check this entry for the update and the tutorial: http://hombremecatronico.es/?p=279
    Sincerely:
    The mechatronic Man.

  15. By tim, 31 de enero de 2010 @ 05:45

    Yeah I still haven’t got it connect through the serial interface. I have it set up without flow control, and have spent many hours trying different things without any luck.

  16. By George, 30 de enero de 2010 @ 21:49

    Hola, tengo el mismo problema que Tim arriba. La Wifly está configurado y conectado a la red WiFi, puedo acceder a ella a través de telnet en el puerto 2000. Pero cuando trato de usar Wiflyterm me sale el mensaje “Initializing”, pero no responde a comandos tales como $$$ o conseguir get wlan. No estoy seguro de lo que está mal?

    • By Jesús Gómez, 30 de enero de 2010 @ 23:25

      Es importante abrir el puerto serie sin control de flujo (ni hardware ni xon/xoff).
      A mi así me funciona. Por favor, coméntame si sigue sin funcionarte.

  17. By FJ_Sanchez, 29 de enero de 2010 @ 22:42

    Muy buen aporte para el que esté empezando en esto.

    @Boops y @Jesús Gonzales, por si no lo sabíais creo que ya habéis coincidido en el RoboCamp de Sevilla… imagino que ya lo sabíais, jeje.

    Un saludo.

    • By Jesús Gómez, 29 de enero de 2010 @ 23:03

      Gracias, Fran.
      Sí lo sabíamos. La verdad que me pareció muy bonito su “galatea”.
      Enhorabuena por tu blog también. Creo que voy a tener que hacerte algunas consultas sobre temas de visión en sistemas embebidos…
      Un saludo de Jesús “Gómez”.

  18. By Jesús Gómez, 25 de enero de 2010 @ 22:57

    Por lo que sé, se le puede cambiar el puerto del servidor para que sea el 80 o el que quieras. Incluso puede desactivarse el servidor para que se conecte como cliente a otro equipo.
    Lo de si puede aceptar varias conexiones tengo que probarlo aún.

    Sobre lo de asociaciones no sé nada, pero estoy interesado en ese tipo de iniciativas y se podría hacer algo interesante.

  19. By BoOpS, 25 de enero de 2010 @ 10:02

    Buenos días:

    Hace tiempo que buscaba alguien que hubiese probado este modulo por que posiblemente lo incluya en mi próximo robot solo una preguntilla: Con el Xport podías atender solo las peticiones del puerto 80 respondiéndolas con html hacías un servidor web fácil y rapido (Ejemplo: http://www.roboops.es/2008/12/20/xport-trabajando-como-servidor-web/ ). ¿sabes si con este modulo se puede hacer algo parecido? O al menos que acepte peticiones de varios puertos?

    PD: Estoy mirando la posibilidad de hacer algo de Robótica en la politécnica, una asociación o algo, ¿sabes algo?

    Gracias!

  20. By Jesús Gómez, 22 de enero de 2010 @ 14:45

    El “1″ extra, en realidad es una “L” minúscula, pero con el tipo de letra que usa el editor del arduino parece un “1″. La “L” sirve para indicar al compilador que use un tipo de dato “long” en lugar de integer. SUpongo que lo hará automáticamente pero lo puse por seguridad.
    Supongo que habrá más gente que haya publicado algo de esto, pero no lo he encontrado.
    Para comprobar la velocidad de transmisión coloqué un osciloscopio en la patilla de transmisión del puente SPI, raspando un poco de la laca ailslante.
    Recuerda que para entrar en modo de comandos tienes que pulsar $$$ seguidos, pero según el manual del módulo wifi hay que dejar al menos un segundo antes y después de estos tres caracteres.
    También se entra por defecto en modo comando si no se realiza la conexión.
    No obstante probaré de nuevo el programa a ver si averiguo qué puede fallarte.

    • By Jesús Gómez, 23 de enero de 2010 @ 21:32

      Estoy probando de nuevo el Wiflyterm 1.0 y funciona bien. Al principio no me funcionó porque la configuración del Hyperterminal el control de flujo debe estar a “ninguno”. Otros valores hacen que no se comunique (aunque se sigue mostrando el mensaje inicial del arduino). Puede que este sea tu problema. Lo voy a aclarar en la entrada del blog.

  21. By Tim, 22 de enero de 2010 @ 13:14

    Si el módulo es de Sparkfun …. el Wifly con RN131 y S750 puente SPI, y un Cyrstal 12,288 Mhz. He encontrado un extra “1″ en el final de la FREC_OSC_SPI2SER (122880001) de código, así que estaba esperando que podría haber sido algún otro error en el código. La luz se pone verde PI07 después de conectar a la wifi. Estoy usando la masilla para conectarse a ella en 9600, 8, 1, N. Se conecta y dice Inicializando, pero nada después de eso … no acepta ninguna orden. No puedo creer que usted es el único en incluir cualquier código en el Internet para esto, gracias por ayudarme

  22. By Tim, 22 de enero de 2010 @ 04:37

    He intentado utilizar el código en mi Wifly y no podía obtener el puente de SPI para responder. No sé cómo diagnosticar el problema Espero que usted puede ayudar. He comprobado la velocidad de transmisión y de su 9600. También fue capaz de conectarse de forma remota, pero no a través de la Arduino.

    • By Jesús Gómez, 22 de enero de 2010 @ 09:56

      ¿El módulo que estás usando es el de Sparkfun?
      ¿Has abierto de Hyperterminal en el puerto correcto y a 9600 bps?
      ¿En qué estado se encuentran las luces del módulo?

  23. By Oscar gonzalez, 18 de enero de 2010 @ 11:39

    Impresionante entrada. Gracias por la aportación!
    He publicado tu entrada aqui:
    http://blog.bricogeek.com/noticias/arduino/como-configurar-wifly-shield-con-arduino/

RSS feed para los comentarios de esta entrada. TrackBack URI

Leave a Reply