Introduction: Arduino Based Self Driving Car

Welcome to my first Instructable!

So I recently was assigned a project of a self driving car as my semester's project. In this project my task was to design a car that could do following:

  • Can be controlled with voice commands through Android Phone.
  • Avoid Hurdles and Obstacles.
  • Can self-drive.
  • Don't move if asked to move but there's a hurdle

Honestly I had no Idea how these things work as I've never been into this before. The only thing that I knew was that i had to use Arduino or Raspberry pi.

So, I started with google. I came to know that there projects of this kind are already available on internet with complete codes but the problem I faced was: The projects are separate for each of the thing that I had to fulfill in my project. The good thing was that the programming language of Arduino is based on C and the projects available on internet were mostly Arduino based, since I'm good at C/C++ so I chose arduino and decided to understand the working.

After understanding everything The first thing that I had to do was make a list of components I needed. so Here's the list:

Supplies

  • Arduino UNO R3
  • Adafruit Motorshield V2
  • 4-Wheel Robot Car Chasis
  • Ultrasonic Sensor (HCSR-04)
  • Micro Servo 9G
  • Ultrasonic Sensor Holder
  • HC-05 Bluetooth Module
  • Jumper Wires

Step 1: Components and Their Working

Now we have a list of which components are required to build this project, lets just have a look at their working and alternatives.

So first of all we will use an Arduino UNO board, as we know that arduino is a controller of our robot so it doesn't need any introduction to go ahead, we can use any UNO compatible board but Arduino/GENUINO UNO is recommended.

Second component of our Smart Car is the Adafruit Motor Shield, You may have heard of Adafruit Motor Shield before the main advantage of using this motorshield is that it has a library with predefined functions which means that while working with it, we will not have to get much into it's working process it will be a plug-n-play for us during the project, an L298N motor Driver can also be used as an alternative to AF Motorshield but it may require changing in code.

Moving to the next thing we will use a 4-Wheel Robot Car chassis, here 2-Wheel chassis can also be used without changing the code so it will be okay. But for better working the recommended is 4-Wheel. 4 BO Motors and wheels come with chassis, but the only thing that is needed to change is connect the two motors of each side together so they work at same signal and similarly do the same with the other side.

An HCSR-04 (Ultrasonic Sensor) will be used for the detection of any hurdles or walls in the car's path so we can make a smart decision hence, avoiding the collision. An Ultra Sonic Sensor Holder will also be used to mount the sensor on our Servo Motor. Here comes the servo Part, the servo motor is an important part as It will help us make a decision while turning the car, When the car will be in self-drive mode or taking a "turn left/right" command it will not run the motors instead it will first move the ultra sonic sensor to look if there is any hurdle already or not, if yes it will simply stop and deny to run. This thing can save much battery because we have 4 DC-Motors and running a servo before them will be a smart move.

A Bluetooth module (HC-05) as we know will be used to establish a connection between our robot and our smartphone through the dedicated app, it will be used to send commands to our robot via wireless connection.

A good battery choice is necessary for better working of a machine, and without a good battery you will end up wasting the money, While working on any project always keep in mind the power requirement of your project, The same mistake I made while working with this project and I ended up wasting 6 rechargeable batteries that costed about 16$ for nothing. All you have to do is to use the Li-po or Li-ion battery to power up your project. Use 2 separate batteries one for Arduino and one for your Motor Shield.

Step 2: Assembling Our Robot

In this part we will start connecting the components together and start shaping our robot.

Assembling the chasis:

Make sure the Motors are below the chassis and not sandwiched between it. this way we can make much space for our components to stay between the chassis without disturbing the motors or wheels.

After attaching the motors we will move to the connections. first of all we will make all the connections with our Arduino and then we will work with our Motor Shield.

HC-05 Bluetooth Module:

// Pin Definitions for HC-05
#define HC05_PIN_RXD 12 // RX of Arduino #define HC05_PIN_TXD 13 // TX of Arduino
  • TX --> Pin 12
  • RX --> Pin 13
  • GND --> GND
  • VCC --> 5V on Arduino

Leave all the other pins as is.

HC-SR04 Ultrasonic Sensor:

// Pin Definitions for Ultrasonic Sensor
#define HCSR04_PIN_TRIG 7 // Trig Pin 
#define HCSR04_PIN_ECHO 8 // Echo Pin
  • Trig --> Pin 7
  • Echo --> Pin 8
  • GND --> GND
  • VCC --> 5V on Arduino

That's it for the Arduino part.

Step 3: Setting Up the Adafruit Motor Shield

Here comes the main part where our project starts coming live. make sure the wires connected on arduino do not contain pins, simply rip off the pins and put just copper in the arduino pins so we can plug in our Motorshield to it.

Place the Adafruit Motor Shield above the Arduino in such a way that all pins of our motor shield are inside the female headers of our Arduino, refer the image above. and now since you have connected your Motor Shield it's time to connect the remaining components to it.

Step 4: Connecting the Motors

Here comes the interesting but tricky part.

"One wrong wire and robot will work oppositely to what you expected"

First of all we have to define the place of motor where we want to connect our wheels and then the servo motor. In my case I used M2 and M4 to run my Motors you can redefine these according to your own choice. lets understand the working.

// We are using DC motors so we will us the function of DC motor from AFMotor.h Library

/*AF_DCMotor is used to define that we are using DC Motors and it take 
2 arguments the first argument specifies the location at which the motor
is connected and the second one is for setting up the frequency of specified
slot MOTOR12 means that we are using slot 1 or 2 and 1KHZ means to set up
the frequency if those slots to 1KHZ you can check cheat sheet of AF motor shield
for frequencies */

AF_DCMotor leftMotor  (2, MOTOR12_1KHZ); //leftMotor is an instance to control Motors on left
AF_DCMotor rightMotor (4, MOTOR34_1KHZ); // rightMotor is an instance to control Motors on right

Now start connecting your motors as 2 Left motors on M2 Slot and 2 Right motors on M4 Slot.

Make sure you remove the power Jumper from AF motor shield asweare giving both of the devices power from different batteries. Use 5V batteries for Arduino and use 6-9V for AF motor Shield

Tip: Swap the wires if the motors dont run in desired direction.


Step 5: The Servo Motor

2 Servo motors can be mounted on AF Motor Shield so we will use one of those slots to power our servo. Refer to image above.

//Defining and connecting the servo
// Pin 9 and 10 can be used to attach servo via Motor shield
//Using Pin 9 
#define SERVO_PIN_ATTACH 9
Servo myServo; // creating object instance to use servo motor
const int servoSMTargetPosition = 90; //Position of servo when looking straight forward

/* Calibrate the servo to look forward at 90 
before mounting Ultrasonic sensor to it */

void setup()
{
	myServo.attach(SERVO_PIN_ATTACH); // Start Servo at defined pin
	myServo.write(servoSMTargetPosition); //Set the position of servo (FORWARD)
}

Now attach the servo motor as shown in image above.

Step 6: Understanding the Working

Now we are pretty much done with the wiring process its time to start understanding the working process of our robot, in this code I have used structured programming so if you face any kind of problem instead of exploring the whole code you can simple jump to the desired section, lets start jump straight into code.

Libraries and Global Variables:

<pre>#include <AFMotor.h><afmotor.h><br>#include <Servo.h><servo.h>
#include <HC05.h><hc05.h>
#include <NewPing.h><newping.h>
#include <Arduino.h><arduino.h></arduino.h></newping.h></hc05.h></servo.h></afmotor.h>
// Pin Definitions
#define HC05_PIN_RXD  12 
#define HC05_PIN_TXD  13   

#define HCSR04_PIN_TRIG 7
#define HCSR04_PIN_ECHO 8

#define SERVO_PIN_ATTACH 9
// Maximum Distance (cm) for Ultrasonic Sensor to detect
#define MAX_DISTANCE 30 // Change it to your required distance
// object initialization

SoftwareSerial mySerial(HC05_PIN_RXD, HC05_PIN_TXD);  //Bluetooth Function

NewPing hcsr04(HCSR04_PIN_TRIG, HCSR04_PIN_ECHO, MAX_DISTANCE); // Sensor Function

AF_DCMotor leftMotor  (2, MOTOR12_1KHZ); 
AF_DCMotor rightMotor (4, MOTOR34_1KHZ);
// Global variables declaration

Servo myServo;
const int servoSMTargetPosition = 90; //Position when event is detected
int distance = MAX_DISTANCE + 1; // initially the maximum distance will be more than max so the car must run 
boolean goesForward = false;
char command;

Setup

void setup()<br>{


// put your setup code here, to run once:
  Serial.begin(9600); // begin at baud rate of 9600
  while (!Serial); // wait for serial port to connect. (wait untill Bluetooth turns on)
  mySerial.begin(9600);

  // Default Bluetooth password '1234' or '0000'
  mySerial.println("Bluetooth Turned On...."); //Open the console to see if this message shows
					       // if this message doesn't show up, something's wrong
  myServo.attach(SERVO_PIN_ATTACH);
  myServo.write(servoSMTargetPosition);
  delay(1000); // wait 1 second or 1000 milliseconds before going further
}

Loop, This is the interesting section, in this section as you can see we are using charachter commands as 1,2,3,4 and 5 instead of hard coded values which is good for us as we will not be bounded to only 5 hard coded commands

<p>void loop()<br>{
  // put your main code here, to run repeatedly:
</p><p>  myServo.write(90);
  while (mySerial.available())	//Check if bluetooth device connected and command is receieved
  {
    command = mySerial.read();	// Read the input and store in 'command'
    Serial.println("Command Receieved....");	//Print a message on serial Monitor
    delay(100); wait for 100 millisecond</p><p>
     if (command != '\0') 
    {
      break;
    }
  
  }</p>
  // Function Calls upon commands
  {
    if (command == '1')	// On receiving this command the car will move forward until an obstacle is found
    {
      forward_car();
    }
    else if (command == '2') // This command will reverse the car for 2 seconds
    {
      back_car();
    }
    else if (command == '3') // this command will turn the car right
    {
      right_car();
    }
    else if (command == '4') // This command will turn the car left
    {
      left_car();
    }
    else if (command == '5') // This command will make the car go to self drive mode as long as user wants
    {
      self_drive();
    }
    command = '\0'; // Reset the command so the new input can be taken
  }
}

/* In the self drive mode the car keep running till the
user is connected to it via bluetooth as soon as the user
disconnects the bluetooth the car stops. In this way
the car can be stopped */

Step 7: Code and Libraries

Simply use "Extract Here"to extract these libraries to default libraries folder of Arduino.

Documents/Arduino/libraries

After extracting and placing the libraries its time to upload the code, before uploading the code you have to disconnect the TX and RX of bluetooth because it will prevent the code from uploading. After you upload the code plug back the TX and RX.

Tip:while uploading code make sure to lift your robot from ground to avoid any surprise as the motors can start unexpectedly.

See Complete code on GitHub

Step 8: The Andriod App

The app that we are gonna use in this project is Arduino BlueControl. Make sure to use only this app since we are not using hard coded commands and this app can be configured as we desire.

Now power up your Robot and open the app. Turn on the bluetooth and wait for HC-05 to show up. As soon as HC-05 shows connect to it and type in the password the default is '1234' in most cases or '0000' otherwise.

after it connects we have to configure our app.

To configure the app Simply Tap the Gear icon on top right corner and Configure it as Shown in video: