HC-SR04 Ultrasonic Sensor
HC-SR04 Ultrasonic Sensor
(a)
(b)
(c)
(d)
Fig 1: (a) HC-SR04 Sensor, (b) Circuit used to test the ultrasonic sensor, (c) Fritzing Circuit
Diagram, (d) Serial monitor display of the acquired data
1. Introduction
The HC-SR04 is the most popular, economical, easy to use ultrasonic distance sensor available
to the general public and hobbyists. its range extends from 2 cm to 400 cm. The most commonly
usage of this sensor is in obstacle-avoidance projects.
HC-SR04 Specifications
Operating voltage 5V
Operating current 15 mA
Resolution (accuracy) 3 mm
Dimension 45 x 20 x 15mm
Fig 2: Speed of sound vs. temperature and relative humidity according to [2], p = 101.3 kP a, 314
ppm CO 2
High Accuracy Acoustic Relative Humidity Measurement in Duct Flow with Air - Scientific
Figure on ResearchGate. Available from: https://www.researchgate.net/figure/Speed-of-sound-
vs-temperature-and-relative-humidity-according-to-2-p-1013-kP-a_fig9_51873087 [accessed 10
Jan, 2021]
We can see that the humidity has very little to no effect on the speed of sound as long as we
operate in the range 0-40˚C. beyond 60˚C, we may not want to ignore the variation in the speed
of sound. However, for any level of humidity, there is a corrective term to be included in the
relationship between the speed of sound and the temperature, where at 0˚C, the speed of sound is
331.3 m/s.
Hence, for more accurate measurements of the speed of sound, one may want to use the
following expression
V = 331.3 + (0.606 × T)
Difficulties
The start of the process requires the triggering of a 10-μs duration TTL rectangular pulse. When
that is done, the sensor will transmit a 40-kHz burst of pulses (sound waves, which at this
frequency is beyond the hearing range of a human being).
When the reflected signal is received, the Echo pin produces a pulse whose duration is
proportional to the time between the time the burst was generated, and the time the reflected
wave was received.
Code
/*
*/
// include libraries for the DHT11, HC-SR04, and the 1602A QAPASS display
#include "DHT.h" // helps interface with the DHT11 (valid also for DHT22)
// Define Constants
// There was a problem when the echo pin was connected to digital pin 13
// (possibly some interference with another Arduino internal component connected to it)
// Define Variables
const int rs = 11, en = 12, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
void setup() {
ECE114.begin(16, 2);
}
void loop()
duration = sonar.ping_median(iterations);
Serial.print(soundsp);
Serial.print("Humid: ");
Serial.print(hum);
Serial.print(temp);
Serial.print(" C, ");
Serial.print("Distance: ");
Serial.print("Out of range");
else {
Serial.print(distance);
Serial.print(" cm");
delay(500);
ECE114.print(distance);
ECE114.print(" cm");
ECE114.setCursor(0, 1);
ECE114.print("Temp: ");
ECE114.print(temp);
As was mentioned in the code, the expression giving the speed of sound for any temperature and
humidity level is:
However, from the previous graph given in Fig 2, as long as the temperature is less than 40˚C,
the humidity variations can be ignored. Hence we used
The speed of sound given as 343 m/s is valid only at the temperature of 19˚C.
Since the waves travel from the sensor to the target and back to the sensor, the duration of the
generated pulse corresponds to twice the distance from the sensor to the target, hence the need
for a division by 2.
The NewPing library allows us to set a max distance to read, as in this case where the sensor has
been specified to work properly when the distance does not exceed 400 cm. In addition, it has a
built-in median filter that yields the average of a datum, in this case the duration, over many
iterations. This library could have been used to evaluate the distance directly through
Unfortunately, in both cases, the result will be an integer, which could be useful in some cases
but not others.
In the absence of the NewPing library, and using only the Arduino library, see how more
complex the coding would be:
#define trigPin 13
#define echoPin 10
// Define variables:
long duration;
int distance;
void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600);
void loop() {
// to make sure we start with a low-to-high transition, we force the pulse to be low for 2 us
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Read the echoPin, pulseIn() returns the duration (length of the pulse) in microseconds:
// Calculate the distance, assuming the speed of sound valid for 19˚C
Serial.print(distance);
Serial.println(" cm");
delay(1000);
Measurements can be taken faster than the 1 second that has been chosen (delay(1000)) if
needed. It is obvious that the limitation will be related to the generation of the triggering pulse,
the burst of 40kHz pulses, the travel time, and the time to process the data. All instructions are
from the Arduino function set only. This is the main reason we appreciate the usage of the
libraries. Not only will the code be simpler, and shorter, we also have access to data that the
Arduino instruction set may not make available readily. Note that since the distance has been
defined as an integer, the results will be given as integers in cm in this case.
NewPing Library
Assuming
• sonar.ping([max_cm_distance]) - Send a ping and get the echo time (in microseconds)
as a result. [max_cm_distance] allows you to optionally set a new max distance.
• sonar.ping_in([max_cm_distance]) - Send a ping and get the distance in whole inches.
[max_cm_distance] allows you to optionally set a new max distance.
• sonar.ping_cm([max_cm_distance]) - Send a ping and get the distance in whole
centimeters. [max_cm_distance] allows you to optionally set a new max distance.
• sonar.ping_median(iterations [, max_cm_distance]) - Do multiple pings (default=5),
discard out of range pings and return median in microseconds. [max_cm_distance] allows
you to optionally set a new max distance.
• sonar.convert_in(echoTime) - Convert echoTime from microseconds to inches.
• sonar.convert_cm(echoTime) - Convert echoTime from microseconds to centimeters.
• sonar.ping_timer(function [, max_cm_distance]) - Send a ping and call function to test
if ping is complete. [max_cm_distance] allows you to optionally set a new max distance.
• sonar.check_timer() - Check if ping has returned within the set distance limit.
• NewPing::timer_us(frequency, function) - Call function every frequency
microseconds.
• NewPing::timer_ms(frequency, function) - Call function every frequency milliseconds.
• NewPing::timer_stop() - Stop the timer.
// --------------------------------------------------------------------------
-
// Example NewPing library sketch that pings 3 sensors 20 times a second.
// --------------------------------------------------------------------------
-
#include <NewPing.h>
void setup() {
Serial.begin(115200); // Open serial monitor at 115200 baud to see ping
results.
}
void loop() {
for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through each sensor and
display results.
delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should
be the shortest delay between pings.
Serial.print(i);
Serial.print("=");
Serial.print(sonar[i].ping_cm());
Serial.print("cm ");
}
Serial.println();
}