Tuesday, October 28, 2014

Hi there,

This is my very first Arduino project. I made a robot by using a RC Car that I found in a recycling depot. This project is structured in 3 main parts: Material List, Physical Connection and Coding.

Before we start I presume you have some basic knowledge about Arduino and C++ programming. If not I invite you to first spend some time on the official Arduino website: www.arduino.cc


Material list:

- Arduino Uno R3
- L298N Motor Drive Board
- HC-SR04 Echolocation Sensor
- Tower Pro Micro servo 9g  - servo motor
-  red LED
- 2 x DC motors
- 9V battery
- wire jumpers: Male/Male, Male/Female, Female/Female.
- RC Car chassis and wheels

In my case DC motors were on the RC Car that I recycled so wasn't necessary to buy them. So if you find any broken RC Car toy I suggest to use that instead of buying a new one.

First step was to repair mechanical problems of the RC Car and remove unnecessary parts and I just discovered the power of the glue gun :-)


Physical connection: 

When the chassis was ready the next important step was to connect the motors, sensors and all boards to Arduino. Please follow the instructions and read the schematics. Double-check each connection and be sure that pins are connected properly.


HC-SR04 Echolocation Sensor to Arduino Uno R3:
(HC-SR04: used to scan the surrounding and help the robot to find his way)
- Trig pin to I/O pin 13
- Echo pin to I/O pin 12
- VCC pin to 5V (power)
- GND pin to GND (ground)

Tower Pro Micro servo 9g to Arduino Uno R3:
(used to rotate HC-SR04 sensor)
+ (red wire) to 5V pin
-  (black wire) to GND pin
signal (yellow wire) to I/O pin 9

L298N Motor Drive Board to Arduino Uno R3:
(L298N Board: used to control the DC motors of the robot)
- ENA pin to I/O pin 5
- ENB pin to I/O pin 3
- IN1 pin to I/O pin 2
- IN2 pin to I/O pin 4
- IN3 pin to I/O pin 6
- IN4 pin to I/O pin 7
- 5V pin to 5V pin
- GND pin to GND pin


Front DC Motor to L298N Motor Drive Board:
(to control direction of the robot: left/right)
 +  to Motor A Output 1
 -   to Motor A Output 2 


Rear DC Motor to L298N Motor Drive Board
(to control propulsion of the robot: forward/backward)
 +  to Motor B Output 1
 -   to Motor B Output 2 


Battery connection:

-   to GND pin on Arduino
+  to VMS on L298N Board
for control of the power you can attach a button between the + wire of the battery and VMS pin on L298N Board


LED to Arduino:
(turns ON when the robot is moving backward)
+ to I/O pin 10
-  to  GND






























Important Tips:
- Connect one component at the time and test it. As you can see in the photos below I've done the same.


- Since there are too many components that needs to connect to the battery I used a prototyping shield, this one multiplies the 5V pins and GND pins. On the other hand on a prototyping shield you are able to multiply any other pin from Arduino Uno R3. Don't know how a prototyping shield looks like? Check the image above.
















Coding:

Important Tips:
The code below may need to be adapted to your robot. Depends on the size of the robot there can occur some changes.

#include <Servo.h>

#define trig 13

#define echo 12
Servo myservo;
int servoLeft = 10; //angle of microservo rotation to scan on left
int servoForward = 45;
int servoRight = 100; //angle of microservo rotation to scan on right
int a=0;
int ena = 5;
int enb = 3;
int in1 = 2;
int in2 = 4;
int in3 = 6; 
int in4 = 7;

int czas, dist1, dist2, dist3;


void setup() {

  // servo pin definition
  myservo.attach(9);

  //buzzer

  pinMode(11, OUTPUT);

  //light

  pinMode(10, OUTPUT);

  //ultrasonic sensor

  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);

  //motors

  pinMode(ena, OUTPUT);
  pinMode(enb, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
}

void loop() {


  scanLeft();

  delay(250);
  scanRight();
  delay(250);
  scanForward();
  delay(250);


  if( dist3<30){

    moveBackward();
    digitalWrite(10, HIGH);
    delay(1000);
    digitalWrite(10, LOW);
    moveStop();
  }
  if(dist2>50 && dist1<20){
    turnRight();
    delay(500);
    moveForward();
    delay(1000);
    moveStop();
    a=2;
  }
  if(dist1>50 && dist2<20){
    turnLeft();
    delay(500);
    moveForward();
    delay(1000);
    moveStop();
    a=3;
  }


  if(dist3>dist2 && dist3>dist1 && dist3>50){

    if(a==2)  {
      lamijlocdindreapta();
    }
    if(a==3)  {
      lamijlocdinstanga();
    }
    moveForward();
    delay(1000);
    moveStop();
    a=1;
  }

  if(dist2>dist3 && dist2>dist1 && dist2>50){   

    turnRight();
    delay(500);
    moveForward();
    delay(1000);
    moveStop();
    a=2;
  }

  if(dist1>dist2 && dist1>dist3 && dist1>50){

    turnLeft();
    delay(500);
    moveForward();
    delay(1000);
    moveStop();
    a=3;
  }
}

void scanForward(){

  myservo.write(servoForward);
  digitalWrite(trig, HIGH);
  delay(500);
  digitalWrite(trig, LOW);
  czas = pulseIn(echo, HIGH);
  dist3 = (czas/2)/29.1;
}

void scanRight(){

  myservo.write(servoRight);

  delay(50);

  digitalWrite(trig, HIGH);
  delay(500);
  digitalWrite(trig, LOW);
  czas = pulseIn(echo, HIGH);
  dist2 = (czas/2)/29.1;
}

void scanLeft(){

  myservo.write(servoLeft);

  delay(50);

  digitalWrite(trig, HIGH);
  delay(500);
  digitalWrite(trig, LOW);
  czas = pulseIn(echo, HIGH);
  dist1 = (czas/2)/29.1;
}

void moveForward(){

  motorB(2, 60);
  motorA(0, 0);
}
void lamijlocdindreapta(){
  turnLeft();
  delay(200);

}

void lamijlocdinstanga(){
  turnRight();
  delay(200);

}

void moveBackward(){
  motorB(1, 80);
  motorA(0, 0);
}

void turnLeft(){

  motorA(2, 50);
  motorB(0, 0);
}

void turnRight(){

  motorA(1, 50);
  motorB(0, 0);
}

void moveStop(){

  motorA(0, 0);
  motorB(0, 0);

}



void buzzerOn(){

  tone(8, 440, 200);
}

void lightOn(){

  digitalWrite(10, HIGH);
  delay(500);
  digitalWrite(10, LOW);
}


//******************   Motor A control   *******************

void motorA(int mode, int percent)
{

  //change the percentage range of 0 -> 100 into the PWM

  //range of 0 -> 255 using the map function
  int duty = map(percent, 0, 100, 0, 255);

  switch(mode)

  {
  case 0:  //disable/coast
    digitalWrite(ena, LOW);  //set enable low to disable A
    break;

  case 1:  //turn clockwise

    //setting IN1 high connects motor lead 1 to +voltage
    digitalWrite(in1, HIGH);   

    //setting IN2 low connects motor lead 2 to ground

    digitalWrite(in2, LOW);  

    //use pwm to control motor speed through enable pin

    analogWrite(ena, duty);  

    break;


  case 2:  //turn counter-clockwise

    //setting IN1 low connects motor lead 1 to ground
    digitalWrite(in1, LOW);   

    //setting IN2 high connects motor lead 2 to +voltage

    digitalWrite(in2, HIGH);  

    //use pwm to control motor speed through enable pin

    analogWrite(ena, duty);  

    break;


  case 3:  //brake motor

    //setting IN1 low connects motor lead 1 to ground
    digitalWrite(in1, LOW);   

    //setting IN2 high connects motor lead 2 to ground

    digitalWrite(in2, LOW);  

    //use pwm to control motor braking power 

    //through enable pin
    analogWrite(ena, duty);  

    break;

  }
}

//******************   Motor B control   *******************

void motorB(int mode, int percent)
{

  //change the percentage range of 0 -> 100 into the PWM

  //range of 0 -> 255 using the map function
  int duty = map(percent, 0, 100, 0, 255);

  switch(mode)

  {
  case 0:  //disable/coast
    digitalWrite(enb, LOW);  //set enable low to disable B
    break;

  case 1:  //turn clockwise

    //setting IN3 high connects motor lead 1 to +voltage
    digitalWrite(in3, HIGH);   

    //setting IN4 low connects motor lead 2 to ground

    digitalWrite(in4, LOW);  

    //use pwm to control motor speed through enable pin

    analogWrite(enb, duty);  

    break;


  case 2:  //turn counter-clockwise

    //setting IN3 low connects motor lead 1 to ground
    digitalWrite(in3, LOW);   

    //setting IN4 high connects motor lead 2 to +voltage

    digitalWrite(in4, HIGH);  

    //use pwm to control motor speed through enable pin

    analogWrite(enb, duty);  

    break;


  case 3:  //brake motor

    //setting IN3 low connects motor lead 1 to ground
    digitalWrite(in3, LOW);   

    //setting IN4 high connects motor lead 2 to ground

    digitalWrite(in4, LOW);  

    //use pwm to control motor braking power 

    //through enable pin
    analogWrite(enb, duty);  

    break;

  }
}

4 comments:

  1. i make the pingbot...but one motor is not working...plzz help me

    ReplyDelete
  2. Thanks, I want to build a 6 motor Rover, Sensor, Arduino and so on for my 10 year old grandson. You have done 90% of the work for me with this source code.

    larystoy

    ReplyDelete
  3. This unique contest car has a designer's designated operating associated with 3-years and more mature, so I wasn't ready for how a 5 year old would operate it. Those who have played with my RADIO MANAGED models before, are teenagers, and they drive the vehicles non-aggressively. best rc cars under 100

    ReplyDelete
  4. Admiring the time and effort you put into your blog and detailed information you offer!.. Wedding Toronto Limousine

    ReplyDelete