Bluetooth HC-05 comunicación simplex «digital», Pic C Compiler

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
   }

}
Scroll al inicio