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
- 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 :-)
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.
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;
}
}
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;
}
}
i make the pingbot...but one motor is not working...plzz help me
ReplyDeleteThanks, 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.
ReplyDeletelarystoy
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
ReplyDeleteAdmiring the time and effort you put into your blog and detailed information you offer!.. Wedding Toronto Limousine
ReplyDelete