Menu


 



     Conheça POBRE-E, nosso robô baseado no Rolly, do autor Simon Monk, o nosso primeiro robô autônomo, utilizando microcontrolador Arduino Uno.
     Qualquer pessoa poderá montar o seu POBRE-E. Basta um pouco de paciência e cuidados com as ferramentas, (furadeira, serras, chaves de fenda e principalmente o ferro de soldar, se não souber manusear peça ajuda à alguém que saiba).
     O Arduino Uno pode ser uma placa básica de 8-bits, mas quando se trata de interagir com o mundo exterior, é muito mais fácil de usar do que uma CPU Intel Core ou AMD FX.
     As conexões de entradas e saídas analógicas e digitais do Uno são perfeitos para muitas tarefas do mundo real.
     No entanto, desta vez, estamos dispostos a ensinar a você que é possível ter seu robô sem te que recorrer a vastos conhecimentos e tecnologias.
     Este não é um robô de controle remoto - POBRE-E pensa por si mesmo, evitando os obstáculos e determinando sua própria direção.

Coletando as peças necessárias!
A primeira coisa que você vai querer fazer é juntar o material. O objetivo na nossa concepção, era fazer um robô que fosse o mais barato possível, fácil de compilar e executar, mas ainda assim capaz de mostrar alguma personalidade.
Talvez, muitas das peças você já tenha, o custo pode cair bastante, por isso o POBRE-E não vai morder tanto a sua carteira.

Diagrama de blocos


 
 Falaremos mais sobre como POBRE-E faz e o que faz mais tarde, mas o diagrama de blocos vai lhe dar uma boa idéia do que está acontecendo.

O nosso pequeno robô combina uma série de dispositivos do mundo real para se movimentar e controlar,  tudo ao mesmo tempo!
Ele começa com o Motor Drive Shield ("Shield" é o nome das placas de expansão do Arduino) para fornecer recursos extras e para lidar com os dois motores CC, mais a "cabeça"  que utiliza um servo motor ao qual está situado o sensor ultra-sônico que são os seus "olhos"
.
  O sensor ultra-sônico fornece informações precisas de distância, todos os centímetros são usados para determinar as necessidades do POBRE-E, por exemplo, parar,   fazer backup ou simplesmente desviar do objeto que está  bloqueando seu caminho.
Apesar de estar ligado ao Motor Drive Shield, os dados do sensor ultra-sônico são passados diretamente para a placa do micro controlador Arduino.

          Está tudo controlado através do código fonte. Mas isso é o suficiente para a teoria -
vamos começar a construir!

Passo 1:
A base
Sim, estamos usando uma tampa de recipiente plástico para alimentos como base para o nosso robô!
Você pode construir o seu do jeito que quiser!
Apenas certifique-se de usar um tamanho adequado e que  a superfície seja bastante rígida.

Pode ser necessário cortar um flange na extremidade de ambos os lados da tampa para permitir que o eixo da roda do motor possa se mover livremente.
Com cuidado, use uma ferramenta adequada.

Dica: Ao perfurar em plástico, coloque sua furadeira na velocidade mais baixa, comece com uma broca de 2 mm.
Se tentar furar em alta velocidade de uma só vez, você pode rasgar o plástico todo. (recomendo obter uma micro-retífica elétrica para que você possa elaborar serviços manuais de maior precisão).



Sim, isso é realmente uma tampa de recipiente plástico de alimentos sendo usada como base - é barato e fácil de encontrar!

Passo 2: Solde os capacitores e cabos
Os capacitores de 0.1uF  (100 NF) tem que ser soldados através das conexões do motor eles ajudam a reduzir o ruído elétrico no circuito.
Desde que você use capacitores de cerâmica ou poliéster, eles não têm polaridade. Você deve soldar um em cada motor.
Tente colocar os capacitores encostado ao corpo na caixa amarela do motor, para manter as coisas organizadas.

 Dica:  As aletas de ligação do motor são muito fracas, por isso não dobre ou force, e não demore mais do que cinco segundos para soldar os capacitores, ou você pode quebrar as aletas de conexão do motor .



Os capacitores 0.1uF ajudam a reduzir o ruído de RF sobre os fios de alimentação.
 

Passo 3: Instalando os motores DC
Instale os dois motores de corrente contínua em lados opostos da base usando a fita dupla face.

Coloque os motores tão perto da borda quanto possível para permitir o livre movimento da roda.



Use fita acolchoada de dupla face para prender os motores base.
 

 

Passo 4: Adicione a engrenagem do servo motor
O pequeno servo motor SG90 dá ao nosso robô um pescoço para que ele possa girar o sensor de ultra-sons em seu eixo.
O próprio servo motor deve vir com um pacote de acessórios anexos.

           Use o braço de dois lados e pressione-o no eixo do servo motor.

Provavelmente vai precisar usar um pouco mais de força para encaixá-la na primeira vez, mas tente não usar muita força.



Use a engrenagem de dois lados do servo motor.
 

Passo 5: Soldar os fios da blindagem
O Motor Drive Shield fornece a potência de acionamento extra para controlar os motores DC.
Ele também fornece conexão para o servo motor e o sensor de ultra-sons, para isso você vai precisar de quatro fios DuPont machos. 



Fios DuPont machos, podem ser comprados prontos, serão usados para se conectar ao Motor Drive Shield
 

Passo 6: Encaixe o Motor Drive Shield no Arduino
O Motor Drive Shield tem uma série de pinos na parte inferior da placa - estes se alinham com os no topo do Arduino.
Alinhe os pinos e pressione o shield na placa Arduino.



Alinhe os pinos conectores e pressione o shield para dentro da placa do Arduino Uno .
 

Passo 7: Instale o Arduino e as pilhas
Pegue um pouco de fita dupla face acolchoada e cole-as na parte inferior da placa Arduino e na caixa de pilhas.
Certifique-se de se orientar pela caixa da bateria para que o interruptor fique sobre a borda traseira para torná-lo mais fácil de operar.

Cole a caixa de bateria para baixo primeiro, assegurando que as saliências do interruptor na parte de trás fiquem alinhadas com a placa do Arduino/shield.


 



Verifique se o interruptor de alimentação está " sobrando" na parte de trás.
 

Passo 8: Instale o sensor e o servo motor
Em seguida, aplique um pouco de fita acolchoada dupla face na parte superior do sensor ultra-sônico,  use o suficiente para envolver em torno dos lados.                    
          Certifique-se que os quatro pinos do sensor estão apontando para cima e pressione o sensor contra a engrenagem do servo.

Coloque também um pouco mais de fita no fundo do servo-motor e instale-o na parte da frente da base, perto dos orifícios de montagem da roda boba.

Conecte o cabo de alimentação do servo motor na porta 'SERVO_2' no topo esquerdo da unidade Motor Shield.



Use a fita dupla face para prender o sensor na engrenagem do servo motor.
 

Passo 9: Conecte os fios DuPont
Em seguida, conecte as extremidades fêmeas dos fios DuPont aos pinos do sensor ultra-sônico.
O fio A5 deve ser conectado no pino " ECHO (eco)" e o fio  A4 no pino "TRIG (gatilho)". 
Eu usei um elástico levemente ajustado para manter os fios organizados e permitir espaço suficiente para se mover livremente.

Dica: O sensor ultra-sônico HC-SR04  é conectado às entrada analógicas do Arduino, embora nós vamos programá-lo  primeiro nas entradas digitais em nosso código fonte.

 



Prenda os fios DuPont nos terminais do sensor (verifique no diagrama de blocos).
 

 

Passo 10: Coloque os fios nos motores e nas pilhas
Conecte as pilhas no seu suporte e parafuse no  EXT_PWR do Shield, mas tenha absoluta certeza de que você colocou a polaridade correta,
ou você vai explodir tudo antes de começar.
          Um dos terminais do conector no referido bloco deve estar rotulado como + M  e outro GND.
Qualquer que seja o suporte de pilhas que você escolher, o fio vermelho vai para o terminal conector + M e o fio preto ao terminal GND.

Os fios do motor DC se conectam aos terminais M1 e M2. Os fios do motor do lado esquerdo vão aos terminais do bloco M1; O motor do lado direito vai para o bloco M2. 
         
Não se preocupe muito com a polaridade nesta fase da montagem - espere até chegar ao estágio de teste que vamos resolver todos os problemas de polaridade.

 



Coloque os fios do motor DC M1 e M2.

 

Passo 11: pré-verificação
 Antes de instalar qualquer pilha, verifique novamente todas as conexões.
O encaixe do servo motor, o sensor de ultra-sons e as ligações da caixa de pilhas devem estar corretas.
Os fios do motor DC são os menos importantes nesse momento.

 

 



Use o Arduino IDE para compilar o código fonte do nosso robô na placa Arduino.
 

 

 

Passo 12: Programa do Arduino
Pegue o código fonte "Pobree.zip". Descompacte-o e copie o conteúdo da pasta 'libraries' para a pasta /Arduino-1.0.5/ (ou superior)
em seu PC.
Copie a pasta Pobree para a pasta sketchbook.
          Inicie o Arduino IDE e você poderá testar e compilar o código fonte.
Conecte o cabo USB na sua placa Arduino e no IDE, vá para 'Ferramentas> Porta Serial "e verifique se você está usando a porta COM correta.
Compile e faça o upload do código para sua placa Arduino.
        
  Quando estiver terminado, está feito!

 



Será necessário realinhar o sensor na primeira vez que for ligar o robô.
 

 

Passo 13: Alinhar o sensor ultra-sônico
Após verificar todas as ligações. coloque as pilhas alcalinas e ligue a chave, conte dois segundos, e desligue .
O servo motor deve mover-se rapidamente, o LED deve acender na unidade Motor Shield, mas o sensor ultra-sônico, provavelmente, já não aponta diretamente para frente.
Não se preocupe - isso é completamente normal.
Retire cuidadosamente a engrenagem do servo motor com o sensor ainda ligado (a fita acolchoada virá com ele) e realinhe a engrenagem para que o sensor de ultra-sons fique voltado diretamente para a frente.
Pressione a engrenagem do servo motor para a posição apontado para frente da base do robô.

Primeiro Teste

           Você está pronto para o primeiro teste.
Coloque o POBRE-E em um terreno aberto, aperte o interruptor na caixa das pilhas e veja o que acontece.
           Depois de um tempo, o servo motor deve balançar o sensor de ultra-sons em ambas as direções e o robô deve começar a se mover para a frente.
Se ele estiver girando em torno de si mesmo, você provavelmente colocou os fios de algum motor DC incorretamente.

Se for virar à direita, o motor do lado direito gira para trás se ele estiver virando à esquerda, o motor do lado esquerdo é que está errado.
           Depois de ter corrigido isso, tente colocar alguns objetos na frente do POBRE-E.
Ele devera perceber o objeto e se desviar dele. Se ele fez isso parabéns - ele está funcionando!

Qual é o próximo passo?

           Se você estiver se sentindo aventureiro, tente modificar o código fonte.
Eu acredito que você possa ser capaz de entender e ter uma mínima compreensão do que está acontecendo, mas vai levar um bom tempo, porque há um bocado de código lá.
          Na verdade, estamos criando uma forma muito rudimentar de inteligência artificial para o nosso micro robô.
          E é justamente o código que determina a sua "personalidade" ou como ele responde ao ambiente.
Porém você não deve alterar as atribuições de pinos no código fonte, tente mudar outras partes do código para ver o que acontece.
 

Dê uma chance a si mesmo!

           A melhor dica que posso dar é estar pronto para improvisar.
Como eu disse logo no início, não estamos construindo um kit, estamos criando algo do zero, então você pode precisar adaptar o projeto para encaixar nas peças que você já tem.
E isso é perfeitamente normal, porque você não está apenas aprendendo a resolução de problemas, você está aprendendo sobre eletrônica, micro controladores e o resto, que irá ajudá-lo com outros projetos e talvez até mesmo gerar toda uma nova carreira!

Opcionalmente... 

Talvez você  queira utilizar um chassi pronto.
já construído pra facilitar o seu trabalho.
Existem várias opções no mercado, mas isso vai aumentar bastante o custo do seu POBRE-E.

 

 

 

Código

#include <AFMotor.h>
#include <Servo.h> 
#include <NewPing.h>

#define TRIG_PIN A4 // Pino A4 no Motor Drive Shield conectado no sensor ultrassônico
#define ECHO_PIN A5 // Pino A5 no Motor Drive Shield conectado no sensor ultrassônico
#define MAX_DISTANCE 200 // Define a distância máxima de medição do sensor utilizável para 200cm
#define MAX_SPEED 180 // ajusta a velocidade dos motores de corrente contínua para 180/256 ou cerca de 70% da velocidade total - para reduzir o consumo de energia.
#define MAX_SPEED_OFFSET 20 // isso define o deslocamento para permitir diferenças entre os dois motores de corrente contínua.
#define COLL_DIST 10 // define a distância na qual o robô para e reverte em 10 cm
#define TURN_DIST COLL_DIST+10 // define a distância na qual o robô se afasta do objeto (não reverte) em 20 cm (10 + 10)
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE); // configura a biblioteca de sensores para usar os pinos corretos para medir a distância.

AF_DCMotor motor1(1, MOTOR12_1KHZ); // cria o motor #1 usando a saída M1 no Motor Drive Shield, ajusta a freqüência PWM de 1kHz
AF_DCMotor motor2(2, MOTOR12_1KHZ); // cria o motor #2 usando a saída M2 no Motor Drive Shield, ajusta a freqüência PWM de 1kHz
//AF_DCMotor motor2(4, MOTOR12_1KHZ); // não usado neste programa


Servo myservo;  // cria o objeto servo para controlar um servo

int pos = 0; // isso configura as variáveis que serão usadas no sketch (código)
  int maxDist = 0;
  int maxAngle = 0;
  int maxRight = 0;
  int maxLeft = 0;
  int maxFront = 0;
int course = 0;
int curDist = 0;
String motorSet = "";
int speedSet = 0;

//-------------------------------------------- LOOP DO SETUP ----------------------------------------------------------------------------
void setup() {
  myservo.attach(9);  // conecta o servo no pino 9 (SERVO_2 no Motor Drive Shield para o objeto servo
  myservo.write(90); // diz ao servo para se posicionar em 90 graus, ou seja. virado para a frente.
  delay(2000); // atraso por dois segundos
  checkPath(); // executa a rotina CheckPath para encontrar o melhor caminho
  motorSet = "FORWARD"; // define a variável seguir em frente (FORWARD)
  myservo.write(90); // certifique-se de que o servo ainda esteja virado para a frente
  moveForward(); // executa a função para fazer o robô avançar
}
//------------------------------------------------------------------------------------------------------------------------------------

//--------------------------------------------- LOOP PRINCIPAL ------------------------------------------------------------------------------
void loop() {
  checkForward(); // verifica se o robô deveria  estar se movendo para a frente, e se os motores de acionamento estão configurados para avançar - isso é necessário para superar alguns problemas usando apenas 4 Pilhas AA NiMH
  checkPath(); // configura o sensor ultrassônico para procurar possíveis obstáculos
}
//-------------------------------------------------------------------------------------------------------------------------------------
void checkPath() {
  int curLeft = 0;
  int curFront = 0;
  int curRight = 0;
  int curDist = 0;
  myservo.write(144); // configura o servo para virar à esquerda a 54 graus em frente
  delay(120); // aguarda 120 milissegundos para que o servo alcance a posição
  for(pos = 144; pos >= 36; pos-=18)     // loop para varrer o servo (& sensor) em 144 graus para a esquerda e 36  graus para a direita em intervalos de 18 graus.
  {
    myservo.write(pos);  // ordena ao servo se mover para a posição na variável 'pos' 
    delay(90); // espera 90 ms para o servo chegar na posição  
    checkForward(); // verifica se o robô ainda está avançando
    curDist = readPing(); // obtém a distância atual de qualquer objeto na frente do sensor
    if (curDist < COLL_DIST) { // se a distância atual do objeto for menor que a distância de colisão
      checkCourse(); // executa a função checkCourse
      break; // pula fora desse loop
    }
    if (curDist < TURN_DIST) { // se a distância atual for menor que a distância do desvio
      changePath(); // executa a função changePath
    }
    if (curDist > curDist) {maxAngle = pos;}
    if (pos > 90 && curDist > curLeft) { curLeft = curDist;}
    if (pos == 90 && curDist > curFront) {curFront = curDist;}
    if (pos < 90 && curDist > curRight) {curRight = curDist;}
  }
  maxLeft = curLeft;
  maxRight = curRight;
  maxFront = curFront;
}
//-------------------------------------------------------------------------------------------------------------------------------------
void setCourse() { // define a direção do percurso com base em um mapa de distância muito básico, simplesmente em qual direção tem a maior distância entre o robô e o objeto? - girando para a direita ou para a esquerda. 
    if (maxAngle < 90) {turnRight();}
    if (maxAngle > 90) {turnLeft();}
    maxLeft = 0;
    maxRight = 0;
    maxFront = 0;
}
//-------------------------------------------------------------------------------------------------------------------------------------
void checkCourse() { // estamos prestes a bater em algo, então volte para trás, pare, encontre onde está o caminho com mais espaço.
  moveBackward();
  delay(500);
  moveStop();
  setCourse();
}
//-------------------------------------------------------------------------------------------------------------------------------------
void changePath() {
  if (pos < 90) {veerLeft();} // se a posição atual do sensor for menor que 90 graus, significa que o objeto está no lado direito, então vire à esquerda
  if (pos > 90) {veerRight();} // Se a posição atual do sensor for maior que 90 graus, significa que o objeto está no lado esquerdo, então vire à direita
}
//-------------------------------------------------------------------------------------------------------------------------------------

int readPing() { // lê a distância do sensor ultrassônico
  delay(70);
  unsigned int uS = sonar.ping();
  int cm = uS/US_ROUNDTRIP_CM;
  return cm;
}
//-------------------------------------------------------------------------------------------------------------------------------------
void checkForward() { if (motorSet=="FORWARD") {motor1.run(FORWARD); motor2.run(FORWARD); } }     // verifica se os motores estão indo para frente
//-------------------------------------------------------------------------------------------------------------------------------------
void checkBackward() { if (motorSet=="BACKWARD") {motor1.run(BACKWARD); motor2.run(BACKWARD); } } // verifica se os motores estão indo para trás
//-------------------------------------------------------------------------------------------------------------------------------------

// Em alguns casos, a proteção do motor pode parar se a tensão de alimentação for muito baixa (devido ao uso de apenas quatro pilhas  AA NiMH).
// As funções acima simplesmente lembram ao Shield que, se é suposto ir para a frente, certifique-se de que ele está indo para frente e vice-versa.

//-------------------------------------------------------------------------------------------------------------------------------------
void moveStop() {motor1.run(RELEASE); motor2.run(RELEASE);}  // Pare os motores.
//-------------------------------------------------------------------------------------------------------------------------------------
void moveForward() {
    motorSet = "FORWARD";
    motor1.run(FORWARD);      // seguir em frente
    motor2.run(FORWARD);      // seguir em frente
  for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // aumente lentamente a velocidade para evitar descarregar as baterias muito rapidamente
  {
    motor1.setSpeed(speedSet);
    motor2.setSpeed(speedSet+MAX_SPEED_OFFSET);
    delay(5);
  }
}
//-------------------------------------------------------------------------------------------------------------------------------------
void moveBackward() {
    motorSet = "BACKWARD";
    motor1.run(BACKWARD);      // retroceder
    motor2.run(BACKWARD);     // retroceder
  for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // aumente lentamente a velocidade para evitar descarregar as baterias muito rapidamente
  {
    motor1.setSpeed(speedSet);
    motor2.setSpeed(speedSet+MAX_SPEED_OFFSET);
    delay(5);
  }
}  
//-------------------------------------------------------------------------------------------------------------------------------------
void turnRight() {
  motorSet = "RIGHT";
  motor1.run(FORWARD);      // move o motor 1 para frente
  motor2.run(BACKWARD);     // move o motor 2 para trás 
  delay(400); // controla os motores desta maneira por 400 ms
  motorSet = "FORWARD";
  motor1.run(FORWARD);      // define ambos os motores para a frente
  motor2.run(FORWARD);      
}  
//-------------------------------------------------------------------------------------------------------------------------------------
void turnLeft() {
  motorSet = "LEFT";
  motor1.run(BACKWARD);     // move o motor 1 para trás
  motor2.run(FORWARD);      // move o motor 2 para frente
  delay(400); // controla os motores desta maneira por 400 ms
  motorSet = "FORWARD";
  motor1.run(FORWARD);      // seguir em frente
  motor2.run(FORWARD);      // seguir em frente
}  
//-------------------------------------------------------------------------------------------------------------------------------------
void veerRight() {motor2.run(BACKWARD); delay(400); motor2.run(FORWARD);} // virando para a direita? ajusta o motor direito para trás por 400 ms
//-------------------------------------------------------------------------------------------------------------------------------------
void veerLeft() {motor1.run(BACKWARD); delay(400); motor1.run(FORWARD);} // virando para a esquerda? ajusta o motor esquerdo para trás por 400 ms
//-------------------------------------------------------------------------------------------------------------------------------------