07 julio 2013

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.

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:

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.

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. 

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.

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!


+Información



9 comentarios:

tffhh dijo...

y si se quiere conectar a processing? porque desde el terminal funciona bien pero processing no detecta el bluetooth como puerto serie

Mario Gómez dijo...

¡Hola tffhh!

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.

Someby Elseee dijo...

HOLA!! QUisiera saber si tienes de eses modulos bluetooth a la venta... soy de EL SAlVADOR y me interese realizar una conexion como la que tu has echo

Fabio Hernan dijo...

Mario , Agradezco el tuto muy bueno. Saludos desde Argentina

Otmane Aammouri dijo...

Podria usarlo para dos cosas a la vez

Gustavo Rodriguez dijo...

ola me ha gustado tu entrada y pues quisiera saber un codigo de arduino que me permita usar el mosulo bluetooth para la reprduccion de musica desde un telefono o algun dispositivo que me lo permita y como seria la coneccion desde el arduino hasta el parlante o parlante a parte de eso he leido sobre un modulador bluetooth mp3 pero lo veo confuso su uso de antemano gracias

Mario Gómez dijo...

¡Hola Gustavo!

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.

AngelGaston Tejada Meraz dijo...

hola que tal me preguntaba puedes utilizar el mismo preincipio para que desde un android puedas enviar y resivir datos no solo una letra como A,a,B........ SINO CODIGOS PERSONALIZADOS ?

Adrian Gomez dijo...

hola buenas noches me preguntaba si alguien sabe si los modulos RN 52 se pueden emparejar entre si es decir que dos modulos RN-52 se puedan emparejar automaticamente mediante la configuracion de sus codigos AT, de la misma manera que se pueden emparejar los modulos HC 06 mediante direccionamiento MAC.. agradeceria su ayuda.