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:
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.
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]
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.
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.
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.
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]
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.
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.
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:
- 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.
- 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.
- 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
[2] https://www.electronicshub.org/ir-sensor/
The post (1/2) 4-Wheel Drive Multifunction (Wireless) Robot Car Kit appeared first on CreateLabz.