Recently I had bought two cheap small line following mobile
robot cars as my part time hobby project. One of them is mobile robot kit
based on Maker UNO (Arduino UNO compatible) microcontroller. I am a mobile
robot newbie.
Online store: https://my.cytron.io/p-line-following-mobile-robot-kit
As shown below, this cheap off-the-shelf small simple mobile
robot consists of:
·
Maker
UNO (Arduino UNO compatible) microcontroller
·
‘Maker
Drive’ dual channel DC brush motor driver
·
acrylic base
·
Two "TT" DC brush motor
with wheels, for differentiate drive
·
4 x AA battery to power the controller
and motor
·
Two IR Line Tracking
Module, for line following
·
Standard Cytron sample
code
https://gist.github.com/suadanwar/b724e33c42e29c5b8ef3d306b417bf7f#file-linefollowing_makerdrive-ino

Off-the-shelf
mobile robot kit components, before assembly
This
small mobile car’s microcontroller I/O pins are exposed outside and easily
accessible. Plus, it come with a small breadboard, that allow us to easily
add-on sensor modules. The acrylic base has multiple mounting holes.
Use
black duct tape to draw black lines on the floor, the mobile car loaded
with merchant standard sample
code will moves following the lines.
https://tutorial.cytron.io/2019/03/28/line-following-robot-using-arduino-maker-drive/

Wiring Table 1: Line Following Robot Connections
Maker Drive: M1A
|
Arduino UNO: Pin 6 (PWM)
|
Maker Drive: M1B
|
Arduino UNO: Pin 9 (PWM)
|
Maker Drive : 5V
|
Arduino UNO: 5V
|
Maker Drive : GND
|
Arduino UNO: GND
|
Maker Drive : M2A
|
Arduino UNO: Pin 10 (PWM)
|
Maker Drive : M2B
|
Arduino UNO: Pin 11 (PWM)
|
Left IR Line Tracking Module :
DO
|
Arduino UNO: Pin A0
|
Right IR Line Tracking Module :
DO
|
Arduino UNO: Pin A1
|
Button onboard of Maker UNO
|
Arduino UNO: Pin 2
|
Piezo Buzzer, onboard of Maker UNO
|
Arduino UNO: Pin 8
|
Maker
UNO controller is fully compatible with Arduino UNO.
Collision Avoidance using Ultrasonic Sensors & Go-Around
Obstruction Action using millis()
Add
ultrasonic sensors ‘HC-SR04 (Generic)’ so that the mobile car will stop
when there are objects in close proximity (20cm) in front.
Furthermore,
the code include a function that when there is object 30cm in front of
mobile car, the mobile car will go around (‘void robotGoAround()’) the
obstruction object.
1.
Firstly,
make mobile car rotates to right for a preset period (200milliseconds)
2.
Make
left motor rotate slower than right motor for a preset period of time (3.2
seconds) so that the mobile car will perform go around object action. At
the same time check if any objects in close proximity (20cm) in front. If
there are objects 20cm in front, stop the mobile car.
3.
After
3.2 seconds, rotates the mobile car to the left for a preset period (300ms)
so that the mobile car resume back to the original travelling direction
after go-around action.
4.
If
there are no obstruction 20cm in front, move forward
5.
Go
around action completed.
This
using millis() (realtime clock) but no
sensors method is flawed. Out of number of trials, handful of times the
mobile car is able to perform go-around action. Possible causes are as
below.
Wiring Table 2: Ultrasonic sensor ‘HC-SR04
(Generic)’ connections plus wiring table-1
HC-SR04 sensor: Vcc
|
Arduino UNO: 5V
|
HC-SR04 sensor: Gnd
|
Arduino UNO: GND
|
HC-SR04 sensor (Front): Trig
|
Arduino UNO: Pin 3 (PWM)
|
HC-SR04 sensor (Front): Echo
|
Arduino UNO: Pin 4
|
Need to select Arduino PWM pins when connecting
to HC-SR04 sensor ‘Trig’ pins.
Maker
UNO controller is compatible with Arduino UNO.
Arduino
source code: SimpleCollisionAvoidanceUltrasonicSensor_ver0.ino
Go-Around Obstruction Action using Ultrasonic Sensors mounted at Left /
Right side
To go-around
an obstruction 30mm ahead, we can use ultrasonic sensors mounted at vehicle
left side to detect the distance to the obstruction and E-Compass to tell
the current orientation. Vehicle perform better go-around action compare to
not using any sensors but millis().
Vehicle
stop when obstruction is 20mm ahead.
1.
Make
mobile car rotates 450 to right by calling ‘robotTurnRight_angle(45)’ function that
use E-Compass as reference.
2.
Make
left motor rotate slower than right motor so that the mobile car will perform
go around obstruction action. At the same time check if any objects in
close proximity (20cm) in front. If there are objects 20cm in front, stop
the mobile car.
During
go-around action, if obstruction too close to the vehicle, make the car
move slightly outward. Vice versa, when car move away from obstruction to much, make the car move slightly inward.
3.
When
moving car’s current orientation is -900 from original planned
orientation, rotate right 450. Run ‘void robotForward_IMU_Guided()’ function and
the mobile car resume back to the original forward travelling direction.
4.
If
there are no obstruction 20cm in front, move forward
5.
Go
around action completed.
Wiring
Table 3: Ultrasonic sensor ‘HC-SR04 (Generic)’ connections plus wiring
table-1, table-2
HC-SR04 sensor: Vcc
|
Arduino UNO: 5V
|
HC-SR04 sensor: Gnd
|
Arduino UNO: GND
|
HC-SR04 sensor (Left): Trig
|
Arduino UNO: Pin 5 (PWM)
|
HC-SR04 sensor (Left): Echo
|
Arduino UNO: Pin 7
|
Arduino
source code: SimpleGoAround_UltraSonicSensors_ver0.ino
Mobile Robot travel in straight-line by
using GY-511 Motion Sensor
When
there are no reference lines on the floor, the small mobile car will wander
randomly. Floor are not perfectly flat, with potholes and dusts.
Furthermore, this mobile car has two driving motors. Each motor rotates
slightly differently, receiving different ground surface frictions. This
cheap mobile car is small, with small wheels and doesn’t have wheel
suspension, therefore moving in random direction.
To
make the mobile car travel in the direction we want, we can use E-Compass
as a reference to closed loop control both motors’ rotation speed. When the
mobile car drifted to the right, we can make the left motor rotate slower
(PWM) so the direction is compensated. Vice versa, when robot drifted to
the left, make the right motor rotates slower.
GY-511
Motion Sensor displays the current mobile car E-Compass x-direction in
0~3600. Install GY-511 Motion Sensor at the mobile car center
front position. Install at car side will make Arduino received slightly off
direction, and car slightly off to the sideway instead of travel in
straight line.

Module: GY-511
Accelerometer and E-Compass Axis Magnetometer Sensor Module
GY-511
Motion Sensor online tutorial: https://create.arduino.cc/projecthub/electropeak/make-a-digital-compass-w-gy-511-accelerometer-magnetometer-df9dc1
Wiring
Table 4: E-compass connections plus wiring table-1
GY-511 module: VIN or VCC or 5V
|
Arduino UNO: 5V
|
GY-511 module: GND
|
Arduino UNO: GND
|
GY-511 module: SCL
|
Arduino UNO: Pin A5 (SCL)
|
GY-511 module: SDA
|
Arduino UNO: Pin A4 (SDA)
|
Maker
UNO controller is compatible with Arduino UNO.
This is a very simple code by me to compensate
the mobile car direction
#include
"CytronMotorDriver.h"
#include
<Wire.h>
#include
<LSM303.h>
//
Configure the motor driver.
CytronMD motor1(PWM_PWM, 6, 9); // PWM 1A =
Pin 6, PWM 1B = Pin 9.
CytronMD motor2(PWM_PWM, 10, 11); // PWM
2A = Pin 10, PWM 2B = Pin 11.
#define BUTTON 2
LSM303
compass;
float
initial_Compass_Heading = 0.0;
float
current_Compass_Heading = 0.0;
bool
Robot_RunStop = false;
void
setup()
{
//Digital Compass
Wire.begin();
compass.init();
compass.enableDefault();
compass.m_min
= (LSM303::vector<int16_t>){-32767,
-32767, -32767};
compass.m_max
= (LSM303::vector<int16_t>){+32767,
+32767, +32767};
Serial.begin(9600);
}
void
loop()
{
if (digitalRead(BUTTON) ==
LOW) {
compass.read();
initial_Compass_Heading
= compass.heading((LSM303::vector<int>){1,
0, 0});
Serial.print("Initial
Compass: ");
Serial.println(initial_Compass_Heading);
Robot_RunStop
= true;
}
while (Robot_RunStop)
{
robotForward_CompassGuided();
}
}
void
robotForward_CompassGuided()
{
compass.read();
current_Compass_Heading
= compass.heading((LSM303::vector<int>){1,
0, 0});
Serial.print("Current
compass: ");
Serial.println(current_Compass_Heading);
if(abs(current_Compass_Heading - initial_Compass_Heading)
< 2.0)
{
motor1.setSpeed(150);
motor2.setSpeed(150);
}
else
{
if(current_Compass_Heading > 270 && initial_Compass_Heading < 90) //Car is drifted to the right direction
{
motor1.setSpeed(150); // Adjust
back to straight line
if(360.0 -
current_Compass_Heading + initial_Compass_Heading
< 2.0)
motor2.setSpeed (150);
else
motor2.setSpeed (150 - (360.0 - current_Compass_Heading + initial_Compass_Heading)*2.0);
}
if(initial_Compass_Heading > 270 && current_Compass_Heading < 90) //Car is drifted to the left direction
{
if(360.0 -
initial_Compass_Heading + current_Compass_Heading
< 2.0 )
motor1.setSpeed (150);
else
motor1.setSpeed (150 - (360.0 - initial_Compass_Heading + current_Compass_Heading)*2.0);
motor2.setSpeed(150); // Adjust
back to straight line
}
else if(current_Compass_Heading < initial_Compass_Heading) //Car is drifted to the right direction
{
motor1.setSpeed(150); // Adjust
back to straight line
motor2.setSpeed(150 - (initial_Compass_Heading - current_Compass_Heading)*2.0);
}
else //Car is drifted to the left
direction
{
motor1.setSpeed(150 - (current_Compass_Heading - initial_Compass_Heading)*2.0);
motor2.setSpeed(150); // Adjust
back to straight line
}
}
delay(5);
}
|
Move Arduino Mobile Car in Preset Route
E-compass value is mainly absolute (earth magnetic
field). Therefore, we can use E-Compass as one of the alternative methods
to set the route directions, beside drawing reference lines on the floor
and etc.
To acquire the mobile car travel
distances & speed, add Speed Sensor Modules on left and right wheels.
https://create.arduino.cc/projecthub/hardyedela/measurement-of-mobile-robots-with-arduino-and-lm393-sensors-16c5b6

Fig.
Speed Sensor Module
The output of the sensor (trigger
signal) is connected to the external interrupt pin of the Arduino
microcontroller. Each time a gap in the grid is detected, an interrupt is
triggered and the code in the ISR (Interrupt Service Routine) is executed.
We can calculate the time interval between two such triggers, hence
calculate the speed of the wheel.
In this implementation, ‘Arduino Mega
2560’ is used instead of Maker
UNO. Because ‘Arduino
Mega 2560’ has more AD I/O pins, external interrupt pins.
Arduino
source code:
Rev 0:
SpeedSensors _ver0.ino
Rev 1:
Slightly modified the mobile car motor rotation control. During mobile car
rotation to the left or right, motor PWM output become smaller gradually when
current mobile car E-compass angle reaching goal E-compass angle. SpeedSensors _ver1.ino
1.
Motor
car move in a preset E-compass direction (current E-compass direction upon
pressing Start button) for a 150cm, then stop.
2.
Rotate
900 to the left. Move 50cm and stop.
3.
Rotate
900 to the right. Move 80cm and stop.
4.
Rotate
1800 to flip direction. Repeat step 1.
In this implementation, the mobile
car can move and rotate according to the preset route but with traveling
distance errors (reasons mentioned above). Therefore, sometimes not
arriving to the desire waypoints. This mobile car cannot travel as accurate
as with floor with reference lines. Maybe we need image processing /
fiducials to know the current location and waypoints’ direction.
Wiring
Table 5: Using ‘Arduino Mega 2560’
Maker Drive: M1A
|
Arduino Mega 2560: Pin 4
|
Maker Drive: M1B
|
Arduino Mega 2560: Pin 5
|
Maker Drive: M2A
|
Arduino Mega 2560: Pin 6
|
Maker Drive: M2B
|
Arduino Mega 2560: Pin 7
|
Maker Drive :
5V
|
Arduino Mega 2560: 5V
|
Maker Drive :
GND
|
Arduino Mega 2560: GND
|
Left IR Line Tracking Module
: DO
|
Arduino Mega 2560: Pin A0
|
Right IR Line Tracking Module : DO
|
Arduino Mega 2560: Pin A1
|
Push Button
|
Arduino Mega 2560: Pin 22
|
Piezo Buzzer
|
Arduino Mega 2560: Pin 23
|
HC-SR04 sensor: Vcc
|
Arduino Mega 2560: 5V
|
HC-SR04 sensor: Gnd
|
Arduino Mega 2560: GND
|
HC-SR04 sensor (Front): Trig
|
Arduino Mega 2560: Pin 9 (PWM)
|
HC-SR04 sensor (Front): Echo
|
Arduino Mega 2560: Pin 24
|
HC-SR04 sensor (Left): Trig
|
Arduino Mega 2560: Pin 10 (PWM)
|
HC-SR04 sensor (Left): Echo
|
Arduino Mega 2560: Pin 26
|
HC-SR04 sensor (Right): Trig
|
Arduino Mega 2560: Pin 11 (PWM)
|
HC-SR04 sensor (Right): Echo
|
Arduino Mega 2560: Pin 27
|
HC-SR04 sensor (Diagonal Left): Trig
|
Arduino Mega 2560: Pin 12 (PWM)
|
HC-SR04 sensor (Diagonal Left): Echo
|
Arduino Mega 2560: Pin 28
|
HC-SR04 sensor (Diagonal Right): Trig
|
Arduino Mega 2560: Pin 13 (PWM)
|
HC-SR04 sensor (Diagonal Right): Echo
|
Arduino Mega 2560: Pin 29
|
GY-511 module: VIN or VCC or 5V
|
Arduino Mega 2560: 5V
|
GY-511 module: GND
|
Arduino Mega 2560: GND
|
GY-511 module: SCL
|
Arduino Mega 2560: Pin 21 (SCL)
|
GY-511 module: SDA
|
Arduino Mega 2560: Pin 20 (SDA)
|
Speed Sensor: VCC
|
Arduino Mega 2560: 5V
|
Speed Sensor: GND
|
Arduino Mega 2560: GND
|
Speed Sensor (Left): DO
|
Arduino Mega 2560: Pin 2 (INT0)
|
Speed Sensor (Right): DO
|
Arduino Mega 2560: Pin 3 (INT1)
|
|