Vídeo: Robô com motor shield – Parte 2 19

Na segunda parte do projeto do robô móvel autônomo utilizando Arduino UNO e Motor Shield L293D, desenvolveremos o sistema de sensoriamento do mesmo. Na primeira parte deste projeto, no post Robô com Motor Shield – Parte 1, explanamos sobre o controle dos motores e lógica de funcionamento.

A lógica de funcionamento completa do Robô com motor shield 4×4 já foi explanada no primeiro post, porém cabe uma breve revisão da mesma, através do fluxograma da Figura 1.

Robô com motor shield Parte 2

Figura 1 – Fluxograma de funcionamento do Robô

Ao iniciar o programa, o robô move-se para frente lendo o sensor frontal de distância e assim permanecerá até que detecte um obstáculo. Detectando um obstáculo frontal, a unidade pára, vira o sensor para esquerda com auxilio de um servo motor e lê a distância. Após, move o sensor para direita e lê a distância. O robô armazenará estas duas medidas. O próximo passo consiste em comparar as distâncias, para determinar qual é a maior. O robô fará a tomada de decisão, desviando para a maior distância encontrada, pois teoricamente, será o caminho mais simples, não existindo um obstáculo tão próximo.

Sensor Ultrassônico HC-SR04

Quando necessitamos medir alguma distância com precisão de centímetros, o sensor HC-SR04 é um dos dispositivos mais indicados (Figura 2). Gerando-se um pulso de trigger a partir do Arduino, é possível fazer o levantamento das curvas do sensor, que gera um pulso no pino ECHO diretamente proporcional à distância a que se encontra de algum obstáculo.

Sensor-Ultrassonico-HC-SR04

Figura 2 – Sensor Ultrassônico HC-SR04

Na Figura 3 pode-se observar as curvas geradas pelo sensor, que o datasheet do fabricante prevê.

Diagrama de tempo HC-SR04

Figura 3 – Curvas do Sensor Ultrassônico

De acordo com o datasheet, envia-se um pulso de gatilho (trigger) com duração de 10µs, após este pulso, o transmissor do sensor envia 8 pulsos ultrassônicos na frequência de 40kHz que o seu receptor receberá em forma de eco. Após isto, o pino ECHO irá a nível alto por um tempo proporcional à distância a que o sensor encontra-se do obstáculo. A distância em centímetros é o resultado do tempo que o pulso de ECHO permanece em nível alto, dividida por 58 (mais detalhes no datasheet).

O diagrama esquemático completo do Robô pode ser visto na Figura 4.

Diagrama Robô 4x4

Figura 4 – Diagrama esquemático completo do Robô

Como pode-se observar, utilizou-se o Motor Shield L293D como driver para controle dos 4 motores do Robô, adicionando-se o sensor ultrassônico HC-SR04 para verificação de obstáculos e medida de distância e um servo motor de posição, que direciona o sensor adequadamente no momento das medidas. Todos estes componentes para montagem do robô com motor shield estão disponíveis na Loja MakerHero.

Programa Robô com motor shield – Final

O software completo e comentado pode ser analisado a seguir.

/*
   Curso de Arduino e AVR WR Kits Channel
   
   Aula 72 - Robô com Motor Shield (Parte 2)
*/

// --- Bibliotecas Auxiliares ---
#include <AFMotor.h>         //Inclui biblioteca AF Motor
#include <Servo.h>           //Inclui biblioteca para controle de Servos

// --- Seleção dos Motores ---
AF_DCMotor motor1(1); //Seleção do Motor 1
AF_DCMotor motor2(2); //Seleção do Motor 1
AF_DCMotor motor3(3); //Seleção do Motor 1
AF_DCMotor motor4(4); //Seleção do Motor 1

// --- Mapeamento de Hardware ---
#define   serv        10                 //controle do Servo 1
#define   trig        A4                 //Saída para o pino de trigger do sensor
#define   echo        A5                 //Entrada para o pino de echo do sensor

// --- Protótipo das Funções Auxiliares ---
float measureDistance();                //Função para medir, calcular e retornar a distância em cm
void trigPulse();                       //Função que gera o pulso de trigger de 10µs
void decision();                        //Função para tomada de decisão. Qual melhor caminho?
void robot_forward(unsigned char v);    //Função para movimentar robô para frente
void robot_backward(unsigned char v);   //Função para movimentar robô para trás
void robot_left(unsigned char v);       //Função para movimentar robô para esquerda
void robot_right(unsigned char v);      //Função para movimentar robô para direita
void robot_stop(unsigned char v);       //Função para parar o robô

// --- Objetos ---
Servo servo1;                           //Cria objeto para o servo motor

// --- Variáveis Globais ---
unsigned char velocidade = 0x00;       //Armazena a velocidade dos motores (8 bits)
float dist_cm;                         //Armazena a distância em centímetros entre o robô e o obstáculo
float dist_right;                      //Armazena a distância em centímetros da direita
float dist_left;                       //Armazena a distância em centímetros da esquerda
         
// --- Configurações Iniciais ---
void setup()
{
  //A biblioteca configura as entradas e saídas pertinentes ao Motor Shield...  
 pinMode(trig, OUTPUT);                       //Saída para o pulso de trigger
 pinMode(serv, OUTPUT);                       //Saída para o servo motor
 pinMode(echo, INPUT);                        //Entrada para o pulso de echo
 
 servo1.attach(serv);                         //Objeto servo1 no pino de saída do servo
 digitalWrite(trig, LOW);                     //Pino de trigger inicia em low
 servo1.write(80);                            //Centraliza servo
 delay(500);                                  //Aguarda meio segundo antes de iniciar
  velocidade = 0xFF; //Inicia velocidade no valor máximo
} //end setup

// --- Loop Infinito ---
void loop()
{
     robot_forward(velocidade);
     delay(80);
     dist_cm = measureDistance();
     if(dist_cm < 20) //distância menor que 20 cm?
     {
         decision();
     }
} //end loop

// --- Desenvolvimento das Funções Auxiliares ---

float measureDistance()                       //Função que retorna a distância em centímetros
{
  float pulse;                                //Armazena o valor de tempo em µs que o pino echo fica em nível alto
  trigPulse();                                //Envia pulso de 10µs para o pino de trigger do sensor
  pulse = pulseIn(echo, HIGH);                //Mede o tempo em que echo fica em nível alto e armazena na variável pulse
  /*
    >>> Cálculo da Conversão de µs para cm:
   Velocidade do som = 340 m/s = 34000 cm/s
   1 segundo = 1000000 micro segundos
   
      1000000 µs - 34000 cm/s
            X µs - 1 cm
            
                  1E6
            X = ------- = 29.41
                 34000
                 
    Para compensar o ECHO (ida e volta do ultrassom) multiplica-se por 2
    
    X' = 29.41 x 2 = 58.82
 */
  
  return (pulse/58.82);                      //Calcula distância em centímetros e retorna o valor
} //end measureDistante

void trigPulse()                             //Função para gerar o pulso de trigger para o sensor HC-SR04
{
   digitalWrite(trig,HIGH);                  //Saída de trigger em nível alto
   delayMicroseconds(10);                    //Por 10µs ...
   digitalWrite(trig,LOW);                   //Saída de trigger volta a nível baixo
} //end trigPulse

void decision()                              //Compara as distâncias e decide qual melhor caminho a seguir
{
   robot_stop(velocidade);                   //Para o robô
   delay(500);                               //Aguarda 500ms
   servo1.write(0);                          //Move sensor para direita através do servo
   delay(500);                               //Aguarda 500ms
   dist_right = measureDistance();           //Mede distância e armazena em dist_right
   delay(2000);                              //Aguarda 2000ms
   servo1.write(175);                        //Move sensor para esquerda através do servo
   delay(500);                               //Aguarda 500ms
   dist_left = measureDistance();            //Mede distância e armazena em dis_left
   delay(2000);                               //Aguarda 2000ms
   servo1.write(80);                         //Centraliza servo
   delay(500);
   if(dist_right > dist_left)                //Distância da direita maior que da esquerda?
   {                                         //Sim...
      robot_backward(velocidade);            //Move o robô para trás
      delay(600);                            //Por 600ms
      robot_right(velocidade);               //Move o robô para direita
      delay(2000);                           //Por 2000ms
      robot_forward(velocidade);             //Move o robô para frente
   } //end if
   else                                      //Não...
   {
    robot_backward(velocidade);            //Move o robô para trás
      delay(600);                            //Por 600ms
      robot_left(velocidade);                //Move o robô para esquerda
      delay(2000);                            //Por 2000ms
      robot_forward(velocidade);              //Move o robô para frente
   } //end else

} //end decision
 
void robot_forward(unsigned char v)
{
     motor1.setSpeed(v);
     motor1.run(FORWARD);
     motor2.setSpeed(v);
     motor2.run(FORWARD);
     motor3.setSpeed(v);
     motor3.run(FORWARD);
     motor4.setSpeed(v);
     motor4.run(FORWARD);
} //end robot forward

void robot_backward(unsigned char v)
{
     motor1.setSpeed(v);
     motor1.run(BACKWARD);
     motor2.setSpeed(v);
     motor2.run(BACKWARD);
     motor3.setSpeed(v);
     motor3.run(BACKWARD);
     motor4.setSpeed(v);
     motor4.run(BACKWARD);
} //end robot backward

void robot_left(unsigned char v)
{
     motor1.setSpeed(v);
     motor1.run(FORWARD);
     motor2.setSpeed(v);
     motor2.run(FORWARD);
     motor3.setSpeed(v);
     motor3.run(BACKWARD);
     motor4.setSpeed(v);
     motor4.run(BACKWARD);
} //end robot left

void robot_right(unsigned char v)
{
     motor1.setSpeed(v);
     motor1.run(BACKWARD);
     motor2.setSpeed(v);
     motor2.run(BACKWARD);
     motor3.setSpeed(v);
     motor3.run(FORWARD);
     motor4.setSpeed(v);
     motor4.run(FORWARD);
} //end robot right

void robot_stop(unsigned char v)
{
     motor1.setSpeed(v);
     motor1.run(RELEASE);
     motor2.setSpeed(v);
     motor2.run(RELEASE);
     motor3.setSpeed(v);
     motor3.run(RELEASE);
     motor4.setSpeed(v);
     motor4.run(RELEASE);
} //end robot stop

Para mais detalhes, acesse o vídeo disponível no início deste post, e para download dos arquivos utilizados neste post sobre robô com motor shield, acesse este link.

Gostou? Deixe seu comentário logo abaixo.

Faça seu comentário

Acesse sua conta e participe

19 Comentários

  1. Para inserir um controle via bluethooth nesse projeto como ficaria o código?

    1. Jair,

      Dê uma olhada nesse link: https://www.makerhero.com/blog/tutorial-modulo-bluetooth-com-arduino/
      Com ele você já consegue ter uma ideia mais ou menos de como chegar lá@

      Abraços!
      Diogo – Equipe MakerHero

  2. Seus projetos são bons

    1. Olá!

      É ótimo saber que gostou do nosso trabalho!

      Abraço!
      Rosana – Equipe MakerHero

  3. Oi, tem uma foto da conexão dos fios do sensor ultrassonico e do servo motor com a placa motor shield? Sou novata em Arduino.

    1. Sim tenho, te mando via e-mail.

  4. Olá pessoal do http://www.makerhero.com, parabéns pelos tutoriais!
    Vocês teriam uma dica de componentes para adicionar conexão wifi a este projeto? é possível utilizar um outro shield wifi? li em alguns fóruns que há uma incompatibilidade de pinos. Ou seria melhor integrar apenas um módulo ESP8266?

    Abraços

  5. Muito bom o tutorial, porém estou enfrentando alguns problemas.

    Ao plugar o USB o carrinho funciona perfeitamente, porém, ao usar a bateria de 9V ele fica com uma velocidade muito alta e acaba batendo nos obstáculos, poderia me ajudar a resolver o problema?

    Aguardo seu retorno,
    Att.

  6. Qual a lista de materiais completa para aquisição do robô?

  7. Wagner,
    como sempre muito didático, parabéns. Cara, montei o projeto, usei o programa, porém estou enfrentando 2 problemas:
    1- ao alimentar o arduino com a bateria de 9v (recarregável – 260mAh), o servo e o sensor parecem não estar recebendo energia suficiente para rodar, quando retiro a alimentação por bateria e plugo o cabo USB, funciona normal. A bateria não me parece ser o problema pois já medi e está com a tensão correta (também troquei por uma nova e nada…). O motor shield estou com as 5 pilhas, conforme orientação.
    2- o funcionamento é automático e não autômato, ou seja, ele segue a rotina do programa fazendo o que está lá passo a passo, mas não está medindo ou tomando decisões. Por exemplo: ao ligar, ele gira o servo, supostamente faz as medições e anda para frente por um intervalo de tempo. Então pára, supostamente faz as medições de novo e segue… isto é, se ao seguir tiver um objeto a frente, ele bate até dar o tempo pré estabelecido e supostamente o sensor fazer as medições novamente, mas ao fazer as medições ele segue “cegamente” para frente, não importa se já estava empurrando o objeto ou não.
    Como faço para que o sensor fique constantemente medindo enquanto o robô anda para frente e se encontrar um obstáculo ele efetivamente pare e tome a decisão?! Desculpe se eu estiver errado na conclusão, mas é o que me parece que este robô está fazendo. O que posso estar fazendo de errado?
    Obrigado pela atenção.
    rogerio.

  8. Olá, tem como fazer esse robô utilizando o módulo Bluetooth? Estou estudando fazer um robô para projeto de Feira na minha escola… e como ficaria o código se colocasse também o Bluetooth?
    Att, Cheila.

  9. Gostei do exemplo. Estou trabalhando em um protótipo que irá funcionar de maneira autonoma e também por meio de comandos que enviarei na porta serial através de uma shield wi-fi e uma interface web. Gostaria de ver algum exemplo prático.

    1. Valeu Eugenio! Podemos pensar em projeto assim para daqui uns tempos, fique ligado aqui no blog.
      Abraço!
      Wagner Rambo

  10. Venho acompanhando filipiflop e WR KIts Engenharia, Adilson…… são feras…… deve ter mais gente (PARABÉNS)….. como faço pra adquirir as peças para montar este projeto? Tenho o arduino já. Me envia contato por e-mail por gentileza. Abraço!

    1. Boa tarde Higor,

      Muito obrigado. O material para construção do robô você encontra na Loja MakerHero: http://www.makerhero.com

      Abraço!

      Adilson – Equipe MakerHero

  11. Gostei, vou fazer um.

    1. Valeu Thiago! Bons projetos para você!

      abs!

  12. WAGNER RAMBO, obrigado pelas orientações. vou montar o meu, se tiver dúvidas entrarei em contato.
    Espero que continues a ajudar nos nossos primeiro passos.
    ABÇS!
    Bernardes

    1. Valeu José! Fique sempre ligado aqui no blog da Filipe Flop!

      abraços