Sempre que passo em uma loja de brinquedos e vejo carrinhos de controle remoto na vitrine, fico doido para levar-los para casa, deve ser porque tinha adoração por este tipo de brinquedo, mas por falta de opções e grana, não cheguei a ter um quando criança. Para compensar e ter uma desculpa para comprar um 😉 vamos desmontar um desses, “raqueando” suas principais partes e substituindo a eletrônica embarcada original por um microcontrolador tipo Arduino facilmente comandado a distância por um dispositivo Android. Com isso, ficará muito fácil adicionar ao carrinho novas funcionalidades, sensores, etc. É uma forma muito barata de se construir um robô para uso didático.
O vídeo abaixo, mostra como ficará o projeto final:
Conhecendo o carrinho
O primeiro passo será desarmar o carrinho para se ter uma idéia de como ele funciona, o que se aproveitará e o que se deve ser adicionado:
Na parte inferior da carcaça, estão os os dois motores (frontal e traseiro), o compartimento da bateria (recarregável, 5V) e o modulo eletrônico. Na parte superior da carcaça, está a antena (placa de cobre conectada a um cabo negro) e os 4 LEDs que funcionam como os faróis dianteiros e traseiros. Cada LED está conectado separadamente por um par de fios. Com esse arranjo, se pode:
- Acender os faróis (acender os dois LEDs frontais)
- Dar pisca (acender os LEDs esquerdos ou direitos)
- Sinalizar uma frenagem (acender os dois LEDs traseiros)
O diagrama em blocos da eletrônica original é:
Em relação a mobilidade, nos projetos anteriores de robôs utilizamos a técnica de “Differential Steering” onde variando-se o sentido de giro das rodas, varia-se a direção do rob0, mas aqui se pode ver que o carrinho, apesar de também possuir dois motores DC , possui uma confirmação diferente de motores:
O motor frontal, não possui nenhum controle de velocidade ou posição, sendo utilizado apenas para virar o carrinho “à direita”ou “à esquerda”, movendo-se simultaneamente todo o conjunto rodas/eixo frontal (mais ou menos como em um automóvel). Em geral o carrinho sempre se move para a frente em linha reta e o motor está desligado, deixando assim as rodas livres. Um comando para “virar à esquerda” p
or exemplo, fará o motor girar, fazendo o mecanismo de engrenagens como um todo se mover para a esquerda. Enquanto o motor estiver alimentado o mecanismo ficará nessa posição limite e o carrinho continuará “virando à esquerda”).
O motor traseiro está acoplado a um sistema redutor de velocidade por engrenagens e fornece torque variável as rodas traseiras (conjunto fixo). Pode-se assim variar a velocidade, mas não a direção (as duas rodas sempre girarão em um mesmo sentido).
Raqueando a eletrônica embarcada
Uma vez que tudo foi identificado, é a hora de remover a eletrônica original, deixando somente os cabos dos motores e bateria. Como não vou voltar a usar a carcaça superior por enquanto, não me preocuparei com os LEDs originais.
No lugar do módulo eletrônico, usaremos um Arduino Uno, que será o responsável pela lógica do processamento, acionando os motores, LEDs e um Buzzer. O controle remoto que antes era conseguido por um sistema receptor de RF de 27MHz será agora substituído pelo modulo HC-06, o qual se comunicará com um dispositivo Android. A bateria original do carrinho será mantida exclusivamente para a alimentação dos motores via a H-Bridge L293D, pois os motores DC além de consumirem bastante corrente geram ruído devido a suas escovas. Pela maneira que o carrinho foi construído, o motor frontal consome bastante energia no momento em que recebe um comando de virar para um dos lados, pois seu eixo será travado e o consumo de corrente será alto. Para o Arduino usaremos uma bateria de 9V (Vin), sendo que o modulo HC-06 será alimentado pela saída de 5V do Arduino).
O novo diagrama de blocos para implementação do circuito é:
Neste ponto é importante testar os motores individualmente. Usando uma bateria, alimente o motor e observe para que lado lado ele gira. Inverta a bateria e repita o teste anotando as cores dos fios:
No caso de meu carrinho, temos:
Front Motor:
- Yellow: LEFT
- White: RIGH
Rear Motor:
- Green: Backward
- Blue: Forward
Montagem Final
O circuito (as cores dos fios do motor não são as corretas):
O HW do novo carrinho à controle remoto está pronto para seus primeiros testes. Agora, falta implementar o SW e o aplicativo Android.
O Aplicativo Android
Para controlar o carrinho, usaremos uma App que desenvolvi utilizando o MIT AppInventor 2: “MJRoBot BT Remote Control”. A app pode ser baixada gratuitamente da loja da Google através do link: MJRoBot BT Remote Control
A app possui uma interface simples, permitindo o envio de comandos ao modulo de BT tanto em modo TEXT, como diretamente via botões pre-programados (cada vez que um botão é pressionado, um caracter é enviado):
w: Forward
s: Backward
d: Right
a: Left
f: Stop
p: ON/OFF
m: Manual / Automatic
+: Speed+
-: Speed-
Também existe uma janela de texto para mensagens recebidas do modulo BT. Esta característica é bem importante durante a fase de testes, pois pode ser usada da mesma maneira que o “Serial monitor”.
O Diagrama de blocos para o projeto no MIT appInventor2:
O Código Arduino
O bloco principal do código é bem simples:
void loop() { checkBTcmd(); // verify if a command is received from BT remote control receiveCmd (); if (turnOn) manualCmd (); else stopRobot (); }
A primeira coisa a se fazer é verificar se existe algum novo comando BT chegando. Quem checará isso é a função “checkBTcmd()”:
void checkBTcmd() // verify if a command is received from BT remote control { if (BT1.available()) { command = BT1.read(); BT1.flush(); } }
A variável “turnOn” é utilizada para ligar ou desligar o carrinho. A função “receiveCmd()” será a encarregada de definir o status dessa variável em função do comando recebido do modulo BT. Observe que pela lógica usada, cada vez que o botão vermelho com o símbolo de “POWER” é pressionado, o caracter “p” será enviado pelo app e a a variável “turnOn”, mudará se valor (de 1 para 0 e vice e versa):
void receiveCmd () { switch (command) { case 'p': turnOn = !turnOn; command = 0; analogWrite(ledStatus, turnOn*128); // Robot ON - Led ON beep(outBuz, 1000, 100); BT1.print(" COMMAND ON/OFF"); BT1.println('\n'); delay(200); //Delay to call attention to mode change break; case 'm': //not used here break; } }
Voltando ao loop principal, enquanto a variável “turnOn” é HIGH (1), a função “manualCmd()” executará um comando, dependendo do caracter recebido:
void manualCmd() { switch (command) { case 'f': moveStop(); //turn off both motors state = command; break; case 'w': moveForward(); state = command; break; case 'd': moveRight(); break; case 'a': moveLeft(); break; case 's': moveBackward(); state = command; break; case '+': if (state == 'w') { motorSpeed = motorSpeed + 10; if (motorSpeed > MAX_SPEED) motorSpeed = MAX_SPEED; command = 'w'; } else command = state; break; case '-': if (state == 'w') motorSpeed = motorSpeed - 10; if (motorSpeed < MIN_SPEED ) motorSpeed = MIN_SPEED; command = state; break; } }
Por exemplo, se o comando “w” é recebido a função específica para mover o carrinho para a frente “moveForward()” é executada.
Em caso “powerOn” esteja em HIGH e a tecla “POWER” seja pressionada, a variável “powerOn”, passará a LOW e a função “stopRobot()” será a executada ao invés de “manualCmd()”. Esta função garante que o motor traseiro esteja parado, os LEDs apagados e variáveis zeradas.
void stopRobot () { digitalWrite(ledBlue, LOW); digitalWrite(ledRed, LOW); state = 0; moveStop(); //turn off both motors }
Acionando os motores DC via H-Bridge
Os motores frontal e traseiro estão ligados a ponte-H como mostrado abaixo:
e a cada um dos pinos do Arduino, os quais deverão ser definidos como OUTPUT, será atribuído uma variável:
const int rearMtFw = 4; // Rear Motor - FW const int rearMtBw = 7; // Rear Motor - BW const int rearMtEne = 6; // Rear Motor - enable const int frontMtLeft = 2; // Front Motor - turn Left const int frontMtRight = 3; // Front Motor - turn right const int frontMtEne = 5; // Front Motor enable
Por exemplo, se desejamos mover o carrinho para a frente, a função “moveForward()” deverá colocar o pino 4 en HIGH e o pino 7 em LOW, isso fará com que a corrente flua “no sentido horário”, como mostrado no diagrama abaixo:
O pino 6 é o “enable”, somente quando ele estiver em “HIGH”, a ponte permitirá o fluxo de corrente pelo motor. Como este pino possui característica PWM, a velocidade com que o motor girará, dependerá do valor da variável “motorSpeed”, no pino 6 (valor de 0 255).
A função também deverá garantir que o motor frontal “gire livremente”, e para isso o pino 5, que é o pino de “enable” deverá estar em LOW (o status dos pinos 2 e 3 não importam, uma vez que o enable está el LOW). O LED vermelho, que funciona como “luz de ré”, deverá sempre estar apagado quando o carrinho se move para a frente:
void moveForward() // rear motor FW { analogWrite(rearMtEne, motorSpeed); digitalWrite(rearMtFw, HIGH); digitalWrite(rearMtBw, LOW); digitalWrite(frontMtEne, LOW); digitalWrite(ledRed, LOW); delay(5); }
por analogia, é obvio que para o carrinho “mover para trás”, basta que o motor gire na direção contrária. Para isto, o pino 4 deverá estar em LOW e o pino 7 em HIGH. Note que nesse caso a “luz de ré”, deverá estar acesa. A função neste caso será:
void moveBackward() // rear motor BW { analogWrite(rearMtEne, motorSpeed); digitalWrite(rearMtFw, LOW); digitalWrite(rearMtBw, HIGH); digitalWrite(frontMtEne, LOW); digitalWrite(ledRed, HIGH); delay(5); }
O mesmo raciocínio pode ser utilizado para o motor frontal, somente que nesse caso, não existe controle de velocidade. Colocando o pino 2 (enable) em HIGH habilita o motor a “tentar girar”, para um lado ou para outro dependendo do status dos pinos 2 e 3:
void moveLeft() // front motor left { digitalWrite(frontMtEne, HIGH); digitalWrite(frontMtLeft, HIGH); digitalWrite(frontMtRight, LOW); digitalWrite(ledRed, LOW); delay(10); } //************************************// void moveRight() // front motor right { digitalWrite(frontMtEne, HIGH); digitalWrite(frontMtLeft, LOW); digitalWrite(frontMtRight, HIGH); digitalWrite(ledRed, LOW); delay(10); }
Para parar o carrinho, basta colocar todas as saídas da ponte relativas ao motor traseiro em LOW, o que “travará” o eixo do motor (o motor frontal basta o enable estar em LOW):
void moveStop() //turn off rear motor { analogWrite(rearMtEne, LOW); digitalWrite(rearMtFw, LOW); digitalWrite(rearMtBw, LOW); digitalWrite(frontMtEne, LOW); digitalWrite(ledRed, LOW); delay(5); }
No link abaixo, você poderá encontrar o código completo para o Arduino:
Conclusão
O carrinho está devidamente raqueado e pronto para ganhar o mundo! Agora o céu é o limite! Comece, por exemplo instando sensores para evitar obstáculos, um HC-04 (ultra-som) funcionará bem, como vimos no caso do “Mars Rover” tupiniquim. Crie um novo comando e envie o “caracter” via texto (ou use o botão Man/Auto: caracter “m”, para o robô executar outras fincões (buzina, por exemplo).
Outra idéia interessante é melhorar a “dirigibilidade” do carrinho. O motor DC frontal poderia ser substituído por um servo de 180o que movimentaria o conjunto frontal de maneira linear, obtendo-se assim ângulos de virada variáveis. A foto ao lado é de um exemplo que encontrei a web. Não é exatamente o mecanismo de meu carrinho, mas mas mostra como poderia ficar.
That’s all folks!
Como sempre, espero que este projeto ajude outras pessoas a encontrar seu caminho no apaixonante mundo da eletrônica e dos robôs!
Não deixe de visitar e seguir minha página: MJRoBot.org no Facebook
Saludos desde el sur del mundo! 😉
Um abraço e até o próximo post!
Obrigado
boa noite ,adorei seus projetos,eu estou cursando superior em analise e desenvolvimento de sistemas e ciencias da computação,estou no 3 semestre ,estou vendo seus projetos e estou muito afim de aprender ainda mais para ficar mais por dentro da programação,o que senhor me indica ?para que eu possa continuar a melhorar meu aprendizado?
CurtirCurtir
Eu queria saber onde fica o comando ipconnect no apo inventor pq eu não tô consseguindo encontra-lo
CurtirCurtir
Preciso de um aplicativo para Iphone IOS 9
CurtirCurtir
Não conheço um App da Apple que trabalhe bem com o BT utilizado no projeto. Además por enquanto é complicado desenvolver para iPhone um App como se faz para Android. O MIT está trabalhando em um AppInventor que deverá fazer isto, mas ainda não tem data de lançamento.
CurtirCurtir
Bom dia Marcelo.
Obrigado, consegui baixar o arquivo aia.
Vou tentar replicar.
CurtirCurtir
Oi Marcelo.
Parabéns pelo seu trabalho, muito bom mesmo, suas explicações são ótimas, tirou várias dúvidas que eu tinha.
Gostei de todos os seus projetos.
Sou iniciante em Arduino/IOT, tenho me interessado bastante pela plataforma ESP8266/bluetooth, oferecem mais possibilidades…
Estou começando também o meu aprendizado no MIT App Inventor, e gostaria de saber se você poderia enviar o arquivo aia, do controle do carro?
Desde já muito obrigado.
Roberto Carlos
CurtirCurtir
Oi Roberto Carlos. Muito obrigado por suas palavras. Fico feliz que tenha gostado dos posts. Espero continuar criando projetos interessantes a medidas que o tempo permita! 😉
Estou viajando sem meu Mac, mais pelo iPhone abaixei este arquivo que acredito ser o último. Da uma olhadinha:
https://www.dropbox.com/s/icabeubcw9vpkpt/MJRoBot_II_BT_Command_V3.aia?dl=0
Sexta feira estarei de novo no Chile e ficará mais fácil te ajudar.
Um abraço.
Marcelo
CurtirCurtir
Oi Marcelo.
Muito obrigado pela resposta tão rápida.
Agora quem esta viajando sou eu, retorno no final de semana pra casa, em Cabo Frio.
Quando chegar em casa vou baixa o arquivo, e deixo vc saber se deu tudo certo.
Muito obrigado, mais uma vez.
É difícil achar pessoas dispostas à ajudar, a compartilhar um pouco do seu tempo e conhecimento, no aprendizado de outros…Parabéns.
Roberto Carlos
CurtirCurtir
não consigo instalar o codigo no arduino
fatal error: robotDefines.h: Arquivo ou diretório não encontrado
poderia dizer como corrigir ?
CurtirCurtir
Oi Daniel,
Voce deve ter os 4 arquivos que compõe o código instalados em um mesmo diretório.
Faca o download dos aerquivos aqui:
https://github.com/Mjrovai/MJRoBot-AutoBot
Você vai ver que um dos arquivos é o “robotDefines.h”, onde mantenho as principais definições de constantes e variáveis do projeto. Você poderá observar que esse arquivo é chamado ao início do código que está no no arquivo principal: “MJRoBot_AutoBot.ino”. No momento que o IDE do Arduino vai compilar o código ele vai e consulta o arquivo .h
Para carregar o programa, no IDE do Arduino, abra o arquivo MJRoBot_AutoBot.ino. Automaticamente os quatro arquivos irão aparecer nas “Tabs” superiores. Basta voce então fazer o upload ao seu Arduino.
CurtirCurtir