domingo, 9 de agosto de 2015

Bluetooth com PIC 16F648A

Olá!
       Hoje vou mostrar como comunicar com um celular Android via Bluetooth, para isto vamos usar um modulo especifico para isso e que já contém toda a pilha e o protocolo bluetooth junto(o que facilita o trabalho).
       O modulo bluetooth funciona com uma interface RS232 com o microcontrolador, funciona como se fosse uma porta serial sem fio(pois no protocolo Bluetooth existe o suporte a esse tipo de dispositivo, pois poderíamos conectar como um dispositivo de áudio, vídeo, telefone ou quaisquer outra forma que é suportada pelo protocolo),para configurar velocidade da porta serial e outros detalhes do modulo é recomendável ler o datasheet, para conseguir entrar no modo de configuração(modo AT) basta ligar-ló com o botão da placa pressionado e o pino "EN" alimentado com +5V,após entrar no modo AT(o led passa a piscar a cada 1 segundo) é possível mudar varias configurações dele.Por padrão  a velocidade de comunicação é de 38400, 1 stopbit,sem paridade.
       Neste exemplo vou demonstrar como ligar e desligar um led além de testar um botão, tudo que é enviado ao microcontrolador é retornado pela porta serial, para isto fiz um programa que roda no android para testar essa funcionalidade do modulo bluetooth, este programa foi feito no "App Inventor 2"(clique aqui para pegar um print da tela de componentes,da tela de algoritmo e o aplicativo) que é um software que roda on line desenvolvido pela faculdade de Massachusetts, pretendo colocar mais uma aba no site para mostrar como está ficando o algoritmo, para instalar basta baixar o arquivo com extensão "apk"(bluetooth.apk), pode ser que dependendo do celular o aplicativo fique com os botões e textos diferentes devido a compatibilidade.
       Na figura a seguir tem um esquemático de como ficou a ligação do modulo ao microcontrolador 16F648A:

O código fonte do microcontrolador 16F648A:

/*
 *                                              Usando a interface bluetooth no MPlab XC8
 *
 * Compilador : MPlabXC8
 * Microcontrolador: 16F648A
 * Autor: aguivone
 * Versão: 1
 * Data :  05 de agosto de 2015
 */
#include <stdio.h>
#include <string.h> //para usar funçoes de string deve se adicionar este header
#include <stdlib.h>
#define _XTAL_FREQ 16000000    // cristal de 20 Mhz
#include <xc.h>
/////////////////////////////////////////////////////////configuraçôes//////////////////////////////////////////////////

#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is digital input, MCLR internally tied to VDD)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EE Memory Code Protection bit (Data memory code protection off)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

////////////////////////////////////////////////////Defines////////////////////////////////////////////////////////////////
#define LIGA_MODULO               PORTBbits.RB4
#define HAB_CFG_MOD               PORTBbits.RB5  //esse pino não será usado neste exemplo 
#define LED                       PORTBbits.RB6  
#define BOTAO                     PORTBbits.RB7  
////////////////////////////////////////////////variaveis globais///////////////////////////////////////////////////////////
char caracter,dados;
bit flag_interrupcao = 0;

/////////////////////////////////funçoes usadas pela uart //////////////////////////////////////////////////////
void inicializa_RS232(long velocidade,int modo)
{////por padrão é usado o modo 8 bits e sem paridade, mas se necessario ajuste aqui a configuração desejada.
    //verifique datasheet para ver a porcentagem de erro e se a velocidade é possivel para o cristal utilizado.
    RCSTA = 0X90;//habilita porta serial,recepção de 8 bit em modo continuo,assincrono.
    int valor;
        if(modo == 1)
        {//modo = 1 ,modo alta velocidade
         TXSTA = 0X24;//modo assincrono,trasmissao 8 bits.
         valor =(int)(((_XTAL_FREQ/velocidade)-16)/16);//calculo do valor do gerador de baud rate
        }
        else
        {//modo = 0 ,modo baixa velocidade
         TXSTA = 0X20;//modo assincrono,trasmissao 8 bits.
         valor =(int)(((_XTAL_FREQ/velocidade)-64)/64);//calculo do valor do gerador de baud rate
        }
    SPBRG = valor;
    RCIE = 1;//habilita interrupção de recepção
    TXIE = 0;//deixa interrupção de transmissão desligado(pois corre se o risco de ter uma interrupção escrita e leitura ao mesmo tempo)
}
void escreve_RS232(char valor)
{
    TXIF = 0;//limpa flag que sinaliza envio completo.
    TXREG = valor;
    while(TXIF ==0);//espera enviar caracter
}
void imprime_RS232(const char frase[])
{
     char indice = 0;
     char tamanho = strlen(frase);
      while(indice < tamanho ) ///veja que o programa pode travar se aqui não tiver as duas aspas
       {
           escreve_RS232(frase[indice]);
           indice++;
       }
}

///////////////////////////////////////////////////interrupção//////////////////////////////////////////////////////////////
void interrupt interrupcoes(void)//vetor de interrupção
 {
    if(RCIF)
    {//se interrupção de recepção da serial
     caracter = RCREG;
     int erro = 0;
     if(caracter == 'A')
     {//liga led
         LED = 1;
         escreve_RS232(caracter);//indica que ligou
     }
     if(caracter == 'B')
     {
         escreve_RS232(caracter);//indica que desligou
         LED = 0;
     }
     if((caracter != 'A')&&(caracter != 'B'))
     {
        escreve_RS232(caracter);//retorna o que leu
     }     
     flag_interrupcao = 1;
     RCIF = 0;//  limpa flag de interrupção de recepção
    }
 }
void espera_resposta()
{
        int tempo=0;
        while((caracter == 'Z')&&(tempo < 10))
        {//espera resposta ou 1s pra saber quando enviar o proximo dado
          __delay_ms(100);//tempo para entra no modo AT
          tempo++;
        }
        __delay_ms(100);//tempo para garantir todo envio;
}

//////////////////////////////////////////////////////Rotina principal///////////////////////////////////////////////////////////////

void main(void)
{
    TRISB = 0X82;//configura portB,  B1(pino RX) e B7 como entrada
    PORTB = 0;  // limpar as portas que estão configuradas como saidas  
    inicializa_RS232(38400,1);//Quando vai comunicar pelo modo "AT" precisa de estar neste valor de comunicação
    PEIE = 1;//habilita interrupção de perifericos do pic
    GIE = 1; //GIE: Global Interrupt Enable bit
    LIGA_MODULO = 0; //esse pino não será usado neste exemplo   
    for(;;)
    {
        if(BOTAO == 1)
        {
           imprime_RS232("Botão pressionado!");
           __delay_ms(500);//debouce
        }
    }//loop infinito
}

A Demonstração:




colocar o video aqui 

links para baixar os arquivos,clique aqui!


2 comentários :

  1. Bom dia!
    Sou de Içara - Santa Catarina, e gostaria de fazer uns teste com o Bluetooth, mas não sei nada de C, por acaso tens o arquivo .HEX, se tiver ficarei muito grato, pois trabalho com eletrônica e gostaria de me atualizar na área de conectividades.
    Se tiver outras informações sobre Bluetooth + PIC 16f628 ou 16F877A ficarei grato com sua ajuda.
    Grato, Odair - E-mail: osrtec@yahoo.com.br

    ResponderExcluir
  2. Digite AT+VERSION, se a versão for 3.0 ou maior tem que colocar a senha entre aspas, tipo AT+PSWD="senha" .

    Obervação: O Módulo Bluetooth HC-05 pode ser alimentado com 5V, mas os pinos de RX/TX trabalham com 3.3V. Por este motivo é altamente recomendado o uso de um Conversor de Nível Lógico: ele realizará as adequações de tensão (tanto de 5V para 3.3V, quanto o inverso) para que a comunicação ocorra corretamente.

    ResponderExcluir

olá,digite aqui seu comentário!