Código de Pesquisa

Lição 28/31: Carro-6 Carro Arduino autônomo SunFounder usando | Robojax

Lição 28/31: Carro-6 Carro Arduino autônomo SunFounder usando | Robojax

Neste projeto, vamos construir um carro autônomo básico usando um Arduino, um sensor ultrassônico e dois sensores infravermelhos. Este é um projeto introdutório fantástico para aprender sobre navegação autônoma, fusão de sensores e lógica de tomada de decisão. O carro pode se mover para frente, para trás e fazer curvas para evitar obstáculos, encontrando efetivamente um caminho livre por conta própria. Este projeto é baseado no kit 3-em-1 da SunFounder para Arduino e faz parte do curso de Arduino da Robojax.

28-SunFounder-Car-6-Self-Driving-path

Este projeto não se trata apenas de construir um brinquedo; é uma introdução prática aos conceitos centrais por trás da robótica autônoma. A mesma lógica e sensores são usados em aplicações do mundo real, como aspiradores robóticos, veículos guiados automaticamente em armazéns e até mesmo os sistemas de navegação de robôs mais complexos. Ao entender como combinar a detecção de distância com regras simples de navegação, você pode criar uma variedade de projetos, tais como:

  • Construir um pequeno robô que possa navegar em uma sala e evitar móveis.
  • Criar um veículo automatizado que possa seguir um caminho simples ou patrulhar uma área.
  • Aprender a implementar algoritmos básicos de desvio de obstáculos para projetos de robótica maiores.

Componentes de Hardware

Este projeto usa os componentes do kit 3-em-1 da SunFounder. As partes essenciais são:

  • Placa Arduino Uno
  • Chassi de carro 2WD ou 3-em-1 da SunFounder com motores
  • Módulo driver de motor (por exemplo, L298N ou similar)
  • Sensor ultrassônico de distância HC-SR04
  • Dois sensores de obstáculo infravermelhos
  • Fios jumper e uma fonte de alimentação para os motores

Guia de Conexões

car_7_8_28_self_driving

A fiação é o primeiro passo crítico para dar vida ao seu carro autônomo. As conexões são simples, mas é essencial verificar cada uma delas para evitar danificar seus componentes. A lógica por trás da fiação é conectar os pinos de controle do Arduino ao driver do motor e aos sensores, permitindo que o Arduino leia dados e envie comandos.

  • Pinos do Driver do Motor (A-1B, A-1A, B-1B, B-1A): Esses pinos controlam a velocidade e a direção dos dois motores. Eles estão conectados aos pinos 5, 6, 9 e 10 do Arduino, que são capazes de PWM, permitindo controle de velocidade variável.
  • Sensor Ultrassônico (Trig e Echo): O pino Trig envia um pulso ultrassônico, e o pino Echo recebe o sinal refletido. O pino Trig está conectado ao pino 3 do Arduino, e o pino Echo está conectado ao pino 4 do Arduino.
  • Sensores IR (Esquerdo e Direito): Esses sensores detectam se há um obstáculo diretamente à sua frente. O sensor IR esquerdo está conectado ao pino 8 do Arduino, e o sensor IR direito está conectado ao pino 7. Eles são usados para verificar o espaço nas laterais do carro.

Para um guia visual detalhado, consulte o diagrama de fiação abaixo, que mapeia cada conexão claramente.

Explicação do Código

O código é escrito na linguagem de programação do Arduino (C++). O programa completo está disponível para download na página de recursos vinculada na descrição do vídeo. Vamos detalhar as partes principais e configuráveis pelo usuário deste esboço.

Definições de Pinos

No topo do código, você define os pinos que conectam o Arduino aos vários componentes. Você pode alterá-los se estiver usando pinos diferentes na sua placa.

const int A_1B = 5;
const int A_1A = 6;
const int B_1B = 9;
const int B_1A = 10;

const int echoPin = 4;
const int trigPin = 3;

const int rightIR = 7;
const int leftIR = 8;

Os pinos A_1B, A_1A, B_1B e B_1A controlam o driver de motor em ponte H. Ao definir esses pinos como HIGH ou LOW em diferentes combinações, você pode controlar a direção de cada motor. Os pinos echoPin e trigPin são para o sensor ultrassônico, e rightIR e leftIR são para os sensores infravermelhos.

Variáveis de Comportamento e Lógica

A lógica central do comportamento autônomo está na função loop(). O carro toma decisões com base nas leituras dos sensores IR e do sensor ultrassônico. O código define distâncias específicas que acionam diferentes ações. Por exemplo, a variável distance é medida em centímetros. A lógica é a seguinte:

  • Se a distância for maior que 50 cm: O caminho à frente está livre, então o carro se move para frente a uma velocidade de 200.
  • Se a distância estiver entre 2 cm e 10 cm: O carro está muito perto de um obstáculo. Ele dá ré por um segundo e depois vira para trás à esquerda por meio segundo para encontrar um novo caminho.
  • Se a distância estiver entre 10 cm e 50 cm: O carro está em uma "zona de cautela". Ele se move para frente, mas a uma velocidade mais lenta de 150.

Esses valores de limite (50 cm, 10 cm e 2 cm) e as velocidades (200 e 150) são as principais variáveis que você pode ajustar para mudar o comportamento do seu carro. Por exemplo, você pode aumentar a distância "segura" para 60 cm se o seu carro estiver se movendo rápido.

Funções Personalizadas

O código inclui várias funções personalizadas para controlar os movimentos do carro. Elas são usadas ao longo do loop principal para tornar o código mais limpo e fácil de entender.

  • moveForward(int speed): Esta função define os pinos do motor para dirigir o carro para frente. O parâmetro speed (0-255) controla a velocidade com que os motores giram.
  • moveBackward(int speed): Semelhante a moveForward, mas inverte a direção do motor para mover o carro para trás.
  • backLeft(int speed) e backRight(int speed): Estas funções fazem o carro virar, executando um motor em reverso enquanto o outro está parado. Isso é uma curva de pivô que ajuda o carro a mudar de direção de forma eficaz.
  • stopMove(): Esta função para todos os motores, definindo todos os pinos de controle para LOW.
  • readSensorData(): Esta função envia um pulso do sensor ultrassônico e mede o tempo que leva para o eco retornar. Em seguida, calcula a distância em centímetros e retorna o valor.

Demonstração ao Vivo do Projeto

(no vídeo em 07:09) Na demonstração, o carro é colocado em um ambiente com vários obstáculos, como caixas e paredes. A lógica do carro é visível enquanto ele navega. Quando o sensor ultrassônico detecta uma parede ou obstáculo a mais de 50 cm de distância, ele dirige para frente com confiança. À medida que se aproxima, os sensores infravermelhos nas laterais verificam se há espaço aberto.

Se um obstáculo é detectado à esquerda, o carro faz uma curva para trás e para a direita para evitá-lo, e vice-versa. Quando o carro se encontra em um espaço apertado, como debaixo de uma mesa (no vídeo em 07:49), ele usa suas funções de ré e curva para se libertar e encontrar um caminho livre. O carro lê continuamente seu ambiente e toma decisões, demonstrando um sistema de controle reativo que não depende de um caminho pré-planejado.

Capítulos do Vídeo

  • [00:00] Introdução ao Projeto do Carro Autônomo
  • [00:28] Sobre o Kit 3-em-1 da SunFounder
  • [01:32] Abrindo o Código e Visão Geral
  • [02:02] Explicação da Estrutura do Código e Novas Funções
  • [03:11] Configuração dos Pinos na Função Setup
  • [03:28] A Lógica Principal de Tomada de Decisão no Loop
  • [05:41] Demonstração ao Vivo: O Carro em Ação
  • [07:09] Demonstração com Obstáculos e Seguimento de Paredes
  • [09:58] Conclusão e Considerações Finais

Imagens

28 SunFounder Car 6 self-driving path
28 SunFounder Car 6 self-driving path
Car 7 8 28 self driving
Car 7 8 28 self driving
897-Lesson 28/31: Car-6 SunFounder self Driving Arduino car
Idioma: C++
/*
Lesson 28/31: Car-6 SunFounder self Driving Arduino car
Get this code and watch video Download and resource page https://robojax.com/RJT611
https://www.youtube.com/watch?v=IyninXUcsn0
*/
const int A_1B = 5;
const int A_1A = 6;
const int B_1B = 9;
const int B_1A = 10;

const int echoPin = 4;
const int trigPin = 3;

const int rightIR = 7;
const int leftIR = 8;

float readSensorData() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  float distance = pulseIn(echoPin, HIGH) / 58.00; //Equivalent to (340m/s*1us)/2
  return distance;
}


void moveForward(int speed) {
  analogWrite(A_1B, 0);
  analogWrite(A_1A, speed);
  analogWrite(B_1B, speed);
  analogWrite(B_1A, 0);
}

void moveBackward(int speed) {
  analogWrite(A_1B, speed);
  analogWrite(A_1A, 0);
  analogWrite(B_1B, 0);
  analogWrite(B_1A, speed);
}


void backLeft(int speed) {
  analogWrite(A_1B, speed);
  analogWrite(A_1A, 0);
  analogWrite(B_1B, 0);
  analogWrite(B_1A, 0);
}

void backRight(int speed) {
  analogWrite(A_1B, 0);
  analogWrite(A_1A, 0);
  analogWrite(B_1B, 0);
  analogWrite(B_1A, speed);
}

void stopMove() {
  analogWrite(A_1B, 0);
  analogWrite(A_1A, 0);
  analogWrite(B_1B, 0);
  analogWrite(B_1A, 0);
}

void setup() {
  Serial.begin(9600);

  //motor
  pinMode(A_1B, OUTPUT);
  pinMode(A_1A, OUTPUT);
  pinMode(B_1B, OUTPUT);
  pinMode(B_1A, OUTPUT);

  //ultrasonic
  pinMode(echoPin, INPUT);
  pinMode(trigPin, OUTPUT);

  //IR obstacle
  pinMode(leftIR, INPUT);
  pinMode(rightIR, INPUT);
}

void loop() {

  int left = digitalRead(leftIR);  // 0: Obstructed   1: Empty
  int right = digitalRead(rightIR);

  if (!left && right) {
    backLeft(150);
  } else if (left && !right) {
    backRight(150);
  } else if (!left && !right) {
    moveBackward(150);
  } else {
    float distance = readSensorData();
    Serial.println(distance);
    if (distance > 50) { // Safe
      moveForward(200);
    } else if (distance < 10 && distance > 2) { // Attention
      moveBackward(200);
      delay(1000);
      backLeft(150);
      delay(500);
    } else {
      moveForward(150);
    }
  }
}

Arquivos📁

Bibliotecas do Arduino (zip)