Tecnologias Bluetooth são comumente aplicadas em objetos do nosso dia a dia, transmitindo informações de forma ágil e descomplicada, sem haver a necessidade de cabos ou de ajustar o módulo em uma determinada posição. Essa interface será uma das opções mais seguras em redes de atuações pessoais (PAN), fornecendo uma conexão sem riscos de invasões e furtos de dados. Módulos HC-05 são conhecidos por estabelecer uma conexão sem fio facilmente programável, possibilitando uma interação entre diferentes tipos de dispositivos, com um alcance médio de até 30 metros em espaço aberto (sem obstáculos). Diferente de outros módulos como HC-06, este modelo poderá ser configurado como Master (mestre), Slave (escravo), e Loopback, adaptando-se as necessidades do programador. A diferença entre cada modo operacional será:

  • Master: Estabelece conexão com outros dispositivos e envia informações;
  • Slave: Apenas recebe as informações enviadas pelo Master;
  • Loopback: Consegue receber informações do Master e depois retorna-las ao mesmo.  

           Neste post iremos explorar algumas opções de configuração, ajustando os parâmetros de funcionamento do módulo de acordo com as necessidades de cada atividade proposta, construindo exemplos de programações voltados á comunicação sem fio entre dispositivos.

          Para concluir as atividades desse post, tenha em mãos os seguintes componentes:

          Você pode compra-los clicando nos links acima ou visitando nosso site: www.curtocircuito.com.br.


Pinagem do Módulo

            Antes de aplicar comunicação Bluetooth em qualquer projeto, será necessário conhecer ao menos um pouco sobre a pinagem e algumas funções básicas, afinal, qualquer ajuste de funcionamento que queira configurar irá lidar com o nível lógico de algum pino específico, pressionar o botão durante um determinado período de tempo, ou até mesmo observar o piscar do LED embutido no próprio módulo. Na imagem a seguir, podemos observar os terminais e principais componentes embutidos em um HC05.


Os pinos STATE e EN serão aplicados a configuração dos parâmetros de funcionamento do módulo.

             O funcionamento do dispositivo em si exigirá apenas quatro terminais, a alimentação (5V e GND) e a comunicação Serial (RX-TX). O terminal EN alterna entre o recebimento de informações (padrão) e o modo de configuração, onde será definida a atuação do componente (entre mestre e escravo), velocidade de transmissão, nome, senha, etc. O pino STATE estará conectado diretamente com LED, indicando o status de conexão do módulo através da velocidade entre cada piscar, por exemplo:

  • Piscar lento (2 segundos): Configurações Comandos AT;
  • Piscar rápido (meio segundo): Procurando conexão;
  • Pisca moderado (1 segundo): Conectado.             

            Se conecta-lo diretamente a um Arduino, por exemplo, possivelmente irá operar em modo Slave, com algumas opções básicas como velocidade e conectividade configuradas de forma padrão. Os ajustes de funcionalidade do componente serão operados via comandos AT, que poderão ser acessados por sistemas de comunicação serial como Termite, ou de forma mais simples através do monitor serial disponível pela IDE do Arduino.


Comandos AT via Arduino

           A linguagem AT poderá ser aplicada em uma grande variedade de componentes, devido a isso nem todos os comando existentes serão aceitos pelo HC05, em alguns testes e pesquisas observamos divergências entre as versões de firmware do módulo. Na versão 3.0, por exemplo, existem duas formas de ativar o modo AT, e dependendo de como o estiver o nível lógico do pino EN, alguns comandos poderão ser recusados. Mas não vamos nos aprofundar nisso por enquanto. Para configurar o HC05 optamos por utilizar a IDE do Arduino, portanto, tenha em mão o software programação disponível gratuitamente no site Arduino.cc.

          Na construção do circuito elétrico, interligue as fileiras de alimentação do Protoboard, em seguida conecte aos pinos GND e 5V do Arduino como mostra o exemplo a seguir.


Alimente o Protoboard nos terminais 5V e GND da placa Arduino.

            Os terminais de controle digitais ou analógicos do Arduino irão fornecer uma tensão de 5V, porém, no pino RX haverá a necessidade de construir um divisor de tensão reduzindo o valor para no máximo 3,3V, caso contrário poderá ocorrer alguma avaria no funcionamento do componente. No exemplo apresentado abaixo, conectamos um jumper entre o RX e dois resistores de 1KΩ, um resistor encaixado no GND, e outro diretamente no Arduino, reduzindo assim a tensão do pino 11 para 2,5V.


A tensão no pino RX deverá ser igual ou menor que 3,3V, portanto, construa um divisor de tensão para conecta-lo ao Arduino.

           Conecte o pino TX diretamente ao terminal 10, e os pinos de 5V e GND as fileiras de alimentação do Protoboard.


O Arduino será utilizado como meio de configurar o módulo através do monitor serial.

               As configurações do HC05 serão realizados por comandos AT, para ativar o recebimento de tais comandos desligue temporariamente a alimentação do circuito, removendo o jumper conectado ao terminal 5 V do Arduino, segure o pequeno botão do módulo e religue o sistema, isso deverá mudar o ritmo do LED para um piscar mais lento, indicando que o STATE entrou em modo AT. Observe a imagem em GIF apresentada abaixo, para compreender melhor a diferença entre o ritmo de conexão e status de configuração.


O piscar do LED irá se tornar mais lento ao entrar em modo AT.

                  Na programação a seguir será possível enviar os comandos de configuração AT ao HC-05, visualizando o status de recebimento do componente através do monitor serial do Arduino IDE.

/* Projeto Curto Circuito – HC05: Comandos AT */
#include <SoftwareSerial.h>

SoftwareSerial HC05(10, 11);/* RX pino 11 , TX pino 10 */

void setup()
{
  Serial.begin(115200); /* Porta Serial do computador */
  HC05.begin(38400);    /* Porta Serial do HC05 */
  Serial.println("Envie os comandos AT para configurar o HC05");
}

void loop()
{
  if (HC05.available())
  { /* Enquanto HC05 receber dados */
    while (HC05.available())
    {
      char c = HC05.read(); /* Lê os caractéres */
      Serial.write(c); /* Escreve os dados na Serial */
    }
  }

  if (Serial.available())
  { /* Enquanto a Serial receber dados */
    delay(10);
    String comando = "";

    while (Serial.available())
    { /* Enquanto receber comandos */

      comando += (char)Serial.read();/* Lê os caracteres */
    }
    HC05.println(comando); /* Escreve os dados no HC05 */
  }
}

           Após transferir a programação abra o monitor serial e ajuste o comando de linha em “Both NL & CR” (destacado em verde), em alguns casos a velocidade deverá ser ajustada em 9600 dbs, porém, obtivemos um melhor taxa de transmissão com  115200 dbs (destacado em azul).


O ajuste do comando de fim de linha será obrigatório, assim como ajuste de velocidade.

            Inicie a comunicação enviando a palavra AT, este comando servirá apenas para avaliar a comunicação do módulo, que deverá responder com um “OK” ou “ERROR”, caso contrário confirme a conexão dos pinos e tente novamente até obter uma das respostas citadas.


O módulo deverá ser responder com ERROR ou OK, indicando o recebimento dos comandos.

            As mensagens de erro serão acompanhadas por um valor entre parênteses, cuja função será indicar o possível problema na transmissão do comando. A lista a seguir baseia-se no exemplo fornecido pelo blog “Dobitaobyte”, e será uma importante ferramenta para auxilia-lo quando houver algum problema no envio de comando AT, no exemplo apresentado acima, encontramos um código de erro (0), que representa uma falha no recebimento da mensagem, para resolver isto basta reenviar o comando, simples assim. 


A lita a seguir irá auxiliar na visualização de possíveis erros ou problemas no recebimento dos comandos.

             Nos exemplos a seguir iremos trabalhar com a configuração de dois módulos HC-05, um em modo mestre e outro como escravo, apresentando alguns dos principais comandos de configuração, e descobrindo algumas aplicações em projetos e sistemas automatizados. Antes de qualquer coisa, verifique os status de funcionamento do componente através dos comandos destacados abaixo.


Como padrão, muitos HC-05 virão configurados em modo SLAVE, pronto para conectar-se a qualquer dispositivo Bluetooth.

            Ao enviar AT+ROLE será exibido o modo de operação do componente, sendo o valor “1” para Master e “0” em SLAVE. O comando AT+CMODE indica o tipo de conexão, que será divida entre aberto (1), aceitando qualquer dispositivo que esteja com a mesma faixa de comunicação, ou fechada (0), para conectar-se apenas a dispositivos específicos. E por fim, AT+ UART para exibir a velocidade de transmissão do módulo, que normalmente vem com um valor padrão de 9600 ou 38400 baud.


Slave

           O Slave (ou escravo) atua como um receptor de informações de uso simples, afinal, este exigirá pouco ou nenhum ajuste. A maioria dos módulos HC-05 apresenta um padrão de configuração similar ao exibido no exemplo acima, com modo operacional escravo, conexão aberta e velocidade de 9600 bps. Para alterar o valor de alguma variável basta escrever o comando "=" e o valor desejado, por exemplo, para a comunicação Slave-Master iremos ajustar a velocidade em 38400bps, portanto, envie "AT+ UART=38400,0,0", e o tipo de conexão fechada com "AT+ CMODE=0", sem as aspas. A conexão será estabelecida através do endereço de identificação (ID) do componente, que deverá ser inserido nos parâmetros de configuração do Master, para descobrir o valor envie “AT+ADDR?”, ou apenas “AT+ADDR”, anote o valor para que possa ser aplicado nas próximas etapas deste projeto. 


Para que o módulo atue como SLAVE, será necessário configurar apenas o comando ROLE como 0, as demais informações serão opcionais.

           Procure certificar-se de que todas as  informações do HC-05 estejam similares ao exemplo (com exceção do ADDR), envie AT+RESET para reiniciar o funcionamento do módulo, e coloca-lo novamente em modo de conexão.


Master

           O modo Master (mestre) tem a função de transmitir informações, exigirá um pouco mais de atenção ao ser configurado, pois muito de seus padrões serão alterados de acordo com o objetivo do projeto. Nas opções de configuração será necessidade ajusta-lo com a mesma velocidade de transmissão utilizada pelo SLAVE (AT+ UART=38400,0,0), definir a conexão como fechada para que busque por um único endereço (“AT+ CMODE=0”), e transformar o módulo em MASTER (AT-ROLE=1).


Diferente do Slave, o Master será aplicado a transmissão de informações.

         O endereço do dispositivo Slave (ADDR) deverá ser inserido no Master através do comando “AT+BIND=xxxx,xx,xxxxxx”, onde os “x” serão substituídos pelo valor coletado anteriormente, substituindo os símbolos dois pontos (:) por vírgulas (,). O formato de endereço geralmente seguirá um padrão com 12 dígitos, e deverá ser inserido com 4 dígitos, 2 dígitos, e 6 dígitos. No exemplo demonstrado abaixo, o endereço do módulo possui dois dígitos a menos no último quadrante, devido a isso surgiu um erro 7, indicando que o valor inserido é muito curto, e para solucionar tal problema tivemos que inserir outros dois dígitos zeros (00).


O comando AT+BIND será empregada ao endereçamento de um dispositivos específico, escolhendo um único Bluetooh para conectar-se ao Master.

Nome e Senha

        Caso tenha dificuldades, substitua o CMODE de ambos os módulos para “1”, tornando o acesso ao componente livre, este será um método menos seguro, pois qualquer outro componente que possua as mesmas especificações poderá conectar-se, porém, irá apresentar resultados praticamente imediatos. A conexão exigirá a configuração de uma senha similar tanto no Master, quanto no Slave, portanto, retorne ao modo AT, e envie "AT+PSWD" para saber se a atual senha do dispositivo, normalmente, o padrão de senhas será "1234" ou "0000", mas poderá ser facilmente substituída ao enviar "AT+PSWD=" e o valor desejado, por exemplo, para defini-la como "123" escreva AT+PSWD="123", com o valor entre aspas. Para nomear seu Bluetooth, simplificando a localização entre os demais dispositivos, envie AT+NAME= e insira o nome desejado.


Para diferenciar os módulo, utilize os comandos AT+NAME e AT+PSWD para definir um novo nome e senha para o HC05.

        Este meio de conexão tem seus pros e contras, embora seja mais simples, o Slave tentará se comunicar com os módulos mais próximos, enviando solicitações a celulares e outros dispositivos que possuam Bluetooth. Mas não há o que temer, pois a comunicação só poderá ser estabelecida ao inserir a senha do componente, por isso, ao localizar um mestre, com senha e parâmetros similares, a conexão será praticamente imediata, sendo sinalizada através dos LEDs embutidos em cada módulo, que irão piscar de forma sincronizada.


Ao estabelecer conexão, os módulos passarão a piscar em sincronia.

          Na tabela abaixo, listamos alguns dos principais comandos AT aplicados a configuração dos parâmetros operacionais, que serão aceitos por quaisquer versões do HC-05.         


A tabela 2 apresenta os principais comandos de configuração voltados ao HC05

Comunicação entre Arduinos

             Após configurar os módulos como Master e Slave, será mais simples aplica-lo ao controle de sistemas distintos, devido a isso, iremos explorar a construção de dois circuitos com o objetivo de acionar um componente a distância. No circuito Emissor (Master) adicione uma chave táctil, seguindo o esquema elétrico apresentado abaixo, cuja função será enviar um determinado comando ao pressionar botão.


O circuito emissor irá transmitir um determinado sinal para o acionamento de um componente no circuito receptor.

O jumper do pino EN poderá ser removido, afinal, todos os parâmetros de comunicação foram configurados anteriormente, sendo assim desnecessário deixa-lo em modo AT. No circuito Receptor (Slave), adicione um LED conectando ao terminal digital 13 do segundo Arduino, este só será acionado ao receber o comando do Master.  


Ao receber o sinal do circuito emissor, o LED será acionado por 10ms.

          Transfira as programações a seguir de acordo com cada circuito.

Arduino Emissor

/* Projeto Curto Circuito – Conectando dois Arduinos (Emissor)
== MASTER == */

/* Biblioteca */
#include <SoftwareSerial.h>

/* Comunicação Serial */
SoftwareSerial HC05(10, 11); /* Simula TX e RX nas portas 10 e 11 */

/* Variáveis e Componentes */
#define button 12 /* Define buttonPin estará na porta 12 */
int led = 13;          /* Define led na porta 13 */
int buttonState = 0; /* Variável para avaliar o status do Botão */

void setup()
{
  pinMode(button, INPUT); /* Declara button como INPUT */
  pinMode(led, OUTPUT);   /* Declara que led como OUTPUT */
  HC05.begin(38400);      /* Taxa de transmissão do Módulo */
  Serial.begin(9600);     /* Taxa de transmissão na serial */
}
void loop()
{

  /* Lê o status do botão */
  buttonState = digitalRead(button); /* Armazena o valor na variável ButtonState */

  if (buttonState == HIGH)
  { /* Se o botão estiver pressionado */ 
    Serial.println("ON");        /* Sinaliza com a palavra "ON" */
    HC05.println(2);             /* HC05 escreve o valor 2 na serial */
    digitalWrite(led, 1);        /* Liga o LED */
  }
  else
  {
    Serial.println("OFF");      /* Sinaliza com a palavra "OFF" */
    digitalWrite(led, 0);       /* Desliga o LED */
  }
  HC05.flush();                 /* Limpa a memória */
  delay(20);                    /* Aguarda 20 ms antes de retornar ao loop */
}

 

Arduino Receptor

/* Projeto Curto Circuito – Conectando dois Arduinos (Receptor) 
== SLAVE == */

/* Biblioteca */
#include <SoftwareSerial.h>

/* Comunicação Serial */
SoftwareSerial HC05(10, 11); /* Simula TX e RX nas portas 10 e 11 */

/* Variáveis e Componentes*/
#define led 13 /* Define led na porta 13 */
int  state ;  /* Variável para avaliar os comando recebidos */

void setup()
{
  pinMode(led, OUTPUT);  /* Declara que led como OUTPUT   */
  digitalWrite(led, LOW);/* Inicia com o led desligado    */
  HC05.begin(38400);     /* Taxa de transmissão do Módulo */
  Serial.begin(9600);    /* Taxa de transmissão na serial */
}
void loop()
{
  if (HC05.available() > 0)
  { /* Se o sinal recebido no HC05 for maior que 0 */

    state = HC05.read(); /* state será igual ao valor de mySerial */
   
   
    if (state != 1)
    {/* Se o valor for diferente de 1 */
      digitalWrite(led, HIGH); /* Liga o LED */
      delay(10);               /* Aguarda 10 ms */
    }
  }
  digitalWrite(led, LOW);     /* Desliga o LED */
}

             Se os módulos HC-05 estiverem em sincronia, sinalizando a conexão entre eles, passarão a compartilhar informações diretamente na serial, então quando o emissor imprimir (print) ou escrever (write) um valor, o receptor irá recebê-lo, e de acordo com a programação executar alguma determinada função. O LED do receptor permanecerá desligado, até o momento em que o botão no emissor for pressionado, quando isto ocorrer o LED permanecerá ligado por 10 milissegundos, indicando a comunicação entre os circuitos. 

            Na programação do Receptor, a função HC05.available() será aplicada para avaliar o recebimento de qualquer tipo de leitura na serial, o valor inicial (0) muda ao identificar outros módulos, e if (state != 1) se torna responsável por filtrar os valores recebidos, acionando o LED sempre que identificar um comando diferente de 1. Devido a isso, no programa Emissor temos HC05.println(2), onde a variável irá transmitir o caractere 2 quando a chave táctil for pressionada.   

 

Ajuste de Posicionamento 

 

          Neste último exemplo, iremos construir um sistema para ajustar a rotação de um servo motor, controlando o ângulo de movimentação a distância. No circuito emissor serão utilizadas duas chaves tácteis, com a função de mover o servo no sentido horário e anti-horário. 

O circuito emissor será responsável por enviar a posição desejada.

          O servo motor deverá ser adicionado ao circuito receptor, conectando o terminal laranja no pino digital 12 do Arduino, e os terminais marrom e vermelho nos polos de alimentação do Protoboard. Finalize o circuito com a adição de um LED na porta digital 13, verificando o recebimento dos comandos enviados pelo Master.  

A posição do servo será ajustada de acordo com os valores enviados pelo emissor.

           Transfira as programações a seguir de acordo com cada circuito.

Arduino Emissor

/* Projeto Curto Circuito – Ajuste de Posicionamento (Emissor) */
 == MASTER == */

/* Biblioteca */
#include <SoftwareSerial.h> /* Inclui Biblioteca Serial */

/* Comunicação Serial */
SoftwareSerial HC05(10, 11);    /* RX pino 11 , TX pino 10 */

/* Variáveis e Componentes */
int bt1 = 0;                    /* Variável de leitura */
int bt2 = 0;                    /* Variável de leitura */
int led = 13;                   /* led na porta 13 */

void setup()
{
  pinMode(2, INPUT);        /* Declara pino 2 como INPUT (Entrada) */
  pinMode(4, INPUT);        /* Declara pino 4 como INPUT (Entrada) */
  Serial.begin(9600);       /* Taxa de transmissão do computador   */
  HC05.begin(38400);        /* Taxa de transmissão do Módulo   */
}
void loop() {
  /* Lê o status dos botões */
  bt1 = digitalRead(2); /* Armazena o valor na variável bt1 */
  bt2 = digitalRead(4); /* Armazena o valor na variável bt2 */

  if (bt1 == 1 )
  { /* Se o botão estiver pressionado */
    Serial.println("Sentido Horário");   /* Sinaliza o sentido da rotação */
    HC05.write('a');                     /* HC05 escreve o caractere na serial */

  }
  if (bt2 == 1 )
  { /* Se o botão estiver pressionado */
    Serial.println("Sentido Anti-Horário");        /* Sinaliza o sentido da rotação */
    HC05.write('b');              /* HC05 escreve o caractere na serial */
  }
  HC05.flush();                 /* Limpa a memória */
  delay(20);                    /* Aguarda 20 ms antes de retornar ao loop */
}

Arduino Receptor

/* Projeto Curto Circuito – Ajuste de Posicionamento (Receptor)
== SLAVE == */

/* Bibliotecas */
#include <SoftwareSerial.h> /* Inclui Biblioteca Serial */
#include <Servo.h> /* Inclui Biblioteca Servo Motor */

/* Comunicação Serial */
SoftwareSerial HC05(10, 11);    /* Simula TX e RX nas portas 10 e 11 */

/* Variável de controle para o Servo */
Servo myservo;
/* Variáveis de leitura */
int input;     /* Lê os valores transmistidos pelo Master */
int pos = 0;   /* Controla a posição do servo */
int LED = 13;
void setup()
{
  pinMode(LED, OUTPUT);     /* LED no pino 13 */
  Serial.begin(9600);       /* Taxa de transmissão */
  HC05.begin(38400);        /* Taxa de transmissão do Módulo */
  /* Setup do Servo Motor */
  myservo.attach(12);        /* Pinagem no Arduino */
  myservo.write(0);          /* Inicia o servo na posição 0º */
}
void loop()
{
  digitalWrite(LED, 0);    /* LED Desligado */

  int input = HC05.read(); /* input será igual ao valor lido em HC05 */

  switch (input)
  { /* De acordo com o valor armazenado em input */

    case 'a':      /* Caso receba o caractere 'a' */
      digitalWrite(LED, 1);   /* LED Liga */
      pos += 10;             /* Aumenta o valor da posição em 10 */
      myservo.write(pos);    /* Posiciona o servo de acordo com pos */
      if (pos >= 181)
      { /* Se pos maior ou igual a 181 */
        pos = 180; /* Mantém pos em 180 */
      }
      break;       /* Finaliza a função */
    case 'b':      /* Caso receba o caractere 'b' */
digitalWrite(LED, 1); /* LED Liga */ pos -= 10; /* Reduz o valor de pos em 10 */ myservo.write(pos); /* Posiciona o servo de acordo com pos */ if (pos >= 0) { /* Se pos menor ou igual a 0 */ pos = 0; /* Mantém pos em 0 */ } break; /* Finaliza a função */ } }

          O Switch Case é uma estrutura de controle voltada aos fluxos de programações, determinando condições específicas para a execução de determinadas partes do código. No caso do programa emissor o interruptor (switch) ativa de acordo com a leitura na variável input, se receber o caractere "a", escrito em minúsculo, direciona o fluxo para a movimentação do servo em sentido horário, indo de 0º a 180º, se receber "b"  move em anti-horário de 180º á 0º. Cada case (caso) deverá ser preenchido com as condições e  funções que deseja-se executar, por exemplo:

    case 'a':      /* Caso receba o caractere 'a' */
      digitalWrite(LED, 1);   /* LED Liga */
      pos += 10;             /* Aumenta o valor da posição em 10 */
      myservo.write(pos);    /* Posiciona o servo de acordo com pos */
      if (pos >= 181)
      { /* Se pos maior ou igual a 181 */
        pos = 180; /* Mantém pos em 180 */
      }
      break;       /* Finaliza a função */

         No exemplo acima, determinamos que ao receber a letra "a" o posicionamento do servo irá aumentar até atingir o valor de 180º, utilizando o if para determinar um limite de avanço. O Switch irá executar tais funções até identificar o final da case, que será definido pela palavra-chave "break".

         As funções myservo.attach(12) e myservo.write(0), determinam o pino de conexão do servo e o posição inicial respectivamente. Em myservo.write(pos), o valor da variável "pos" será utilizado para ajustar a posição através da lógica aplicada em pos += 10 e pos -= 10, aumentando ou reduzindo o valor até atingir 180 ou 0. 

 

 


Sentido Horário e Anti-Horário, controlado de forma simples e ágil.

 

           Na imagem GIF apresentada acima, substituímos os botões por um módulo Joystick Analógico 3 eixos, e um Arduino Uno por um Nano, para tornar o projeto mais compacto e próximo de um controle de verdade. As mudanças na imagem foram apenas visuais, caso opte por utilizar um joystick em seu projeto, por exemplo, basta substituir as variáveis de leituras digitais por analógicas. 


Considerações Finais  

           Interfaces Bluetooth apresentam-se de forma diferencial dos demais meios de comunicação sem fio, afinal, este comunica-se facilmente com qualquer dispositivo, fornecendo uma velocidade de transmissão de até 25 Mbps, além de um consumo de potência e energia consideravelmente baixo. Embora não consiga atingir grandes distâncias como a conexão Wi-Fi, o módulo HC-05 apresenta diversos pontos positivos, encaixando-se em praticamente qualquer projeto de forma simples e eficiente. Nesse post, procuramos nos ater a comunicação entre módulos, que normalmente será o grande vilão para quem está aprendendo a trabalhar com esse tipo de comunicação. Mas como foi visto no decorrer dos exemplos e atividades, depois de configurar o Master e o Slave tudo fica mais simples.