Fork me on GitHub

05/11/13

PIC: Módulo Bluetooth + Android

PIC: Módulo Bluetooth + Android



Neste post, falarei do módulo Bluetooth HC-06.



Este dispositivo é barato e fácil de usar. Deve ser alimentado com tensão de 3.6V até 6V e comunica com o microcontrolador via serial RS232 TTL. A velocidade padrão é de 9600 bps.

A ligação é simples. O pino RX do módulo é ligado ao pino TX do microcontrolador e o pino TX do módulo é ligado ao pino RX do microcontrolador.

Você pode enviar informações ao módulo bluetooth usando um adaptador bluetooth conectado ao PC ou utlizar um smartphone com Android.

BIBLIOTECA ( Para realizar a comunicação com o aplicativo para Android )
MikroC PRO PIC
#define MESSAGE_BUTTON 0xFF
#define MESSAGE_VOL_UP 0xFE
#define MESSAGE_VOL_DOWN 0xFD
#define MESSAGE_SEEKBAR 0xFC
#define MESSAGE_ACEL 0xFB

void BT_Init()
{
     UART1_Init( 9600 );
     delay_ms( 10 );
     RCIE_bit = 1;
     GIE_Bit = 1;
     PEIE_Bit = 1;
}

char BT_Read( char *msg )
{
char rd;
static char cnt = 0, tp = 0;
     if(RCIF_Bit)
     {
        RCIF_Bit = 0;

        rd = UART1_Read();
        
        if(tp == 0)
        {
         switch( rd )
         {
           case MESSAGE_BUTTON: tp = MESSAGE_BUTTON; break;
           case MESSAGE_VOL_UP: tp = MESSAGE_VOL_UP; break;
           case MESSAGE_VOL_DOWN: tp = MESSAGE_VOL_DOWN; break;
           case MESSAGE_ACEL: tp = MESSAGE_ACEL; break;
           case MESSAGE_SEEKBAR: tp = MESSAGE_SEEKBAR; break;
           default: tp = 0; break;
         }
           
           cnt = 0;
        }
        else
        {
             if(tp == MESSAGE_BUTTON)
             {
                 cnt++;
                 if(cnt == 1)
                 {
                     msg[1] = rd; //Button ID
                 }
                 else if(cnt == 2)
                 {
                    msg[2] = rd;  //Estado
                    msg[0] = MESSAGE_BUTTON;
                    tp = 0;
                    return 1;
                 }
             }
             else if(tp == MESSAGE_VOL_UP)
             {
                 msg[1] = rd;
                 msg[0] = MESSAGE_VOL_UP;
                 tp = 0;
                 return 1;
             }
             else if(tp == MESSAGE_VOL_DOWN)
             {
                 msg[1] = rd;
                 msg[0] = MESSAGE_VOL_DOWN;
                 tp = 0;
                 return 1;
             }
             else if(tp == MESSAGE_SEEKBAR)
             {
                cnt++;
                if(cnt == 1)
                 {
                      msg[1] = rd;
                 }
                 else if(cnt == 2)
                {
                      msg[2] = rd;
                      msg[0] = MESSAGE_SEEKBAR;
                      tp = 0;
                      return 1;
                }
             }
             else if(tp == MESSAGE_ACEL)
             {
                 cnt++;
                 if(cnt == 1)
                 {
                    msg[1] = rd; //Eixo X
                 }
                 else if(cnt == 2)
                 {
                    msg[2] = rd; // Eixo Y
                 }
                 else if(cnt == 3)
                 {
                    msg[3] = rd; // Eixo Z
                    msg[0] = MESSAGE_ACEL;
                    tp = 0;
                    return 1;
                 }
                 
             }
        }
        return 0;
     }
     else
     {
        return 0;
     }
     

}


EXEMPLO:
MikroC PRO PIC
//Copie e cole o código da biblioteca aqui

char Mensagem[4];

void Interrupt()
{
    if( BT_Read(&Mensagem) ) //recebeu todos os bytes? Sim!!
    {
       if(Mensagem[0] == MESSAGE_BUTTON)//recebeu um comando de um Botao?
       {
          if( Mensagem[1] == 1 )  //comando ( Byte 1 )
          {
             PORTA.F4 = Mensagem[2].B0; //valor ( Byte 2 )
          }
          else if(Mensagem[1] == 2)
          {
             PORTA.F5 = Mensagem[2].B0;
          }   
       }
    }
}

void main() 
{
    BT_Init();
    ADCON1 = 0x0F;
    TRISA = 0;
    PORTA = 0;
}

O código foi feito pra comunicar com um aplicativo para android. O aplicativo envia de 2 a 4 bytes de acordo com o tipo( botão, barra deslizante ou acelerômetro ). O PIC irá receber esse bytes através da interrupção da UART( serial ) e será tratada pela função BT_Read(). após isso o usuário desenvolverá o restante do código.

APLICATIVO
O Aplicativo que desenvolvi, utilizando o Android Studio, comunica-se com o microcontrolador via bluetooth, possui 6 botões de comando, uma barra deslizante, e  acelerômetro. Também é possível utilizar os botões de volume para enviar algum dado. Possui um campo destinado ao envio de uma string ou um byte.




COMANDOS ENVIADOS PELO APLICATIVO:
1.MESSAGE_BUTTON (0xFF)
Sintaxe: [0xFF][ID][STATE]
ID: Indica qual botão foi acionado ou um comando a ser enviado.
STATE: Indica o estado do botão ou um valor a ser enviado.

2.MESSAGE_VOL_UP (0xFE)
Sintaxe: [0xFE][Value]
Value: é um valor de 0 a 255

3.MESSAGE_VOL_DOWN (0xFD)
Sintaxe: [0xFD][Value]
Value: é um valor de 0 a 255

4.MESSAGE_SEEKBAR (0xFC)
Sintaxe: [0xFC][Value][Value]
Value: são dois bytes(MSB e LSB), com o valor atual do seekbar.

5.MESSAGE_ACEL (0xFB)
Sintaxe: [0xFB][X][Y][Z]
X, Y, Z: São os eixos. Varia de 0 a 100. O bit 7 indica se o valor é negativo.


DOWNLOAD
Aplicativo + código-fonte: ANDROIDTOPIC.rar



 NOVO APLICATIVO

57 comentários:

  1. Grande post. Parabéns, foi de grande ajuda!!!

    ResponderExcluir
  2. Amigo... Muito bom mesmo. Tenho uma dúvida. Quando vc diz para: //Cole o código aqui... (do exemplo).. vc quer dizer para colar o código da linha 01 até a 115 da biblioteca?

    ResponderExcluir
  3. Por acaso teria recebido um e-mail sobre a utilização de um display LCD junto ao DS18B20?

    ResponderExcluir
  4. Ola, to com um projeto identico a este, porem nao consigo receber dados do modulo, o pic que estou a utilizar é o 877a. consigo enviar dados mas nao receber, mais quando conecto o modulo a um max232 e comunico com o pc, funciona perfeitamente. Abraços..

    ResponderExcluir
    Respostas
    1. Boa tarde, estou com o mesmo problema que você. Conseguiu resolver?!

      Excluir
  5. Boa noite amigo, gostei muito do seu projeto, mas tenho uma dúvida quando envio um valor tipo 1 pelo botão enviar string funciona, mas pelo botão 1 colocando todos os valores = 1 não funka...

    ResponderExcluir
  6. Tenho uma pergunta amigo, conseguisse fazer receber dados enviados pelo modulo como o app (Bluetooth SPP) do playstore?
    Valeu, ja me ajudou muito

    ResponderExcluir
  7. Olá fiz a compilação do código , mas o mesmo apresenta erro na compilação , só consigo compilar quando comento as seguinte linha :

    if(Mensagem[0] == MESSAGE_BUTTON)//Se recebeu um comando de um Botao
    {
    //if((Mensagem[1] == 1 ) //comando/ ID
    {
    PORTA.F4 = Mensagem[2].B0; //Valor/ State
    }
    //else if(Mensagem[1] == 2)
    {
    PORTA.F5 = Mensagem[2].B0;

    ResponderExcluir
    Respostas
    1. "if((Mensagem[1] == 1 ) //comando/ ID"
      Tem um parentese sobrando aí...

      Excluir
  8. ola amigo gostei do seu post..
    queria saber se você poderia me enviar este simulador do hc-06 no proteus!!
    mesmo que for so imagem já me ajuda!!

    ResponderExcluir
    Respostas
    1. Eu tbm estou precisando de um hc-05 pro proteus...

      Excluir
  9. bom dia thiago tudo bem? adorei o seu blog, esta me ajudando muito voce esta de parabens.
    o thiago sera que voce nao teria este mesmo programa para o pic16f628a, pois estou fazendo um projeto para a escola e estamos usando ele com um modulo bluetooth. obrigado.

    ResponderExcluir
  10. Olá! Não entendo muito como funciona, poderiam me ajudar?

    ResponderExcluir
  11. Olá! Não entendo muito como funciona, poderiam me ajudar?

    ResponderExcluir
    Respostas
    1. Olá!
      O código foi feito pra comunicar com o aplicativo para android. O aplicativo envia de 2 a 4 bytes de acordo com o tipo( botão, barra deslizante ou acelerômetro ). O PIC irá receber esse bytes através da interrupção e será tratada pela função "BT_Read()". apos isso o usuário desenvolverá o restante do código.

      Excluir
    2. Hum.. estou começando a entender! Não estou conseguindo baixar o programa para instalar no celular, vc teria o ele em arquivo ou teria um outro site para baixar? Obrigado pela atenção! !!

      Excluir
  12. Em que variável ficam guardados os dados recebidos pelo pic??

    ResponderExcluir
    Respostas
    1. Obrigado pela resposta rápida... Estou a tentar colocar o texto enviado pelo Bluetoth do telemóvel para o pic e mostra-lo num display LCD....corre tudo quase perfeito.. eu escrevo caracteres do género...12345 ..e no display mostra sempre caracteres chineses...mandarim... sabe me dizer pk?

      Excluir
  13. Normalmente usando Bluetooth em celular, temos que tornar "visível"... parear, etc.... como faz para "dar um nome" ao HC-06? Ele fica visível sempre?

    ResponderExcluir
    Respostas
    1. Para renomear o módulo Bluetooth você deve enviar um comando via serial. Veja nesse Link os comandos disponíveis.
      Sim, ele ficará sempre visível.

      Excluir
  14. Olá Tiago, tudo bem? Ótimo post. Muito obrigado. Gostaria de um exemplo do que devo escrever no campo do "Enviar String" para ser a mesma coisa que o segundo botão está enviando, por exemplo.

    Obrigado novamente.

    ResponderExcluir
  15. Bom dia,

    Estou com uma tremenda duvida. O meu projeto funciona do seguinte modo. A partir de um aplicativo Android, clico um botão "ligar" e ele envia a letra 'a' para mim ou clico um botão "desligar" e ele envia a letra 'b' para mim. Meu programa em C deve receber essa letra e verificar as condicionais, ou seja, se a minha variavel 'char receb' tera valor igual a 'a' ou a 'b' e enviar sinal alto ou baixo para a porta desejada (exemplo: porta pin_b0); Neste caso, devo ainda sim utilizar essa biblioteca e o codigo ou devo fazer outro codigo? Caso possa me ajudar, segue email: mthsdiniz@gmail.com ou jdsferreira1@netsite.com.br

    Grato desde já.

    Atenciosamente,

    Matheus Diniz Ferreira
    Cursando Bacharelado em Engenharia de Computação

    ResponderExcluir
    Respostas
    1. Bom dia Matheus,
      Essa biblioteca serve justamente para esse propósito, que eh receber um comando e interpreta-lo.

      Excluir
    2. No meu caso, eu só iria utilizar o botão "message_button" ? Você teria algum exemplo que se encaixa ao meu programa? Receber 'a' ou 'b', realizar uma condicional e ligar ou desligar uma porta através da condicional

      Excluir
    3. Quando tento compilar ele da varios erros =s. Alguns erros estão na imagem do link abaixo:
      http://i62.tinypic.com/nv3w60.png
      Obrigado desde já.

      Excluir
    4. Quando voce clica em um botao ele envia 3 bytes ( 255, ID, VALOR )

      if(Mensagem[0] == MESSAGE_BUTTON) //recebeu um comando de um Botao?
      {
      if( Mensagem[1] == 1 ) //ID - qual botao foi pressionado
      {
      if( Mensagem[2] == 'a' )
      PORTB.B0 = 1; //liga alguma carga
      else if( Mensagem[2] == 'b' )
      PORTB.B0 = 0; //desliga alguma carga

      }
      }

      O link da imagem nao esta abrindo. veja que esse código deve ser compilador no MikroC PRO PIC.
      Abraços.

      Excluir
    5. Ok. Muito obrigado. Eu estava tentando usar o Pic C compiler, dando erro de inexistência de alguns comandos, como o comando "UART1_Read". Obrigado desde já!

      Excluir
    6. Realmente não entendo como seria essa implementação =/ Tentei mas não obtive sucesso. Você poderia me mostrar um código com esta implementação ja feita?
      email: mthsdiniz@gmail.com
      Obrigado desde já.

      atenciosamente

      Matheus Diniz

      Excluir
  16. ola, em primeiro lugar quero te desejar muito sucesso e que DEUS continue te abençoando, tenho uma perdida aqui
    para ligar um led no pino B7 !!!

    if(Mensagem[0] == MESSAGE_BUTTON) //recebeu um comando de um Botao?
    {
    if( Mensagem[1] == 1 ) //ID - qual botao foi pressionado
    {
    if( Mensagem[2] == 'a' )
    PORTB.B7 = 1;
    else if( Mensagem[2] == 'b' )
    PORTB.B7 = 0;

    eu nao entendi as letras 'a' e 'b'.
    obrigado.

    ResponderExcluir
    Respostas
    1. Olá!
      Quando receber um comando com a letra 'a' o led irá acender, caso receba um comando com a letra 'b' o led irá apagar...no lugar das letras pode utilizar um número qualquer se preferir.
      Abraços.

      Excluir
  17. Qual programa ,esquema de ligação e procedimentos para configurar o modulo Bluetooth ???

    ResponderExcluir
  18. olá, como faço para simular o hc05 no proteus?

    ResponderExcluir
  19. Ola, sou novato nessa area de programação e hardware, e gostaria de saber como faço para resolver o seguinte problema: Quando eu copio essa biblioteca e a colo no meu compilador, recebo a seguinte mensagem " A #DEVICE required before this line" E o problema aparece ser antes do void da biblioteca do modulo bluetooth. Como resolvo esse problema, por favor?? Outra coisa seria onde encontro o HC-06 no Proteus? Desde já agradeço !

    ResponderExcluir
  20. Muito bom mesmo, porém estou tentando adicionar mais botões no aplicativo, mas ele não compila, da erro na classe "Values" o que poderia ser? , também estou usando AndroidStudio

    ResponderExcluir
  21. Tem como usar esse aplicativo para receber dados do pic?

    ResponderExcluir
  22. Excelente tutorial. Muito bom mesmo. Mas gostaria de saber se teria como adaptar para o PIC16F877A e ainda, poderia dar um pequeno exemplo como funcionaria o BT_Read() acendendo um LED?
    Obrigado!

    ResponderExcluir
  23. Consigo usar outro PIC 16f877a com essa configuração que você passou de biblioteca e programação???

    ResponderExcluir
  24. Olá, estou trabalhando em um projeto com Bluetooth tbm, mas precisava de um módulo pequeno, acabei encontrando o módulo RF-BM-S02, mas estou com uma dificuldade muito grande de encontrar modulo adaptador para programá-lo. Vocês conhecem esse módulo? Poderia me indicar uma loja ou exemplo de algum projeto com o produto?

    ResponderExcluir
  25. Amigo, essa ligação não queima o módulo bluetooth já q o pic opera em 5v e o hc-06 opera em uma tensão de 3.3 na comunicação?

    ResponderExcluir
    Respostas
    1. na vdd queima, essa ligação queimou o meu, comprei outro e liguei com um divisor de tensão para ajustar atensão do pino rx para 3,3v

      Excluir
    2. Isso depende muito da fabricante. O meu suporta até 6V e está impresso no próprio módulo e em alguns datasheets que encontrei. Mas como são Xing Ling...

      Excluir
  26. Como implementar o código fonte do android para receber uma leitura enviada pelo microcontrolador?

    ResponderExcluir
  27. Olá, estou tentando enviar um array de bytes através do outputStream, porém utilizando um programa que eu mesmo escrevi. No entanto, eu peguei a sua função write(int cmd, byte[] value) como exemplo e modifiquei. Ela ficou assim :public void dadosEnvio(int cmd, byte[] value)
    {
    if(btSocket == null) return;
    try {
    outStream = btSocket.getOutputStream();
    } catch (Exception e) {}
    try {
    outStream.write(cmd);
    for (int i = 0; i < value.length; i++)
    {
    outStream.write(value[i]); //
    }

    } catch (Exception e) {}
    Toast.makeText(getApplicationContext(), "Erro ao enviar dados!", Toast.LENGTH_LONG).show();
    } Quando tento chamar essa função por meio de um botão, passando um cmd e um array de bytes ele da erro, talvez seja no outputstream. Como resolver isto ? Ele não trata o try e passa para a exceção.

    ResponderExcluir
  28. Agorá o erro sumiu, percebi que tinha colocado o toast depois do catch... Enfim, a mensagem de erro parou de aparecer. No entanto, eu continuo sem receber dados no pic, testei o codigo que fiz com o arduino e basicamente eu utilizo o mesmo esquema (btSocket) e outpustream para enviar dados. Porém eu não estou conseguindo receber nem um dado do tipo String, quanto mais um array de byte ou buffer. Poderia me ajudar?

    ResponderExcluir

Postagens Relacionadas!!