Utilizando el módulo serie Bluetooth en Arduino
Si estás cansado de tener mil cables por doquier, es posible que en este momento estés pensando en agregar un módulo Bluetooth a tu proyecto Arduino.
En esta entrada, revisaremos el módulo de JY-MCU que podemos conectar al puerto serie de nuestro Arduino para agregar funcionalidad bluetooth de una manera sencilla y sobre todo de muy bajo costo.
¿Por qué bluetooth?
El Bluetooth es un estándar de redes inalámbricas personales, el rango típico de un dispositivo Bluetooth ronda entre 1-9m dependiendo de la potencia del transmisor. Tal vez lo más relevante de esta tecnología es que viene incluía de fábrica en prácticamente todo teléfono móvil.
Ya en artículos anteriores hemos explicado como utilizar el puerto serie para conectarnos con otros dispositivos desde el Arduino como por ejemplo nuestra Raspberry Pi.
El módulo que utilizaremos en esta entrada, provee de funcionalidad de puerto serial sobre la conexión bluetooth. Esto significa que si utilizamos este módulo nuestra computadora esta lo reconocerá como si fuera un puerto serie de toda la vida.
El módulo JY-MCU
Este pequeñísimo módulo se puede adquirir fácilmente en línea a través de páginas como DealExtreme o también, si vives en El Salvador, podrás adquirir uno a través de la Tienda TeUbi.co en los próximos días.
Una de las ventajas de este módulo es que es tolerante a 5V. El chip originalmente (BC417) trabaja con 3.3V pero este módulo en particular incluye un pequeño regulador de voltaje que nos permite utilizarlo en variedad de dispositivos. Esto significa que podemos utilizarlo también en nuestra Raspberry Pi sin temor a dañar el módulo y/o la Raspberry.
La conexión de este módulo es sumamente sencilla, simplemente nos guiamos por el siguiente diagrama:
Solo deben tener especial cuidado en invertir las líneas TX y RX del arduino y del módulo, es decir TX->RX y RX->TX.
La razón por la que utilizo el Serial1 es porque el Arduino Mega utiliza el Serial0 para comunicarse vía USB con el programador y en ocasiones se generan conflictos al momento de programar cuando este puerto tiene un dispositivo conectado.
La razón por la que utilizo el Serial1 es porque el Arduino Mega utiliza el Serial0 para comunicarse vía USB con el programador y en ocasiones se generan conflictos al momento de programar cuando este puerto tiene un dispositivo conectado.
Configurando la conexión en Linux
Nota: Antes de continuar, asegúrense de tener instalado "bluez". Estas son un conjunto de herramientas para administrar fácilmente las conexiones Bluetooth desde consola en Linux.
Primero, tenemos que averiguar la dirección MAC de nuestro adaptador serial. Para ello conectamos nuestro Arduino para para que este provea de alimentación al módulo y luego ejecutamos el siguiente comando desde Linux:
$ sudo hcitool scan Scanning ... D4:CB:AF:D3:19:4A Mxgxw's N97 mini 4C:80:93:4D:87:89 v131-0 00:12:10:22:09:69 linvor
En mi caso aparecen tres dispositivos: mi teléfono, la laptop y un dispositivo llamado "linvor". Este último es nuestro adaptador Bluetooth. Debemos de anotar el código hexadecimal de la dirección ya que lo seguiremos utilizando en los siguientes pasos.
Luego debemos determinar en que "canal" se encuentra el puerto serial, esto lo podemos averiguar con el siguiente comando:
$ sudo sdptool records 00:12:10:22:09:69 Service Name: Dev B Service RecHandle: 0x10000 Service Class ID List: "Serial Port" (0x1101) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 1 Language Base Attr List: code_ISO639: 0x656e encoding: 0x6a base_offset: 0x100
Pueden notar como el servicio que aparece en el canal 1, corresponde al puerto serial.
El siguiente paso consiste en agregar las siguientes líneas al archivo rfcomm.conf que se encuentra en /etc/bluetooth:
El siguiente paso consiste en agregar las siguientes líneas al archivo rfcomm.conf que se encuentra en /etc/bluetooth:
rfcomm1 { bind yes; device 00:12:10:22:09:69; channel 1; }
Esta configuración se encargará de crear el dispositivo /dev/rfcomm1 que se conectará automáticamente en tanto el módulo Bluetooth se encuentre al alcance.
Luego "reiniciamos" el servicio Bluetooth con el siguiente comando:
$ sudo /etc/init.d/bluetooth restart
Si hacen un ls /dev/rfcomm* verán que aparece el nuevo puerto. Sin embargo, antes de comenzar a enviar/recibir datos debemos "parear" el dispositivo.
Pareando el dispositivo
Primero debemos abrir dos consolas de comandos (sí, dos). Luego en una de ellas ejecuten el siguiente comando:
$ sudo bluez-simple-agent Agent registered
Mientras este comando se está ejecutando abrimos una consola nueva y ejecutamos el siguiente comando (no olviden reemplazar por la dirección MAC de su lector):
sudo hcitool cc 00:12:10:22:09:69; sudo hcitool auth 00:12:10:22:09:69
Justo en ese momento, en la primera consola que abrimos aparecerá un mensaje como el que se muestra a continuación:
RequestPinCode (/org/bluez/3023/hci0/dev_00_12_10_22_09_69) Enter PIN Code: 1234
Ingresen el pin por defecto "1234" y ¡Listo! Ya pueden comenzar a utilizar su adaptador serie Bluetooth desde Linux.
El proyecto de Arduino
Para demostrar el funcionamiento del módulo vamos a hacer un programa muy sencillo con el Arduino Mega.
Este programa se mantendrá leyendo continuamente el puerto serial y cuando reciba una palabra que contenga la secuencia "led" encenderá o apagará el led conectado al pin 13 de nuestro Arduino Mega.
Este programa se mantendrá leyendo continuamente el puerto serial y cuando reciba una palabra que contenga la secuencia "led" encenderá o apagará el led conectado al pin 13 de nuestro Arduino Mega.
Primero incluyamos la biblioteca "string.h" e incluyamos algunas variables:
#include <string.h> char buffer[255]; int i = 0; int pinVal = 0;
Notarán que definimos un arreglo de caracteres "buffer", utilizaremos esta variable para guardar temporalmente las líneas leídas del puerto serie y compararlas luego para saber si contienen las letras "led".
pinVal es la variable que se encargará de almacenar el valor del led (apagado o encendido) e i es una variable que nos indica el tamaño actual del buffer.
Luego debemos inicializar el puerto Serial1 a donde tenemos conectado el módulo Bluetooth y configuramos el pin 13 como salida. De fábrica este pin está conectado a un led en la tableta Arduino Mega, así podemos comprobar el funcionamiento fácilmente sin necesidad de agregar cables extra.
pinVal es la variable que se encargará de almacenar el valor del led (apagado o encendido) e i es una variable que nos indica el tamaño actual del buffer.
Luego debemos inicializar el puerto Serial1 a donde tenemos conectado el módulo Bluetooth y configuramos el pin 13 como salida. De fábrica este pin está conectado a un led en la tableta Arduino Mega, así podemos comprobar el funcionamiento fácilmente sin necesidad de agregar cables extra.
void setup() { Serial1.begin(9600); pinMode(13,OUTPUT); digitalWrite(13,pinVal); }
El código del loop principal es bastante sencillo:
void loop() { while(Serial1.available()>0) { char c = Serial1.read(); append_buffer(c); if(c=='\n') { if(strstr(buffer,"led")!=0) { digitalWrite(13,pinVal^=1); if(pinVal==1) { Serial1.write("Led ON\r\n"); } else { Serial1.write("Led OFF\r\n"); } } flush_buffer(); } } }
Este código funciona de la siguiente manera: Cuando existan datos disponibles en el puerto Serial1 vamos a leer un carácter que será agregado al buffer y si es un fin de línea (\n) compararemos el texto almacenado en el buffer para ver si contiene una ocurrencia de la palabra "led".
La comparación del texto se realiza con la función strstr, esta función devuelve un 0 cuando la cadena de texto no es encontrada y un valor diferente de cero en caso contrario.
La comparación del texto se realiza con la función strstr, esta función devuelve un 0 cuando la cadena de texto no es encontrada y un valor diferente de cero en caso contrario.
Si se encuentra la palabra "led", se cambia el valor en la línea 13, pasando de 1 a 0 y viceversa. La función "flush_buffer" se encarga de limpiar el buffer y de enviar de regreso la palabra almacenada por el puerto serial.
A continuación les dejo las funciones de "ayuda" para trabajar con el buffer":
void flush_buffer() { Serial1.write((const uint8_t*)buffer,i); for(int j=0;j<=i;j++) { buffer[j] = 0; } i = 0; } void append_buffer(char c) { if(i<255) { buffer[i++] = c; } else { flush_buffer(); } }
La función "append_buffer" se encarga de ir llenando nuestra cadena interna carácter por carácter y asegurarse de que no se supere el tamaño definido. Si por alguna razón superamos el tamaño del buffer entonces se llama a la función "flush_buffer" que limpia el buffer y reinicia el tamaño del arreglo.
Probando el Sketch
Para probar el Sketch, les recomiendo abran dos consolas. En la primera utilicen el software "minicom" para conectarse al puerto serial con el siguiente comando:
$ minicom -D /dev/rfcomm1
Luego desde otra consola envíen este comando:
$ echo $'led\r' > /dev/rfcomm1
Cada vez que ejecuten el comando, el led en la tableta Arduino pasará de encendido a apagado y viceversa. De igual manera en la consola en que tengamos abierto el minicom podrán ver los mensajes de estado generados por la tableta arduino.
Concluyendo
El pequeño módulo bluetooth si bien nos provee únicamente de la funcionalidad de puerto serie, nos abre una gran gama de posibilidades de control remoto inalámbrico. ¿Que tal por ejemplo?... Controlar nuestro Arduino desde nuestro Android vía bluetooth.
Pueden utilizar el código de este Sketch para agregar sus comandos personalizados vía serie, solo agreguen más "if" con sus respectivos strstr para capturar más comandos.
Les daría unas cuantas ideas más pero por ahora el sueño me ataca, así que no habiendo nada más que decir por hoy... ¡Hasta la próxima!
Comentarios
Si funciona bien desde terminal puede significar algun problema con la configuración de processing o con el bootloader grabado en el Arduino.
No he utilizado processing, pero dejame revisar a ver si puedo reproducir tu problema.
Revisa en general las velocidades de conexión, estos módulos bluetooth se conectan a 9600bps, tomalo en consideración.
¡Saludos!
Mario.
Lastimosamente este módulo solo funciona para utilizarse como puerto serie. Para transmitir audio necesitas un módulo bluetooth que soporte A2DP que es el perfil para transmisión de audio.
La tableta de expansión del RN-52 de Sparkfun Electronics te permite hacer hacer lo que necesitas. Puedes encontrar información en su página como también ejemplo de código.
¡Saludos!
Mario.