0% found this document useful (0 votes)
19 views

Measurement of Mobile Robots With Arduino LM393 Sensors

Measurement of Mobile Robots with Arduino LM393 Sensors
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views

Measurement of Mobile Robots With Arduino LM393 Sensors

Measurement of Mobile Robots with Arduino LM393 Sensors
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

Measurement of Mobile Robots with Arduino LM393 Sensors

COMPONENTS AND SUPPLIES

Arduino UNO

× 1

Texas Instruments LM393 chip × 1


NECESSARY TOOLS AND MACHINES

Solder Pot, LCD Display

APPS AND ONLINE SERVICES

Arduino IoT Cloud

ABOUT THIS PROJECT

LM393 Speed Sensor Module (H206)


Before we start the project's circuit diagram and code, let us understand the LM393 speed sensor
module, because it plays a vital role in the project. H206 speed sensor module is composed of
infrared light sensor and LM393 voltage comparator IC, so it is named as LM393 speed sensor.
The module also includes a grid plate, which must be mounted on the rotating shaft of the motor.
All components are marked in the image below.
The infrared light sensor is composed of infrared LED and phototransistor, separated by a small
gap. As shown above, the entire sensor device is placed in a black housing. The grid plate is
composed of grooves, and the plate is arranged between the gaps of the infrared light sensors so
that the sensor can sense the gap in the grid plate. Each gap in the grid plate triggers the IR sensor
when passing through the gap; a comparator is then used to convert these triggers into a voltage
signal. The comparator uses ON Semiconductor's LM393 IC. The module has three pins, two of
which are used to power the module, and one output pin is used to count the number of triggers.
H206 Sensor Installation
Installing these types of sensors is a bit tricky. It can only be installed on motors with shaft
protruding on both sides. One side of the axle is connected to the wheel, while the other side is
used to install the grid, as shown above.
Since the wheels and wheels are connected on the same axis, both rotate at the same speed, so by
measuring the vehicle speed, we can measure the speed of the wheels. Make sure that the gap in
the grid plate passes through the infrared sensor before the sensor can count the number of gaps
that pass through. As long as the specified conditions are met, you can also set up your own
mechanical device to install the sensor. Infrared sensors are commonly used in many robot
projects to guide robots to understand obstacles.
The grid plate shown above has 20 slots (grids). This means that the sensor will find 20 gaps for
one full rotation of the wheel. By calculating the number of gaps detected by the sensor, we can
calculate the distance traveled by the wheel, and similarly by measuring the speed of the gap
found by the sensor, we can detect the speed of the wheel. In our robot, we install this sensor on
two wheels, so we can also find the angle of the robot. However, using an accelerometer or
gyroscope can calculate the rotation angle more wisely. Here we learn to use the Arduino to
interface the accelerometer with the gyroscope and try to use them to measure the rotation angle.
Schematic
The complete circuit diagram of the speed and distance sensing robot is shown below. The robot
uses the Arduino Nano as its brain, and the two DC motors for the wheels are driven by the
L298N H-bridge motor driver module. The joystick is used to control the speed and direction of
the robot, and the two speed sensors H206 are used to measure the speed, distance and angle of
the robot. Then, the measured value is displayed in the 1602 LCD module. The potentiometer
connected to the LCD can be used to adjust the contrast of the LCD, and the resistor is used to
limit the current flowing to the LCD backlight.
The entire circuit is powered by a 7.4V lithium battery. The 7.4V power supply is provided to the
12V pin of the motor driver module. The voltage regulator on the motor driver module then
converts 7.4V to a regulated voltage + 5V for powering the Arduino, LCD, sensors and joystick.
The motor is controlled by Arduino digital pins 8, 9, 10 and 11. Since the speed of the motor must
also be controlled, we should provide a PWM signal to the positive pole of the motor. Therefore,
we have pins 9 and 10, which are both PWM pins. The X and Y values of the joystick are read
using analog pins A2 and A3, respectively.
We know that the H206 sensor triggers when it detects gaps in the grid. Since these triggers
cannot always be accurately read to calculate the correct speed and distance, the trigger (output)
pins are connected to external interrupt pins 2 and 3 of the Arduino board. Assemble the entire
circuit on the chassis and install the speed sensor according to the instructions. After the
connection is completed, the robot will look like the following.
The hardware part has been completed. let's dive into how to measure the speed, distance and
angle of the robot, and then enter the programming part.
The logic behind measuring speed with the H206 sensor
From the sensor installation settings, you should know that the H206 sensor only measures the
gaps present in the grid. When installing, ensure that the wheels (whose speed should be
measured) and the baffle rotate at the same speed. Just like here, since we install the wheels and
wheels on the same shaft, they will all rotate at the same speed.
In our setup, we installed two sensors for each wheel to measure the angle of the robot. But if
your goal is to measure only speed and distance, we can install the sensor on any wheel. The
output of the sensor (trigger signal) is most often connected to the external interrupt pin of the
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. If we can calculate the time interval between two
such triggers, we can calculate the speed of the wheel.
In Arduino, we can easily calculate this time interval using the millis () function. Since the device
is powered on, this millisecond function will increase by 1 every millisecond. Therefore, when
the first interrupt occurs, we can save the value of millis () in a dummy variable (such as pevtime
in the code), and then when the second interrupt occurs, we can calculate to subtract from millis
() The time required for the pevtime value.
Formula:
Time taken = current time – previous time
timetaken = millis()-pevtime; //timetaken in millisec
Once we have calculated the time used, we can simply calculate the value of rpm using the
following formula, where (1000 / timetaken) gives RPS (revolutions per second) and multiplies it
by 60 to convert RPS to RPM Revolutions per minute).
Formula:
rpm=(1000/timetaken)*60;
After calculating the speed, we can use the following formula to calculate the speed of the
vehicle, provided that we know the radius of the wheel.
Formula:
Velocity = 2π × RPS × radius of wheel.
v = radius_of_wheel * rpm * 0.104
Note that the above formula is used to calculate the speed in m / s. If km / hr is to be used,
replace 0.0104 with 0.376. If you want to know how to get the value 0.104, then try to simplify
the formula V = 2π × RPS × wheel radius.
Even if a Hall sensor is used to measure the speed of a rotating object, the same technique is
used. But there is a defect for the H206 sensor, the grid board has 20 slots, so the time used to
measure the gap between the two slots will overload the microcontroller. Therefore, we only
measure the speed when the wheel is fully rotated. Since each gap will generate two interruptions
(one at the beginning and the other at the end of the gap), we will get a total of 40 interruptions to
allow the wheel to complete a full rotation. So we wait for 40 interruptions before actually
calculating the wheel speed. The code is as follows.
Code:
if(rotation>=40)
{
timetaken = millis()-pevtime; //timetaken in millisec
rpm=(1000/timetaken)*60; //formulae to calculate rpm
pevtime = millis();
rotation=0;
}
Another disadvantage of this method is that the speed value will not drop to zero, because the
interruption will always wait for the wheel to complete a revolution to calculate the rpm value.
This shortcoming can be easily overcome by adding a simple code that monitors the time interval
between two interrupts. If it exceeds the normal value, then we can force the rpm and velocity
values to zero. Link In the following code we use the variable dtime to check the time difference.
If it exceeds 500 milliseconds, the speed and rpm values are forced to zero.
Code:
/*To drop to zero if vehicle stopped*/
if(millis()-dtime>500) //no inetrrupt found for 500ms
{
rpm= v = 0; // make rpm and velocity as zero
dtime=millis();
}
The logic behind measuring wheel travel distance
We already know that when the wheel completes a full rotation, the Arduino will sense 40
interruptions. Therefore, for each rotation made by the wheel, it is obvious that the distance
traveled by the wheel is equal to the circumference of the wheel. Since we already know the
radius of the wheel, we can easily calculate the covered distance using the following formula.
Distance = 2πr * number of rotations
distance = (2*3.141*radius_of_wheel) * (left_intr/40)
In the case of calculating the wheel circumference using the formula 2πr, then multiply by the
number of revolutions of the wheel.
The logic behind measuring robot angle
There are many ways to determine the angle of the robot. Accelerometers and gyroscopes are
commonly used to determine these values. But another cheap method is to use H206 sensors on
both wheels. In this way, we can know the number of turns of each wheel. The figure below
illustrates how to calculate the angle.
When the robot is initialized, the angle it faces is regarded as 0 °. From there when it rotates the
left to initialize the robot, the angle it faces is regarded as 0 °. From there it rotates to the left, the
angle increases negatively, and if it rotates to the right, the angle increases positive. For
understanding, let us consider the range of -90 to +90, as shown. In this arrangement, since both
wheels have the same diameter, if either wheel is fully rotated, we will turn at an angle of 90 °.
For example, if the left wheel completes one rotation (80 interruptions), the robot will turn 90 °
to the left, and if the right wheel completes one rotation (80 interruptions), the robot will turn 90
° to the right. Now we know that if the Arduino detects 80 interruptions on one wheel, then the
robot has turned 90 ° and we can judge whether the robot is rotating by positive (right) or
negative (left). So you can use the following formula to calculate the left and right angles:
Formula:
int angle_left = (left_intr % 360) * (90/80) ;
int angle_right = (right_intr % 360) * (90/80) ;
90 is the angle covered when interrupting 80. The resulting value is multiplied by the number of
interrupts. We also used a modulus of 360 so that the resulting value does not exceed 36. Once
we have calculated the left and right corners, we can simply obtain the effective angle the robot
is facing by subtracting the left corner from the right angle.
angle = angle_right - angle_left;
Arduino Programming
We start the program by defining digital I / O pins for the two motors. Please note that we must
also control the speed of the motor, so the PWM pin on the Arduino must be used to control the
motor. Pins 8, 9, 10 and 11 are used here.
Code:
#define LM_pos 9 // left motor
#define LM_neg 8 // left motor
#define RM_pos 10 // right motor
#define RM_neg 11 // right motor
#define joyX A2
#define joyY A3
To measure the speed and distance covered, we need to know the radius of the wheel, and the
measured value is entered in meters as shown below. For robots, the radius is 0.033 meters, but
depending on your robot, it may be different.
Code:
float radius_of_wheel = 0.033; //Measure the radius of your wheel and enter it here in cm
In the setup function, we initialize all the values to zero, and then display a brief text on the LCD.
We also initialized the serial monitor for debugging. Then we mentioned that the speed sensor
H206 is connected to pins 2 and 3 as an external interrupt. This is where the interruption is
detected, and the ISR functions Left_ISR and Right_ISR will be executed accordingly.
Code:
void setup()
{
rotation = rpm = pevtime = 0; //Initialize all variable to zero
Serial.begin(9600);
lcd.begin(16, 2); //Initialise 16*2 LCD
lcd.print("Bot Monitor"); //Intro Message line 1
lcd.setCursor(0, 1);
lcd.print("-CircuitDigest "); //Intro Message line 2
delay(2000);
lcd.clear();
lcd.print("Lt: Rt: ");
lcd.setCursor(0, 1);
lcd.print("S: D: A: ");
pinMode(LM_pos, OUTPUT);
pinMode(LM_neg, OUTPUT);
pinMode(RM_pos, OUTPUT);
pinMode(RM_neg, OUTPUT);
digitalWrite(LM_neg, LOW);
digitalWrite(RM_neg, LOW);
attachInterrupt(digitalPinToInterrupt(2), Left_ISR, CHANGE); //Left_ISR is called when left
wheel sensor is triggered
attachInterrupt(digitalPinToInterrupt(3), Right_ISR, CHANGE);//Right_ISR is called when right
wheel sensor is triggered
}
In the Left_ISR function code, we simply add a variable named left_intr, which will be used later
to measure the angle of the robot. Inside Right_ISR, we do the same thing, but in addition we are
still calculating the speed here. Each interruption will increase the variable rotation, and then use
the above logic to calculate the speed.
Code:
void Left_ISR()
{
left_intr++;delay(10);
}
void Right_ISR()
{
right_intr++; delay(10);
rotation++;
dtime=millis();
if(rotation>=40)
{
timetaken = millis()-pevtime; //timetaken in millisec
rpm=(1000/timetaken)*60; //formulae to calculate rpm
pevtime = millis();
rotation=0;
}
}
Within the main loop function, we monitor the values of X and Y in the joystick. Based on the
value of the moving joystick, we control the robot accordingly. The speed of the robot depends on
the pushing distance of the joystick.
Code:
int xValue = analogRead(joyX);
int yValue = analogRead(joyY);
int acceleration = map (xValue, 500, 0, 0, 200);
if (xValue<500)
{
analogWrite(LM_pos, acceleration);
analogWrite(RM_pos, acceleration);
}
else
{
analogWrite(LM_pos, 0);
analogWrite(RM_pos, 0);
}
if (yValue>550)
analogWrite(RM_pos, 80);
if (yValue<500)
analogWrite(LM_pos, 100);
The following function will help the user to move the robot and check whether the obtained value
is as expected. Finally, we can use the above logic to calculate the speed, distance and angle of
the robot, and use the following code to display it on the LCD.
Code:
v = radius_of_wheel * rpm * 0.104; //0.033 is the radius of the wheel in meter
distance = (2*3.141*radius_of_wheel) * (left_intr/40);
int angle_left = (left_intr % 360) * (90/80) ;
int angle_right = (right_intr % 360) * (90/80) ;
angle = angle_right - angle_left;
lcd.setCursor(3, 0); lcd.print(" "); lcd.setCursor(3, 0); lcd.print(left_intr);
lcd.setCursor(11, 0); lcd.print(" "); lcd.setCursor(11, 0);lcd.print(right_intr);
lcd.setCursor(2, 1); lcd.print(" "); lcd.setCursor(2, 1);lcd.print(v);
lcd.setCursor(9, 1); lcd.print(" "); lcd.setCursor(9, 1);lcd.print(distance);
lcd.setCursor(13, 1); lcd.print(" "); lcd.setCursor(13, 1);lcd.print(angle);
Test Arduino robot to measure distance, speed and angle
When the hardware is ready, upload the code to the Arduino and use the joystick to move the
robot. The speed of the robot, the distance and angle it covers will be displayed on the LCD
screen as shown below.
On the LCD, the terms Lt and Rt denote the left interrupt count and the right interrupt count,
respectively. You can find that each gap detected by the sensor increases these values. Time S
represents the speed of the robot in meters / second, and the term D represents the distance in
meters. The angle of the robot is displayed at 0 ° as the end of a straight line, counterclockwise
rotation is negative, and clockwise rotation is positive.

SCHEMATICS
CODE
#define LM_pos 9 // left motor
#define LM_neg 8 // left motor
#define RM_pos 10 // right motor
#define RM_neg 11 // right motor
#define joyX A2
#define joyY A3
float radius_of_wheel = 0 .033; //Measure the radius of your wheel and enter it here in cm
void setup ()
{
rotation = rpm = pevtime = 0 ; //Initialize all variable to zero
Serial.begin (9600) ;
lcd.begin (16 , 2) ; //Initialise 16 *2 LCD
lcd.print ( "Bot Monitor" ) ; //Intro Message line 1
lcd.setCursor (0 , 1) ;
lcd.print ( "-CircuitDigest " ) ; //Intro Message line 2
delay (2000) ;
lcd.clear () ;
lcd.print ( "Lt: Rt: ");
lcd.setCursor (0 , 1) ;
lcd.print ( "S: D: A: " ) ;

pinMode ( LM_pos, OUTPUT ) ;


pinMode ( LM_neg, OUTPUT ) ;
pinMode ( RM_pos, OUTPUT ) ;
pinMode ( RM_neg, OUTPUT ) ;

digitalWrite ( LM_neg, LOW ) ;


digitalWrite ( RM_neg, LOW ) ;

attachInterrupt ( digitalPinToInterrupt (2) , Left_ISR, CHANGE ) ; //Left_ISR is called when left wheel sensor is triggered
attachInterrupt ( digitalPinToInterrupt (3) , Right_ISR, CHANGE ) ;//Right_ISR is called when right wheel sensor is triggered
}
void Left_ISR ()
{
left_intr++;delay (10) ;
}

void Right_ISR ()
{
right_intr++; delay (10) ;

rotation++;
dtime= millis () ;
if ( rotation> =40)
{
timetaken = millis () -pevtime; //timetaken in millisec
rpm=(1000 /timetaken ) *60; //formulae to calculate rpm
pevtime = millis () ;
rotation=0 ;
}
}
int xValue = analogRead ( joyX ) ;
int yValue = analogRead ( joyY ) ;

int acceleration = map ( xValue, 500 , 0 , 0 , 200) ;

if ( xValue< 500)
{
analogWrite ( LM_pos, acceleration ) ;
analogWrite ( RM_pos, acceleration ) ;
}

else
{
analogWrite ( LM_pos, 0) ;
analogWrite ( RM_pos, 0) ;
}

if ( yValue>550 )
analogWrite ( RM_pos, 80) ;

if ( yValue< 500)
analogWrite ( LM_pos, 100) ;
v = radius_of_wheel * rpm * 0 .104; //0.033 is the radius of the wheel in meter
distance = (2 *3.141*radius_of_wheel ) * ( left_intr/40 ) ;
int angle_left = ( left_intr % 360) * (90 /80 ) ;
int angle_right = ( right_intr % 360) * (90 /80 ) ;
angle = angle_right - angle_left;

lcd.setCursor (3 , 0) ; lcd.print ( " " ) ; lcd.setCursor (3 , 0) ; lcd.print ( left_intr ) ;


lcd.setCursor (11 , 0) ; lcd.print ( " " ) ; lcd.setCursor (11 , 0) ;lcd.print ( right_intr ) ;
lcd.setCursor (2 , 1) ; lcd.print ( " " ) ; lcd.setCursor (2 , 1) ;lcd.print ( v ) ;
lcd.setCursor (9 , 1) ; lcd.print ( " " ) ; lcd.setCursor (9 , 1) ;lcd.print ( distance ) ;
lcd.setCursor (13 , 1) ; lcd.print ( " " ) ; lcd.setCursor (13 , 1) ;lcd.print ( angle ) ;

You might also like