Autonomous Robot Car - Arduino RoboMaster part 12

 Today I made my first autonomous robot car which is a modification of the my first Arduino RC Car. Until now, I used bluetooth for control navigation of the diy Arduino robomaster. Now, I wanted to add autonomous driving feature to the robot car because I thought it would be great experience to test code, test servo motors and HC-SR04 ultrasonic sensor and get hand on experience. Maybe I will incorporate both bluetooth and autonomous self driving or self aware robotic feature into the final Arduino Robomaster. 

This autonomous robot car is a Obstacle Avoidance Robot car. It uses ultrasonic senor to detect distances and servo motor is used the sensor around to look for obstacles and objects.

self driving car

I told in my previous blog post Adding and Checking Ultrasonic Sensor and Servo Motor how I made assembled the servo and the sensor onto the robot car chassis. 

Robot Car Circuit Diagram

Following is the circuit diagram for the sensor based robot car using Arduino.

 

circuit diagram autonomous arduino robot car

I have already explained how I built and added the lithium ion recharging circuit to the Arduino robot car. In that blog post I said that this recharging circuit is not yet confirmed. But I checked for 1 day and the recharging circuit seems to work. To learn the basic of servo motor control see controlling a hobby servo motor with L293D motor shield and Arduino. To learn the basic of ultrasonic sensor look at my previous tutorial intruder sensor with ultrasonic sensor. For bluetooth and other aspects you can read the references links.

Ultrasonic sensor robot car code

After I had built the sensor and actuator onto it, I uploaded a obstacle avoiding program code for the robot. Below is the ultrasonic Arduino robot car code that I used.


#include <AFMotor.h>  
#include <NewPing.h>
#include <Servo.h> 

#define TRIG_PIN A0
#define ECHO_PIN A1
#define MAX_DISTANCE 200 
#define MAX_SPEED 200 // sets speed of DC  motors
#define MAX_SPEED_OFFSET 20

NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE); 

AF_DCMotor motor1(1, MOTOR12_1KHZ); 
AF_DCMotor motor2(2, MOTOR12_1KHZ);
AF_DCMotor motor3(3, MOTOR34_1KHZ);
AF_DCMotor motor4(4, MOTOR34_1KHZ);
Servo myservo;   

boolean goesForward=false;
int distance = 100;
int speedSet = 0;

void setup() {
 Serial.begin(9600);
  myservo.attach(10);  
  myservo.write(50); //115
  delay(2000);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);
  distance = readPing();
  delay(100);

  myservo.write(100);
  delay(500);
  myservo.write(54);
  delay(500);
  myservo.write(142);
  delay(500);
  myservo.write(100);
  delay(500);
  Serial.print(distance);
   Serial.println(" cm");
}

void loop() {
 int distanceR = 0;
 int distanceL = 0;
 delay(40);
 Serial.print(distance);
   Serial.println(" cm");
 
 if(distance<=15) {
  moveStop();
  delay(100);
  moveBackward();
  delay(300);
  moveStop();
  delay(200);
  distanceR = lookRight();
  delay(200);
  distanceL = lookLeft();
  delay(200);

  if(distanceR>=distanceL)  {
    turnRight();
    moveStop();
  }
  else{
    turnLeft();
    moveStop();
  }
 }
 else{
  moveForward();
 }
 distance = readPing();
}

int lookRight(){
    myservo.write(54); 
    delay(500);
    int distance = readPing();
    delay(100);
    myservo.write(100);
    return distance;
}

int lookLeft(){
    myservo.write(142); 
    delay(500);
    int distance = readPing();
    delay(100);
    myservo.write(100); 
    return distance;
    delay(100);
}

int readPing(){ 
  delay(70);
  int cm = sonar.ping_cm();
  if(cm==0){
    cm = 250;
  }
  return cm;
}

void moveStop(){
  motor1.run(RELEASE); 
  motor2.run(RELEASE);
  motor3.run(RELEASE);
  motor4.run(RELEASE);
  } 
  
void moveForward(){

 if(!goesForward){
    goesForward=true;
    motor1.run(FORWARD);      
    motor2.run(FORWARD);
    motor3.run(FORWARD); 
    motor4.run(FORWARD);
         
   for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2){
    motor1.setSpeed(speedSet);
    motor2.setSpeed(speedSet);
    motor3.setSpeed(speedSet);
    motor4.setSpeed(speedSet);
    delay(5);
   }
   
  }
}

void moveBackward() {
    goesForward=false;
    motor1.run(BACKWARD);      
    motor2.run(BACKWARD);
    motor3.run(BACKWARD);
    motor4.run(BACKWARD);  
  for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2){
    motor1.setSpeed(speedSet);
    motor2.setSpeed(speedSet);
    motor3.setSpeed(speedSet);
    motor4.setSpeed(speedSet);
    delay(5);
  }
}  

void turnRight() {
  motor1.run(FORWARD);
  motor2.run(FORWARD);
  motor3.run(BACKWARD);
  motor4.run(BACKWARD);     
  delay(500);
  motor1.run(FORWARD);      
  motor2.run(FORWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);      
} 
 
void turnLeft() {
  motor1.run(BACKWARD);     
  motor2.run(BACKWARD);  
  motor3.run(FORWARD);
  motor4.run(FORWARD);   
  delay(500);
  motor1.run(FORWARD);     
  motor2.run(FORWARD);
  motor3.run(FORWARD);
  motor4.run(FORWARD);
}  
 

Let's break down the code section by section to understand its functionality:

 1. Libraries and Definitions

#include <AFMotor.h> #include <NewPing.h> #include <Servo.h> #define TRIG_PIN A0 #define ECHO_PIN A1 #define MAX_DISTANCE 200 #define MAX_SPEED 200 // sets speed of DC motors #define MAX_SPEED_OFFSET 20

In this section, the code includes three libraries: AFMotor for controlling DC motors, NewPing for interfacing with ultrasonic distance sensors, and Servo for controlling a servo motor. It also defines some constants like TRIG_PIN, ECHO_PIN, MAX_DISTANCE, MAX_SPEED, and MAX_SPEED_OFFSET, which are used throughout the code.

2. Object Initialization

NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE); 

AF_DCMotor motor1(1, MOTOR12_1KHZ); 
AF_DCMotor motor2(2, MOTOR12_1KHZ);
AF_DCMotor motor3(3, MOTOR34_1KHZ);
AF_DCMotor motor4(4, MOTOR34_1KHZ);
Servo myservo; 

This part of the code initializes objects for the NewPing sensor (sonar) and four DC motors (motor1, motor2, motor3, motor4) using the AFMotor library. It also initializes a servo motor object (myservo) to control a servo.

 3. Global Variables

boolean goesForward=false;
int distance = 100;
int speedSet = 0;

 Here, some global variables are declared. goesForward is a boolean flag indicating the direction of movement, distance stores the distance measured by the sensor, and speedSet keeps track of the motor speed.

4. setup() Function

void setup() {
  Serial.begin(9600);
  myservo.attach(10);  
  // ...
}

 The setup() function initializes the serial communication and attaches the servo motor to pin 10. It also performs some initializations involving the servo and ultrasonic sensor, reading the sensor's value after each delay.

5. loop() Function

void loop() {
  // ...
}

The loop() function is the core of the code, where the main actions take place. It reads the distance from the sensor, and depending on the distance value, it decides whether to move forward, stop, or take evasive actions (move backward, turn right, or turn left) to avoid obstacles.

6. Sensor Reading Functions

  • lookRight() and lookLeft(): These functions turn the servo to specific angles to scan for obstacles and return the distance measured at those angles.

  • readPing(): Reads the distance from the ultrasonic sensor and returns it. If the sensor returns 0 (indicating no valid distance measurement), it assigns a value of 250 to cm (centimeters) as a placeholder.

7. Motor Control Functions

  • moveStop(): Stops all four motors.

  • moveForward(): Moves the vehicle forward by gradually increasing the speed of the motors.

  • moveBackward(): Moves the vehicle backward by gradually increasing the speed of the motors in the opposite direction.

  • turnRight(): Turns the vehicle to the right.

  • turnLeft(): Turns the vehicle to the left.

These functions control the direction and speed of the motors based on the situation determined by the distance readings from the sensor.

After uploading the code I tested it. In the robot car code, the angle for the servo to turn left and right has to be adjusted according to your requirement. For me, on the right side the angle needed was 54 degree and for the left was 142 degree, 100 degree being the center. To find the angle values to set in the above program code, you can use a joystick to move the servo arm around and take note of the angles.

Video demonstration

Following is video demonstration of testing the autonomous Arduino robot car.


# Arduino RoboMaster Modifications with Crane Part - Arduino RoboMaster Part 9

 

Post a Comment

Previous Post Next Post