How To Detect Objects With HC-SR04 Ultrasonic Sensor, Arduino and Millis - Into Robotics
How To Detect Objects With HC-SR04 Ultrasonic Sensor, Arduino and Millis - Into Robotics
Different projects may have different requirements. At the end of this tutorial, you will have a exible
structure that can be used in different robots and make it possible to add more sensors, or use only
one sensor,
This website or use another
or its third-party tools usetype of sensor
cookies, (for
which are example,
necessary infrared
to its sensor).
functioning and required to achieve the
purposes illustrated in the cookie policy. If you want to know more or withdraw your consent to all or some of the cookies,
Accept
please refer to the cookie policy. By closing this banner, scrolling this page, clicking a link or continuing to browse
If you
otherwise, youplan
agreetotobuild
the useadvanced
of cookies.robots in a productive and professional manner, this is the point where
More info
you can start.
Before starting to connect the sensor and write the rst line of code, let’s be sure that we have all the
hardware parts. Here is the list of hardware that I use to write the tutorial:
1 X Arduino UNO
1 X USB cable
1 X HC-SR04
1 X Breadboard
female-to-female/male-to-male/female-to-male jumper wires
For the moment, I use a USB cable to power the Arduino UNO. The 5V USB port of a personal
computer or laptop provides enough power to run a 5V Arduino and the three ultrasonic sensors.
The above set up is just for connecting and testing the ultrasonic sound detection system. When the
sensor and the Arduino board will be mounted on a mobile robot, the entire detection system will run
on batteries.
Operating Voltage: DC 5V
Operating Current: 15mA
Operating Frequency: 40KHz
Range: from 2cm to 4m
Ranging Accuracy: 3mm
Trigger Input Signal: 10µS TTL pulse
The operating voltage of the sensor is the same as the Arduino 5V output pin – DC 5V. The operating
current for an ultrasonic sensor is 15mA, which can be supported by Arduino even if it is connected to
a USB port of a computer. The 5V output pin of Arduino UNO is suitable for ~400 mA on USB, ~900 mA
when using an external power adapter. At this step, we will take into consideration only these two
speci cations and start to connect the sensor to the board.
For connections, I use female-to-male jumper wires, a breadboard, one HC-SR04, and an Arduino UNO
board.
Connections:
Before writing the rst line of code, let’s recapitulate how an ultrasonic sensor works.
It pings a sound wave (for at least 10us according to speci cations), which travels through the air, and
if there is an object that re ects the sound wave, the sensor measures the time that ping took to
return to the receiver. To calculate the distance between sensor and object detected, we consider the
travel time and the speed of the sound.
Info: The sound moves through the air at different speeds depending on the temperature. Since we are using
the speed of sound to measure the time that ping took to return to the receiver, the environmental
temperature can affect the accuracy of an ultrasonic sensor. Temperature compensation is not part of this
tutorial, but you can add it later in your code.
C++
/*
:Version 1.0
:Author: Dragos Calin
:Email: [email protected]
:License: BSD
:Date: 06/04/2020
*/
void startTimer() {
timerStart = millis();
}
/*Sets the data rate in bits per second and configures the pins */
void setup() {
Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
}//end switch
}//end loop
Once the sensor is connected to Arduino and the output is transformed in centimeters, we can go on
and do the tests to determine the range of the sensor.
The size, shape, and orientation of the object target affect the maximum distance at which it can be
detected. For example, round shape objects or sound-absorbing materials such as fabrics re ect less
energy or nothing directly back to the sensor. The ultrasonic sensor is not affected by optical
characteristics such as color, re ectivity, transparency, or opaqueness. Also, objects may be introduced
into the detection zone from any direction.
Note: I did my tests in a noisy environment, and I use a ruler and a paper agenda, which is an object that can
be easily detectable. I didn’t do tests on an object with round shapes which de ected in all directions the
majority of the echo. Please don’t forget that this is just a test, and may have results that are not very
accurate.
The rst step in determining the range of an HC-SR04 ultrasonic sensor is to decide the range that
you need for your robot. Let me explain what it means!
For example, I have a 2WD mobile chassis, and I want to use it to detect and avoid obstacles. I know
from the speci cation that the HC-SR04 sensor’s range is between 2 and 400 centimeters.
I did a test with one sensor, and the result was that under 5 centimeters, the sensor performed no
reliable measurements. 5cm is a minimum detection range starting from the sensor head. The zone
area between 0cm and 5cm should be considered as a blind zone.
The next step was to determine the operating detection range that we need for our application. This
is the range in which the sensor can do a detection or measurement during all times with high
accuracy. If we search in the speci cations, we can see a maximum detection range of 400
centimeters. This range couldn’t be taken into consideration in this case. These values are most
probably taken when all conditions are very good to optimal. In a real-life application, we are using
the sensor in a noisy environment with different temperatures and humidity.
Info: If the sensor is very close to an object, less than 3 centimeters, you will notice some strange values for
distance returned by the sensor. This behavior is the situation when the sensor will not detect the rst echo
but may detect a second or third echo which is translated as a longer distance than the actual value.
The HC-SR04 is not a highly precise sensor but is good enough to use it for learning how to build
robots. For this reason, I took into consideration an operating detection range of 100 centimeters – 1
meter in front of the sensor. This range is enough to learn how to build an autonomous mobile robot
with DIY components and test it in a living room area.
The ultrasonic beam angle for HC-SR04 is typically 10-15 degrees and conically shaped. I add in the
above picture the optimal values when the sensor accuracy is high in the range of 5 to 100cm.
For the moment, we detect the objects and know the operating detection range. In the next part of
the tutorial, I will show you how to write classes and build a exible structure that can be used in
different robots and make it possible to add more sensors.
Step 1: To create a new tab in Arduino IDE, go to the top right and press on button 1. Then select from
menu 2 “New Tab“:
Step 2: In the lower part of the IDE should appear a new eld. In this eld, we write the name of the
new le. For the rst tab, type “Range.h” – the le where we will store the class for range detection
sensors – and then press the OK button.
Range.h
Step 3: At this point, you should see in your Arduino IDE a tab like this:
Tab Range.h
Follow steps 1 and 2 to create a new tab for class Timer. The tab name is Timer.h.
Tab Timer.h
3.1 Ultrasonic_Sensors_to_Detect_Obstacles
Ultrasonic_Sensors_to_Detect_Obstacles
C++
1 /*
2 :Version 2.0
3 :Author: Dragos Calin
4 :Email: [email protected]
5 :License: BSD
6 :Date: 06/04/2020
7 :Last update: 09/04/2020
8 :Apply best practice methods and create two classes: Range and Timer
9 */
10
11 #include "Range.h"
12 #include "Timer.h"
13
14 /*create an object for each sensor*/
15 Range range(3, 2);
16 Timer timerLoop;
17
18 void setup() {
19 Serial.begin(9600);
20 }
21
22 void loop() {
23 if (timerLoop.isTimeForLoop(50)) { /*loop for every 50 milliseconds*/
24 Serial.print("Distance measured is: ");
25 Serial.print(range.sensorRange());
26 Serial.println(" cm");
27 timerLoop.startTimer();
28 }
29 }//end loop
Lines 15-16: We are using object-oriented programming, and we have to instantiate the Range and
Timer classes to create an object and an instance of the class.
Line 19: we are in the setup function and the rst thing we do is to open the serial port and set data
rate to 9600 bps.
Lines 23 and 27: We check the time and publish every 50 milliseconds.
3.2 Range.h
Tab Range.h
C++
1 #ifndef RANGE_H
2 #define RANGE_H
3
4 #include "Timer.h"
5
6 Timer tm;
7
8 class Range {
9 enum SensorStates {
10 TRIG_LOW,
11 TRIG_HIGH,
12 ECHO_HIGH
13 };
14 SensorStates _sensorState = TRIG_LOW;
15
16 int _TrigPin;
17 int _EchoPin;
18 int _triggerHigh = 10;
19 int _timerLow = 2;
20
21 public:
22 Range(int TRIG_PIN, int ECHO_PIN) {
23 _TrigPin = TRIG_PIN;
24 _EchoPin = ECHO_PIN;
25 pinMode(_TrigPin, OUTPUT);
26 pinMode(_EchoPin, INPUT);
27 }
28
29 float sensorRange() {
30 switch (_sensorState) {
31 case TRIG_LOW: {
32 trigStateLOW();
33 tm.startTimer();
34 if (tm.isTimerReady(_timerLow)) {
35 _sensorState = TRIG_HIGH;
36 }
37 } break;
38
39 case TRIG_HIGH: {
40 trigStateHIGH();
41 tm.startTimer();
42 if (tm.isTimerReady(_triggerHigh)) {
43 _sensorState = ECHO_HIGH;
44 }
45 } break;
46
47 case ECHO_HIGH: {
48 trigStateLOW();
49 _timeDuration = pulseIn(_EchoPin, HIGH);
50 _sensorState = TRIG_LOW;
51 return (_timeDuration * 0.034 / 2);
52 } break;
53
54 }
55 }
56
57 private:
58 float _timeDuration, _distance;
59
60 void trigStateLOW() {
61 digitalWrite(_TrigPin, LOW);
62 }
63 void trigStateHIGH() {
64 digitalWrite(_TrigPin, HIGH);
65 }
66
67 };
68 #endif
Lines 1-2 and 68: prevent multiple includes of the header. It checks if a unique value of Range.h is
de ned. Then if it’s not de ned, it de nes Range.h and continues with the rest of the page.
Lines 9-14: Enumerate the states of the sensor. We start to deactivate the trigger pin, then activate
the trigger, and in the end, we activate the echo pin to return the time duration of the impulse.
Lines 22-27: The constructor of the class Range. In constructor are de ned the pins and the mode of
the pins.
Lines 29-54: I use the switch statement to select one-by-one the states of the sensor. In the rst case
TRIG_LOW, ensure the trigger pin is low, then count two milliseconds until we switch to TRIG_HIGH –
the second state of the sensor.
In the case of TRIG_HIGH, ensure that the trigger pin is high and count ten milliseconds until
switching to the next state ECHO_HIGH.
In the case of ECHO_HIGH, ensure trigger pin is low, read the time duration of the pulse, set the next
state as TRIG_LOW, and transform in centimeters the readings from the sensor.
Lines 57-65: In the private section of the class are added two functions. One function is to change the
trigger state to low, and a second function to change the trigger state to high.
3.3 Timer.h
Tab Timer.h
C++
1 #ifndef TIMER_H
2 #define TIMER_H
3 class Timer {
4 private:
5 unsigned long _timerStart = 0;
6
7 public:
8 void startTimer() {
9 _timerStart = millis();
10 }
11
12 bool isTimerReady(int _mSec) {
13 return (millis() - _timerStart) < _mSec;
14 }
15
16 bool isTimeForLoop(int _mSec) {
17 return (millis() - _timerStart) > _mSec;
18 }
19 };
20
21 #endif
Lines 1,2 and 21: prevent multiple includes of the header. It checks if a unique value of Timer.h is
de ned. Then if it’s not de ned, it de nes Timer.h and continues with the rest of the page.
Lines 4-5: In the private section of the class, de ne the time to start variable.
Lines 8-10: the function to start counting the time using millis(). I prefer to use millis() instead of
delay() from two reasons: millis() is more accurate than delay(), and is a non-blocking alternative of
delay().
Lines 12-18: Two functions that do the same thing, check if the time passed and return true.
Depending on the situation, we call one of the two functions.
After going through this tutorial, you learn how to use millis(), how to build classes, determine the
detection range, and print the output of an ultrasonic sensor.
Related Posts:
8 Tutorials To Solve Problems and Improve the Performance of HC-SR04
Ultrasonic Sensors in Robotics
How to Detect and Track Objects Using Matlab
Leave a Reply
Your email address will not be published. Required elds are marked *
Comment
Name *
Email *
Website
Post Comment
T W I T T E R U P D AT E
L AT E S T P O S T S
How to Use sensor_msgs/Range (ROS) For Multiple Sensors with rosserial May 5, 2020
Getting started with the Garmin (Qwiic) LIDAR-Lite v4 LED May 1, 2020
S U P P O R T T H I S B LO G
A RT I C L E S TO YO U R I N B OX
Name:
John Doe
Email address:
I consent to receive articles, information about services and special offers by email. For more information, see the Privacy Policy
No spam, ever. That's a promise.
Subscribe