sábado, 14 de maio de 2016

Demonstração do funcionamento com um circuito teste.


Então pessoal, aqui segue um vídeo em que gravei explicando e demonstrando como funciona o controle do Arduino pelo aplicativo. Utilizei um circuito teste com quatro LEDs para demonstrarem de forma mais simples a locomoção ou não do robô. Espero que sirva como demonstração.
Até!


Recebendo as informações do Aplicativo ChicoBot via Módulo HC-05 através de um código-teste...


Ao enviar as informações (números) pelo aplicativo é necessário ter um algoritmo programado no Arduino para que os comandos sejam recebidos, interpretados e o robô se mova nas direções correspondentes às esperadas no aplicativo.

O aplicativo ChicoBot ao enviar os números "1", "2", "3" e "4", correspondentes as direções de locomoção, "empacotados" em variáveis, envia uma sequência de 0s e 1s que define o código do caracter na tabela ASCII enviado. Ou seja, a cada vez que um caracter é enviado, são mandados 8 bits, sendo eles "0" ou "1", para o módulo bluetooth HC-05. 

Se estudarmos como funciona o protocolo de comunicação do módulo bluetooth, o protocolo RS232, veremos que na transmissão de dados são enviados: 1 bit de início de transmissão, 1 bit de fim de transmissão, 1 bit de paridade e 8 bits de dados. Não precisamos nos preocupar com os bits que não sejam os 8 bits de dados. A grande questão para a comunicação funcionar é: saber como são representadas em bits os tipos de variáveis da linguagem Arduino para saber como declarar o comando que será recebido.

Depois deste resumo, vamos ao código com alguns comentários...


1ª parte: instruções na função "void setup".




Muita atenção a declaração da variável "comando". Por que ela é declara como byte? Não podia ser um "int"? Um "char"?
r: Ela é declarada como um byte porque na linguagem Arduino, os bytes são computados como um dado de 8 bits. Não poderia ser declarada como "int" porque os "ints" são computados como dados de 16 bits (consultar a "Reference" disponível em arduino.cc).

Em seguida temos as variáveis do tipo "boolean" que representaram os "estados das direções". Enquanto o robô estiver indo para a direita, por exemplo, a variável "direita" estará setada para "true" e quando não estiver mais indo para a direita, a variável estará setada para "false". Veremos como isso funcionará na função "void loop".

O circuito montado conta com 4 LEDs, um em cada pino, um no pino 4, um no pino5, um no pino 6 e outro no pino 7. Fiz isto para testar se a comunicação entre o aplicativo e o módulo estava rolando e cada LED indica uma direção na qual o robô estará se movendo ou não (LED aceso = o robô está indo naquela direção, LED apagado = o robô não está indo naquela direção). Para que isso se aplique no robô quando estiver pronto, vou precisar fazer as devidas conexões eletrônicas na ponte H e nos terminais dos motores, mas isso ocorrerá mais pra frente, só quando o robô já estiver pronto. 

Além das declarações de como funcionarão os pinos em que os LEDs estão (funcionarão como saída), a função "void setup" conta com os valores iniciais das variáveis correspondentes as direções. Elas começarão todas em "false" pois o robô não deverá sair andando sozinho. Estas declarações são feitas dentro desta função pois este código será executado primeiro e só uma vez, por isso se chama "setup".

Ah, e tem também a frequência baud rate em que porta serial funcionará, que é 9600 bauds. 


2ª parte: instruções na função "void loop".



Na estrutura da função "void loop" encontramos o comando "Serial.available()" sendo comparado com zero. Esta instrução diz que, se tiver algo na serial (no buffer da serial), o Arduino lê este dado com o comando "serial.read()" e armazena na variável "comando" o que estava na serial para ser lido. Por que comparar "serial.available" com zero? Porque se tiver algo na serial para ser lido, seu "comprimento"/valor será maior que zero. Só seria zero caso não houvesse nada na serial.

Depois que estas condições e ações são feitas, partimos para a parte de controle dos LEDs. Há basicamente mais três destas funções que vou explicar agora, totalizando quatro funções (controlar quatro LEDs que representam as quatro direções em que o robô vai se mover).

A estrutura começa com uma condição que compra a variável comando com o caractere "1" referente ao comando de andar para frente. A seguir, outra condição para testar se a variável "frente" é "false". Se esta for "false" e o que estiver armazenado em comando (que previamente estava na porta serial) for igual a "1", então a variável booleana "frente" se torna "true" e o LED correspondente a direção acende. Caso "frente" seja "true", então ao receber o caractere "1", o Arduino seta "frente" para "false" e apaga o LED.

Repare que as instruções estão preparadas para funcionar com o valor/estado anterior da direção, que no caso é representado visualmente pelo LED (aceso ou apagado = seguindo na direção ou não, respectivamente). Por isso, quando definimos a função "void setup", setamos inicialmente o valor de todas as direções para "false", assim o robô estará inicialmente parado.

3ª Parte: Instruções restantes do código.

 



Como disse a vocês, a estrutura da função explicada na segunda parte desta documentação se repete para as direções restantes. O comando "delay" para aplicar 1 segundo de atraso no programa foi posto apenas para teste e acompanhamento pela Serial Monitor.

É isso... Espero ter explicado claramente o código e quaisquer dúvidas perguntas são bem vindas no blog!





sexta-feira, 6 de maio de 2016

Enviando comandos para o Chico pelo aplicativo ChicoBot...


Esta documentação parte do princípio de que você, leitor, já sabe usar o MIT App Inventor 2 ou está minimamente familiriazado com o mesmo, ferramenta utilizada para desenvolver este aplicativo.
Caso não esteja familiarizado, você pode pesquisar por "tutorial como usar o app inventor" ou "como usar app inventor 2 arduino" que trará vídeos no YouTube ensinando a usar a ferramenta e ensinando a dar os primeiros passos para fazer algo com uma aplicação legal!

Bem, vamos lá...


1ª Parte: Comandos realizados assim que a tela inicial é aberta.



O primeiro passo é fazer a inicialização das variáveis de comando: Frente, Ré, Esquerda e Direita. 
Tente evitar pôr nomes com caracteres especiais nas variáveis como acentos, tiles e etc, pois alguns sistemas não reconhecem estes caracteres de acordo com a tabela ASCII e você pode ter problema ao rodar seu programa. Neste caso eu já havia tentado a palavra "Ré" sem acento e posteriormente tentei com acento e deu certo.

As outras duas variáveis ("StatusConText" e "comando") representam, respectivamente, a string atribuída a variável "StatusConText" que aparecerá abaixo do label "Status da Conexão" na tela inicial do dispositivo Android e a variável que armazenará o comando a ser enviado via bluetooth para o HC-05 ligado ao Arduino, por isso "comando" é definida como uma string ("texto") que não contém nenhum caracter.

Assim que a tela (Screen1) inicializa, seu texto na barra cinza localizada no topo da tela é setado para "ChicoBot" e o texto presente na caixa abaixo do label "Status da Conexão" é setado para "Não realizada!", pois assim que o aplicativo é fechado a conexão é desfeita, logo, se o aplicativo é iniciado, a conexão sempre ainda não terá sido realizada.

A seguir, encontramos uma condição que verifica se o bluetooth do dispositivo Android está ativado. Se ele está ativado, estão o texto abaixo do label "Status BT" é setado para "BT Ativado". Caso o bluetooth do dispositivo não esteja ativado, o texto sera setado para "BT desativado". 

* Aqui no código, sempre que encontrarmos funções com classes como "BluetoothAndroid.Enabled", para acharmos essas funções no App Inventor 2 devemos procurar pelo primeiro nome antes do ponto "BluetoothAndroid" no canto esquerdo inferior da página, onde aparecerão todos os recursos que adicionamos na área "Designer"(botão ao lado de "Blocks" no canto superior direito próximo ao e-mail em que a conta está logada). Clicando nestes recursos, o AI2 (App Inventor 2) disponibiliza todas as funções disponíveis para usar a determinada variável como argumento.

O próximo comando armzena no banco de dados do aplicativo "TinyDB1" o endereço do dispositivo pareado sob a tag "Dispositivo armazenado" para que quando procuremos por dispositivos e encontremos dispositivos que o Android já se conectou anteriormente utilizando esta aplicação, consigamos encontrar pela mesma.

A condição seguinte, indaga se o tamanho da conteúdo da variável que contém o endereço do dispositivo a quem o Android vai se conectar é maior que zero. Ou seja, se há um dispositivo a se conectar, o retorno desta condição será verdadeiro porque o tamanho do conteúdo da variável será maior que zero. Atendendo a esta condição, encontra-se mais uma em seguida que questiona se o dispositivo armazenado na tag está pareado com o Android. Se estiver pareado, segue o baile, se não estiver o aplicativo emite um alerta dizendo "Dispositivo não pareado!". Terminando de executar os comandos da condição anterior, caso nada esteja armazenado na variável "EndDispositivo", sob a tag "Nenhum" um valor "vazio" ficará armazenado.

2ª Parte: Procurando via bluetooth por dispositivos disponíveis.



Esta segunda parte do código começa com as ações executadas assim que o botão "Conectar" é clicado. Assim que isto ocorre, uma tela é aberta com uma lista dos endereços MAC, dos dispositivos pareados com o Android, seguidos dos nomes destes dispositivos.

Assim que o usuário seleciona o dispositivo na lista (tradução literal do verbo "Pick"), uma primeira condição testa se o bluetooth do Android está disponível. Caso esteja disponível, seta a variável "EndDispotivo" para o endereço do dispositivo selecionado na lista aberta pelo botão "Conectar". Em seguida, dentro desta mesma condição, o aplicativo chama o banco de dados para armazenar sob a tag "Dispositivo armazenado" o endereço contido na variável "EndDispositivo". 

Na próxima condição, o código testa novamente se o dispositivo selecionado está mesmo pareado. Caso esteja pareado, uma nova condição testa se a conexão com o dispositivo selecionado foi realizada. Se a conexão foi realizada, seta o texto na caixa de texto abaixo do label "Dispositivo:" para o endereço e o nome do dispositivo ao qual o Android está conectado, seta o texto que indica o status da conexão para "Pronta!" e envia de volta para o dispositivo conectado o seu próprio endereço. Esta última ação de enviar o endereço do próprio dispositivo (ao qual o Android está conectado) para ele mesmo foi necessária para estabilizar a conexão. Antes, quando o código não tinha esta instrução, assim que o Android enviava um comando para o HC-05 o aplicativo exibia erros 507 e 515, questionando se o Android estava mesmo conectado a algum dispositivo ou se o dispositivo conectado estava ativado. Por quê? Não tenho a menor idéia, não sei se é um padrão da comunicação RS232 via SPP, mas comparando alguns códigos encontrados na internet e testando-os, percebi que esta instrução se fazia necessária para "selar" a conexão.

Em seguida, se a conexão não for realizada por algum problema (comunicação, erros, bugs e etc) o aplicativo emite um alerta dizendo "Problemas na conexão!" e o usuário deverá novamente clicar no botão "Conectar".

Caso o botão "Desconectar" seja pressionado, o Android encerra a conexão estabelecida no momento. Caso não haja nenhuma conexão no momento, nada acontece.

3ª Parte: Enviando os comandos para o módulo HC-05.



Chegando a última parte do código, temos as funções de cada botão que ordena uma ação. A lógica de funcionamento dos botões é exatamente a mesma: quando o botão de determinada direção é clicado, o aplicativo testa se o Android está conectado a algum dispositivo e envia o conteúdo armazenado na variável correspondente a direção em questão. Assim que o botão é "desclicado", o aplicativo repete este teste da conexão e envia novamente o número armazenado na variável correspondente a direção. Exemplo: se o usuário clicou no botão "Ré" o aplicativo testa se o Android está conectado a algum dispositivo. Se estiver, o Android enviará o conteúdo armazenado na variável global "Ré" que é a string contendo apenas o número "2". Assim que o usuário retirar o dedo do botão "Ré", o aplicativo repetirá o teste e enviará novamente o algarismo "2". Se o usuário der um toque, clicar e tirar o dedo rápido do botão, o número "2" será enviado duas vezes de forma bem rápida.

* O número é enviado quando o usuário pressiona o botão e depois novamente quando solta o botão porque eu desejo que o meu robô siga para determinada direção enquanto o usuário estiver com o dedo no botão. No código do Arduino, que comentarei aqui no blog, vocês vão entender melhor como funciona este procedimento e como fiz para o Arduino interpretar esta forma de comando.

** Anteriormente tentei enviar direto uma string contendo apenas o número "2", mas por algum motivo desconhecido isso não deu certo. A recepção só ocorreu quando criei uma variável global para armazenar o conteúdo referente a direção de locomoção desejada e a enviei. 
O arduino ao receber comandos via bluetooth deve receber comandos de início de envio e término de envio. Talvez, criando uma variável com um conteúdo e a enviando, o aplicativo já insira os comandos de início e parada de transmissão, já que, quando transmitia apenas o algarismo "2", nenhum comando \n ou \r estava sendo enviado.

No próximo post, comentarei todo o meu código da sketch do Arduino que diz respeito a recepção destes comandos enviados pelo aplicativo ChicoBot.

Hello World!

Oi!

Chico vai ser um robô que poderá funcionar de duas formas: como robô seguidor de linha ou como um robô controlado via bluetooth de um dispositivo Android.


As peças terminaram de chegar hoje, mas mais pra frente estou pra encomendar mais alguns dispositivos pra que ele fique funcionando bem direitinho.


Não sei quando ele vai nascer, mas garanto que será em breve e eu vou documentar todos os passos e feitios aqui neste blog!


O Chico vai ter:
- 02 rodas motorizadas, cada uma com um motor DC 48:1
- 01 módulo bluetooth HC-05
- 01 sensor ultrassônico HC-SR04
- 03 sensores de refletância
- 01 display LCD
- 01 roda de apoio
- 01 microcontrolador ATMEGA328P (será programado em Arduino)


Será montado diretamente numa placa de fenolite feita em casa e “designada” no Eagle Cadsoft.


Por enquanto é isso!



Quem será Chico?


Chico começa a se desenvolver hoje.

Chico vai ser documentado passo a passo e vai nascer em breve.


Como dito, poderá funcionar de dois modos: um robô seguidor de linha ou um robô controlado via bluetooth de um dispositivo Android.


O objetivo de fazer Chico é o aprendizado e o aprofundamento dos meus conhecimentos de programação e o estímulo a criação de soluções para diversos problemas encontrados na robótica.


Aqui, futuramente, também será registrada a passagem de Chico por diversos lugares da cidade e quiçá do país ou do mundo.