Carro RobÔ

Lista de material:

  • 1 Arduino Uno

  • 1 Sensor shield v5.0

  • 1 chassis duplo de acrílico para carro com 4 rodas

  • 4 motores DC

  • 4 rodas

  • 1 módulo bluetooth HC-06 (HC-06 bluetooth module)

  • 1 ponte dupla H SparkFun L298 (Dual H-Bridge motor drivers L298)

  • 1 servo-motor SG90 (SG90 Micro-servo motor)

  • 1 sensor de ultrassom (Ultrasonic Sensor HC-SR04)

  • 1 placa de sensores versão 5 (Sensor Shield v5)

  • 1 alojamento para baterias ou pilhas (3 baterias 18650 ou 4 pilhas alcalinas)

Opcionais:

  • 1 Auto-falante piezo-elétrico (piezo speaker ou buzzer)

  • 2 LEDs brancos 10 mm

  • 2 LEDs vermelhos 5 mm

  • 4 resistores 220 ohms

Errata

  • Na conexão do motor: o pino 6 deve ser ligado ao ENA e o pino 13 ao IN4. Ambos, ENA e ENB devem ser ligados a saídas PWM.

Objetivos

Primeira fase - vai andar:

Módulos utilizados:

  • Bluetooth

  • Driver do motor

  • Sensor de proximidade

  • Servo-motor

Nessa fase, vamos usar um módulo Bluetooth para receber os comandos de movimentação do carro. O Arduino irá acionar o módulo de potência dos motores para avançar, recuar e fazer curvas. O servo-motor será utilizado para fazer com que o sensor de proximidade aponte sempre para a direção que o carro está se movendo. Vamos usar esse sensor para (tentar) evitar que o carro colida com obstáculos

Segunda fase - aprimoramentos básicos:

Os aprimoramentos são bem básicos mas importantes para o carro. Vamos colocar faróis, luzes de freio e buzina.

Terceira fase - vamos ver e ser vistos (ainda em estudos):

Uso do ESP32-CAM para incluir câmera no carro. Desenvolvimento de aplicativo para visualizar as imagens da câmera. Na 3a fase, parte B, o aplicativo será portado para óculos 360°. Provavelmente será difícil dirigir o carro usando as imagens da câmera porque é esperado um atraso significativo que pode inviabilizar a direção.

Nesta fase também está previsto a inclusão de sensor de rotação nas 4 rodas para verificar se as rodas estão girando mesmo depois de ordem para o carro parar, ou seja, vamos implementar um ABS!


Montagem:

Montagem dos motores

Solde os fios vermelhos e pretos nos quatro motores, criando quatro conjuntos iguais. Não existe problema de polaridade, uma vez que o carro irá andar para frente e para trás, ou seja, durante o funcionamento, haverá inversão natural de tensão. Apenas certifique-se de que todos os motores foram montados igualmente.

Use um par de presilhas em cada motor para fixar o motor na parte de cima da placa do chassis inferior. As cabeças dos parafusos devem ficar voltadas para o lado de fora do carro enquanto que as porcas, para o lado de dentro.

Fixe as rodas. Os discos pretos vazados não serão utilizados nesse projeto.

Fixe as rodas com cuidado para não quebrar o acrílico. Certifique-se que as rodas estejam firmemente colocadas.

Uma boa referência para esse montagem está nesse blog.

Montagem do chassis

O servo-motor vai ser utilizado para direcionar o sensor ultrassom quando o carro andar para frente ou fizer alguma curva da mesma forma que os faróis dos carros topo de linha trabalham. Posicione o servo-motor abaixo do chassis de cima, dentro do furo maior, no lado que você considerar a frente do carro (qualquer ponta pode ser a frente). Marque e fure (dois furos) usando uma broca de aço rápido. Fixe o motor, fixe uma das barras brancas no eixo do servo. Marque e fure (dois furos) o acrílico em L. Fixe usando um parafuso para plástico bem fino. Fixe o sensor ultrassom usando cola quente no acrílico em L.

Posicione o Arduino logo após o sensor em L, depois a ponte, com o dissipador de calor voltado para frente, e, na parte mais distante do sensor ultrassom, o alojamento das baterias. Note que dificilmente algum furo vai poder ser aproveitado. Faça as marcações e novos furos para fixar os três elementos. Fixe os três elementos.

Fixe os seis espaçadores separando as duas camadas do chassis.

Após essa etapa, as partes mecânicas devem estar prontas, faltando o cabeamento e o software.

Cabeamento

Coloque o sensor shield sobre o Arduino.

Cabeamento do sensor ultrassom:

Alimentação:

  • +5V

  • GND

I/O:

  • GPIO8: TRIGPIN

  • GPIO9: ECHOPIN

Para fixar o sensor no suporte acrílico em L foi necessário fazer 4 furos com brocas de 1 mm. Para encaixar o cristal foi necessário limar um pouco o acrílico porque eu utilizei parafusos de óculos e eles eram curtos.

Usando um cabo de quatro fios, conecte o sensor no shield como mostrado a seguir:

Cabeamento do servo-motor

Alimentação:

  • +5V

  • GND

I/O:

  • GPIO7: SERVOPIN

O servo-motor é usado para posicionar o sensor ultrassônico sempre na direçao do movimento do carro.

O acrílico deve ser aparafusado em cima do motor usando a barra reta que vem com o motor.

Cabeamento do módulo Bluetooth:

Alimentação:

  • +5V

  • GND

I/O:

  • TX: TxD

  • RX: RxD

Prenda com uma gravatinha (ou um lacre de embalagem de pão) o módulo Bluetooth. Note que ele não tem furação de fixação. Com um cabo de quatro fios, conecte o módulo no shield como mostrado a seguir:

Cabeamento da ponte:

Ver ERRATA!

Conecte os dois fios vermelhos dos motores direito em OUT4.

Conecte os dois fios pretos dos motores direito em OUT3.

Conecte os dois fios vermelhos dos motores esquerdo em OUT2.

Conecte os dois fios pretos dos motores esquerdo em OUT1.

Termine o cabeamento da ponte como mostrado a seguir (antes, retire os dois jumpers que estão na ponte para fazer o cabeamento):

Cabeamento da energia:

Conecte o fio vermelho da bateria em +12V da ponte.

Conecte o fio preto da bateria em GND da ponte. Nesse mesmo ponto, conecte um fio preto até GND do sensor shield.

Conecte o fio vermelho de VCC da ponte até VCC do shield.

Opcionalmente, conecte o positivo (vermelho) do suporte da bateria no módulo de potência através de uma chave liga-desliga.

Cabeamento completo:

A imagem apresenta o cabeamento completo do carro.

Opcionais:

  • LEDs brancos na frente. Dois LEDs brancos, cada um com um resistor de 220 Ω ligados no pino 10

  • LEDS vermelhos atrás. Dois LEDs vermelhos, cada um com um resistor de 220 Ω ligados no pino 1

  • Buzina: Uma buzina (buzzer) ligada no pino 11

  • Chave liga/desliga em série com as baterias.


Cabeamento completo:

A imagem apresenta o cabeamento completo, incluindo quatro LEDs e buzina opcionais.

Resumo das conexões

D00 - NC

D01 - LEDs vermelhos

D02 - DC motor drive

D03 - DC motor drive

D04 - DC motor drive

D05 - DC motor drive

D06 - DC motor drive

D07 - Servo

D08 - Ultrasom

D09 - Ultrasom

D10 - LEDs brancos

D11 - Buzzer

D12 - NC

D13 - DC motor drive

TX - Bluetooth

RX - Bluetooth

Código

IMPORTANTE: antes de fazer upload do código, não se esqueça de desconectar os pinos TX e RX do shield. Eles estão conectados ao Bluetooth, que usa os mesmos pinos da interface serial USB. Lembre-se de reconectar para poder usar o carro.

/*

*/


#include <Servo.h>

#include <NewPing.h>


void forward(void);

void back(void);

void left(void);

void right(void);

void stopAll(void);

int readPing(void);

void forwardRight(void);

void forwardLeft(void);


/*

* Ultrasonic sensor

*/

#define TRIGPIN 8

#define ECHOPIN 9

const int maximumDistance = 100;

NewPing sonar(TRIGPIN, ECHOPIN, maximumDistance); //sensor function

int distance;

unsigned long previousMillis = 0; // will store last time distance was updated

/*

* Motor

*/

unsigned char carSpeed = 255;

boolean movingForward = false;

const int turningFactor = 70; // unbalance factor to turn left or right, and move forward simultaneously

// Left Motor

const int motorEnLeft = 5;

const int motorInLeft1 = 3;

const int motorInLeft2 = 2;

// Right Motor

const int motorEnRight = 6;

const int motorInRight3 = 13;

const int motorInRight4 = 4;


/*

* Servo

*/

int servoPin = 7; // Declare the Servo pin

Servo servo; // Create a front servo object


/*

* Lights

*/

const int ledPinFrontRight = 11; // the number of the LED pin

const int ledPinFrontLeft = 10;

const int ledPinRearRight = 1; // the number of the LED pin

const int ledPinRearLeft = 12; // the number of the LED pin


// Generally, you should use "unsigned long" for variables that hold time

// The value will quickly become too large for an int to store


void setup() {

// Serial setup

Serial.begin(9600);

// Motor setup

pinMode(motorInLeft1, OUTPUT);

pinMode(motorInLeft2, OUTPUT);

pinMode(motorInRight3, OUTPUT);

pinMode(motorInRight4, OUTPUT);


pinMode(motorEnLeft, OUTPUT);

pinMode(motorEnRight, OUTPUT);


// Servo setup

servo.attach(servoPin);


// Light setup

// set the digital pin as output:

pinMode(ledPinFrontRight, OUTPUT);

pinMode(ledPinFrontLeft, OUTPUT);

pinMode(ledPinRearRight, OUTPUT);

pinMode(ledPinRearLeft, OUTPUT);

digitalWrite(ledPinFrontRight, LOW);

digitalWrite(ledPinFrontLeft, LOW);

digitalWrite(ledPinRearRight, LOW);

digitalWrite(ledPinRearLeft, LOW);


/*

* Ultrasonic

*/

pinMode(TRIGPIN, OUTPUT);

pinMode(ECHOPIN, INPUT);

delay(2000);

distance = readPing();

delay(100);

distance = readPing();

delay(100);

distance = readPing();

delay(100);

distance = readPing();

delay(100);

Serial.println("Começando...\n");

}


void loop() {

// here is where you'd put code that needs to be running all the time.

static char command;


if(distance < 20) {

digitalWrite(ledPinFrontRight, HIGH);

digitalWrite(ledPinFrontLeft, HIGH);

digitalWrite(ledPinRearRight, HIGH);

digitalWrite(ledPinRearLeft, HIGH);

if(movingForward) stopAll();

}


command = Serial.read();

switch(command) {

case 'b':

case 'B': // move back

servo.write(90);

back();

break;

case 'D': // Stop all

stopAll();

break;

case 'f':

case 'F': // move forward

servo.write(90);

forward();

break;

case 'G': // Move forward left

servo.write(90+45);

forwardLeft();

break;

case 'H': // Move back left

servo.write(90);

backLeft();

break;

case 'I': // Move forward right

servo.write(90-45);

forwardRight();

break;

case 'J': // Move back right

servo.write(90);

backRight();

break;

case 'L': // move left

servo.write(180);

left();

break;

case 'R': // Right

servo.write(0);

right();

break;

case 'S': // Stop

stopAll();

break;

case 'W': // Front lights on

digitalWrite(ledPinFrontRight, HIGH);

digitalWrite(ledPinFrontLeft, HIGH);

break;

case 'w': // Front lights off

digitalWrite(ledPinFrontRight, LOW);

digitalWrite(ledPinFrontLeft, LOW);

break;

case 'U': // back lights on

digitalWrite(ledPinRearRight, HIGH);

digitalWrite(ledPinRearLeft, HIGH);

break;

case 'u': // back ligths off

digitalWrite(ledPinRearRight, LOW);

digitalWrite(ledPinRearLeft, LOW);

break;

case '0': // Speed 0;

carSpeed = 255*0/100;

break;

case '1': // Speed 10;

carSpeed = 255*10/100;

break;

case '2': // Speed 20;

carSpeed = 255*20/100;

break;

case '3': // Speed 30;

carSpeed = 255*30/100;

break;

case '4': // Speed 40;

carSpeed = 255*40/100;

break;

case '5': // Speed 50;

carSpeed = 255*50/100;

break;

case '6': // Speed 60;

carSpeed = 255*60/100;

break;

case '7': // Speed 70;

carSpeed = 255*70/100;

break;

case '8': // Speed 80;

carSpeed = 255*80/100;

break;

case '9': // Speed 90;

carSpeed = 255*90/100;

break;

case 'q': // Speed 100;

carSpeed = 255*100/100;

break;

}

distance = readPing();

}


/**

* Motor forward

*/

void forward(void){

movingForward = true;

// if(distance < 20) {

// stopAll();

// } else {

analogWrite(motorEnLeft,carSpeed);

analogWrite(motorEnRight,carSpeed);

digitalWrite(motorInLeft1,HIGH);

digitalWrite(motorInLeft2,LOW);

digitalWrite(motorInRight3,LOW);

digitalWrite(motorInRight4,HIGH);

// }

Serial.println("Forward");

}

void back(){

movingForward = false;

analogWrite(motorEnLeft,carSpeed);

analogWrite(motorEnRight,carSpeed);

digitalWrite(motorInLeft1,LOW);

digitalWrite(motorInLeft2,HIGH);

digitalWrite(motorInRight3,HIGH);

digitalWrite(motorInRight4,LOW);

Serial.println("Back");

}

void backLeft(void){

movingForward = false;

analogWrite(motorEnLeft,carSpeed * turningFactor / 100);

analogWrite(motorEnRight,carSpeed);

digitalWrite(motorInLeft1,LOW);

digitalWrite(motorInLeft2,HIGH);

digitalWrite(motorInRight3,HIGH);

digitalWrite(motorInRight4,LOW);

Serial.println("Back");

}

void backRight(void){

movingForward = false;

analogWrite(motorEnLeft,carSpeed);

analogWrite(motorEnRight,carSpeed * turningFactor / 100);

digitalWrite(motorInLeft1,LOW);

digitalWrite(motorInLeft2,HIGH);

digitalWrite(motorInRight3,HIGH);

digitalWrite(motorInRight4,LOW);

Serial.println("Back");

}

void left(){

analogWrite(motorEnLeft,carSpeed);

analogWrite(motorEnRight,carSpeed);

digitalWrite(motorInLeft1,LOW);

digitalWrite(motorInLeft2,HIGH);

digitalWrite(motorInRight3,LOW);

digitalWrite(motorInRight4,HIGH);

Serial.println("Left");

}

void forwardLeft(void){

movingForward = true;

// if(distance < 20) {

// stopAll();

// } else {

analogWrite(motorEnLeft,carSpeed * turningFactor / 100);

analogWrite(motorEnRight,carSpeed);

digitalWrite(motorInLeft1,HIGH);

digitalWrite(motorInLeft2,LOW);

digitalWrite(motorInRight3,LOW);

digitalWrite(motorInRight4,HIGH);

// }

Serial.println("Left");

}

void right(){

analogWrite(motorEnLeft,carSpeed);

analogWrite(motorEnRight,carSpeed);

digitalWrite(motorInLeft1,HIGH);

digitalWrite(motorInLeft2,LOW);

digitalWrite(motorInRight3,HIGH);

digitalWrite(motorInRight4,LOW);

Serial.println("Right");

}

void forwardRight(){

movingForward = true;

// if(distance < 20) {

// stopAll();

// } else {

analogWrite(motorEnLeft,carSpeed);

analogWrite(motorEnRight,carSpeed * turningFactor / 100);

digitalWrite(motorInLeft1,HIGH);

digitalWrite(motorInLeft2,LOW);

digitalWrite(motorInRight3,LOW);

digitalWrite(motorInRight4,HIGH);

// }

Serial.println("Right");

}

void stopAll(){

movingForward = false;

digitalWrite(motorEnRight,LOW);

digitalWrite(motorEnLeft,LOW);

digitalWrite(ledPinRearRight, HIGH);

digitalWrite(ledPinRearLeft, HIGH);

Serial.println("Stop!");

}


/**

* Ultrasonic sensor reader

*/

int readPing(){

static unsigned long currentMillis;

static unsigned long deltaT;


currentMillis = millis();

deltaT = currentMillis - previousMillis;

previousMillis = currentMillis;

if(deltaT < 70) delay(70 - deltaT);

// delay(70);

int cm = sonar.ping_cm();

if (cm==0){

cm=250;

}

return cm;

}

Link para o código, cabeamento e muito mais: https://github.com/AlexandreMeslin/RobotCar.