Robô Autônomo Básico com Arduino Nano e Sensor Ultrassônico HC-SR04

Já pensou em montar o seu próprio robô autônomo, mas acha algo muito complicado e caro? Este tutorial vai mostrar que essa tarefa não é nenhum bicho de sete cabeças. Desenvolvemos um projeto que simplifica ao máximo os conceitos de software e hardware, possibilitando que qualquer pessoa seja capaz de fazê-lo por um custo bastante reduzido.

Usaremos um kit de chassi básico para construir um robô capaz de se livrar de obstáculos. A eletrônica necessária será montada numa pequena protoboard, sem a necessidade de uma placa de circuito impresso. Para reduzirmos o tamanho do projeto, utilizaremos o Arduino Nano em conjunto com o sensor ultrassônico HC-SR04 e Módulo Driver Ponte H L298N para controle dos motores DC.

O grande barato é que utilizaremos um código reduzido e acessível para iniciantes no mundo da eletrônica embarcada. Além de pensarmos numa maneira de utilizar o mínimo possível de componentes. Sejam bem vindos e vamos começar a diversão.

Montagem do Projeto e Detalhamento de Hardware

Componentes Utilizados:

Você pode ver todos os componentes utilizados neste tutorial na lista acima, ou você pode comprar tudo junto no Kit Start Robô Autônomo. Temos também um cupom que vale 10% de desconto na compra do Kit Start Robô Autônomo ou qualquer outro produto, para conseguir o desconto basta utilizar o seguinte cupom:

BEMVINDO

Agora sem mais delongas vamos iniciar a parte técnica do tutorial 🙂

A)  Preparativos Iniciais:

Precisamos preparar alguns detalhes antes de iniciar o projeto. Os motores DC não vem com os fios soldados. Para isso, é necessário soldar fios flexíveis de aproximadamente 12cm conforme figura abaixo.

Outro detalhe que facilitará muito a nossa vida é complementar os fios do adaptador da bateria de 9V com jumpers. O objetivo é possibilitar que a bateria seja conectada facilmente na protoboard. A figura abaixo mostra o efeito desejado. Moleza né?

B) Montagem do Chassi:

Agora é hora de montar o chassi do seu robô. A foto abaixo mostra um chassi redondo 2WD apenas com a base montada (sem o segundo andar). Aconselhamos usar para este projeto o chassi mais simples e barato possível. Pois teremos poucos componentes e o espaço utilizado será muito reduzido.

C) Fonte de Energia:

Utilizaremos uma bateria de 9V comum. Porém, nada impede que você use qualquer outra forma de energia que alcance tal valor.

Agora que sabemos que utilizaremos 9V como fonte, temos um desafio. O Arduino Nano precisa de 5V para funcionar e não podemos ultrapassar esse valor para não danificá-lo. Para isso, apresentaremos o conceito de circuito regulador de tensão.

Um circuito regulador de tensão é capaz de reduzir e regular uma tensão de entrada para uma tensão de saída desejada. Utilizaremos o famoso CI 7805 que disponibilizará 5V em sua saída e servirá perfeitamente para alimentar o Arduino. A figura abaixo propõe um circuito muito simples que servirá perfeitamente para o nosso projeto.

Outro desafio é isolar o circuito de alimentação dos motores e o circuito que alimenta o Arduino. Não entraremos em detalhes sobre esse tópico, mas basicamente é necessário saber que motores são cargas indutivas e podem retornar ruídos que podem afetar o funcionamento do Arduino. Sem entrar no mérito, usaremos um diodo na saída da bateria que alimentará os motores para evitar que qualquer tipo de corrente reversa atinja o regulador de tensão de 5V.

Assim, teremos uma divisão da energia fornecida pela bateria, onde isolaremos 5V para o circuito lógico e aproximadamente 8,3V para os motores (8,3V é o resultado de 9V da bateria com uma queda de 0,7V do diodo).

A figura abaixo mostra a montagem da fonte com o acréscimo de um interruptor para ligarmos e desligarmos o robô. Notem que tudo fica na protoboard e facilita muito a montagem do robô.

D) Montagem do Arduino Nano:

Essa etapa é muito simples. Devemos colocar o Arduino na protoboard e conectar a saída regulada de 5V no pino Vin do Arduino e o GND da fonte ao GND do Arduino, como pode ser visto na imagem abaixo:

E) Montagem do Sensor Ultrassônico:

Não iremos entrar no detalhe do funcionamento do sensor ultrassônico, pois já temos um tutorial exclusivo para este sensor: Medindo distâncias com o sensor ultrassônico, mas basicamente trata-se de um sensor que possui um emissor e receptor de ondas ultrassônicas de 40KHz. O mesmo emite a onda e a partir do tempo de ida e volta do sinal o mesmo calcula a distância de um obstáculo.

Apenas para título de conhecimento, a equação que o código da biblioteca do sensor utilizará para cálculo da distância ao obstáculo é simples. A distância (d) é obtida a partir da velocidade do som (v = 340m/s) multiplicado pelo tempo (t) de recepção do sinal dividido por 2 por conta da onda ir até o obstáculo e voltar.

d = (v * t)/2

Os pinos do Sensor ultrassônico HC-SR04 são:

  • VCC: Alimentação do sensor (5V);

  • GND: GND do sensor;

  • Trigger: Gatilho para disparo dos pulsos ultrassônicos. O Trigger é controlado pelo Arduino;

  • Echo: Dispara um pulso cuja largura de tempo em alta representa o tempo para retorno da onda recebida pelo sensor. O Arduino utilizará este sinal para realizar o cálculo da distância.

Para o nosso projeto ligaremos devidamente o VCC e GND aos pinos do Arduino Nano e o Trigger e Echo do sensor aos pinos digitais D4 e D5 do Arduino Nano conforme figura abaixo:

F) Montagem do Módulo Driver Ponte H L298N

Utilizaremos o Modulo Ponte H L298N para controlar não somente o sentido de rotação dos motores DC, como também sua velocidade.

  • MOTOR A (OUT1 e OUT2) e MOTOR B (OUT3 e OUT4): São os conectores para ligarmos no Motor A e no Motor B;

  • ATIVA MA (ENA) e ATIVA MB (ENB): Para o nosso projeto, devemos retirar os jumpers destes pinos, pois iremos controlar a velocidade dos motores com o Arduino. Caso não fossemos alterar a velocidade, deveríamos manter os jumpers;

  • ATIVA 5V: Devemos manter este jumper, pois iremos utilizar alimentação de aproximadamente 8V e o mesmo ativa um regulador de tensão interno do módulo que garante os 5V de alimentação para o circuito;

  • 6-35V e GND: Conectaremos a fonte dos motores nestes terminais, VCC e GND;

  • ENTRADA (IN1, IN2, IN3 e IN4): Pinos responsáveis pelo sentido de rotação do Motor A (IN1 e IN2) e Motor B (IN3 e IN4). Abaixo segue a tabela para entendermos a configuração necessária.

STATUS MOTOR

IN1 (ou IN3)

IN2 (ou IN4)

Rotação Sentido Horário

5V

GND

Rotação Sentido Anti-Horário

GND

5V

Ponto Morto

GND

GND

Freio

5V

5V

Agora que entendemos, resumidamente, como funciona o Módulo L298N, vamos iniciar sua conexão. Primeiramente, devemos conectar os motores nos conectores OUT1/OUT2 e OUT3 e OUT4.

Próximo passo é ligar a alimentação de energia nos conectores 6-35V e GND, conforme figura abaixo:

 

Iremos conectar os pinos IN1, IN2, IN3 e IN4 do Módulo aos pinos D6, D7, D8 e D9 do Arduino respectivamente. Finalmente, conectaremos os pinos ENA e ENB do Módulo aos pinos PWM D10 e D11 do Arduino respectivamente. Pronto! Tudo conectado!

A montagem final do projeto pode ser vista na imagem abaixo:

Mergulhando no projeto

Software

1 – Lógica de Decisão de desvio do Obstáculo

O objetivo é fazer a menor quantidade possível de movimento para simplificar o código e economizar o máximo de bateria. Ao se deparar com um obstáculo a menos de 20cm de distância frontal ao robô, o mesmo irá parar e desviar aproximadamente 90 graus à esquerda e verificará se há novo obstáculo, caso tenha, irá virar novamente à esquerda e caso contrário deve seguir em frente.

2 – Desenvolvendo o Código

O código final do projeto pode ser visto abaixo:

#include           
#define TRIGGER_PIN 4               
#define ECHO_PIN    5               
Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN); 
#define IN1 6                       
#define IN2 7                       
#define IN3 8                       
#define IN4 9                       

#define ENA 10                      

#define ENB 11                      
void setup() 
{
  pinMode(IN1,OUTPUT);              
  pinMode(IN2,OUTPUT);              
  pinMode(IN3,OUTPUT);             
  pinMode(IN4,OUTPUT);              
  pinMode(ENA,OUTPUT);              
  pinMode(ENB,OUTPUT);              
  analogWrite(ENA,120);             
  analogWrite(ENB,120);             
  delay(1000);                    
} //end setup

void loop()                         
{
  robo_frente();                    
  float dist_cm = distancia();     

    if(dist_cm < 20)                
    {
      decisao();
    } 

delay(100);                           
} 

float distancia()                   
{
  float cmMsec;
  long microsec = ultrasonic.timing();
  cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
  return(cmMsec);                   
delay(10);
} 

void robo_frente()                  
{
  digitalWrite(IN1,HIGH);
  digitalWrite(IN2,LOW);
  digitalWrite(IN3,HIGH);
  digitalWrite(IN4,LOW);
} 

void robo_esquerda()             
{
  digitalWrite(IN1,HIGH);
  digitalWrite(IN2,LOW);
  digitalWrite(IN3,LOW);
  digitalWrite(IN4,HIGH); 
} 

void robo_parado()                  
{

  digitalWrite(IN1,LOW);
  digitalWrite(IN2,LOW);
  digitalWrite(IN3,LOW);
  digitalWrite(IN4,LOW);   
} 

void decisao()                      
{
  robo_parado();
  delay(500);
  robo_esquerda();
  delay(400);                       
  robo_parado();
  delay(500);
}

Acesse o código fonte deste tutorial em nosso repositório do Gitbhub!

3 – Detalhes do Código

  1. Instalando a Biblioteca do Sensor Ultrassônico
  • Abra a IDE do Arduino, clique em “Sketch” > “Incluir Biblioteca” > “Adicionar Biblioteca .ZIP” e selecione o arquivo “Ultrassonic.zip”.

  • Pronto, agora você já é capaz de visualizar os exemplos do código clicando em “Arquivo” > “Exemplos” > (Exemplos de Bibliotecas Personalizadas) “Ultrasonic-master” > “UltrasonicDemo”

  1. Detalhamento do Código

Primeiramente, precisamos carregar a biblioteca do sensor e definir os pinos que serão utilizados como Trigger e Echo:

#define IN1 6 //Pinos motor A (Direita)
#define IN2 7 //Pinos motor A (Direita)
#define IN3 8 //Pinos motor B (Esquerda)
#define IN4 9 //Pinos motor B (Esquerda)

O próximo passo é definir os pinos 10 e 11 do Arduino para controle de velocidade dos motores. Novamente utilizaremos os mesmos nomes dos respectivos pinos do Módulo L298N (ENA para motor A e ENB para o motor B).

#define ENA 10 //Pino velocidade motor A (Enable A) 
#define ENB 11 //Pino velocidade motor B (Enable B)

A função de inicialização irá declarar os pinos IN1, IN2, IN3, IN4, ENA e ENB como pinos de saída.

void setup() { 
pinMode(IN1,OUTPUT); //Saída para motor A 
pinMode(IN2,OUTPUT); //Saída para motor A 
pinMode(IN3,OUTPUT); //Saída para motor B
pinMode(IN4,OUTPUT); //Saída para motor B 
pinMode(ENA,OUTPUT); //Controle velocidade motor A 
pinMode(ENB,OUTPUT); //Controle velocidade motor B

Estamos utilizando um controle de pulsos PWM para controlar a velocidade dos motores. É como se ligássemos e desligássemos muito rapidamente (alta freqüência) os motores. A relação entre o tempo que ele fica ligado em relação ao tempo que fica desligado define a tensão que estamos entregando ao motor e conseqüentemente é definindo a velocidade do mesmo.

A resolução do PWM do Arduino é de 8bits, podendo assumir valores de 0 (velocidade zero) a 255 (velocidade máxima).

Nesse ponto do projeto deve-se empiricamente regular a velocidade dos motores de forma distinta para compensar as diferenças de fabricação que podem fazer com que possuam velocidades diferentes para a mesma tensão aplicada, garantindo que o robô andará em linha reta quando desejado:

analogWrite(ENA,110); //Controle PWM do motor A (0 a 255) 
analogWrite(ENB,110); //Controle PWM do motor A (0 a 255) 
delay(1000); //Aguarda 1s antes de iniciar 
} //end setup

No loop principal iremos inicialmente “chamar” a função responsável por fazer o robô andar para a frente:

void loop() //loop principal 
{ 
   robo_frente(); //Robô inicia andando para frente

Iremos declarar a variável “dist_cm” do tipo “float” que armazenará o valor retornado pela função que calcula a distância do robô ao obstáculo:

float dist_cm = distancia(); //Declara variável que armazena a distância do obstáculo

Com a função IF, iremos acionar a função decisao() caso o obstáculo esteja numa distância menor do que 20 cm. Sinta-se a vontade para alterar este parâmetro:

if(dist_cm < 20) //distância menor que 20cm? 
{ 
  decisao(); } //end if 
  delay(100); } //end loop

Agora é hora de definir as funções auxiliares. São elas que foram utilizadas no loop principal. A função distancia() retornará o valor em cm da distância do robô ao obstáculo. Não se preocupe com o código, pois o mesmo é o padrão da biblioteca do sensor ultrassônico:

float distancia() //função que mede a distância em cm 
{ 
   float cmMsec; //declara a variável tipo float cmMsec 
//Associa à variável tipo long microsec o tempo em microsegundos 
long microsec = ultrasonic.timing();
//função da biblioteca para converter a distância em cm e associá-la a cmMsec 
cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM);
return(cmMsec); // retorna o valor em cm para a função delay(10); 
} //end função

Função auxiliar para andar para frente, definindo os valores das variáveis IN1, IN2, IN3 e IN4:

void robo_frente() //função para mover o robô para frente 
{ 
digitalWrite(IN1,HIGH); 
digitalWrite(IN2,LOW); 
digitalWrite(IN3,HIGH); 
digitalWrite(IN4,LOW); 
} //end função

Função auxiliar para andar para esquerda, definindo os valores das variáveis IN1, IN2, IN3 e IN4:

void robo_esquerda() //função para mover o robô para esquerda 
{ 
digitalWrite(IN1,HIGH); 
digitalWrite(IN2,LOW); 
digitalWrite(IN3,LOW); 
digitalWrite(IN4,HIGH); 
} //end função

Função auxiliar para parar o robô, definindo os valores das variáveis IN1, IN2, IN3 e IN4:

void robo_parado() //função para parar o robô 
{ digitalWrite(IN1,LOW); 
  digitalWrite(IN2,LOW); 
  digitalWrite(IN3,LOW); 
  digitalWrite(IN4,LOW); 
} //end função

A função auxiliar decisao() segue o fluxo que definimos para que o robô ultrapasse o obstáculo. No nosso projeto, para simplificar, ele sempre pára e vira para a esquerda e caso não tenha obstáculo, continua em frente:


void decisao() //função para decidir a ação do robô
{
  robo_parado();
  delay(500);
  robo_esquerda();
  //esse tempo precisa ser avaliado para que o robô vire por volta de 90 graus
  delay(400);                         
  robo_parado();
  delay(500);
} //end função

Conclusão

O objetivo de simplificar o projeto foi mostrar que você é capaz de montar o seu próprio robô e certamente já deve estar pensando em melhorá-lo. Fique a vontade, que tal alterar o modelo de decisão do robô ao se deparar com um obstáculo?

Você perceberá que, para obter melhores resultados, o robô precisará de mais sensores. Por exemplo, apenas com o sensor ultrassônico você pode ter problemas com colisão em objetos com ângulo próximo a 45 graus do robô. Que tal incluirmos bumpers de colisão na parte frontal do robô. Bumpers de colisão são chaves (interruptores) que ao serem tocados podem ser usados para alterar a decisão de percurso do robô. Enfim, são inúmeras idéias possíveis e espero ter aberto esse mundo para a sua imaginação. Abraços e boa sorte neste desafio.

Referências

McRoberts, Michael Arduino básico / Michael McRoberts; [tradução Rafael Zanolli]. — São Paulo : Novatec Editora, 2011.

Datasheet: Sensor ultrassônico HC-SR04

Datasheet: Chip ST L298N

Alex da Rocha Mattos
Sobre Alex da Rocha Mattos 4 artigos
Engenheiro de Telecomunicações – Universidade do Estado do Rio de Janeiro UERJ Instagram: https://www.instagram.com/curtoecircuito/ Email:curtoeckt@gmail.com

24 Comentários

  1. Escrevi a programação e fui compilar, mas está dando erro logo na primeira linha, vocês poderiam dar uma olhada ?? Pois tentei arrumar mas não consegui 🙁

  2. Olá, lembrando que para competições utilizar baterias 9v é horrível, o robô não aguenta muito tempo andando pois a amperagem é super baixa, aconselho a utilizar pilhas AA de lítio ou baterias do tipo LiPO para melhor resultados.

    No mais muito boa sua postagem.

    • Oi Allef, exato. Porém o nosso objetivo é fazer um projeto básico e acessível a todos! E para os iniciantes terem contato com a tecnologia! Certamente, projetos mais elaborados exigem uma bateria melhor e mais cara. Abraços

  3. Ola,sou aluno e minha sala esta fazendo este projeto em conjunto com nosso professor para nossa feira de ciências que é sobre robótica.Mas estamos enfrentando um problema,esse problema ocorre quando vamos conectar o Arduíno Nano no computador(Windows 10),quando conecta passa energia mas ele não é reconhecido pelo programa (Arduíno 1.8).Por Favor você poderia nos ajudar.Desde já agradeço.

    • Oi Carlos, desculpe-me a demora na resposta! Tente o seguinte procedimento: No menu “Ferramentas”, selecione: “Placa: Arduino Nano”, “Processador: ATmega328P (Old Bootloader)” e a “Porta” que aparecer o seu Arduino conectado.

  4. Alex, muito bom o conteúdo, montei meu carrinho perfeito, só que o bichinho só anda em circulo, um motor anda mais que o outro, tem como corrigir isso?

    • Olá Rodrigo!

      Tive um problema igual a este recentemente, e resolvi trocando a bateria, estava usando uma bateria chinessa e troquei por uma Duracell, e funcionou perfeitamente.
      E alguns dias atrás, o projeto já tinha alguns meses que estava funcionando, o problema voltou, e troquei a Duracell por uma nova Duracell e o problema foi resolvido
      novamente, quando a bateria está fraca, apenas um motor consegue ser energizado, e por isso o veículo anda em círculos.

      Abraço.

    • Olá Geovana tudo bem? O primeiro passo é conferir se o circuito está sendo energizado, se a bateria está realmente alimentando o circuito. Depois confira as ligações na Ponte H, na parte de trás, onde é feita a conexão do terra (GND) e o VCC, confira se está chegando energia nesta parte do circuito, a ponte H tem um led indicador, verifique se ele está acesso.

  5. Prezados,
    estou iniciando agora em Arduino, não tenho noção nenhuma.
    O que uso para proceder a compilação do programa e como envio do PC para o arduino?
    Algum tutorial / video explicativo?

  6. Não entendi onde realmente se encaixa o diodo retificador. Ficou um pouco confuso no esquema.
    O interruptor tem 3 pinos que vão em E3, E4, e E5. No Esquema parece que uma das pernas do diodo entra em E4. É isso? Se sim, o pino do meio do interruptor não pode entrar em E4, certo?

    • Olá Ricardo tudo bem? Sim o interruptor tem 3 pinos, e o diodo é conectado em série no pino do meio, é como se você fosse conectar um jumper no pino do meio, então você deve fazer a ligação do diodo no primeiro ponto(buraco) da protoboard após o pino do meio, veja na imagem real do projeto:

      Espero ter esclarecido a sua dúvida. Abraço.

  7. Ola
    copiei o programa e na hora de compilar esta dando erro.
    long microsec = ultrasonic.timing();nessa linha.Com a menssagem
    nenhuma função correspondente para chamada para ´ultrasonic::timing(int)`

    delay(10);

    • Olá Marcelo tudo bem? Você seguiu os passos descritos na sessão 3 intitulada “Detalhes do código”?

      Veja neste print abaixo:

      É só adicionar a biblioteca como descrito nessa parte, que o seu código vai funcionar!
      Abraço!

  8. Passei horas revisando o projeto e está tudo ok, mas o robô não sai do lugar. Poderiam disponibilizar como fica o código final com a o código do sensor adicionado? A base do veículo de acrílico veio bem diferente da mostrada na foto, maior, inclusive eu até consegui montar o veículo com os motores invertidos. A foto real do veículo com a ligação dos motores no Módulo ponte H possui uma ligação que está invertida da proposta no esquema, foi proposital? Funcionou?
    Já montei outras coisas com o Arduino, mas realmente este está mais complicado.

    • Olá Roberto tudo bem?

      O código exibido no tutorial está completo, o sensor é acionado na função “float distancia”, e esta função é chamada em void loop, se você acessar o nosso Github nete link: https://github.com/omegacomponenteseletronicos/arduino-robo-autonomo/blob/master/robo_autonomo.ino verá que a função distancia é chamada na linha 29 do código.

      A base do veículo no tutorial é menor, nós estamos enviando uma base maior atualmente, atendendo a pedidos dos clientes, mas isso não muda em nada o código ou a montagem do esquema elétrico.

      A ligação da Ponhe H nos motores segue a tabela mostrada no tutorial, onde é explicado com quais ligações o motor gira para o lado horário ou anti-horário, resumidamente, você deve ligar o terra (fio preto) do motor 1 em out1, e o vcc em out2, e para o motor 2 o terra é ligado em out3 e o vcc em out4, a imagem ilustrativa da Ponte H nem sempre corresponde as posições corretas dos pinos out1, out2, out3 e out4, por isso você fico com a impressão que está invertido, pois na sua Ponte H, out1 pode ser o pino de cima e out2 o pino de baixo, por exemplo.

      Conferira também se a sua bateria de 9v está com uma boa carga, essas baterias chinesas são decepcionante, a maioria dos problemas que os leitores tem ao montar o projeto é com a bateria de 9v, confira também se a Ponte H está recebendo energia, ela tem um led indicador, se este led não estiver ascendo, isto indica que a ponte H não está recebendo energia.

      Espero ter te ajudado Roberto! Abraço!

      • Olá Renan, tudo bem?

        Você conseguiu me ajudar sim, o código estava bem assim mesmo. O motivo do não funcionamento pode ser realmente a Bateria que troquei, bem como a adaptação do Arduino na Protoboard, percebi que os contatos não estavam precisos e bem conectados, mas com a ajuda dos jumpers eu consegui finalmente ligar tudo e fazer funcionar. Dessa forma, consegui ajustar a direção das conexões no módulo para fazer o robô funcionar de forma correta. Assim, tudo bem por aqui e muitíssimo obrigado!

1 Trackback / Pingback

  1. Robô Básico controlado via Bluetooth por Smartphone - Portal do Arduino

Deixe uma resposta

O seu endereço de email não será publicado.


*