martes, 1 de julio de 2014

Comunicación inalámbrica con Arduino

Una de las dudas que, irremediablemente, tarde o temprano nos asalta cuando empezamos a trabajar con Arduino es ¿Y cómo puedo intercambiar datos con un Arduino sin necesidad de usar cables? Las necesidades para conseguir esto son de lo más variopintas, desde controlar el comportamiento de nuestro Arduino a distancia ya que lo estamos usando para leer datos de un sensor en un lugar apartado del PC, hasta permitir la comunicación inalámbrica de dos Arduinos.

Existen varias alternativas, cada una con sus pros y sus contras, así que voy a comentar aquí mis experiencias con este tema para que no os volváis locos haciendo pruebas como me pasó a mí :)

Zigbee

En realidad Zigbee es una especificación de protocolos de comunicación inalámbricos definidos por la Zigbee Alliance y enfocados a entornos de bajo consumo. Varios fabricantes producen módulos compatibles, como el que aparece en la siguiente foto:

Módulo XBee, compatible con el protocolo Zigbee

Es la opción más elegante y la que mayor alcance y tasa de transferencia de datos garantiza, de todas las que veremos en este artículo. Su uso es bastante sencillo, pues en última instancia nos provee de un puerto serie por donde enviaremos y recibiremos los datos intercambiados con otros módulos Zigbee.

Para aquellos que se decidan por Zigbee, existe gran cantidad de documentación y ejemplos para las distintas plataformas de microcontroladores existentes en el mercado. Nuestro querido Arduino no podía ser menos y, como era de esperar, disponemos incluso de shields para poder usar módulos Zigbee en nuestros proyectos:

Shield de Arduino para un módulo XBee similar al visto anteriormente

Como os podréis imaginar, esta opción tiene una pega importante y es el alto coste que implican estos módulos, mucho mayor que el del resto de opciones que veremos.


Módulos con codificación OOK

Existen unos módulos de envío y recepción de datos basados en codificación OOK (On/Off Keying) los cuales nos permiten enviar pequeñas cantidades de datos como grupos de unos y ceros. Estos módulos son realmente simples, por lo que no incorporan en el hardware ningún tipo de mecanismo de control de errores, señalización ni direccionamiento; simplemente envían aquello que se les manda a todo aquel que se encuentre a su alcance. Al no disponer de control de flujo ni errores, deberemos ser nosotros los que, mediante código, implementemos dichos controles para garantizar un envío y recepción correctos. Estos módulos se utilizan principalmente en mandos a distancia por radiofrecuencia, ya que su coste es realmente bajo y para pequeños paquetes de datos son más que suficiente, además de que al no necesitar ningún tipo de secuencia de establecimiento de conexión, pueden empezar a emitir rápidamente y finalizar en un corto espacio de tiempo, con lo que el gasto en batería es ínfimo. Podemos encontrar estos módulos, por ejemplo, en eBay:

http://www.ebay.com/sch/i.html?_trksid=p2050601.m570.l1313.TR12.TRC2.A0.X433mhz+module&_nkw=433mhz+module&_sacat=0&_from=R40

Aquí os dejo una foto de la pareja de emisor/receptor que tengo yo:

Es importante que busquéis módulos que operen en la frecuencia dde 433 Mhz u 868 MHz, que son las frecuencias habilitadas en Europa para uso libre por los ciudadanos. Veréis que hay disponibles módulos de 315 MHz, que se usan en Estados Unidos y otros países.

Estos módulos tienen 3 pines:
  1. Vcc, que debe ser alimentado con 5V, por lo que deberá conectarse al pin de 5V de Arduino.
  2. GND, que debe conectarse a cualquier pin GND de nuestro Arduino.
  3. DATA, que será el pin a través del cual enviaremos o recibiremos los datos.
Existe en ambos módulos un pad donde podremos soldar una antena apropiada, para aumentar así el alcance de los módulos. El tipo de antena más simple que podemos utilizar es un trozo de cable recto de aproximadamente unos 16 centímetros y medio (en caso de que sean módulos de 433 MHz). En esta imagen podéis apreciar otros tipos de antena:


El módulo de envío no tiene mucho misterio y sólo hay que alternar el pin de datos entre 0 y 1, dejando una pausa determinada entre las transiciones del pin. Es muy recomendable que los bits de los datos a enviar se representen con varias transiciones entre cero y uno, por ejemplo aquí podemos ver una codificación bastante típica:




Se observa como un valor se representa mediante un pulso corto seguido de otro pulso largo, mientras que el otro valor se representa con dos pulsos cortos seguidos.

El módulo de recepción sí que tiene más miga, puesto que estos aparatos no traen circuitería de filtrado y las bandas de frecuencia libres como la de 433 MHz están llenas de ruido, por lo que cuando no estemos transmitiendo nada, recibiremos gran cantidad de transiciones entre cero y uno en el pin de datos, las cuales son erráticas y no siguen ningún patrón aparente, como podéis comprobar en esta imagen:



Se ve claramente y a simple vista la diferencia entre los periodos donde se está transmitiendo información y los tramos donde sólo hay ruido, pero esto complica un poco la discriminación que deberemos realizar nosotros por software para filtrar todo aquello no deseado.

Lo más sencillo para manejar un receptor de este tipo es declarar una interrupción y conectar el pin de datos del módulo RF al pin correspondiente del arduino (D2 o D3, dependiendo de la interrupción declarada). De este modo, sólo tendremos que medir el tiempo transcurrido entre las transiciones para saber si se ajusta a nuestro patrón o no.

Los pros de este sistema os los podéis imaginar: un precio realmente bajo con un alcance considerable (con la antena adecuada he alcanzado sin problemas distancias de unos 100 metros a campo abierto). Las pegas, sin embargo, son importantes, porque por un lado necesitaremos 2 módulos (uno de envío y uno de recepción en cada arduino, salvo que queramos comunicación en un único sentido) y, por otra parte, no se consiguen buenas tasas de transferencia de datos, además del mayor "coste" en términos de programación que requieren estos módulos debido a tener que controlar los errores, el reenvío de paquetes perdidos o erróneos, etc.


Módulos Nordic RF

Hace tiempo, investigando una alternativa intermedia entre los Zigbee y los módulos OOK que comentamos anteriormente, di con estos transceptores poco conocidos y que tenían un precio atractivo, por lo que decidí comprar un par para probarlos y ver su desempeño.



Este modelo concreto es el NRF24L01 y dispone de una librería para Arduino que podemos usar en nuestros desarrollos: http://playground.arduino.cc/InterfacingWithHardware/Nrf24L01

La comunicación con estos módulos se realiza mediante SPI, por lo que deberemos conectarlo a los pines SCK, MISO y MOSI de nuestro arduino preferido (pines 13, 12 y 11) y dos pines digitales de I/O (por defecto, la librería utiliza los pines D7 y D8), además de alimentación (3.3V). En esta imagen podéis ver el esquema de conexionado:




Antes de poder conectar el módulo RF a una protoboard para poder hacer las primeras pruebas, deberemos construir un pequeño adaptador con un par de tiras de pines y un trozo de pcb perforada, ya que estos módulos utilizan como conexionado dos tiras de 5 pines en paralelo. En esta foto podéis ver uno de mis módulos y el adaptador que construí:



Por ahora, no he tenido la oportunidad de usar estos módulos en una aplicación real, simplemente he cargado los sketches de ejemplo de la librería y los he probado. Tan pronto como pueda ponerlos a prueba y realice algunas mediciones de distancia, velocidad, etc. publicaré aquí los resultados.

¡Hasta la próxima!