(1/2) 4-Wheel Drive Multifunction (Wireless) Robot Car Kit

Overview

This is the first part of the 2-part project for 4-wheel drive multifunction (wireless) robot car kit. The first part covers the functionality of a robot car with its own obstacle avoidance capability using both ultrasonic sensors and infrared obstacle avoidance modules. The robot car is completely autonomous to the robot car kit owner. The robot car uses the left-facing obstacle avoidance mechanism for simplicity. Whenever an obstacle is detected in either the Ultrasonic sensor or the IR Obstacle Avoidance modules, the car will automatically face to the left and assess if there’s still an obstacle ahead. The process repeats until no obstacle is detected.

Here’s a sample gif of my robot car:

Hardware Components

The whole smart robot car kit (batteries not included)

Components used in the kit:

  • Geared motor – 4 pcs
  • High-quality car tires – 4 pcs
  • Motor-fixed pieces – 4 pcs
  • 100 x 213 x 5mm acrylic plates – 2 pcs
  • L298N Motor Driver Board – 1 pc
  • Arduino Uno w/ USB Cable
  • Arduino Sensor Extension Board v4.0 – 1 pc
  • Servo holder kit – 1 pc
  • SG90 servo – 1 pc
  • Ultrasonic sensor module – 1 pc
  • TCRT5000 Tracing Modules (IR Obstacle Avoidance) – 2 pcs
  • 6V (4 AA) battery holder – 1 pc
  • 9V battery holder – 1 pc
  • Jumper wires
  • Screw kit – 1 pc

Software Components

Application Discussion

How Servo Motors Work (RC/Hobby Servo)

Inside a hobby servo motor, there’s a gearbox, potentiometer, DC motor, and control circuit. As seen in the picture, the DC motor is high speed and low torque. Attached to it is the gearbox, which reduces the speed to 60 RPM and increases the torque.

The potentiometer and control circuit work together to compare the potentiometer voltage and the voltage coming from the signal line. The integrated H-Bridge in the controller enables the motor to rotate in either direction until two signals reach a difference of zero.

How Hobby Servo Works Inside Components DC Motor Potentiometer Control Circuit

The angle of the servo motor is controlled by the different streams of pulses through the signal line. The frequency should be 50 Hz and pulses should occur every 20ms. 0 to 180-degree control vary from 0.5 ms to 2.5ms pulse. [1]

RC Servo Motor Control Signal

For more info about this servo, visit our store.

How Ultrasonic Sensors Work

Ultrasonic sensors are used to measure proximity by emitting and receiving sound waves. The trigger pin of the sensor enables the sound waves to be emitted from the sensor and unto the nearest object. The sound wave that is bounced back is then received by the echo, which calculates the travel time of the sound waves. The proximity is then measured through this mechanism.

Related image
Photo Credit: hallroad.org

For more info about the technical details of ultrasonic sensors, visit our store.

How IR (Infrared) Obstacle Detectors Work

Infrared (IR) sensors are either passive or active sensors. Passive infrared sensors are basically infrared detectors or receivers. They detect radiation from an IR transmitter. IR receivers come in the form of photodiodes and phototransistors. Infrared Photodiodes are different from normal photodiodes as they detect only infrared radiation.

IR Receiver
Photo Credit: Electronics Hub

An IR transmitter, which is an active IR sensor, is a light-emitting diode (LED) which emits infrared radiation. Although it looks like a normal LED, the light emitted is not visible to the naked eye. You can see the light through the camera of your smartphone.

IR LED
Photo Credit: Electronics Hub

The process of obstacle detecting is shown in the picture below. The rays reflected from the surface determines the distance of the object/body. In Arduino, the IR receiver only detects HIGH or LOW. HIGH means that there’s no obstacle ahead or little-to-no ray is reflected to the receiver. LOW means that the object is near and/or there’s a high amount of rays reflected or received by the IR receiver. [2]

4. Working principle of IR sensor

For more info about this IR obstacle detector, visit our shop.

How does an L298N Motor Driver module work?

The L298N Motor Driver is actually essential in this project because it controls both the speed and direction of the motors with the use of dual H-Bridge motor control. The H-Bridge aids in the direction of control by “switching” or reversing the current flow. The switching elements are transistors or MOSFETs that open or close two at a time to change the rotation direction of the motor.

H-Bridge configuration How It Works

Since the L298N Motor Driver is a dual H-Bridge motor control, it can control the speed and direction of two motors. Let’s take a look at the pin configurations of the module.

Image result for l298n motor driver
Photo Caption: Geeetech

 

There are two sets of yellow screw clamps for two motors. The middle screw clamps are for the VMS (to power up the module), GND, and 5V output to power other devices/boards such as the Arduino UNO board. However, the 5V output is not always used to supply voltage output. It can only be used if the input voltage (VMS) is up to 12V. In that way, the voltage regulator is activated, which also activates the 5V port as an output. But if the input voltage (VMS) is greater than 12V, we have to disconnect the jumper in the voltage regulator and make the 5V port as an input so that the IC will work properly and not be damaged.

The enable pins and input pins on the right corner of the picture are the connection between the Arduino and the module and to the motors. Input 1 and 2 control Motor A and Input 3 and 4 control Motor B. This input pins also control the switches in the H-bridge. If input 1 is LOW and input 2 is HIGH, the motor will move forward. It is the same for input 3 and 4, but it isn’t always the case. You can also reverse the input wires in the screw clamps to change the direction of the motors.

Set-up the Hardware

Setting up the hardware is divided into 2 parts: setting up the bottom chassis and top chassis.

Before setting up the smart robot car, you must prepare the hardware components needed. The list of materials is already stated above.

Setting up the bottom chassis

The first thing to do is to solder the wires to the geared motors like the sample photo below.

Then, screw one geared motor to the indicated spot in the photo with these materials. Repeat this step to the other 3 geared motors.

 

Attach the tires and steering gears to the geared motors. After that, screw the following copper pillars and screws on the indicated spots on the bottom chassis.

 

Your output should look like this.

Each side (left and right motors) should have one wire for power source and ground. You have to wind or twist both red wires and black wires on each side.

Note: The color of the wires on top of the geared motor should not be the same since the motors are placed facing each other. 

Now, screw in place the infrared obstacle avoidance modules on the front-facing side of the bottom chassis.

We’re done with the assembly of the bottom chassis! It should look like this.

Setting up the top chassis

The top chassis constitutes the following devices shown in the picture above (except for the infrared obstacle avoidance modules and geared motors).

Things to note about the top chassis:

  1. The wires for the battery case should follow the convention as seen in the picture above. Red wire goes to the VMS/power source port of the L295N Motor Driver. The black wire should be wind with the GND wire from the Arduino to the GND port of the L295N Motor Driver.
  2. If your motor driver doesn’t have labels (positive and negative) for the motor ports, you can arrange it like this. If the tires are rotating in the opposite direction, you may switch the red and black wires of the motor until it rotates in the correct direction.
  3. You may use the different holes in the top chassis to make the wires from the bottom chassis (i.e. IR Obstacle Avoidance Module to Arduino) pass through.

Here’s a picture of the arrangement of my top chassis. You can arrange it however you want just make sure that the servo and ultrasonic sensor are in front of the car. Also, space maximization and wire organization are also things to consider when arranging your top chassis. You don’t want your devices to far from each other that you use longer wires.

 

Code

Library included

Servo.h by Arduino

This library is a default library in your Arduino IDE. No need to download the library. This library allows the Arduino board to control servo motors. Standard servos allow the shaft to be positioned at various angles, usually between 0 and 180 degrees. Continuous rotation servos allow the rotation of the shaft to be set to various speeds.

Arduino code

A big thanks to Chen the Design Maker for letting us use his Arduino code for this project. I edited some parts since I made the robot left-facing when there’s an obstacle ahead.

#include <Servo.h>

// Pins
#define TRIG_PIN 9
#define ECHO_PIN 10

//Define all the connections maps to the L298N
#define enA 13
#define in1 12
#define in2 11
#define in3 7
#define in4 6
#define enB 5
#define servoPin 2

//IR avoidance module
#define IRleft 4
#define IRright 8

class Motor {

    int enablePin;
    int directionPin1;
    int directionPin2;

  public:

    //Method to define the motor pins
    Motor(int ENPin, int dPin1, int dPin2) {
      enablePin = ENPin;
      directionPin1 = dPin1;
      directionPin2 = dPin2;
    };

    //Method to drive the motor 0~255 driving forward. -1~-255 driving backward
    void Drive(int speed) {
      if (speed >= 0) {
        digitalWrite(directionPin1, LOW);
        digitalWrite(directionPin2, HIGH);
      }
      else {
        digitalWrite(directionPin1, HIGH);
        digitalWrite(directionPin2, LOW);
        speed = - speed;
      }
      analogWrite(enablePin, speed);
    }
};

Motor leftMotor = Motor(enA, in1, in2);
Motor rightMotor = Motor(enB, in3, in4);
Servo myservo; // create servo object to control a servo

void motorInitiation() {
  pinMode(enA, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  // Set initial direction and speed
  digitalWrite(enA, LOW);
  digitalWrite(enB, LOW);
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
}

//Variables--------------------------------------------------------------------------
// Anything over 400 cm (23200 us pulse) is "out of range"
const unsigned int MAX_DIST = 23200;
bool USObstacle = false; //ultrasonic sensor obstacle
bool IRObstacleL = false; //left infrared sensor obstacle
bool IRObstacleR = false; //right infrared sensor obstacle
int servoPos = 90;

//IR variables
int isObstacleL = HIGH;  // HIGH MEANS NO OBSTACLE ON LEFT SIDE
int isObstacleR = HIGH;  // HIGH MEANS NO OBSTACLE ON RIGHT SIDE

enum Directions { Forward, TurnLeft, TurnRight, TurnAround, Brake};

Directions nextStep = Forward;

unsigned long t1;
unsigned long t2;
unsigned long pulse_width;
float cm;
float inches;

//SETUP--------------------------------------------------------------------------
void setup() {

  // The Trigger pin will tell the sensor to range find
  pinMode(TRIG_PIN, OUTPUT);
  digitalWrite(TRIG_PIN, LOW);

  //IR pins
  pinMode(IRleft, INPUT);
  pinMode(IRright, INPUT);

  // We'll use the serial monitor to view the sensor output
  Serial.begin(9600);
  myservo.attach(servoPin);
  motorInitiation();
  Directions nextStep = Forward;
}

void loop() {
  IRObstacleL = false;
  IRObstacleR = false;
  USObstacle = false;

  checkDistance();
  checkDirection();
  drive();
}

void checkDistance() {

  // Hold the trigger pin high for at least 10 us
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  // Wait for pulse on echo pin
  while ( digitalRead(ECHO_PIN) == 0 );

  // Measure how long the echo pin was held high (pulse width)
  // Note: the micros() counter will overflow after ~70 min
  t1 = micros();
  while ( digitalRead(ECHO_PIN) == 1);
  t2 = micros();
  pulse_width = t2 - t1;

  // Calculate distance in centimeters and inches. The constants
  // are found in the datasheet, and calculated from the assumed speed
  //of sound in air at sea level (~340 m/s).
  cm = pulse_width / 58.0;
  inches = pulse_width / 148.0;
  Serial.println(pulse_width);

  //IR digital read
  isObstacleL = digitalRead(IRleft);
  isObstacleR = digitalRead(IRright);

  // Print out results
  if ( pulse_width > MAX_DIST ) {
    Serial.println("Out of range");
  } else {
    Serial.print(cm);
    Serial.print(" cm \t");
    Serial.print(inches);
    Serial.println(" in");
  }

  // Wait at least 60ms before next measurement
  delay(60);

  if (cm <= 30) {
    USObstacle = true;
    Serial.println("Problem Ahead");

  }
  else {
    USObstacle = false;
  }

  //IR if-else statements
  if (isObstacleL == LOW && isObstacleR == HIGH) {
    IRObstacleL = true;
    IRObstacleR = false;
    Serial.println("Obstacle on left side");
  }
  else if (isObstacleR == LOW && isObstacleL == HIGH) {
    IRObstacleR = true;
    IRObstacleL = false;
    Serial.println("Obstacle on right side");
  }
  else if (isObstacleR == LOW && isObstacleL == LOW) {
    IRObstacleR = true;
    IRObstacleL = true;
    Serial.println("Obstacle on both sides");
  }
  else {
    IRObstacleL = false;
    IRObstacleR = false;
  }
}
void checkDirection() {
  Serial.println("checking direction");
  
  //the while loop will only exit when there's no obstacle detected by the sensors
  while ((IRObstacleL == true || IRObstacleR == true) || USObstacle == true) {
    Serial.println("Obstacle detected.");
    nextStep = Brake;
    drive();
    delay(300);
    nextStep = TurnLeft;
    drive();
    delay(200);
    nextStep = Brake;
    drive();
    delay(100);    
    checkDistance(); //check if there's still an obstacle ahead
  }
  nextStep = Forward;
  drive();
}
 
void drive() {
  switch (nextStep) {
    case Forward:
      leftMotor.Drive(255);
      rightMotor.Drive(255);
      Serial.println("Forward");
      break;
      
    case TurnLeft:
      leftMotor.Drive(255);
      rightMotor.Drive(-255);
      Serial.println(" TurnLeft");
      delay(200);
      break;

    case Brake:
      leftMotor.Drive(0);
      rightMotor.Drive(0);
      Serial.println(" stopped");
  }

}

 

Conclusion

There you have it! You can now play with your robot car. You can add more sensors to your car to add more functionality to it. You can also change the obstacle detection method of your robot.

References

[1] https://howtomechatronics.com/how-it-works/how-servo-motors-work-how-to-control-servos-using-arduino/

[2] https://www.electronicshub.org/ir-sensor/

The post (1/2) 4-Wheel Drive Multifunction (Wireless) Robot Car Kit appeared first on CreateLabz.

Arduino sensor shield v4.0Arduino unoCarInfraredInfrared obstacle avoidance moduleIr obstacleKnowledgebaseL295nL295n motor driverObstacle avoidanceRobotRobot carServoServo motorServo.hSmart robot carTcrt5000 tracing moduleUltrasonic sensor

Leave a comment

All comments are moderated before being published