Last Updated: 12/08/2021
HC-SR04 Ultrasonic Sensor
Components >> HC-SR04 Ultrasonic Sensor
What is a HC-SR04 Ultrasonic Sensor?
The HC-SR04 Ultrasonic sensor is a sensor that measures distance from an obect by sending out a high frequency sound that is reflected and it's return timed. A bit like timing the echo from someone clapping under a bridge.
As sound travels at approx 343 metres per second (speed varies with temperature, humidty and certain other factors). The distance from an object can be found by timing the pulse to and from the object,and dividing it by 343. We the divide the result by 2 again as the sound travelled to the object and back and we only want the distance to the object.
The sensor works by sending an ultrasonic sound of 40khz that is above the frequency that humans can hear that is about 20khz and reducing as we get older.
NOTE: Cats, Dogs, Rabbits, mice, hedge Hogs and many similar sized mammals can hear this frequency. Although the pulse only lasts about 1000th of a second care should be taken not to continually fire pulses in close proximatly to animals as it is the type of pulse used in Ultrasonic Cat scarers owever pets, especially in cages cannot run away.
These sensors are very popular when building obstacle avoidance robot cars, however they are part of a bigger family of sensors. If you look at the waterproof JSN-SR04T Ultrasonic Distance Sensor you will recognise the sensor shape as it is the sort of thing that is used in many car parking sensors. Therefore what we learn in controlling the HC-SR04 can be applied to many other similar types of sensor.
HC-SR04 Range and Issues to consider
The HC-SR04 is supposed to have a range of between 20mm and 4000mm (4 metres). However certain factors need to be taken into account at both ends of this range.
Close range: In my experiemnts I managed to get the sensor to read down to about 24mm a few times but care needs to be taken as if the item gets closer than this, the distance readings increase. I assume this is because the sound is bouncing of the object and instead of reflecting back the the receiver bounces back and hits the centre of the board before reflecting back a 2nd time.
This needs to be taken into account with any obstacle avoiding project as waiting for the reading to reach below 30mm could easily lead to a collision as the vehicle momentum will take it a further 10mm before stopping at which point the relection will increase the range. I would advise using 50mm as the minimum distance to stop the vehicle to prevent this issue. You can test this issue for yourself by loading example 1 and moving your hand or an object closer to the sensor.
Long Range: Although the maximum range quoted is over 4000mm, the usuable range for obstacle detenction is much less unless the object being approached is very big such as a wall. As an experiment use script 1 and this time keep your hand flat with the palm of your hand pointed towards the sensor. Now move your hand away and you will see that it becomes more difficult to keep your hand in the beam of the sensor. If you rotate your hand so that the side of your hand is pointed at the sensor you will notice that it is very easy for the sensor to miss your hand. If you move other objects in front of the sensor to simulate things like chair legs you will see that it's very easy to miss the items as the distance increases, especially when they are not centred on the sensor. It is why cars have multiple parking sensors fitted to make sure that any item is in range of at least one sensor.
HC-SR04 Ultrasonic Distance Sensor pins
The sensor has 4 pins:
VCC: 5v DC to power the sensor
Trig: The trigger pin causes a set of pulses to be sent when it is held HIGH (5v) for 10 microseconds ( a microsecond is millionth of a second), this is a very short period of time. When we blink it takes approx 350,000 microseconds ( about 1/3 of a second).
Echo: This is the pin that gives us the received pulse.
Gnd: The common ground for the unit.
HC-SR04 Ultrasonic Distance Sensor Arduino Circuit example
Below are two circuit diagrams, the one on the left is connecting to the Arduino sensor shield (for those doing the robot car project), the right hand diagram connects straight to an Arduino UNO with no shield. Both circuits are connected to the same pins so the code will work whichever way you wire up the sensor.
VCC: to Arduino 5V
Trig: Arduino digital pin 7
Echo: Arduino digital pin 6
Gnd: To Arduino Ground (Gnd).
I chose to connect the Trig and Echo to pins 6 & 7 as they have not been used in the robot car tutorial. They can be changed by changing the pin in the sketches.
HC-SR04 Ultrasonic Distance Sensor Arduino Tutorial
The first example will show how the HC-SR04 Ultrasonic Distance sensor is ue
Example 1: HCSR04UltrasonicDistanceSensorv1.ino
For those doing the robot car who just want to check their wiring just download the code and upload it to your Arduino,
Open the Serial monitor and move your hand in front of the sensor and if all is working you will see the change in distance displayed once a second...
Click to Download code:HCSR04UltrasonicDistanceSensorv1.ino
New items learnt in this lesson:
pulsein() function
This code uses lessons learnt in:
Lesson2 "Hello World"
Lesson 6: Basic Numeric variables, boolean, byte, int, unsigned int, long, unsigned long
Lesson 7: delay();
Functions 1: digitalWrite();
/* HCSR04UltrasonicDistanceSensorv1
*
* Basic sketch to learn how the HC-SR04 sensor works
* The sketch works but because it uses delay() would be harder to integrate with other components or sensors.
*
* pins used
* pin 7 to Trig Pin
* pin 6 to Echo pin
*/
//const int is a constant integer that cannot have it's value changed.
const int triggerPin = 7;
const int echoPin = 6;
//An unsigned long is needed because the numbers produced can be much larger
//than an int can hold (max value 32,767)
unsigned long duration; //time taken for echo
int distance; //in mm
void setup() {
Serial.begin(9600);
Serial.println("HCSR04UltrasonicDistanceSensorv1...");
Serial.println(" ");//Blank line
//pinMode set for OUTPUT...sending HIGH of LOW
pinMode(triggerPin, OUTPUT); //sends signal
//pinMode set for INPUT, we will receive an incoming HIGH or LOW on this pin
pinMode(echoPin, INPUT); //receives signal
}
void loop() {
// Clears the trigPin condition, just in case it had been left HIGH
//Same as turing the LED off in the blink sketch
digitalWrite(triggerPin, LOW);
//A tiny delay 2 millionths of a second
delayMicroseconds(2);
// Sets the trigPin HIGH (ACTIVE) for 10 microseconds
//same as turing the LED on in the blink sketch
digitalWrite(triggerPin, HIGH);
//pin stays HIGH (5v) for 10 microseconds to trigger a pulse
delayMicroseconds(10);
//Pin taken LOW (0v) after pulse triggered ready for next pulse
digitalWrite(triggerPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
//Pulse in HIGH waits for the echoPin to go HIGH (5v) and then starts a timer until it goes LOW
//At that point the HC-SR04 has received it's set of echos
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
// Speed of sound wave divided by 2 as the sound travels to and from the object
distance = duration * 0.34 / 2;
// Displays the distance on the Serial Monitor
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" mm");
//wait 1 second before runing the code again
delay(1000);
}
Example 2: HCSR04UltrasonicDistanceSensorv2Function.ino
Click to Download code:HCSR04UltrasonicDistanceSensorv2Function.ino
New items learnt in this lesson:
Declaring a Local variable in a function
This sketch uses the code from example 1 and turns it into a function called by a millis() timer.
This code uses lessons learnt in:
Lesson 7: delay() v's millis(), controlling timing of programs
Lesson 9: Basics of creating and using functions
/* HCSR04UltrasonicDistanceSensorv2Function
*
* The goal of this sketch is to make the distance reading from the module into a function
* The function needs to be able to use multiple HC-SR04 modules if needed (front and rear)
* Basic sketch to learn how the HC-SR04 sensor works
*
* pins used
* pin 7 to Trig Pin
* pin 6 to Echo pin
*/
//const int is a constant integer that cannot have it's value changed.
const int triggerPin = 7;
const int echoPin = 6;
//Global Variable
unsigned long sensorTimer1;
//Function to trigger a sensor
//It receives the pins of the sensor and send back the distance
int getDistanceHCSSR04(int funcTriggerPin, int funcEchoPin){
//An unsigned long is needed because the numbers produced can be much larger
//than an int can hold (max value 32,767)
//Local variables
unsigned long duration; //time taken for echo
int myDistance;
digitalWrite(funcTriggerPin, LOW);
//A tiny delay 2 millionths of a second
delayMicroseconds(2);
// Sets the trigPin HIGH (ACTIVE) for 10 microseconds
//same as turing the LED on in the blink sketch
digitalWrite(funcTriggerPin, HIGH);
//pin stays HIGH (5v) for 10 microseconds to trigger a pulse
delayMicroseconds(10);
//Pin taken LOW (0v) after pulse triggered ready for next pulse
digitalWrite(funcTriggerPin, LOW);
duration = pulseIn(funcEchoPin, HIGH);
myDistance = duration * 0.34 / 2;
return myDistance;
}
void setup() {
Serial.begin(9600);
Serial.println("HCSR04UltrasonicDistanceSensorv2Function...");
Serial.println(" ");//Blank line
//pinMode set for OUTPUT...sending HIGH of LOW
pinMode(triggerPin, OUTPUT); //sends signal
//pinMode set for INPUT, we will receive an incoming HIGH or LOW on this pin
pinMode(echoPin, INPUT); //receives signal
}
void loop() {
//Local variable
int distance; //in mm
if(millis() > sensorTimer1){
sensorTimer1 = millis() + 1000;
distance = getDistanceHCSSR04(triggerPin,echoPin);
// Displays the distance on the Serial Monitor
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" mm");
}
}
Example 3: HCSR04UltrasonicDistanceSensorv3Function.ino
Click to Download code:HCSR04UltrasonicDistanceSensorv3Function.ino
This sketch shows how the function is called by three seperate HC-SR04 modules at independant times controlled by millis()
This code uses lessons learnt in:
Lesson 7: delay() v's millis(), controlling timing of programs
Lesson 9: Basics of creating and using functions
/* HCSR04UltrasonicDistanceSensorv3Function
*
* The goal of this sketch is to use multiple HC-SR04 modules triggering at independant intervals
*
* pins used
* pin 7 to Trig Pin...sensor 1
* pin 6 to Echo pin...sensor 1
* pin 5 Trig pin...sensor 2
* pin 4 Echo pin...sensor 2
* pin 3 Trig pin...sensor 3
* pin 2 Echo pin...sensor 3
*/
//Global Variables
//const int is a constant integer that cannot have it's value changed.
const int triggerPin = 7;
const int echoPin = 6;
const int triggerPin2 = 5;
const int echoPin2 = 4;
const int triggerPin3 = 3;
const int echoPin3 = 2;
//the three timers
unsigned long sensorTimer1;
unsigned long sensorTimer2;
unsigned long sensorTimer3;
//Function to trigger a sensor
//It receives the pins of the sensor and send back the distance
int getDistanceHCSSR04(int funcTriggerPin, int funcEchoPin){
//An unsigned long is needed because the numbers produced can be much larger
//than an int can hold (max value 32,767)
//Local Variables
unsigned long duration; //time taken for echo
int myDistance;
digitalWrite(funcTriggerPin, LOW);
//A tiny delay 2 millionths of a second
delayMicroseconds(2);
// Sets the trigPin HIGH (ACTIVE) for 10 microseconds
//same as turing the LED on in the blink sketch
digitalWrite(funcTriggerPin, HIGH);
//pin stays HIGH (5v) for 10 microseconds to trigger a pulse
delayMicroseconds(10);
//Pin taken LOW (0v) after pulse triggered ready for next pulse
digitalWrite(funcTriggerPin, LOW);
duration = pulseIn(funcEchoPin, HIGH);
myDistance = duration * 0.34 / 2;
return myDistance;
}
void setup() {
Serial.begin(9600);
Serial.println("HCSR04UltrasonicDistanceSensorv3Function...");
Serial.println(" ");//Blank line
//pinMode set for OUTPUT...sending HIGH of LOW
pinMode(triggerPin, OUTPUT); //sends signal
//pinMode set for INPUT, we will receive an incoming HIGH or LOW on this pin
pinMode(echoPin, INPUT); //receives signal
//more pinModes for 2 more sensors
pinMode(triggerPin2, OUTPUT); //sends signal
pinMode(echoPin2, INPUT); //receives signal
pinMode(triggerPin3, OUTPUT); //sends signal
pinMode(echoPin3, INPUT); //receives signal
}
void loop() {
//Local variable
int distance; //in mm
if(millis() > sensorTimer1){
sensorTimer1 = millis() + 1600;
distance = getDistanceHCSSR04(triggerPin,echoPin);
// Displays the distance on the Serial Monitor
Serial.print(" Sensor 1 Distance: ");
Serial.print(distance);
Serial.println(" mm");
}
if(millis() > sensorTimer2){
sensorTimer2 = millis() + 1500;
//different set of pins passed to function
distance = getDistanceHCSSR04(triggerPin2,echoPin2);
// Displays the distance on the Serial Monitor
Serial.print(" Sensor 2 Distance: ");
Serial.print(distance);
Serial.println(" mm");
}
if(millis() > sensorTimer3){
sensorTimer3 = millis() + 1400;
//different set of pins passed to function
distance = getDistanceHCSSR04(triggerPin3,echoPin3);
// Displays the distance on the Serial Monitor
Serial.print(" Sensor 3 Distance: ");
Serial.print(distance);
Serial.println(" mm");
}
}
Example 4: HCSR04UltrasonicDistanceSensorv4Function.ino
Click to Download code:HCSR04UltrasonicDistanceSensorv4Function.ino
This sketch reads from 3 sensors in sequence at a specified time controlled by a millis() timer.
This code uses lessons learnt in:
Lesson 5: using switch() to control code
Lesson 7: delay() v's millis(), controlling timing of programs
Lesson 9: Basics of creating and using functions
/* HCSR04UltrasonicDistanceSensorv4Function
The goal of this sketch is to use multiple HC-SR04 modules triggered in Order
pins used
pin 7 to Trig Pin...sensor 1
pin 6 to Echo pin...sensor 1
pin 5 Trig pin...sensor 2
pin 4 Echo pin...sensor 2
pin 3 Trig pin...sensor 3
pin 2 Echo pin...sensor 3
*/
//Global Variables
//const int is a constant integer that cannot have it's value changed.
const int triggerPin = 7;
const int echoPin = 6;
const int triggerPin2 = 5;
const int echoPin2 = 4;
const int triggerPin3 = 3;
const int echoPin3 = 2;
//nextsensor keeps a record of which sensor to trigger next
int nextSensor = 0;
unsigned long sensorTimer1;
//Function to trigger a sensor
//It receives the pins of the sensor and send back the distance
int getDistanceHCSSR04(int funcTriggerPin, int funcEchoPin) {
//An unsigned long is needed because the numbers produced can be much larger
//than an int can hold (max value 32,767)
//Local Variables
unsigned long duration; //time taken for echo
int myDistance;
digitalWrite(funcTriggerPin, LOW);
//A tiny delay 2 millionths of a second
delayMicroseconds(2);
// Sets the trigPin HIGH (ACTIVE) for 10 microseconds
//same as turing the LED on in the blink sketch
digitalWrite(funcTriggerPin, HIGH);
//pin stays HIGH (5v) for 10 microseconds to trigger a pulse
delayMicroseconds(10);
//Pin taken LOW (0v) after pulse triggered ready for next pulse
digitalWrite(funcTriggerPin, LOW);
duration = pulseIn(funcEchoPin, HIGH);
myDistance = duration * 0.34 / 2;
return myDistance;
}
void setup() {
Serial.begin(9600);
Serial.println("HCSR04UltrasonicDistanceSensorv4Function...");
Serial.println(" ");//Blank line
//pinMode set for OUTPUT...sending HIGH of LOW
pinMode(triggerPin, OUTPUT); //sends signal
//pinMode set for INPUT, we will receive an incoming HIGH or LOW on this pin
pinMode(echoPin, INPUT); //receives signal
//more pinModes for 2 more sensors
pinMode(triggerPin2, OUTPUT); //sends signal
pinMode(echoPin2, INPUT); //receives signal
pinMode(triggerPin3, OUTPUT); //sends signal
pinMode(echoPin3, INPUT); //receives signal
}
void loop() {
//Local variable
int distance; //in mm
//A single millis() timer loop
if (millis() > sensorTimer1) {
sensorTimer1 = millis() + 500;
//A switch statement to decide which sensor to trigger next
switch (nextSensor) {
case 1:
distance = getDistanceHCSSR04(triggerPin2, echoPin2);
Serial.print(" Sensor 2 Distance: ");
Serial.print(distance);
Serial.println(" mm");
break;
case 2:
distance = getDistanceHCSSR04(triggerPin3, echoPin3);
Serial.print(" Sensor 3 Distance: ");
Serial.print(distance);
Serial.println(" mm");
break;
default:
distance = getDistanceHCSSR04(triggerPin, echoPin);
Serial.print(" Sensor 1 Distance: ");
Serial.print(distance);
Serial.println(" mm");
break;
}
//increment the vale of nextSensor so that the next sensor will be selected next time round
nextSensor++;
//If the value is greater than 2 got back to sensor 0
if (nextSensor > 2) {
nextSensor = 0;
}
}
}
Additional Resource Links
How to use an HC-SR04 Ultrasonic Distance Sensor with Arduino
Ultrasonic Sensor HC-SR04 and Arduino Tutorial
Comments
This site has been designed to be child friendly, this means that comments cannot be added to videos or directly to the site. To add a comment or ask a question please email the address in this image: and use HC-SR04 Ultrasonic Sensor as a reference.