En esta sección aprenderás a establecer una comunicación inalámbrica en modo simplex utilizando dos módulos Bluetooth para enviar y recibir datos. El objetivo es establecer la comunicación inalámbrica entre un PIC Maestro y un PIC Esclavo para enviar comandos al pulsar un botón y recibir comandos para encender un LED correspondiente.
Bluetooth HC-05
El Bluetooth HC-05 es un módulo de comunicación inalámbrico que utiliza la tecnología Bluetooth para establecer un enlace de comunicación serie entre dos dispositivos. Es un dispositivo muy popular en proyectos de electrónica y robótica, ya que permite la comunicación inalámbrica entre un microcontrolador, como Arduino, y otros dispositivos como un ordenador, smartphone o tablet. El HC-05 puede funcionar como maestro o esclavo y utiliza el perfil serial port profile (SPP) de Bluetooth, lo que lo hace compatible con una amplia variedad de dispositivos que soportan este perfil.
Características:
- Tecnología: Bluetooth 2.0 + EDR (Enhanced Data Rate)
- Alcance de comunicación: hasta 10 metros (en condiciones ideales)
- Velocidad de transmisión: 2.1 Mbps máx. en modo EDR, 721 kbps máx. en modo estándar
- Frecuencia: 2.4 GHz a 2.4835 GHz banda ISM
- Potencia de transmisión: Clase 2, hasta 4 dBm (2.5 mW)
- Sensibilidad de recepción: -80 dBm típico
- Protocolos de soporte: Bluetooth serial port profile (SPP)
- Modo de operación: Maestro o Esclavo
- Compatibilidad: Compatible con dispositivos que soportan Bluetooth SPP
- Interfaz: UART (Universal Asynchronous Receiver/Transmitter)
- Voltaje de alimentación: 3.3V a 5V DC
- Consumo de energía: 30 mA en modo de operación, 1 mA en modo de espera
- Dimensiones: 28 mm x 15 mm x 2.35 mm
Circuito de conexión
Configuración
Inicialmente se deben configurar los módulos Bluetooth en modo maestro y esclavo para poder transmitir los datos mediante una comunicación inalámbrica.
Programación PIC Maestro
Inicialmente se establecen los parámetros de la comunicación RS232.
- baud = Velocidad de transmisión y recepción configurada en el módulo Bluetooth.
- stop = Bits de parada.
- parity = Bit de paridad.
- xmit = Pin de transmisión.
- rcv = Pin de recepción.
- bits = Datos de transmisión.
- stream = identificación de transmisión.
#use rs232(baud=38400, stop=0, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8)
Se definen los pines digitales de entrada conectados a los botones.
#define boton1 input(pin_d0)
#define boton2 input(pin_d1)
#define boton3 input(pin_d2)
Se utiliza una variable para registrar el estado pasado de los botones.
int1 pasboton1 = 0;
int1 pasboton2 = 0;
int1 pasboton3 = 0;
Cuando el botón cambia de estado se envía el comando correspondiente, si esta pulsado envía «LED1_ON\r» y si no esta pulsado se envía «LED1_OFF\r».
if (pasboton1 != boton1)
{
delay_ms(10);
if(pasboton1==0)
{
printf("LED1_ON\r");
pasboton1=1;
}else
{
printf("LED1_OFF\r");
pasboton1=0;
}
}
Para el boton2 y boton3 se realiza el código con la misma lógica.
Código completo PIC Maestro
#FUSES NOMCLR
#use rs232(baud=38400, stop=0, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8)
#define boton1 input(pin_d0)
#define boton2 input(pin_d1)
#define boton3 input(pin_d2)
int1 pasboton1 = 0;
int1 pasboton2 = 0;
int1 pasboton3 = 0;
void main()
{
while(TRUE)
{
if (pasboton1 != boton1)
{
delay_ms(10);
if(pasboton1==0)
{
printf("LED1_ON\r");
pasboton1=1;
}else
{
printf("LED1_OFF\r");
pasboton1=0;
}
}
if (pasboton2 != boton2)
{
delay_ms(10);
if(pasboton2==0)
{
printf("LED2_ON\r");
pasboton2=1;
}else
{
printf("LED2_OFF\r");
pasboton2=0;
}
}
if (pasboton3 != boton3)
{
delay_ms(10);
if(pasboton3==0)
{
printf("LED3_ON\r");
pasboton3=1;
}else
{
printf("LED3_OFF\r");
pasboton3=0;
}
}
}
}
Programación PIC Esclavo
Inicialmente se establecen los parámetros de la comunicación RS232.
- baud = Velocidad de transmisión y recepción configurada en el módulo Bluetooth.
- stop = Bits de parada.
- parity = Bit de paridad.
- xmit = Pin de transmisión.
- rcv = Pin de recepción.
- bits = Datos de transmisión.
- stream = identificación de transmisión.
#use rs232(baud=38400, stop=0, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8)
Se definen los pines de salida conectados a los LED´s.
#define LED1 PIN_D0
#define LED2 PIN_D1
#define LED3 PIN_D2
Se habilitan las interrupciones para la comunicación serial rs232.
enable_interrupts(int_rda);
enable_interrupts(global);
Cuando se reciben datos por el pin de recepción el programa detiene sus funciones para recibir los datos, el programa guarda los datos en la variable recibido[i] y termina la comunicación rs232 cuando recibe un carácter de salto de linea.
#int_rda
void rda_isr()
{
memset(recibido, 0, sizeof(recibido)); //limpia los registros de la varible
int8 i=0;
while(true)
{
recibido[i]=getc();//RECIBE EL CARACTER
if(recibido[i]=='\r')//busca el salto de linea \r
{
recibido[i]='\0';//fin de la cadena = caracter nulo \0
leds();
return;
}
i++;
}
}
Se define una variable de caracteres que contienen el identificador del led que se encenderá o apagara.
char LED1_ON[20] = "LED1_ON";
char LED1_OFF[20] = "LED1_OFF";
La función strcmp() compara los datos recibidos por el puerto rs232 y con las variables anteriores.
result = strcmp(recibido, LED1_ON);//compara, si son iguales (0), no (+-1)
Si los datos recibidos y LED1_ON es igual, resultado=0 por lo tanto encenderá el led1, si no es igual pasa a la siguiente comparación.
if(result==0)
{
OUTPUT_BIT(LED1,1);
return;
}
Si los datos recibidos y LED1_OFF es igual resultado = 0, entonces apagara el led1, si no es igual pasa a la siguiente comparación.
result = strcmp(recibido, LED1_OFF);
if(result==0)
{
OUTPUT_BIT(LED1,0);
return;
}
Finalmente se aloja en la función void main(){} y espera hasta activarse la interrupción nuevamente.
Código completo PIC Esclavo
#include "string.h"
#FUSES NOMCLR
#use rs232(baud=38400, stop=0, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8)
#define LED1 PIN_D0
#define LED2 PIN_D1
#define LED3 PIN_D2
char recibido[20];
void leds();
#int_rda
void rda_isr()
{
memset(recibido, 0, sizeof(recibido)); //limpia los registros de la varible
int8 i=0;
while(true)
{
recibido[i]=getc();//RECIBE EL CARACTER
if(recibido[i]=='\r')//busca el salto de linea \r
{
recibido[i]='\0';//fin de la cadena = caracter nulo \0
leds();
return;
}
i++;
}
}
void leds()
{
signed int8 result;
char LED1_ON[20] = "LED1_ON";
char LED1_OFF[20] = "LED1_OFF";
char LED2_ON[20] = "LED2_ON";
char LED2_OFF[20] = "LED2_OFF";
char LED3_ON[20] = "LED3_ON";
char LED3_OFF[20] = "LED3_OFF";
while (true)
{
result = strcmp(recibido, LED1_ON);//compara, si son iguales (0), no (+-1)
if(result==0)
{
OUTPUT_BIT(LED1, 1);
return;
}//enciende el led1
result = strcmp(recibido, LED1_OFF);
if(result==0)
{
OUTPUT_BIT(LED1, 0);
return;
}//apaga el led1
result = strcmp(recibido, LED2_ON);
if(result==0)
{
OUTPUT_BIT(LED2, 1);
return;
}
result = strcmp(recibido, LED2_OFF);
if(result==0)
{
OUTPUT_BIT(LED2, 0);
return;
}
result = strcmp(recibido, LED3_ON);
if(result==0)
{
OUTPUT_BIT(LED3, 1);
return;
}
result = strcmp(recibido, LED3_OFF);
if(result==0)
{
OUTPUT_BIT(LED3, 0);
return;
}
return;
}
}
void main()
{
enable_interrupts(int_rda);
enable_interrupts(global);
while(TRUE)
{
//TODO: User Code
}
}