Introduction: Recycled Runaway Robot Car • Carro Robô Fujão Reciclado

About: Artista brasileiro interessado em gambiarras no geral!
Eu e meu filho Gabriel começamos esse projetinho para reciclar um carro de controle remoto que eles quebraram.

Ficamos com o chassi e dois motores. A placa de circuito impresso e a unidade de controle remoto não serviam para nada. Acho que os meninos derrubaram o carro na banheira, ou deixaram na chuva.

A idéia é aprender a usar o Arduino e dar uma nova utilidade para alguns brinquedos eletrônicos que se quebraram.

Isso aqui é um Work in Progress. Por isso ainda não está traduzido para o inglês e o sketch final AINDA NAO ESTA PRONTO.

This is a Work in Progress. There is no english translation for now. The Arduino Sketch still not ready.


Lista de Materiais:

1 Arduino Uno
1 Arduino Motor Shield White (Dealextreme - http://dx.com/p/218207) e http://linksprite.com/wiki/index.php5?title=Motor_Shield
2 Sensores Ultrasonicos HC-SR04 (http://elecfreaks.com/store/download/HC-SR04.pdf)
1 Chassi completo de carro por controle remoto (com dois motores - um para direção e outro para propulsão)
1 Caixa de DVD (Só pelo plástico)
Fios, Solda, Estilete, Dremel

Step 1: Ajustes • Adjusting

Do carro original, só utilizamos a estrutura de plástico e os dois motores DC. O circuito de controle original foi inutilizado.
O projeto original usava um motor DC simples para a direção do carro (sem servo) e um outro motor para a propulsão.

Então o Arduino Motor Shield pareceu perfeito para o nosso caso.

Conectamos o Motor Shield no Arduino Uno e fizemos um primeiro teste usando o exemplo do próprio Shield (https://s3.amazonaws.com/linksprite/Shields/motor_shield/Grobe-_Motor_Shield_Demo_Code.zip)

Na saída M1 (M1+ e M1-) ligamos o motor de direção. Na saída M2 (M2+ e M2-) ligamos o motor de propulsão.

O Shield tem conexões tipo Grove para sensores, mas nós não temos nenhum cabo desse tipo.

Fizemos algumas experiências com o ajuste de velocidade e direção. No nosso caso, a velocidade do Motor de Direção precisava ficar em 255, porque uma redução nessa velocidade diminuía o ângulo de giro do carro e o torque do motor, resultando em uma curva muito sutil.



Step 2: Sensores HC SR04 • Sensors HC SR04

Eu comprei um par desses sensores, porque pensei num robô que pudesse prever a melhor rota de fuga. 
Colocamos os dois sensores na dianteira do carrinho e para isso eu criei uma moldura de plástico cortando uma caixa de DVD sem uso. Mantive 4 cm de distância entre os sensores.

Minha idéia com os sensores colocados desta maneira é que o carro seja capaz de prever se é melhor fugir pela direita ou pela esquerda, dependendo de qual lado estiver desimpedido.

A gente vai usar a biblioteca NewPing.h que possui a seguinte sintaxe:

Using NewPing (Syntax)

NewPing sonar(trigger_pin, echo_pin [, max_cm_distance]); - Initialize an ultrasonic device, trigger pin, echo pin, and optional maximum distance you wish to sensor to measure (default = 500cm).
sonar.ping(); - Send a ping and get the echo time (in microseconds) as a result.
sonar.ping_in(); - Send a ping and get the distance in whole inches.
sonar.ping_cm(); - Send a ping and get the distance in whole centimeters.
sonar.ping_median(iterations); - Do multiple pings (default=5), discard out of range pings and return median in microseconds.
sonar.convert_in(echoTime); - Convert echoTime from microseconds to inches.
sonar.convert_cm(echoTime); - Convert echoTime from microseconds to centimeters.
sonar.ping_timer(function); - Send a ping and call function to test if ping is complete.
sonar.check_timer(); - Check if ping has returned within the set distance limit.
NewPing::timer_us(frequency, function); - Call function every frequency microseconds.
NewPing::timer_ms(frequency, function); - Call function every frequency milliseconds.
NewPing::timer_stop(); - Stop the timer.

Step 3: O Carro Montado • the Car, Mounted

O interessante com o Arduino é que não adianta eu colocar o código que eu usei aqui para que você possa copiar. É preciso que eu explique todo o raciocínio e as condições de montagem para que você seja capaz de construir sua própria versão deste projeto.

Então a gente tirou essa foto do carro totalmente montado com as descrições de todas as ligações que fizemos no Motor Shield.

M1+ = Motor de Direção + (Fio vermelho)
M1- = Motor de Direção - (Fio Preto)

M2+ = Motor de Propulsão + (Fio Verde)
M2- = Motor de Propulsão - (Fio Branco)

Sensor do Lado Esquerdo
Pino 3 (Arduino e Motor Shield) = Trigger (Laranja)
Pino 4 (Arduino e Motor Shield) = Echo (Vermelho)
VCC - Fio Amarelo e GND - Fio Marrom

Sensor do Lado Direito
Pino 5 (Arduino e Motor Shield) = Trigger (Cinza)
Pino 6 (Arduino e Motor Shield) = Echo (Branco)
VCC - Fio Roxo e GND - Fio Preto

Step 4: Um Programa Teste • a Test Program

Esse programinha aqui é só para ver se os sensores estão lendo as distâncias corretamente.

/* Carro Robo
Essa e uma experiencia de reciclagem de um brinquedo dos meus filhos Pedro e Gabriel
Eles ganharam um carro de controle remoto da avo que acabaram destruindo.
So temos o chassi, com dois motores funcionais.

No nosso projeto, estamos usando um Motor Shield que comprei na DX.com
No shield, temos dois motores.
MA, que vai ser nossa direcao e MB que vai ser  nossa propulsao

Para evitar colisoes, estamos usando dois sensores ultrassonicos
HC-SR04, posicionados no parachoque dianteiro, um de cada lado.

*/

#include <NewPing.h> // Incluindo a Biblioteca para lidar com o Sensor.
#define TRIG_E 3
#define ECHO_E 4
#define TRIG_D 5
#define ECHO_D 6
#define AVOID 150
NewPing sonarEsq (TRIG_E,ECHO_E,AVOID);  // Cria um objeto para o sensor sonarEsq (Trigger, Echo)
// A ordem de cores e VCC Amarelo, Trigger Laranja, Echo Vermelho, GND Marrom
NewPing sonarDir (TRIG_D,ECHO_D, AVOID);  // Cria um objeto para o sensor sonarDir (Trigger,Echo)
// A ordem de cores e VCC Roxo, Trigger Cinza, Echo Branco, GND Preto

/*Configura os motores
M2 vira para a esquerda quando M2- = GND e M2+ =VCC
M2 vira para a direita quando M2- = VCC e M2+ = GND */

int pinI1=8; // Preparando os pinos de entrada de M2
int pinI2=11;
int speedpinA=9; // Motor do Volante

int pinI3=12;
int pinI4=13;
int speedpinB=10; // Motor da Propulsao

int speedA=255; // Velocidade do Volante
int speedB=255; // Velocidade do Carro



void setup ()
{
  Serial.begin(115200); // Isso eu abri so para fazer o debug do carrinho
  pinMode (pinI1, OUTPUT);
  pinMode (pinI2, OUTPUT);
  pinMode (speedpinA, OUTPUT); // inicializando o motor do volante

  pinMode (pinI3,OUTPUT);
  pinMode (pinI4, OUTPUT);
  pinMode (speedpinB, OUTPUT); //inicializando motor de Propulsao
}
void frente()
{
  analogWrite (speedpinB, speedB); //aciona o motor de propulsao
  digitalWrite (pinI3, LOW);
  digitalWrite (pinI4,HIGH);

  analogWrite (speedpinA, LOW); // mantem o motor de volante parado
  digitalWrite (pinI1,LOW);
  digitalWrite (pinI2,LOW);
  Serial.println ("Frente");
}
void atras()
{
  analogWrite (speedpinB, speedB); //aciona o motor de propulsao
  digitalWrite (pinI3, HIGH);
  digitalWrite (pinI4,LOW);

  analogWrite (speedpinA, LOW); // mantem o motor de volante parado
  digitalWrite (pinI1,LOW);
  digitalWrite (pinI2,LOW);
  Serial.println ("Marcha Re");
}
void direita()
{
  analogWrite (speedpinB, speedB); //aciona o motor de propulsao
  digitalWrite (pinI3, LOW);
  digitalWrite (pinI4,HIGH);

  analogWrite (speedpinA, speedA); // estabelece a velocidade de giro do volante
  digitalWrite (pinI1,HIGH); // gira a direita
  digitalWrite (pinI2,LOW);
  Serial.println ("Direita");
}
void esquerda()
{
  analogWrite (speedpinB, speedB); //aciona o motor de propulsao
  digitalWrite (pinI3, LOW);
  digitalWrite (pinI4,HIGH);

  analogWrite (speedpinA, speedA); // estabelece a velocidade de giro do volante
  digitalWrite (pinI1,LOW); // gira a esquerda
  digitalWrite (pinI2,HIGH);
  Serial.println ("Esquerda");
}
void fogedireita()
{
  analogWrite (speedpinB, speedB); //aciona o motor de propulsao
  digitalWrite (pinI3, HIGH);
  digitalWrite (pinI4,LOW);

  analogWrite (speedpinA, speedA); // manobra de fuga em re pela direita
  digitalWrite (pinI1,HIGH); // gira a esquerda
  digitalWrite (pinI2,LOW);
  Serial.println ("Saida pela direita");
}
void fogeesquerda()
{
  analogWrite (speedpinB, speedB); //aciona o motor de propulsao
  digitalWrite (pinI3, HIGH);
  digitalWrite (pinI4,LOW);

  analogWrite (speedpinA, speedA); // manobra de fuga em re pela esquerda
  digitalWrite (pinI1,LOW); // gira a direita
  digitalWrite (pinI2,HIGH);
  Serial.println ("Saida pela esquerda");
}
void parar()
{
  digitalWrite (speedpinA,LOW);
  digitalWrite (speedpinB,LOW);
  delay (1000);
  Serial.println("Parei");
}
/* Vou construir aqui um loop apenas para fazer o carro andar em circulos.
Ainda falta criar a logica de fuga; */

void loop() {
  unsigned int sE = sonarEsq.ping();
  unsigned int sD= sonarDir.ping();
  int distEsq = sE / US_ROUNDTRIP_CM;
  int distDir = sD / US_ROUNDTRIP_CM;
  int safe = 30; // Distancia segura
  delay(50);                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
 
  while (distDir > safe) {
    frente ();
    delay (1000);
   }
esquerda ();
delay (1000);
  
  Serial.print("Ping Sensor Direito: ");
  Serial.print(distDir);
  Serial.println("cm");
  Serial.print("Ping Sensor Esquerdo: ");
  Serial.print(distEsq);
  Serial.println("cm");
}