Manual
do
Maker
.
com
Diferente do módulo HC-06, esse módulo serial Bluetooth HC-05 funciona não apenas como slave, mas também como master, de modo que você poderá ter um sistema ativo em sua MCU.
Esse módulo tem sua própria controladora e a interface serial recebe comandos AT para interação. Assim, você poderá enviar mensagens a partir de um PIC, Arduino, ESP8266, Raspberry, Onion Omega ou qualquer outro dispositivo que disponha de interface serial para comunicação externa.
Também diferente do HM-10, ambos bluetooth HC-05 e HC-06 não são BLE (Bluetooth Low Energy), por isso eles não podem ser utilizados como beacon. Se você não sabe o que é beacon e gostaria de ver informações a respeito, recomendo esse artigo, assim como esse outro e esse aqui.
Nesse post pretendo mostrar como trocar informação de texto via bluetooth entre um Arduino e um computador rodando Linux. Sinceramente, não sei se é possível fazer um passthrough do bluetooth em uma máquina virtual, mas de qualquer modo recomendo que tenha um sistema Linux instalado (ainda que em dual boot com o Windows) para que você possa desfrutar de todas essas facilidades que só o Linux oferece. Dito isso, passemos ao próximo tópico.
Bem, se você ainda não tem PIC, Arduino, ESP8266 nem um Raspberry Pi ou algo similar, está mais do que na hora de adquirir. Além de uma CPU/MCU, você vai precisar de um módulo bluetooth HC-05, exceto esteja utilizando um Raspberry 3, porque aí não faz sentido ter um módulo bluetooth serial.
Gostaria de salientar que esse artigo não é da parceria com a Fulltronic, mas o material adquiri deles pela confiabilidade e agilidade que já demonstraram há algum tempo (desde que comecei a ser cliente e certamente antes disso), por isso recomendo a aquisição através dos links que disponho. Escolha suas ferramentas:
Tipicamente ele opera de 1.8V à 3.6V. Possui uma interface UART com baud rate configurável e antena integrada.
No datasheet a informação é que as configurações UART padrão são:
Ele faz uma auto-conexão com o último dispositivo pareado, por padrão, assim como permite auto-conexão de dispositivos que já tenham sido pareados.
Uma informação importantíssima é o código pin para auto-parear: '0000' por padrão.
Em caso de desconexão, se reconecta em 30 minutos.
Esse dispositivo tem um monte de pinos de IO e eles podem ser utilizados. O problema é que o módulo feito não disponibiliza uma interface física, então você precisará fazer soldas se quiser utilizá-los. A interação através da comunicação UART é feita utilizando o protocolo AT.
Ao ligá-lo, ele piscará constante, rápida e ininterruptamente, até que seja pareado. Então quando conectado, pisca 1 vez a cada 2 segundos.
Possui alcance de até 10m.
O bacana mesmo é a simplicidade no Wiring, bastando conectar o TX do HC-05 ao RX do Arduino (conforme o modelo utilizado) e o RX do HC-05 ao TX do Arduino. Se o Arduino for nível lógico 5V, será necessário um divisor de tensão, conforme o desenho a seguir. Repare que para o envio dos comandos AT (só nesse módulo eu tive que fazer isso e não sei o porquê) o pino EN também precisa ser conectado em 3.3V. Apesar de algumas pessoas conectarem o o pino RX e EN do HC-05 em 5V, não é recomendado, atrás do próprio dispositivo está escrito que seu nível lógico é 3.3V e só é possível alimentá-lo em 5V porque ele possui um regulador de tensão. Avisadus est.
Outra coisa importante; precisei apertar o botão que está na board do HC-05 para entrar em modo de comando AT, não se esqueça disso.
O divisor de tensão é um resistor de 10k e um resistor de 20k. Conecte o TX do Arduino a uma perna do resistor de 10k. A outra perna do resistor de 10k vai em uma perna do resistor de 20k. A outra perna do resistor de 20k por sua vez, vai ao ground. Entre os dois resistores, conecte o fio que vai ao RX do HC-05.
O comando até deve ser procedido por CRLF ('\r\n'), enviado pela aplicação, não literal. Para ter informação de todos os comandos AT disponíveis, refira-se ao datasheet.
Aqui utilizaremos basicamente os comandos para essa comunicação. Primeiro, utilize sempre o comando de status. Esse comando já lhe permite de imediato saber se está tudo pronto para operação; se wiring está correto, a velocidade serial está compativel, o módulo está operante. Tendo o 'OK' como resposta, já pode seguir adiante.
Comando | Resposta | Parâmetro |
AT | OK | - |
Se retornar 'OK', sinta-se à vontade para seguir adiante, senão, verifique qual o problema antes de seguir. Você também poderá tirar suas dúvidas através dos nossos grupos, onde diversas outras pessoas também poderão lhe auxiliar. Disponho agora dos comandos AT que vamos (ou podemos) utilizar para esse post.
Comando | Resposta | Parâmetro, exemplo e função |
AT+ORGL | OK | Nenhum.Volta ao estado padrão:Slave mode, pin code :1234, device name: H-C-2010-06-01 ,Baud 38400bits/s |
AT+ADDR? | +ADDR:OK | O parâmetro é o endereço do dispositivo. Ex: "Alameda dos Arapanés, 132". (brincadeira, calma!) |
AT+NAME= | OK | Mudar o nome do dispositivo. Se utilizar AT+NAME?, consulta. Todos os parâmetro consultáveis são procedidos de interrogação. |
AT+RNAME? | 1. +NAME: OK2. FAIL | Consulta ou muda o nome do dispositivo bluetooth. |
AT+ROLE= | 1.OK | |
2.+ROLE: | Se consultado, retorna o modo do módulo. Parâmetro 0 é slave, 1 é master, 2 é slave-loop. | |
AT+PSWD= | 1.OK2.+PSWD: | Param: PIN (padrão 1234) |
AT+UART= | 1.OK | |
2.+UART= | Se consultado, retorna os parâmetros. Os parâmetros são:Param1: baud rateParam2: Stop bitParam3: Paridade | |
AT+CMODE= | 1.OK | |
2.+CMODE:OK | Consulta ou ajusta o endereço físico. A atribuição dos valores podem ser:0 - fixo1 - dinâmico2 - slave-loop | |
AT+BIND= | OK ou comando | O parâmetro é um endereço fisico:00:00:00:00:00:00 |
AT+POLAR= | OK ou comando | Checa ou configura o modo de I/O do LED.Param1: o LOW, 1 HIGH (PIO8)Param2: o LOW, 1 HIGH (PIO9) |
AT+PIO= | OK | Você pode utilizar os pinos de I/O do módulo. |
Param1: número do pino | ||
Param2: nível | ||
Nível: 0 LOW, 1 HIGH | ||
1. | ||
AT+ RMAAD | ||
2. | ||
AT+PMSAD= | OK | 1. Apaga todos os dispositivos autenticados |
2. Apaga determinado dispositivo anteriormente autenticado | ||
AT+ADCN? | +ADCN: | Pega o número de dispositivos autenticados. |
AT+MRAD? | +MRAD: | Pega o dispositivo mais recentemente autenticado |
AT+STATE | +STATE: | Devolve o estado de trabalho do módulo. As respostas possíveis são:“INITIALIZED”, “READY”, “PAIRABLE”, “PAIRED”, “INQUIRING” “CONNECTING”, “CONNECTED” ,“DISCONNECTED” ,“UNKNOW” |
AT+INIT | 1.OK | |
2.FAIL | Inicializa o SPP (Serial Port Profile), fundamental para a comunicação serial de dados desse artigo. | |
AT+PAIR= | 1.OK | |
2.FAIL | Parear com um dispositivo. | |
Param1: endereço do dispositivo | ||
Param2: Time out | ||
AT+LINK= | 1.OK | |
2.FAIL | Conecta a um dispositivo que já tenha sido pareado. | |
Param: endereço do dispositivo | ||
AT+DISC | 1. +DISC:SUCCESS OK 2. +DISC:LINK_LOSS OK 3. +DISC:NO_SLC OK 4. +DISC:TIMEOUT OK 5. +DISC:ERROR OK | Desconecta. Retorna o endereço do dispositivo. |
AT+ENSNIFF= | OK | Modo de economia de energia. |
dev: endereço do dispositivo. | ||
AT+EXSNIFF= | OK | Sai do modo de economia. |
dev:endereço do dispositivo. | ||
1.AT+IPSCAN= | ||
2.AT+IPSCAN? | OK | Scan. |
p1:intervalo da query | ||
p2: duração da query | ||
p3:intervalo de paginação | ||
p4:duração da chamada |
Não usaremos todos esses comandos nesse artigo, mas deixo-os dispostos para que você tenha facilidade em utilizá-los, caso deseje.
Para fazer essa interação com o módulo bluetooth HC-05, vamos utilizar um pouco de shell script e um pouco de Python. No caso do Python, será necessário instalar o python-serial:
sudo apt-get install python-serial
Você deverá conhecer alguns comandos, por isso vou apresentá-los previamente. Primeiro, você precisa passar um scan na rede bluetooth para ver que dispositivos estão disponíveis. Para isso:
hcitool scan
Esse comando retornará o endereço físico do dispositivo seguido pelo nome que o representa. Por exemplo:
E podemos verificar agora se o nosso dispositivo suporta SPP e qual é o endereço do canal a ser utilizado. Para isso, utilizamos o comando 'sdptool records <endereço físico>', que no meu caso retornou:
Claro que o suporte já era sabido, uma vez que o recurso está descrito no datasheet, lá nos comandos AT, inclusive citado aí na tabela acima. Mas o importante para nós no momento é o canal de rádio (RFCOMM), que está utilizando (no meu caso) o canal 1.
Tendo as informações necessárias do dispositivo remoto, agora podemos criar nossa porta serial virtual, utilizando como parâmetros o endereço do dispositivo e o canal que ele está utilizando:
sudo rfcomm bind /dev/rfcomm0 20:16:03:21:83:27 1
Você "poderia" fazer a conexão e criação do dispositvo por outro meio, só vou deixar as próximas linhas de exemplo, mas as de cima devem funcionar perfeitamente:
sdptool add --channel=1 SP
mknod -m 666 /dev/rfcomm0 c 216 0
Se quiser monitorar a conexão por linha de comando mesmo, você pode escutar a SPP assim:
rfcomm listen /dev/rfcomm0
Você deverá ver uma mensagem:
Waiting for connection on channel 1
Connection from 20:16:03:21:83:27 to /dev/rfcomm0
E se quiser ver os dados enviados a partir do Arduino sem iniciar nenhum programa, um 'cat' resolve o problema:
cat /dev/rfcomm0
Ou ainda, com o próprio rfcomm:
rfcomm watch /dev/rfcomm0 1 $(which agetty) rfcomm0 115200 linux
Se for para conectar-se como client (apenas exemplo novamente), você poderia fazer (lembrando que endereço e canal devem ser descobertos com os comandos acima ou criados com o script abaixo):
rfcomm connect /dev/rfcomm0 20:16:03:21:83:27 1
E para interagir, o bom e velho screen:
screen /dev/rfcomm0 115200
Um segundo modo de criar o dispositivo SPP é utilizando as ferramentas do bluez. Para isso, instale-as primeiramente:
apt-get install bluez-tools
bt-device -l
O segundo comando deverá retornar uma lista de dispositivos, dos quais você deverá escolher um para criar a conexão.
bt-serial -c 20:16:03:21:83:27 1
bt-serial
No exemplo da imagem foi criado o dispositivo rfcomm1 porque já existia o rfcomm0, que criei previamente. A partir do momento que você tiver um dispositivo criado no sistema, enviar mensagem para o HC-05 é uma piada de tão simples:
hc-05 recebendo
Como você pode ver, poderá criar uma interação em qualquer linguagem, bastando escrever para o dispositivo, sem nenhuma complexidade mais.
A comunicação bi-direcional eu consegui utilizando o GTKTerm, colocando a velocidade em 115200 e apontando a porta /dev/rfcomm0. No final do artigo você vê o video de teste.
hc-05 bi-direcional
Agora já podemos partir para o shell script que automatize essa tarefa.
#!/bin/sh
#Created by: Djames Suhanko
#website: manualdomaker.com
help(){
echo "Passe o nome do dispositivo desejado como parametro"
}
[ $# -ne 1 ] && {
hcitool scan
help
exit 0
}
[ "$1" = "help" ] && {
help
exit 0
}
echo "Escaneando o dispositivo $1..."
BT_DEVICE=`hcitool scan |egrep "$1"|awk '{print $1}'`
[ `echo $BT_DEVICE|wc -c` -lt 15 ] && {
echo "Voce passou o nome correto? Tente executar sem parametros"
echo "Saindo..."
exit 0
}
echo "Escaneando o suporte e canal RFCOMM para executar o SPP..."
BT_CHANNEL=`sdptool records $BT_DEVICE|egrep 'Channel'|sed -re 's/Channel: (.*)/\1/'`
[ `echo $BT_CHANNEL | wc -c` -lt 1 ] && {
echo "Parece que esse dispositivo nao tem suporte a SPP"
echo "ou esse suporte nao esta habilitado. Saindo..."
exit 0
}
echo "Criando o dispositivo /dev/rfcomm0..."
rfcomm bind /dev/rfcomm0 $BT_DEVICE $BT_CHANNEL
[ -c /dev/rfcomm0 ] || {
echo "Nao foi possivel criar o dispositivo"
echo "(esse script deve ser executado com prioridade de root)"
echo "Saindo..."
exit 0
}
echo "Dispositivo criado com sucesso."
echo "Fim da execucao do script."
echo "manualdomaker.com"
Eu já havia digitado os comandos previamente, por isso eu já tinha o SPP criado, mas não poderia deixar de experimentar o script que escrevi:
Tendo enfim finalizado a configuração de sistema, podemos partir para o programa que rodará no Linux, feito em Python.
#!/usr/bin/env python
import serial,thread
#Tempo de expiracao
TIMEOUT = 1
#Dispositivo SPP criado com o script anterior
PORT = '/dev/rfcomm0'
# Velocidade da comunicacao com o BT
BAUDRATE = 921600
# Inicia a porta serial
mySPP = serial.Serial(port=PORT, baudrate=BAUDRATE, timeout=TIMEOUT)
mySPP.open()
# Thread de leitura
def myReader(mySPP):
while True:
#Lendo algum valor da porta
msg = mySPP.read(512)
# Decode comum
answer = bytes.decode("utf-8")
if answer:
print "Mensagem: " + answer
thread.start_new_thread(myReader,(mySPP,))
while True:
userWrote = raw_input('Entre com um valor: ')
if len(userWrote):
if userWrote == '
Lembre-se de rodar como root. No último loop (fora da thread), o programa fica pegando entrada do usuário. Essa entrada (uma mensagem qualquer) é enviada ao dispositivo bluetooth e deverá ser lida pelo Arduino na serial. Se quiser finalizar esse programa, apenas envie o cifrão ("$") e o laço será interrompido.
Consegui pegar uma série de erros diferentes com esse módulo, de forma que tive que pesquisar uma lista de código de erros que pudesse me guiar. Acabei encontrando um PDF que continha a tabela de código de erros. Tirei um print e aqui está:
Em sua primeira execução, tratei de verificar alguns parâmetros do dispositivo e configurar outros. Isso pode ser sempre necessário se a configuração inicial do seu firmware for a mesma que a minha.
Se você não tiver um FTDI (USB/TTL), utilize esse sketch que escrevi para fazer essa configuração. A primeira e a terceira linha podem ser comentadas se você estiver utilizando o Arduino Leonardo. Coloquei o nome de Serial1 justamente para ficar transparente na utilização de um Arduino que possua mais de 1 serial.
Repare no código que coloquei a velocidade à 9600bps. Não é um erro, testei todas as velocidades e apesar de o datasheet dizer que o padrão é 38400, ele é sim 9500. Talvez o seu seja 38400, faça o teste.
#include <SoftwareSerial.h>
//RX,TX: caso de arduino com 1 serial apenas
SoftwareSerial Serial1(7, 8);
#define BAUDRATE 9600
void setup() {
Serial.begin(BAUDRATE);
Serial1.begin(BAUDRATE);
Serial.println("Digite o comando AT:");
}
void loop() {
if (Serial1.available() > 0) {
Serial.write(Serial1.read());
}
if (Serial.available() > 0) {
Serial1.write(Serial.read());
}
delay(10);
}
Hora de fazer a conexão!
No primeiro teste que fiz, retornei às configurações de firmware padrão, onde aí sim a velocidade serial era 38400. Coloquei a senha '0000' para tentar facilitar as coisas, porque tive diversos problemas com a conexão, que deveria ser transparente, mas não foi. Após isso, fiz uma conexão com ele no modo slave mesmo, através de um smartphone Android.
HC-05 e Android (pareados)
Voltei ao terminal serial após parear os dispositivos e confirmei se o módulo bluetooth HC-05 estava "entendendo o que se passava", utilizando o comando "AT+STATE", que me retornou "PAIRED". Beleza. Para testar a comunicação, fiz uma conexão utilizando o programa para Android Bluetooth Terminal. Quando conectado, os comandos AT deixam de responder e o que for digitado vai para o Android. O que for digitado no Android, vai para o módulo bluetooth HC-05, que por vez repassa à serial, graças ao pequeno sketch que fiz.
(O vídeo da comunicação](https://youtu.be/lsFubGT3kFY)
Ao desconectar-se do terminal bluetooth, o terminal serial volta a responder comandos AT.
Para chegar nesse objetivo, tive que realmente executar alguns comandos que foram obrigatórios e pelo que vi, todo mundo usa igual por ser obrigatório.
AT+ORGL - Fui obrigado a retornar a configuração de fábrica, que por acaso está em velocidade diferente da primeira conexão; a primeira conexão estava configurada a 9600bps e ao resetar as configs, ele passa a se conectar à 38400bps.
AT+RMAAD - remove dispositivos anteriormente pareados. Tive que remover porque eu já havia maculado o estado original do dispositivo.
AT+NAME=DobitAoByte - Aceitou, mas não funcionou.
AT+ROLE=1 - define como master. Quando em master, ele envia e recebe comandos. Quando em slave, ele é passivo e quando em slave-loop, ele recebe e "cospe" de volta a informação ao originador da mensagem.
AT+RESET - reinicia no novo modo. Ao fazer o reset é necessário apertar novamente o botão que está no canto da board para ele entrar em modo AT.
Apos o reset é necessário mudar a velocidade para38400, que é a velocidade padrao. apertar o botao de novo para modo AT.
AT+CMODE=1 - permite conectar a qualquer endereço. Tive que fazer para conseguir parear com o Android e o notebook, é obrigatório também.
AT+INQM=0,5,20 - faz um scan de 5 dispositivos no intervalo de 20 segundos. Só funcionou uma vez, forcei toda a configuração do lado Linux.
AT+INQM sem parâmetros pra confirmar o ultimo comando.
AT+PSWD=0000 - Eu forcei a senha '0000' pra tentar facilitar a interfae com o Linux pelo KDE, mas não deu certo. Mas o objetivo era mesmo comunicação por linha, isso deu certo como você pode ver.
AT+INIT - inicia o profile de envio/recebimento. se pegar error(17), significa que ja esta iniciado; e já estava.
AT+INQ - scan por dispositivos. Me retornou:
+INQ:303A:64:3A08D0,700100,7FFF - Tendo esse endereço, apenas as 3 primeiras partes são o endereço. Substitua dois pontos (":") por vírgula (",").
AT+STATE - foi bom para diagnosticar o status do dispositivo em cada momento.
Para o teste de comunicação bi-direcional, utilizei o GTKTerm. Gostou do artigo?
Inscreva-se em nosso canal Dobitaobyte no Youtube.
Próximo post a caminho!
Autor do blog "Do bit Ao Byte / Manual do Maker".
Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.