En Construyendo un pequeño marcador electrónico expliqué los fundamentos de la comunicación serie, la forma más básica de comunicación entre dos dispositivos. La pregunta que se hace un maker a continuación es: ¿Entonces sólo puedo comunicarme con un dispositivo que esté físicamente próximo y mediante un incómodo cable de impresora?
Evidentemente no. La comunicación serie es el medio más básico para comunicar dispositivos entre sí, pero las redes actuales de IoT serían inconcebibles si esa fuese la única posibilidad.
Pero antes de correr hay que empezar a andar y vamos a ver la progresión natural de la comunicación serie: la comunicación serie inalámbrica. O, lo que viene a ser lo mismo, bluetooth.
La diferencia básica con la transmisión de datos a través del cable USB, por ejemplo, está en el medio físico empleado. Si entonces hablábamos de pulsos de tensión alta y baja que se transmiten en un conductor eléctrico, aquí tenemos ondas de radio de ultra-alta frecuencia (UHF, ultra-high frequency) en el entorno de los 2.4 GHz.
Bluetooth permite además crear una pequeña red de dispositivos, basada en jerarquía maestro-esclavo (master–slave), en la que un maestro (típicamente el PC) puede emparejarse con varios esclavos.
Conectar con el dispositivo bluetooth
La parte clave, por tanto, está en que en al utilizar un módulo bluetooth (y ahora presentaré alguno de ellos), este será el que se hará cargo de la comunicación serie. O lo que es lo mismo, cualquiera que sea el módulo bluetooth empleado, tendrá como mínimo, además de los pines de alimentación (Vcc y GND), 2 pines Tx/Rx que tendremos que conectar a los pines Rx/Tx de la placa de desarrollo (e.g. Arduino).
Fijaos muy bien en que he invertido el orden de las letras Rx y Tx que identifican receiver y transmitter respectivamente. Esto es de crucial importancia. Podríamos decir que al emparejar el módulo bluetooth con nuestro PC, el primero se convierte en una especie de «extensión» del segundo, de modo que la transmisión de datos microcontrolador–PC se hace por el Tx de la placa de desarrollo y se recibe en el Rx del módulo bluetooth y viceversa.
Teniendo en cuenta estas indicaciones, no será nada difícil usar cualquier montaje equipado con un módulo bluetooth.
Tan sólo señalar un pan de consideraciones que debéis tener en cuenta a la hora de usar estos dispositivos:
- Son dispositivos de baja potencia y eso se traduce en un corto alcance de la señal. Hay diferentes clases y diferentes potencias, pero los más extendidos son los de clase 2, con una distancia máxima de 10 metros aprox., que se reducen además si hay obstáculos por medio. Por tanto, si pensáis en comunicaros con un dispositivo que esté en la otra punta de vuestra casa, por ejemplo, tendréis que recurrir a otras tecnologías como WiFi, LoRa, Zigbee… pero bluetooth desde luego no satisfará vuestras necesidades.
- Una vez cargado el programa en nuestro Arduino (u otro microcontrolador) debemos desconectar el cable «de impresora» y dejar el montaje sin ese «cordón umbilical» que, además de habilitar la comunicación serie, le proporciona tensión al montaje. Debemos disponer por tanto de una fuente de tensión, sea una pila, una batería un conjunto de pilas…. Debéis ser cuidadosos en la elección de dicho suministrador pues darán más o menos tensión, y más o menos potencia (intensidad) y eso puede hacer que nuestro montaje no funcione (porque no le llega corriente suficiente, por ejemplo), que la autonomía sea limitada o, en el extremo contrario, que provoquemos una sobretensión en los componentes.
Dados estos tips iniciales, vamos a ver algunos de los módulos bluetooth más conocidos.
BlueSMIRF Gold
Este dispositivo de SparkFun, una de las firmas de referencia para todo maker que se precie, fue mi primer módulo bluetooth. Por la misma razón que cuando os conté la adquisición de mi Arduino MKR1000 (https://jjosemayorga.com/como-programar-nodemcu/) el hecho de estar respaldado por SparkFun me hizo pagar unos nada desdeñables 53 euros.
Y la verdad es que BlueSMIRF no me defraudó. Tan sencillo como conectar el dispositivo según lo descrito arriba, configurar la comunicación seria a los 115200 baud no configurables a los que funciona y a rodar. Sin complicaciones.
Veamos un pequeño proyecto de ejemplo… montaremos un LED rojo y un LED amarillo y los encenderemos/apagaremos mediante una aplicación Java hecha exprofeso,
Aquí os dejo el esquema del circuito.

Este es el programa que vamos a subir a Arduino. Lo dicho: esta subida la haremos con el cable «de impresora» a través del puerto COM reconocido y con el módulo desconectado, pero una vez hayamos cargado el programa quitaremos el cable USB, conectaremos el módulo bluetooth y la fuente de alimentación.
const int yellowLED = 13; //LED connected to digital pin 13
const int redLED=8;
int inByte = 0;
void setup()
{
Serial.begin(115200); //Open the serial port
pinMode(redLED, OUTPUT); //Set the digital pin as output
pinMode(yellowLED,OUTPUT);
}
void loop(){
if(Serial.available() > 0){
inByte = (char)Serial.read(); //read the incoming byte
if(inByte == 'a')
{
digitalWrite(yellowLED, HIGH);
}
if(inByte == 'b')
{
digitalWrite(yellowLED, LOW);
}
if(inByte == 'c')
{
digitalWrite(redLED, HIGH);
}
if(inByte == 'd')
{
digitalWrite(redLED, LOW);
}
}
}
Este programa es muy simple. La única funcionalidad implementada es que Arduino se mantiene «a la escucha» de lo que le llegue por comunicación serie y si le llega alguno de los mensajes definidos (una a, una b, una c o una d) ejecuta la acción correspondiente: encender/apagar LED amarillo o encender/apagar LED rojo.
Bluetooth es una tecnología especialmente indicada para su uso con smartphones. Si vais a Google Play (soy muy de Android, lo veréis en entradas futuras) podéis encontrar muchas aplicaciones que os van a permitir emparejar, conectar y mandar mensajes a dispositivos bluetooth, de modo que ni siquiera nos haría falta desarrollar un aplicación específica en el lado del PC o el smartphone.
Yo, por ejemplo, utilizo frecuentemente la aplicación ArduController para labores de depuración de código y pruebas. He mirado su disponibilidad en Google Play, pero no es la misma que yo descargué en su momento. Pero cualquiera de las que veáis funcionará.
Ya que hemos verificado que el módulo bluetooth funciona, pasemos a la parte del PC, la aplicación Java.
Utilizaremos las mismas librerías RXTXcomm.jar, rxtxSerial.dll y rxtxParallel.dll que en https://jjosemayorga.com/construyendo-un-pequeno-marcador-electronico/ y debemos averiguar en que puerto COM está el módulo bluetooth.
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
public class Java2led extends JFrame implements ActionListener
{
/**
*
*/
private static final long serialVersionUID = -3573271532589422066L;
JFrame marco=new JFrame("Prueba Bluetooth con 2 LED");
JLabel titulo=new JLabel("<html><font size=20 color=blue>Prueba con 2 LED</font></html>");
JButton yellowLEDon=new JButton("Encender LED amarillo");
JButton yellowLEDoff=new JButton("Apagar LED amarillo");
JButton redLEDon=new JButton("Encender LED rojo");
JButton redLEDoff=new JButton("Apagar LED rojo");
/** The output stream to the port */
private OutputStream output = null;
SerialPort serialPort;
private final String PORT_NAME = "COM16";
/** Milliseconds to block while waiting for port open */
private static final int TIME_OUT = 2000;
/** Default bits per second for COM port. */
private static final int DATA_RATE = 115200;
Java2led()
{
marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
marco.setIconImage(Toolkit.getDefaultToolkit().createImage("bluetooth.png"));
GridBagLayout gridbag=new GridBagLayout();
GridBagConstraints gbc=new GridBagConstraints();
marco.setLayout(gridbag);
gbc.insets=new Insets(10,10,10,10);
gbc.gridx=0;
gbc.gridy=0;
gbc.gridwidth=2;
gbc.gridheight=1;
marco.add(titulo,gbc);
gbc.gridx=0;
gbc.gridy=1;
gbc.gridwidth=1;
gbc.gridheight=1;
yellowLEDon.setPreferredSize(new Dimension(200, 40));
yellowLEDon.addActionListener(this);
marco.add(yellowLEDon,gbc);
gbc.gridx=0;
gbc.gridy=2;
gbc.gridwidth=1;
gbc.gridheight=1;
yellowLEDoff.setPreferredSize(new Dimension(200, 40));
yellowLEDoff.addActionListener(this);
marco.add(yellowLEDoff,gbc);
gbc.gridx=1;
gbc.gridy=1;
gbc.gridwidth=1;
gbc.gridheight=1;
redLEDon.setPreferredSize(new Dimension(200, 40));
redLEDon.addActionListener(this);
marco.add(redLEDon,gbc);
gbc.gridx=1;
gbc.gridy=2;
gbc.gridwidth=1;
gbc.gridheight=1;
redLEDoff.setPreferredSize(new Dimension(200, 40));
redLEDoff.addActionListener(this);
marco.add(redLEDoff,gbc);
initializeArduinoConnection();
marco.pack();
marco.setLocationRelativeTo(null);
marco.setVisible(true);
}
public void initializeArduinoConnection(){
CommPortIdentifier portId = null;
Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();
// iterate through, looking for the port
while (portEnum.hasMoreElements()) {
CommPortIdentifier currPortId = (CommPortIdentifier)
portEnum.nextElement();
if (PORT_NAME.equals(currPortId.getName())) {
portId = currPortId;
break;
}
}
if (portId == null) {
showError("Could not find COM port.");
System.exit(ERROR);
return;
}
try {
// open serial port, and use class name for the appName.
serialPort = (SerialPort) portId.open(this.getClass()
.getName(), TIME_OUT);
// set port parameters
serialPort.setSerialPortParams(DATA_RATE,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
// open the streams
output = serialPort.getOutputStream();
} catch (Exception e) {
showError(e.getMessage());
System.exit(ERROR);
}
}
private void sendData(String data){
try {
output.write(data.getBytes());
} catch (IOException e) {
showError("Error sending data");
System.exit(ERROR);
}
}
private void showError(String errorMessage){
JOptionPane.showMessageDialog(marco,
errorMessage,
"Error",
JOptionPane.ERROR_MESSAGE);
}
public static void main(String[] args)
{
Java2led app=new Java2led();
}
public void actionPerformed(ActionEvent e)
{
if("Encender LED amarillo".equals(e.getActionCommand()))
{
sendData("a");
}
if("Apagar LED amarillo".equals(e.getActionCommand()))
{
sendData("b");
}
if("Encender LED rojo".equals(e.getActionCommand()))
{
sendData("c");
}
if("Apagar LED rojo".equals(e.getActionCommand()))
{
sendData("d");
}
}
}
Veamos un vídeo de demostración.
Otros módulos bluetooth: HC-05 y HC-06
Hemo visto una demo del módulo BlueSMIRF Gold. Este módulo cumple perfectamente el objetivo buscado y es muy, muy sencillo de usar. Pero presenta un gran inconveniente: es muy caro. O era, porque en la actualidad se encuentra descatalogado.
Y es que existen otros módulos igual de válido y que son notablemente más baratos, por lo que son mucho más interesantes para el bolsillo del maker aficionado.
Estos módulos son los HC-05 y HC-06.
HC-05
El módulo HC-05 tiene la particularidad de que puede funcionar tanto como maestro (master) o como esclavo (slave). Lo diferenciaréis del HC-06 porque tiene 6 patillas. Podéis comprarlo aquí.
Esto exige que antes de empezar a emplearlo tengamos que configurarlo. Esta configuración nos permite elegir el modo de funcionamiento (maestro o esclavo), el nombre del dispositivo y más cosas.
Esto está muy bien si queremos aprovechar todas esas opciones en nuestro proyecto. Pero si sólo queremos conectar nuestra plataforma de desarrollo (Arduino o similar) con nuestro PC o smartphone, esto será más bien un inconveniente.
En todo caso os explico cómo configurar el dispositivo.
Configuración de HC-05
La configuración del módulo HC-05 se hace a través de los llamados comandos AT (https://es.wikipedia.org/wiki/Conjunto_de_comandos_Hayes).
Para enviar estos comandos al módulo tenemos que comunicarnos con él. Esto lo haremos con un pequeño montaje en el que usaremos un Arduino como intermediario. Por este motivo, usaremos comunicación serie entre el PC y Arduino y entre Arduino y HC-05. Por ello, tendremos que habilitar un puerto serie adicional, por software. Esto se hace con la librería SoftwareSerial.h.
Este es el montaje físico.

Y este el código a cargar en Arduino:
#include <SoftwareSerial.h>
SoftwareSerial BTSerial(10, 11); // RX | TX
void setup()
{
pinMode(9, OUTPUT); // this pin will pull the HC-05 pin 34 (key pin) HIGH to switch module to AT mode
digitalWrite(9, HIGH);
Serial.begin(38400);
Serial.println("Enter AT commands:");
BTSerial.begin(38400); // HC-05 default speed in AT command more
}
void loop()
{
// Keep reading from HC-05 and send to Arduino Serial Monitor
if (BTSerial.available())
Serial.write(BTSerial.read());
// Keep reading from Arduino Serial Monitor and send to HC-05
if (Serial.available())
BTSerial.write(Serial.read());
}
Así, para entrar en el modo de configuración AT debe desconectarse la alimentación al HC-05, mantener pulsado el botón del módulo y volver a conectar la alimentación. Entonces la luz parpadeará más lentamente indicando que podemos enviarle comandos AT.
Después abriremos el monitor serial con las opciones “Ambos NL & CR” y 38400 baudio y escribiremos AT para ver si hay conexión. Se debe recibir un OK.

Ahora ya podemos enviar los comandos de configuración que queramos. Os dejo un enlace a un blog que lo explica muy bien:
Configuración del módulo bluetooth HC-05 usando comandos AT (naylampmechatronics.com)
Otra de las pegas que encontraremos al utilizar este módulo es que su nivel alto de comunicación es 3.3V. Esto se traduce en que una vez configurado todo, cuando tengamos intención de poner en marcha el proyecto, la señal que circula entre el Tx de Arduino y el Rx de HC-05 deberá trabajar a 3.3V para el nivel alto, cuando el nivel alto de Arduino es 5V. La forma más sencilla de solucionarlo es usando un divisor de tensión en esta conexión. Un ejemplo puede ser el que se muestra en esta imagen:

Podemos calcular fácilmente que si cogemos la tensión en ese punto el valor será de 2/(1+2)*5 = 3.33V.
En resumen, y como decía de entrada HC-05 complica en exceso el montaje. Salvo que queramos usar las opciones de configuración, no es un módulo nada amigable.
HC-06
Así llegamos a mi módulo favorito: el HC-06. Sencillo como un BlueSMIRF, barato como un HC-05. Por unos 5€ tendréis el dispositivo adecuado para añadir conectividad bluetooth a vuestros proyectos. Podéis comprarlo aquí.
Me veréis utilizarlo profusamente en entradas futuras, y es que este componente es de esos con los que debéis rellenar vuestra cesta de la compra cuando os faltan unos eurillos para ahorraros los gastos de envío.




0 comentarios