Comunicación Bluetooth con los módulos HC-05

Tutorial con diferentes ejemplos de conexión Bluetooth entre diferentes dispositivos: PICs, Smartfone, sistemas embebidos, etc.

MICROCONTROLADORES

Biblioman

1/25/201315 min read

Ejemplos de conexión Bluetooth entre diferentes dispositivos: PICs, Smartfone, sistemas embebidos, etc. De manera fácil, con los módulos HC-05.

Características de los módulos HC-05

  • Chipset CSR BC417143

  • Bluetooth versión V2.0+EDR

  • Tensión de alimentación: 3.3V

  • Frecuencia: 2.4GHz banda ISM

  • Modulación: GFSK (Gaussian Frequency Shift Keying)

  • Seguridad: Autentificación y encriptación.

  • Velocidad-> Asíncrono: 2.1Mbps (Max) / 160 kbps ; Síncrono: 1Mbps/1Mbps

  • Soporta comandos AT para configuración a través de un puerto serie.

  • Configuración por defecto para el puerto COM: 9600, N, 8,1

  • Temperatura de trabajo: -20 ºC a +75 ºC

  • Dimensiones: 26.9mm x 13mm x 2.2 mm

1º Ejemplo: Bluetooth con HC-05 + BeagleBoard-XM + GPIO + Qt

Comunicación desde un smartphone (HTC Desire C) con S.O Android 4 por bluetooth con el módulo HC-05 configurado como esclavo, este a su vez está conectado a través del puerto serie a la BeagleBoard-XM. La interfaz de usuario con la BeagleBoard es una aplicación de escritorio hecha en Qt y compilada para la plataforma ARM, también está configurado el puerto GPIO de la BeagleBoard de tal forma que cuando se envío un comando desde la aplicación del teléfono (hecha con Basic4android) me muestre el comando enviado (números) en un display de 7 segmentos.

Código Principal aplicación BeagleBoard en Qt:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

// Esta conexión es la que cada vez que se recibe un dato por el puerto serie se me
//ejecuta el slot_newDataReceive

serialPort=serialPort = new ManageSerialPort;
connect(serialPort, SIGNAL(newDataReceived(const QByteArray &)), this, SLOT(slot_newDataReceived(const QByteArray &)));

// Controles puerto serie, en este caso la parte de Windows no se utiliza
#ifdef TTYWIN_
ui->comboBoxPortName->addItem("COM1", QVariant::fromValue(QString("COM1")));
ui->comboBoxPortName->addItem("COM2", QVariant::fromValue(QString("COM2")));
ui->comboBoxPortName->addItem("COM3", QVariant::fromValue(QString("COM3")));
ui->comboBoxPortName->addItem("COM4", QVariant::fromValue(QString("COM4")));
ui->comboBoxPortName->addItem("COM5", QVariant::fromValue(QString("COM5")));
ui->comboBoxPortName->addItem("COM6", QVariant::fromValue(QString("COM6")));
ui->comboBoxPortName->addItem("COM7", QVariant::fromValue(QString("COM7")));
ui->comboBoxPortName->addItem("COM8", QVariant::fromValue(QString("COM8")));
ui->comboBoxPortName->setCurrentIndex(0); //COM1
#endif

#ifdef TTYPOSIX_
ui->comboBoxPortName->addItem("ttyS0", QVariant::fromValue(QString("/dev/ttyS0")));
ui->comboBoxPortName->addItem("ttyS1", QVariant::fromValue(QString("/dev/ttyS1")));
ui->comboBoxPortName->addItem("ttyS2", QVariant::fromValue(QString("/dev/ttyS2")));
ui->comboBoxPortName->addItem("ttyS3", QVariant::fromValue(QString("/dev/ttyS3")));
ui->comboBoxPortName->addItem("ttyS4", QVariant::fromValue(QString("/dev/ttyS4")));
ui->comboBoxPortName->addItem("ttyS5", QVariant::fromValue(QString("/dev/ttyS5")));
ui->comboBoxPortName->addItem("ttyS6", QVariant::fromValue(QString("/dev/ttyS6")));
ui->comboBoxPortName->addItem("ttyS7", QVariant::fromValue(QString("/dev/ttyS7")));
ui->comboBoxPortName->addItem("ttyACM0", QVariant::fromValue(QString("/dev/ttyACM0")));
ui->comboBoxPortName->addItem("ttyACM1", QVariant::fromValue(QString("/dev/ttyACM1")));
ui->comboBoxPortName->addItem("ttyUSB0", QVariant::fromValue(QString("/dev/ttyUSB0")));
ui->comboBoxPortName->addItem("ttyUSB1", QVariant::fromValue(QString("/dev/ttyUSB1")));
ui->comboBoxPortName->setCurrentIndex(2); //ACM0
#endif

ui->comboBoxBaudRate->addItem("110", QVariant::fromValue(BAUD110));
ui->comboBoxBaudRate->addItem("300", QVariant::fromValue(BAUD300));
ui->comboBoxBaudRate->addItem("600", QVariant::fromValue(BAUD600));
ui->comboBoxBaudRate->addItem("1200", QVariant::fromValue(BAUD1200));
ui->comboBoxBaudRate->addItem("2400", QVariant::fromValue(BAUD2400));
ui->comboBoxBaudRate->addItem("4800", QVariant::fromValue(BAUD4800));
ui->comboBoxBaudRate->addItem("9600", QVariant::fromValue(BAUD9600));
ui->comboBoxBaudRate->addItem("19200", QVariant::fromValue(BAUD19200));
ui->comboBoxBaudRate->addItem("38400", QVariant::fromValue(BAUD38400));
ui->comboBoxBaudRate->addItem("57600", QVariant::fromValue(BAUD57600));
ui->comboBoxBaudRate->addItem("115200", QVariant::fromValue(BAUD115200));
ui->comboBoxBaudRate->addItem("128000", QVariant::fromValue(BAUD128000));
ui->comboBoxBaudRate->addItem("256000", QVariant::fromValue(BAUD256000));
ui->comboBoxBaudRate->setCurrentIndex(6); //115200 bauds

ui->comboBoxDataBits->addItem("5", QVariant::fromValue(DATA_5));
ui->comboBoxDataBits->addItem("6", QVariant::fromValue(DATA_6));
ui->comboBoxDataBits->addItem("7", QVariant::fromValue(DATA_7));
ui->comboBoxDataBits->addItem("8", QVariant::fromValue(DATA_8));
ui->comboBoxDataBits->setCurrentIndex(3); //8 bit

ui->comboBoxParity->addItem("Ninguna", QVariant::fromValue(PAR_NONE));
ui->comboBoxParity->addItem("Par", QVariant::fromValue(PAR_EVEN)); //pair
ui->comboBoxParity->addItem("Impar", QVariant::fromValue(PAR_ODD)); //impair
ui->comboBoxParity->addItem("Space", QVariant::fromValue(PAR_SPACE));
ui->comboBoxParity->setCurrentIndex(0); //Parity none

ui->comboBoxStopBits->addItem("1", QVariant::fromValue(STOP_1));
ui->comboBoxStopBits->addItem("2", QVariant::fromValue(STOP_2));
ui->comboBoxStopBits->setCurrentIndex(0); //1 stop bit

ui->comboBoxFlowControl->addItem("Ninguno", QVariant::fromValue(FLOW_OFF));
ui->comboBoxFlowControl->addItem("Xon/Xoff", QVariant::fromValue(FLOW_XONXOFF));
ui->comboBoxFlowControl->addItem("Hardware", QVariant::fromValue(FLOW_HARDWARE));
ui->comboBoxFlowControl->setCurrentIndex(0); //Flow control none

//Connexión con los botones de abrir, cerrar y enviar del puerto serie
connect(ui->pushButtonOpen, SIGNAL(clicked()), this, SLOT(slot_openPort()));
connect(ui->pushButtonClose, SIGNAL(clicked()), this, SLOT(slot_closePort()));
connect(ui->pushButtonSend, SIGNAL(clicked()), this, SLOT(slot_sendPort()));

}

MainWindow::~MainWindow()
{
delete ui;
}


void MainWindow::slot_openPort()
{
ui->groupBoxSettings->setEnabled(false);
ui->pushButtonOpen->setEnabled(false);
ui->pushButtonClose->setEnabled(true);
ui->pushButtonSend->setEnabled(true);

if (serialPort->isOpen())
serialPort->close();

//Parámetros de configuración del puerto, según las opciones seleccionadas en los
//controles
QVariant temp;

temp = ui->comboBoxPortName->itemData(ui->comboBoxPortName->currentIndex());
serialPort->setPort(temp.value<QString>()); //Puerto

temp = ui->comboBoxBaudRate->itemData(ui->comboBoxBaudRate->currentIndex());
serialPort->setBaudRate(temp.value<BaudRateType>()); //BaudRate

temp = ui->comboBoxDataBits->itemData(ui->comboBoxDataBits->currentIndex());
serialPort->setDataBits(temp.value<DataBitsType>()); //Nº de bits

temp = ui->comboBoxParity->itemData(ui->comboBoxParity->currentIndex());
serialPort->setParity(temp.value<ParityType>()); //Pariedad

temp = ui->comboBoxStopBits->itemData(ui->comboBoxStopBits->currentIndex());
serialPort->setStopBits(temp.value<StopBitsType>()); //Bits de parada

temp = ui->comboBoxFlowControl->itemData(ui->comboBoxFlowControl->currentIndex());
serialPort->setFlowControl(temp.value<FlowType>()); //Control de flujo

serialPort->setTimeout(0, 10);
serialPort->enableSending();
serialPort->enableReceiving();

serialPort->open();
serialPort->receiveData();
};

void MainWindow::slot_closePort()
{
serialPort->close();

ui->groupBoxSettings->setEnabled(true);
ui->pushButtonOpen->setEnabled(true);
ui->pushButtonClose->setEnabled(false);
ui->pushButtonSend->setEnabled(false);
};

void MainWindow::slot_sendPort()
{
QString Message;
Message =ui->lineEditSend->text();

//Añadimos el carácter retorno de carro y nueva línea al mensaje a enviar
//necesarios para el módulo HC-05

Message += "\x0D";//Retorno de carro
Message += "\x0A";//Nueva Línea

QByteArray temp(Message.toUtf8());
serialPort->sendData(temp);

ui->lineEditSend->clear();
}

//Slot para recibir los datos por el puerto serie.
void MainWindow::slot_newDataReceived(const QByteArray &dataReceived)
{
//Comprobamos el valor guardado en la posición cero del Array
//para mostrar su valor en el display y enviar el estado de los
//bits al display de 7 segmentos.

dato=dataReceived;

if (dato[0]=='0')
{
PuestaCero();//reseteamos el display conectado al puerto GPIO
ui->lcdNumber->display(0);
system("echo 1 >/sys/class/gpio/gpio132/value");
system("echo 1 >/sys/class/gpio/gpio138/value");
system("echo 1 >/sys/class/gpio/gpio134/value");
system("echo 1 >/sys/class/gpio/gpio136/value");
system("echo 1 >/sys/class/gpio/gpio135/value");
system("echo 1 >/sys/class/gpio/gpio133/value");
}

if (dato[0]=='1')
{
PuestaCero();
ui->lcdNumber->display(1);
system("echo 1 >/sys/class/gpio/gpio136/value");
system("echo 1 >/sys/class/gpio/gpio138/value");
}

if (dato[0]=='2')
{
PuestaCero();
ui->lcdNumber->display(2);
system("echo 1 >/sys/class/gpio/gpio132/value");
system("echo 1 >/sys/class/gpio/gpio136/value");
system("echo 1 >/sys/class/gpio/gpio137/value");
system("echo 1 >/sys/class/gpio/gpio134/value");
system("echo 1 >/sys/class/gpio/gpio135/value");
}

if (dato[0]=='3')
{
PuestaCero();
ui->lcdNumber->display(3);
system("echo 1 >/sys/class/gpio/gpio132/value");
system("echo 1 >/sys/class/gpio/gpio136/value");
system("echo 1 >/sys/class/gpio/gpio138/value");
system("echo 1 >/sys/class/gpio/gpio137/value");
system("echo 1 >/sys/class/gpio/gpio135/value");
}
if (dato[0]=='4')
{
PuestaCero();
ui->lcdNumber->display(4);
system("echo 1 >/sys/class/gpio/gpio136/value");
system("echo 1 >/sys/class/gpio/gpio138/value");
system("echo 1 >/sys/class/gpio/gpio137/value");
system("echo 1 >/sys/class/gpio/gpio133/value");
}

if (dato[0]=='5')
{
PuestaCero();
ui->lcdNumber->display(5);
system("echo 1 >/sys/class/gpio/gpio132/value");
system("echo 1 >/sys/class/gpio/gpio133/value");
system("echo 1 >/sys/class/gpio/gpio137/value");
system("echo 1 >/sys/class/gpio/gpio138/value");
system("echo 1 >/sys/class/gpio/gpio135/value");
}

if (dato[0]=='6')
{
PuestaCero();
ui->lcdNumber->display(6);
system("echo 1 >/sys/class/gpio/gpio132/value");
system("echo 1 >/sys/class/gpio/gpio133/value");
system("echo 1 >/sys/class/gpio/gpio138/value");
system("echo 1 >/sys/class/gpio/gpio135/value");
system("echo 1 >/sys/class/gpio/gpio134/value");
system("echo 1 >/sys/class/gpio/gpio137/value");
}

if (dato[0]=='7')
{
PuestaCero();
ui->lcdNumber->display(7);
system("echo 1 >/sys/class/gpio/gpio132/value");
system("echo 1 >/sys/class/gpio/gpio136/value");
system("echo 1 >/sys/class/gpio/gpio138/value");
}
if (dato[0]=='8')
{
PuestaCero();
ui->lcdNumber->display(8);
system("echo 1 >/sys/class/gpio/gpio132/value");
system("echo 1 >/sys/class/gpio/gpio133/value");
system("echo 1 >/sys/class/gpio/gpio134/value");
system("echo 1 >/sys/class/gpio/gpio135/value");
system("echo 1 >/sys/class/gpio/gpio136/value");
system("echo 1 >/sys/class/gpio/gpio137/value");
system("echo 1 >/sys/class/gpio/gpio138/value");
}

if (dato[0]=='9')
{
PuestaCero();
ui->lcdNumber->display(9);
system("echo 1 >/sys/class/gpio/gpio132/value");
system("echo 1 >/sys/class/gpio/gpio136/value");
system("echo 1 >/sys/class/gpio/gpio138/value");
system("echo 1 >/sys/class/gpio/gpio137/value");
system("echo 1 >/sys/class/gpio/gpio133/value");
}
//con esta variable concatenamos todos los datos recibidos
allDataReceived += dataReceived;

//vamos moviendo el cursor para que no se sobreescriban los caracteres
ui->textEditReceive->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);

//Muestro en la caja de texto los caracteres recibidos
QString Texto = dataReceived;
ui->textEditReceive->insertPlainText(Texto);
}

//Configuro para escritura y como pines de salida los pines a utilizar en el puerto GPIO
void MainWindow::on_pushButton_clicked()
{

system("echo 132 >/sys/class/gpio/export");
system("echo out >/sys/class/gpio/gpio132/direction");

system("echo 133 >/sys/class/gpio/export");
system("echo out >/sys/class/gpio/gpio133/direction");

system("echo 134 >/sys/class/gpio/export");
system("echo out >/sys/class/gpio/gpio134/direction");

system("echo 135 >/sys/class/gpio/export");
system("echo out >/sys/class/gpio/gpio135/direction");

system("echo 136 >/sys/class/gpio/export");
system("echo out >/sys/class/gpio/gpio136/direction");

system("echo 137 >/sys/class/gpio/export");
system("echo out >/sys/class/gpio/gpio137/direction");

system("echo 138 >/sys/class/gpio/export");
system("echo out >/sys/class/gpio/gpio138/direction");

}

//para liberar los pines
void MainWindow::on_pushButton_2_clicked()
{
system("echo 132 >/sys/class/gpio/unexport");
system("echo 133 >/sys/class/gpio/unexport");
system("echo 134 >/sys/class/gpio/unexport");
system("echo 135 >/sys/class/gpio/unexport");
system("echo 136 >/sys/class/gpio/unexport");
system("echo 137 >/sys/class/gpio/unexport");
system("echo 138 >/sys/class/gpio/unexport");

}
//Pone a cero todos los leds del Display conectado al puerto GPIO
void MainWindow::PuestaCero()
{
system("echo 0 >/sys/class/gpio/gpio132/value");
system("echo 0 >/sys/class/gpio/gpio133/value");
system("echo 0 >/sys/class/gpio/gpio134/value");
system("echo 0 >/sys/class/gpio/gpio135/value");
system("echo 0 >/sys/class/gpio/gpio136/value");
system("echo 0 >/sys/class/gpio/gpio137/value");
system("echo 0 >/sys/class/gpio/gpio138/value");

}

Foto de la aplicación:

Nota (1): Los módulos HC-05 vienen configurados de fábrica como esclavos, con el nombre de dispositivo: HC-05 y la clave: 1234.

Nota (2): La aplicación en Android está hecha con Basic4Android la página oficial.

Un vídeo de la demo funcionando:

2º Ejemplo: Comandando el motor de una lavadora con el Smartphone


En este ejemplo la comunicación es entre el Smartphone y un microcontrolador PIC. El módulo HC-05 conectado al PIC está configurado como esclavo y el celular hace de maestro para establecer una comunicación bidireccional entre ambos.

Esquema del circuito:

Código fuente del PIC:

////////////////////////////////////////////////////////////
// //
// Ejemplo (2) HC-05 Configurado como esclavo y conectado //
// a un PIC a través del puerto serie. //
// Autor: Biblioman //
// www.aquihayapuntes.com //
// //
////////////////////////////////////////////////////////////

#include <16F877.h>
#device ICD=TRUE
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use FAST_IO(B)
#use FAST_IO(C)

void main(void)
{
char valor=0;
SET_TRIS_B(0x00);
while(TRUE)
{
valor=getch();
switch (valor){
case '1'://On
output_bit( PIN_B1, 0);//Orden de arranque al motor
delay_ms(100);
break;
case '0': //Off
output_bit( PIN_B1, 1);//Orden de parada al motor
delay_ms(100);
break;
case '\n':
break;
default:
printf("Comando incorrecto, prueba de nuevo\r\n"); //Respuesta del PIC hacia el móvil
break;
}
}
}

Un vídeo de la demo funcionando:

Nota: en la imagen de arriba hay un error, el adaptador de niveles tiene que ser un MAX3232 para que sea compatible con los niveles de 3.3 V del módulo HC-05.

Los módulos HC-05 tienen dos modos de funcionamiento:

1. Funcionamiento normal o modo comunicación: este es el modo en que el módulo trabajará normalmente una vez configurado como Maestro o Esclavo.

2. Modo configuración o comandos AT: es el modo que utilizaremos cada vez que queramos configurar los módulos a través de los diferentes comandos AT que acepta.

Los pines 31 y 32 del módulo HC-05 llevan conectados dos leds a través de dos resistencias de 470 Ω para indicar los modos de funcionamiento de este.

  • Led conectado al PIN31: parpadeo lento (1 Hz) indicación de que el módulo está en modo comandos AT. Parpadeo rápido (2 Hz) indica modo comunicación intentando vincularse a otro dispositivo. Doble parpadeo por segundo indica de que el dispositivo se ha vinculado y está listo para comunicarse.

  • Led conectado al PIN32: antes de vincularse esta apagado, después de la sincronización esta encendido.

Las indicaciones de los Leds son iguales tanto si el módulo está configurado como maestro o como esclavo.

Para entrar en modos comandos AT al encender el módulo el Pin 34 tiene que estar conectado a un potencial positivo (3,3 V) tal y como se ve en la figura de arriba. El envío de comandos AT se realiza a través del puerto serie y un adaptador de niveles MAX3232, en el PC se utiliza una aplicación de escritorio como el Hyperterminal o la Terminal.

Los comandos deben de terminar con los caracteres retorno de carro y nueva línea: “\r\h” (HEX: 0x0D 0x0A). La configuración del puerto serie en modo comandos tiene que ser la que se muestra en la figura de abajo (38400, 8, 1):

3º Ejemplo: Configurando el módulo Bluetooth HC-05 como Master

Como se ha comentado ya los módulos HC-05 vienen configurados de fábrica como esclavos. La configuración como master se realiza a través de comandos AT. Para ello montaremos el siguiente circuito:

Los comandos que utilizaremos son los siguientes:

  • Comprobar conexión: at

  • Configuración como maestro: at+role=1

  • Conecta el módulo a una MAC específica: at+cmode=0

  • Conecta a la dirección MAC del esclavo: at+bind=12,8,272504

  • para saber la dirección MAC del dispositivo: at+addr?

  • para saber la configuración del puerto en modo comunicación: at+uart?


La respuesta de este último comando nos da la configuración del puerto serie en modo comunicación:

AT+ UART?
+UART:9600,0,0
OK

El significado de los parámetros es el siguiente:

+ UART :< Param1 >,< Param2 >,< Param3>

Param1 (Baud rate( bits/s): 4800, 9600,19200, 38400, 57600, 115200, 230400, 460800, 921600,1382400

Param2 (Bits de parada): 0-> 1 bit, 1-> 2 bit

Param3 (Bit de paridad): 0-> Ninguna, 1-> Impar, 2->Par

El vídeo:

4º Ejemplo: Comunicación Bluetooth entre dos Microcontroladores

Este último ejemplo consiste en controlar un motor paso a paso unipolar por medio de Bluetooth. El módulo que se conecta como master al PIC es el que recibe los comandos para el control del motor, el receptor conectado como esclavo a otro PIC recibe las instrucciones para gobernar un pequeño motor paso a paso (28BYJ-48).

Esquema del circuito:

Fotos de la Demo:

Código fuente de los PICs:

  • Maestro:

///////////////////////////////////////////////////////////
// Ejemplo (4) HC-05 Configurado como Maestro y conectado
// a un PIC a través del puerto serie.
// Autor: Biblioman
// www.aquihayapuntes.com
//////////////////////////////////////////////////////////

#include <16F877.h>
#device ICD=TRUE
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#bit DERECHA = 0x08.0
#bit MARCHA = 0x08.1
#bit RAPIDO = 0x08.2
#bit PASO = 0x08.3

void main(void)
{

while(TRUE){


if ((MARCHA==0)&&(DERECHA==0)&&(RAPIDO==0)&&(PASO==0)){
printf("a");//Motor parado
delay_ms(500);
}
if ((MARCHA==0)&&(DERECHA==0)&&(RAPIDO==0)&&(PASO==1)){
printf("b");//Marcha Manual lenta izquierda
delay_ms(500);
}
if ((MARCHA==0)&&(DERECHA==0)&&(RAPIDO==1)&&(PASO==0)){
printf("c");//Motor parado
delay_ms(500);
}
if ((MARCHA==0)&&(DERECHA==0)&&(RAPIDO==1)&&(PASO==1)){
printf("d");//Marcha manual rápida izquierda
delay_ms(500);
}
if ((MARCHA==0)&&(DERECHA==1)&&(RAPIDO==0)&&(PASO==0)){
printf("e");//Motor parado
delay_ms(500);
}
if ((MARCHA==0)&&(DERECHA==1)&&(RAPIDO==0)&&(PASO==1)){
printf("f");//Marcha manual lenta derecha
delay_ms(500);
}
if ((MARCHA==0)&&(DERECHA==1)&&(RAPIDO==1)&&(PASO==0)){
printf("g");//Motor parado
delay_ms(500);
}
if ((MARCHA==0)&&(DERECHA==1)&&(RAPIDO==1)&&(PASO==1)){
printf("h");//Marcha manual rápida derecha
delay_ms(500);
}
if ((MARCHA==1)&&(DERECHA==0)&&(RAPIDO==0)&&(PASO==0)){
printf("A");//Marcha Automática lenta izquierda
delay_ms(500);
}
if ((MARCHA==1)&&(DERECHA==0)&&(RAPIDO==0)&&(PASO==1)){
printf("B");//Marcha Automática lenta izquierda
delay_ms(500);
}
if ((MARCHA==1)&&(DERECHA==0)&&(RAPIDO==1)&&(PASO==0)){
printf("C");//Marcha Automática rápida izquierda
delay_ms(500);
}
if ((MARCHA==1)&&(DERECHA==0)&&(RAPIDO==1)&&(PASO==1)){
printf("D");//Marcha Automática rápida izquierda
delay_ms(500);
}
if ((MARCHA==1)&&(DERECHA==1)&&(RAPIDO==0)&&(PASO==0)){
printf("E");//Marcha Automática lenta derecha
delay_ms(500);
}
if ((MARCHA==1)&&(DERECHA==1)&&(RAPIDO==0)&&(PASO==1)){
printf("F");//Marcha Automática lenta derecha
delay_ms(500);
}
if ((MARCHA==1)&&(DERECHA==1)&&(RAPIDO==1)&&(PASO==0)){
printf("G");//Marcha Automática rápida derecha
delay_ms(500);
}
if ((MARCHA==1)&&(DERECHA==1)&&(RAPIDO==1)&&(PASO==1)){
printf("H");//Marcha Automática rápida derecha
delay_ms(500);
}
}
}

  • Esclavo:

///////////////////////////////////////////////////////////
// Ejemplo (4) HC-05 Configurado como esclavo y conectado
// a un PIC a través del puerto serie.
// Autor: Biblioman
// www.aquihayapuntes.com
//////////////////////////////////////////////////////////

#include <16F877.h>
#device ICD=TRUE
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use FAST_IO(B)
#use FAST_IO(C)
#byte FASES= 0x06
int velocidad=300;
void GiroDerecha(){
FASES=0b000110; //paso 1
delay_ms(velocidad);
FASES=0b000011; //paso 2
delay_ms(velocidad);
FASES=0b001001; //paso 3
delay_ms(velocidad);
FASES=0b001100; // paso 4
delay_ms(velocidad);
}
void GiroIzquierda(){
FASES=0b001100; //paso 1
delay_ms(velocidad);
FASES=0b001001; //paso 2
delay_ms(velocidad);
FASES=0b000011; //paso 3
delay_ms(velocidad);
FASES=0b001100; // paso 4
delay_ms(velocidad);
}
void main(void)
{
char valor=0;
SET_TRIS_B(0x00);
while(TRUE){
if(kbhit())
valor=getc();
switch (valor){
case 'a'://motor parado
FASES=0b000000;
break;

case 'b': //Marcha Manual Lenta Izquierda
velocidad=10;
GiroIzquierda();
break;

case 'c': //Motor parado
FASES=0b000000;
break;

case 'd': //Marcha manual rápida izquierda
velocidad=3;
GiroIzquierda();
break;

case 'e': //Motor parado
FASES=0b000000;
break;

case 'f': //Marcha manual lenta derecha
velocidad=10;
GiroDerecha();
break;

case 'g': //Motor parado
FASES=0b000000;
break;

case 'h': //Marcha manual rápida derecha
velocidad=3;
GiroDerecha();
break;

case 'A': //Marcha Automática lenta izquierda
velocidad=10;
GiroIzquierda();
break;

case 'B': //Marcha Automática lenta izquierda
velocidad=10;
GiroIzquierda();
break;

case 'C': //Marcha Automática rápida izquierda
velocidad=3;
GiroIzquierda();
break;

case 'D': //Marcha Automática rápida izquierda
velocidad=3;
GiroIzquierda();
break;

case 'E': //Marcha automática lenta derecha
velocidad=10;
GiroDerecha();
break;
case 'F': //Marcha automática lenta derecha
velocidad=10;
GiroDerecha();
break;

case 'G': //Marcha automática rápida derecha
velocidad=3;
GiroDerecha();
break;

case 'H': //Marcha automática rápida derecha
velocidad=3;
GiroDerecha();
break;
case '\n':
break;

default:
velocidad=15;
break;
}

}
}

El vídeo:

Nota (3): Las resistencia que van conectadas a los pines 32 y 31 y a los Leds indicadores del modo de funcionamiento del módulo son de 470 Ω en vez de los 10 KΩ que aparecen en los esquemas.

Nota (4): El pin UART_RXD (2) no tiene resistencia pull-up en el módulo HC-05 por lo que hay que habilitar la pull-up en el pin del PIC o poner una resistencia externa de 10 k tal y como se muestran en los esquemas.

Fuentes de información

http://es.wikipedia.org/wiki/Bluetooth
http://www.wavesen.com/products.asp?pId=3
http://www.ccsinfo.com/

Y hasta aquí mis experiencias con los módulos HC-05 …espero que os sean de utilidad.


Un saludo y hasta la próxima