Siguenos en ...

Google+facebooktwitter

youtubepinterest RSS aquihayapuntes

Últimos Tutoriales

Licencia

Creative Commons

 

Todo el contenido de este sitio está bajo una licencia de Creative Commons

 

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

Bluetooth_Hc-05Ejemplos 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

Módulo HC-05

 

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.

 

Ejemplo Beagleboard + Android + Qt

 

BeagleBoard GPIO

 

Aplicación Android

 

 

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 _TTY_WIN_ 
  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 _TTY_POSIX_ 
  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:

 

 

Aplicación BeagleBoard 

 

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 y está basada en el ejemplo Demo que trae el IDE para la comunicación con el puerto serie. No se publica el código fuente aquí porque dichas demos no son libres, hay que haber adquirido el software para tener acceso a ellas a través del foro de la página oficial.   
 

Un vídeo de la demo funcionando:
 


 

© 2007-2017 AquiHayapuntes.com