Table of Contents
One of the most useful sensors for robotics projects is a distance sensor. The HC-SR04 is an inexpensive Ultrasonic Distance Sensor that can assist your robot in navigating around a room. With a bit of care and an additional component it can also be used as a measurement device. In this article you’ll learn everything you need to know to use this wonderful little device with an Arduino.
The HC-SR04 Ultrasonic Distance Sensor
The HC-SR04 Ultrasonic Distance Sensor is an inexpensive device that is very useful for robotics and test equipment projects. This tiny sensor is capable of measuring the distance between itself and the nearest solid object, which is really good information to have if you’re trying to avoid driving into a wall!
The HC-SR04 can be hooked directly to an Arduino or other microcontroller and it operates on 5 volts. It can also be used with the Raspberry Pi, however since the HC-SR04 requires 5-volt logic you’ll need a couple of resistors to interface it with the Pi’s 3.3 volt GPIO port.
This ultrasonic distance sensor is capable of measuring distances between 2 cm to 400 cm (that’s about an inch to 13 feet for those of you who don’t “speak” Metric). It’s a low current device so it’s suitable for battery powered devices. And as a bonus it even looks cool, like a pair of Wall-E Robot eyes for your latest robotic invention!
So read on and I’ll show you how to hook up and use the HC-SR04 Ultrasonic Distance Sensor. We’ll also put it through some tests to see how accurate it is and we’ll look at how we can possibly improve upon that accuracy. And of course I’ll have some sample code and projects for you to try out.
Let’s get started!
How the HC-SR04 Works
Ultrasonic distance sensors use pulses of ultrasonic sound (sound above the range of human hearing) to detect the distance between them and nearby solid objects. The sensors consist of two main components:
- An Ultrasonic Transmitter – This transmits the ultrasonic sound pulses, it operates at 40 KHz
- An Ultrasonic Receiver – The receiver listens for the transmitted pulses. If it receives them it produces an output pulse whose width can be used to determine the distance the pulse travelled.
The HC-SR04 has the following four connections:
- VCC – This is the 5 Volt positive power supply.
- Trig – This is the “Trigger” pin, the one driven to send the ultrasonic pulses.
- Echo – This is the pin that produces a pulse when the reflected signal is received. The length of the pulse is proportional to the time it took for the transmitted signal to be detected.
- GND – This is the Ground pin.
The device operates as follows:
- A 5 volt pulse of at least 10 uS (10 microseconds) in duration is applied to the Trigger pin.
- The HC-SR04 responds by transmitting a burst of eight pulses at 40 KHz. This 8-pulse pattern makes the “ultrasonic signature” from the device unique, allowing the receiver to discriminate between the transmitted pattern and the ultrasonic background noise.
- The eight ultrasonic pulses travel through the air away from the transmitter. Meanwhile the Echo pin goes high to start forming the beginning of the echo-back signal.
- If the pulse in NOT reflected back then the Echo signal will timeout after 38 mS (38 milliseconds) and return low. This produces a 38 mS pulse that indicates no obstruction within the range of the sensor.
- If the pulse IS reflected back the Echo pin goes low when the signal is received. This produces a pulse whose width varies between 150 uS to 25 mS, depending upon the time it took for the signal to be received.
- The width of the received pulse is used to calculate the distance to the reflected object. Remember that the pulse indicates the time it took for the signal to be sent out and reflected back so to get the distance you’ll need to divide your result in half.
The illustration below shows the dimensions of the HC-SR04 Ultrasonic Distance Sensor as well as the effective angle of operation. As you can see the sensor is most accurate when the object to be detected is directly in front of it but you do get a response from objects within a 45 degree “window”. The documentation recommends confining that window to 30 degrees (15 degrees on either side) for accurate readings.
Hooking Up the HC-SR04
Connecting the HC-SR04 to the Arduino is pretty easy. You’ll need a couple of digital I/O ports and a connection to the Arduino’s 5-Volt and Ground pins.
Actually if you’re short of pins you can even connect both the Trigger and Echo pins of the HC-SR04 to just one digital I/O pin on the Arduino and use code to switch the pin between output (to send the 10 uS pulse) and input (to receive the Echo pulse). Some ultrasonic sensors actually have only one pin that does both Trigger and Echo. I’ll discuss this and give an example further down, so keep reading.
Most of the examples I’ll be showing you here use the more conventional two-pin method. Any Arduino and any digital I/O pins that are free can be used so if you wish to hook it up to a different set of I/O pins then simply change the sketches to reflect those changes. For our demo I’ll use an Arduino Uno and pin 10 for the Trigger and pin 13 for the Echo.
The application notes for the HC-SR04 stress that you need to have the Ground pin connected before you hook up VCC (5-Volts), so if you’re experimenting “live” on a solderless breadboard you might want to keep that in mind.
So now that we’ve hooked up our ultrasonic distance sensor it’s time to write some code and test it out.
Basic Arduino Demonstration
In our first demonstration we will simply test the sensor to see if it is working. The sketch is pretty simple and it uses the Serial Monitor to display the distance it detects, measured in centimeters. Let’s look it over in detail.
In order to test out the accuracy of the ultrasonic distance sensor I setup a test board with a sensor mounted on one end (I used Velcro to mount it). I put a 1 metre stick on the board so I could test the sensor in the 2 -100 cm range. You can watch the video associated with this article if you want to see the results for this and the other demos.
If you want to display your results in inches instead of centimeters there are two ways you can do this:
- Use the Imperial value for the speed of sound instead of the Metric one. At sea level at 20 degrees Celsius (68 degrees Fahrenheit) sound travels at 343 metres per second, which is 1,125 feet per second or 13500 inches per second.
- Keep the code as it is but convert to inches at the end. There are 2.54 centimetres in an inch. Personally this is how I would do this, as it would allow me to display the results in both Imperial and Metric values.
Otherwise just use the Metric system, it’s used all over the world and (more importantly) it was used on Star Trek The Next Generation. If it’s good enough for Captain Picard then it’s good enough for me!
So on to the sketch. This is the basic HC-SR04 sketch, for a detailed breakdown on how it works just look at the video or simply read the comments in the code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
/* HC-SR04 Basic Demonstration HC-SR04-Basic-Demo.ino Demonstrates functions of HC-SR04 Ultrasonic Range Finder Displays results on Serial Monitor DroneBot Workshop 2017 http://dronebotworkshop.com */ // This uses Serial Monitor to display Range Finder distance readings // Hook up HC-SR04 with Trig to Arduino Pin 10, Echo to Arduino pin 13 #define trigPin 10 #define echoPin 13 float duration, distance; void setup() { Serial.begin (9600); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); } void loop() { // Write a pulse to the HC-SR04 Trigger Pin digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); // Measure the response from the HC-SR04 Echo Pin duration = pulseIn(echoPin, HIGH); // Determine distance from duration // Use 343 metres per second as speed of sound distance = (duration / 2) * 0.0343; // Send results to Serial Monitor Serial.print("Distance = "); if (distance >= 400 || distance <= 2) { Serial.println("Out of range"); } else { Serial.print(distance); Serial.println(" cm"); delay(500); } delay(500); } |
Arduino Code Libraries
In our first sketch we didn’t use any code libraries, we simply used the Arduino’s delayMicrosecond command to create our 10 uS pulse for triggering and the pulseIn command to measure the received signal pulse width. However there are other ways of doing this using special code libraries. There are quite a few of them available, the most versatile is one called “NewPing”.
If you haven’t had any experience using libraries in your Arduino sketches it’s a skill that you really need to learn. Libraries provide code functions for specific tasks, and there are literally hundreds of libraries available for the Arduino for tasks and to support all kinds of external hardware.
The Arduino website has instructions for installing new libraries in your Arduino IDE.
The NewPing library was written by Tim Eckel and it replaces the older Ping library which was written by Caleb Zulawski and designed primarily for the Parallax Ping ultrasonic sensor (although it will work with the HC-SR04 if you use it in 3-pin mode).
The NewPing library is quite advanced and it improves upon the accuracy of our original sketch considerably. It also supports up to 15 ultrasonic sensors at once and it can directly output in centimetres, inches or time duration.
Here is our sketch rewritten to use the NewPing library:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
/* HC-SR04 NewPing Library Demonstration HC-SR04-NewPing.ino Demonstrates functions of NewPing Library for HC-SR04 Ultrasonic Range Finder Displays results on Serial Monitor DroneBot Workshop 2017 http://dronebotworkshop.com */ // This uses Serial Monitor to display Range Finder distance readings // Include NewPing Library #include "NewPing.h" // Hook up HC-SR04 with Trig to Arduino Pin 10, Echo to Arduino pin 13 // Maximum Distance is 400 cm #define TRIGGER_PIN 10 #define ECHO_PIN 13 #define MAX_DISTANCE 400 NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); float distance; void setup() { Serial.begin (9600); } void loop() { distance = sonar.ping_cm(); // Send results to Serial Monitor Serial.print("Distance = "); if (distance >= 400 || distance <= 2) { Serial.println("Out of range"); } else { Serial.print(distance); Serial.println(" cm"); delay(500); } delay(500); } |
The above sketch is simple and works well but it only has a resolution down to one centimeter. If you want to bring back the decimal point values you can use NewPing in duration mode instead of in distance mode. We can then use the duration to calculate the distance as we did in the first sketch we looked at.
Here is our sketch NewPing rewritten to use duration instead of distance.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
/* HC-SR04 NewPing Duration Demonstration HC-SR04-NewPing-Duration.ino Demonstrates using Duration function of NewPing Library for HC-SR04 Ultrasonic Range Finder Displays results on Serial Monitor DroneBot Workshop 2017 http://dronebotworkshop.com */ // This uses Serial Monitor to display Range Finder distance readings // Include NewPing Library #include "NewPing.h" // Hook up HC-SR04 with Trig to Arduino Pin 10, Echo to Arduino pin 13 // Maximum Distance is 400 cm #define TRIGGER_PIN 10 #define ECHO_PIN 13 #define MAX_DISTANCE 400 NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); float duration, distance; void setup() { Serial.begin (9600); } void loop() { duration = sonar.ping(); // Determine distance from duration // Use 343 metres per second as speed of sound distance = (duration / 2) * 0.0343; // Send results to Serial Monitor Serial.print("Distance = "); if (distance >= 400 || distance <= 2) { Serial.println("Out of range"); } else { Serial.print(distance); Serial.println(" cm"); delay(500); } delay(500); } |
Another function of NewPing is “iterations” To iterate means to go over something more than once, and that’s precisely what the iteration mode does. It takes many duration measurements instead of just one, throws away any invalid readings and then averages the remaining ones. By default it takes 5 readings but you can actually specify as many as you wish.
Here we go again with a NewPing sketch written to use iterations. As you can see it’s virtually identical to the previous sketch, all that has been added is a variable to specify the number of iterations.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
/* HC-SR04 NewPing Iteration Demonstration HC-SR04-NewPing-Iteration.ino Demonstrates using Iteration function of NewPing Library for HC-SR04 Ultrasonic Range Finder Displays results on Serial Monitor DroneBot Workshop 2017 http://dronebotworkshop.com */ // This uses Serial Monitor to display Range Finder distance readings // Include NewPing Library #include "NewPing.h" // Hook up HC-SR04 with Trig to Arduino Pin 10, Echo to Arduino pin 13 // Maximum Distance is 400 cm #define TRIGGER_PIN 10 #define ECHO_PIN 13 #define MAX_DISTANCE 400 NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); float duration, distance; int iterations = 5; void setup() { Serial.begin (9600); } void loop() { duration = sonar.ping_median(iterations); // Determine distance from duration // Use 343 metres per second as speed of sound distance = (duration / 2) * 0.0343; // Send results to Serial Monitor Serial.print("Distance = "); if (distance >= 400 || distance <= 2) { Serial.println("Out of range"); } else { Serial.print(distance); Serial.println(" cm"); delay(500); } delay(500); } |
Getting Improved Accuracy
The HC-SR04 is reasonably accurate, in it’s basic form it is quite useable for robots, intruder detection or proximity alarms. But there are times you might want a bit more accuracy, for example you may be building a measuring tool or might be using your robot to map out the perimeter of a room. If so there are a few things you can do to improve upon the accuracy of the HC-SR04.
As I mentioned in the last section the NewPing library has implemented a number of internal techniques to improve the accuracy of the sensor. In most cases this is all you’ll need to improve your readings.
If you’re designing a device that is to be used outdoors or in an unusually hot or cold environment you might want to take into account the fact that the speed of sound in air varies with temperature, air pressure and humidity. Since the speed of sound factors into our HC-SR04 distance calculation this could affect our readings if the temperature was a lot hotter or colder than room temperature.
In order to factor in temperature and humidity I decided to use the DHT22 sensor, it’s relatively inexpensive but very accurate. You could also use the less expensive DHT-11 to do this experiment with slightly less accuracy. Here is how I hooked it up:
The DHT22 requires a couple of code libraries to get it to function, Adafruit has two libraries that will work well with both the DHT22 and the DHT11. The Adafruit AM2315 library and the Adafruit Unified Sensor library can both be installed directly within the Arduino IDE using the Library Manager.
After I installed the Adafruit libraries I wrote a quick test sketch to be sure my DHT22 was working correctly.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
/* DHT22 Basic Demonstration DHT22-Basic-Demo.ino Demonstrates functions of DHT22 Digital Temperature & Humidity Sensor Displays results on Serial Monitor DroneBot Workshop 2017 http://dronebotworkshop.com */ // Include DHT Libraries from Adafruit // Dependant upon Adafruit_Sensors Library #include "DHT.h"; // Define Constants #define DHTPIN 7 // DHT-22 Output Pin connection #define DHTTYPE DHT22 // DHT Type is DHT 22 (AM2302) // Initialize DHT sensor for normal 16mhz Arduino DHT dht(DHTPIN, DHTTYPE); // Define Variables float hum; //Stores humidity value float temp; //Stores temperature value void setup() { Serial.begin(9600); dht.begin(); } void loop() { delay(2000); // Delay so sensor can stabalize hum = dht.readHumidity(); // Get Humidity value temp= dht.readTemperature(); // Get Temperature value // Print temperature and humidity values to serial monitor Serial.print("Humidity: "); Serial.print(hum); Serial.print(" %, Temp: "); Serial.print(temp); Serial.println(" Celsius"); } |
And finally here is a sketch that factors in both temperature and humidity to improve accuracy using the DHT22.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
/* HC-SR04 with Temp and Humidity Demonstration HC-SR04-Temp-Humid-Demo.ino Demonstrates enhancements of HC-SR04 Ultrasonic Range Finder With DHT22 Temperature and Humidity Sensor Displays results on Serial Monitor DroneBot Workshop 2017 http://dronebotworkshop.com */ // Include DHT Libraries from Adafruit // Dependant upon Adafruit_Sensors Library #include "DHT.h"; // Include NewPing Library #include "NewPing.h" // Define Constants #define DHTPIN 7 // DHT-22 Output Pin connection #define DHTTYPE DHT22 // DHT Type is DHT 22 (AM2302) #define TRIGGER_PIN 10 #define ECHO_PIN 13 #define MAX_DISTANCE 400 NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // Define Variables float hum; // Stores humidity value in percent float temp; // Stores temperature value in Celcius float duration; // Stores HC-SR04 pulse duration value float distance; // Stores calculated distance in cm float soundsp; // Stores calculated speed of sound in M/S float soundcm; // Stores calculated speed of sound in cm/ms int iterations = 5; // Initialize DHT sensor for normal 16mhz Arduino DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin (9600); dht.begin(); } void loop() { delay(2000); // Delay so DHT-22 sensor can stabalize hum = dht.readHumidity(); // Get Humidity value temp= dht.readTemperature(); // Get Temperature value // Calculate the Speed of Sound in M/S soundsp = 331.4 + (0.606 * temp) + (0.0124 * hum); // Convert to cm/ms soundcm = soundsp / 10000; duration = sonar.ping_median(iterations); // Calculate the distance distance = (duration / 2) * soundcm; // Send results to Serial Monitor Serial.print("Sound: "); Serial.print(soundsp); Serial.print(" m/s, "); Serial.print("Humid: "); Serial.print(hum); Serial.print(" %, Temp: "); Serial.print(temp); Serial.print(" C, "); Serial.print("Distance: "); if (distance >= 400 || distance <= 2) { Serial.print("Out of range"); } else { Serial.print(distance); Serial.print(" cm"); delay(500); } Serial.println(" "); } |
In my testing on the workbench I found that it did indeed improve the accuracy of the readings.
Using 3-Wire Mode
As I alluded to earlier it is possible to use the HC-SR04 in “3-Wire Mode”. In this mode you will only require one connection to a single Arduino digital I/O pin. There are other ultrasonic sensors that only operate in 3-Wire Mode.
In 3-Wire mode the single I/O pin is used as both an input and as an output. This is possible because there is never a time when both the input and output are being used. By eliminating one I/O pin requirement we can save a connection to our Arduino and use it for something else. It also is useful when using a chip like the ATtiny85 which has a limited number of I/O pins.
Here is how I hooked up the HC-SR04 to the Arduino.
As you can see all I did was to connect both the trigger and echo to Arduino pin 10.
And here is the sketch I wrote to use it. Note that the only difference between this sketch and the previous one is that I’ve specified pin 10 for both the Trigger and Echo pin values. The rest of the sketch is identical.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
/* HC-SR04 in 3-Wire Mode with Temp and Humidity Demonstration HC-SR04-3Wire-Temp-Humid-Demo.ino Demonstrates enhancements of HC-SR04 Ultrasonic Range Finder With DHT22 Temperature and Humidity Sensor Displays results on Serial Monitor DroneBot Workshop 2017 http://dronebotworkshop.com */ // Include DHT Libraries from Adafruit // Dependant upon Adafruit_Sensors Library #include "DHT.h"; // Include NewPing Library #include "NewPing.h" // Define Constants #define DHTPIN 7 // DHT-22 Output Pin connection #define DHTTYPE DHT22 // DHT Type is DHT 22 (AM2302) #define TRIGGER_PIN 10 // Trigger and Echo both on pin 10 #define ECHO_PIN 10 #define MAX_DISTANCE 400 NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // Define Variables float hum; // Stores humidity value in percent float temp; // Stores temperature value in Celcius float duration; // Stores HC-SR04 pulse duration value float distance; // Stores calculated distance in cm float soundsp; // Stores calculated speed of sound in M/S float soundcm; // Stores calculated speed of sound in cm/ms int iterations = 5; // Initialize DHT sensor for normal 16mhz Arduino DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin (9600); dht.begin(); } void loop() { delay(2000); // Delay so DHT-22 sensor can stabalize hum = dht.readHumidity(); // Get Humidity value temp= dht.readTemperature(); // Get Temperature value // Calculate the Speed of Sound in M/S soundsp = 331.4 + (0.606 * temp) + (0.0124 * hum); // Convert to cm/ms soundcm = soundsp / 10000; duration = sonar.ping_median(iterations); // Calculate the distance distance = (duration / 2) * soundcm; // Send results to Serial Monitor Serial.print("Sound: "); Serial.print(soundsp); Serial.print(" m/s, "); Serial.print("Humid: "); Serial.print(hum); Serial.print(" %, Temp: "); Serial.print(temp); Serial.print(" C, "); Serial.print("Distance: "); if (distance >= 400 || distance <= 2) { Serial.print("Out of range"); } else { Serial.print(distance); Serial.print(" cm"); delay(500); } Serial.println(" "); } |
Using Multiple HC-SR04 Sensors
In many applications you’ll want to use more than one HC-SR04 ultrasonic sensor in your design. This can happen when you want to monitor the distance to external objects from different sides of your robot or project. Two of them can be used for front and rear sensors, or hookup 6 of them and monitor each side of a cube – it’s up to you!
When using multiple sensors one obvious consideration is that you need to keep the signal emitted by one sensor from being picked up and measured by another sensor. The easiest way to accomplish this is to simply pulse the trigger on one sensor and wait until you receive the echo back before proceeding to the next sensor. It might be wise to leave a small delay between readings just in case the previous sensors sound waves are still bouncing around the room!
Here is how I used two HC-SR04 ultrasonic sensor with the Arduino. Note that I wired these in 3-wire mode, if you wish you can also connect them in the conventional 4-wire fashion. If you do then just modify the sketch to specify different trigger and echo pins.
Here is a sketch that uses the NewPing library and two sensors. As with all of the other sketches it outputs the results to the serial monitor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
/* Dual HC-SR04 with Temp and Humidity Demonstration HC-SR04-Temp-Humid-Dual-Demo.ino Demonstrates enhancements of HC-SR04 Ultrasonic Range Finder With DHT22 Temperature and Humidity Sensor Displays results on Serial Monitor DroneBot Workshop 2017 http://dronebotworkshop.com */ // Include DHT Libraries from Adafruit // Dependant upon Adafruit_Sensors Library #include "DHT.h"; // Include NewPing Library #include "NewPing.h" // Define Constants #define DHTPIN 7 // DHT-22 Output Pin connection #define DHTTYPE DHT22 // DHT Type is DHT 22 (AM2302) #define TRIGGER_PIN_1 10 #define ECHO_PIN_1 10 #define TRIGGER_PIN_2 5 #define ECHO_PIN_2 5 #define MAX_DISTANCE 400 NewPing sonar1(TRIGGER_PIN_1, ECHO_PIN_1, MAX_DISTANCE); NewPing sonar2(TRIGGER_PIN_2, ECHO_PIN_2, MAX_DISTANCE); // Define Variables float hum; // Stores humidity value in percent float temp; // Stores temperature value in Celcius float duration1; // Stores First HC-SR04 pulse duration value float duration2; // Stores Second HC-SR04 pulse duration value float distance1; // Stores calculated distance in cm for First Sensor float distance2; // Stores calculated distance in cm for Second Sensor float soundsp; // Stores calculated speed of sound in M/S float soundcm; // Stores calculated speed of sound in cm/ms int iterations = 5; // Initialize DHT sensor for normal 16mhz Arduino DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin (9600); dht.begin(); } void loop() { delay(1000); // Delay so DHT-22 sensor can stabalize hum = dht.readHumidity(); // Get Humidity value temp= dht.readTemperature(); // Get Temperature value // Calculate the Speed of Sound in M/S soundsp = 331.4 + (0.606 * temp) + (0.0124 * hum); // Convert to cm/ms soundcm = soundsp / 10000; // Measure duration for first sensor duration1 = sonar1.ping_median(iterations); // Add a delay between sensor readings delay(1000); // Measure duration for first sensor duration2 = sonar2.ping_median(iterations); // Calculate the distances for both sensors distance1 = (duration1 / 2) * soundcm; distance2 = (duration2 / 2) * soundcm; // Send results to Serial Monitor Serial.print("Distance 1: "); if (distance1 >= 400 || distance1 <= 2) { Serial.print("Out of range"); } else { Serial.print(distance1); Serial.print(" cm "); } Serial.print("Distance 2: "); if (distance2 >= 400 || distance2 <= 2) { Serial.print("Out of range"); } else { Serial.print(distance2); Serial.print(" cm"); } Serial.println(" "); } |
Be Kind to Animals!
One thing that bears consideration when designing a device around any ultrasonic emitter, like the HC-SR04, is that many animals can hear ultrasonic sound. According to WikiPedia this includes dogs, cats, gerbils and rabbits.
If you have furry 4-legged friends roaming your house you might want to refrain from subjecting them to the sound emitted by the sensor as it could be very annoying to them. Imagine hearing a high pitched series of “beeps” every second nonstop and you can empathize with what your pet might be going through.
There are other methods of measuring distance like IR light and LIDAR that don’t involve ultrasonic sound, so you might want to look into that if animals are a consideration in your home. At the very least it’s probably a good idea in general to keep Rover or Fifi out of the workshop!
Moving On
As you’ve see the HC-SR04 Ultrasonic Distance Sensor is an inexpensive yet useful device that can be used for a myriad of applications. If you are into building robots this is an essential component in your toolkit.
Hopefully you have found this article to be useful. If you have any questions about the HC-SR04 or the sketches I’ve presented here please write them in the comments section below. And if you come up with a project based around the HC-SR04 I’d love to hear about it.
So let’s get sensing – I’ll ping you later!
Parts List
Here are some components that you might need to complete the experiments in this article. Please note that some of these links may be affiliate links, and the DroneBot Workshop may receive a commission on your purchases. This does not increase the cost to you and is a method of supporting this ad-free website.
COMING SOON!
Resources
HC-SR04 Sketches All of the sketches used in this article.
Arduino Site NewPing Article The NewPing library as described on the official Arduino website.
NewPing Library on BitBucket The NewPing Library repository on BitBucket. Go here for the latest version.
Adafruit DHT22 Library The Adafruit Library for DHT22 on GitHub. You can also just install this from your Library Manager in the Arduino IDE.
Adafruit Unified Sensor Library The Adafruit Unified Sensor Library on GitHub. Again you can just install this from your Library Manager.
Great video. You do an awesome job. Having taught electronics and computer equipment at various times throughout my career I recognize excellent presentations. You covered everything thoroughly enough to eliminate almost all questions.
Keep up the excellent work. Wished my workshop looked like yours.
Dear Dronebot Many thanks for all your tutorials I find them fascinating and most informative . I am new to electronics and the Arduino so the learning curve is somewhat steep! I have completed all your sessions on the HC-SR04 and have also included an LCD screen as well as the serial monitor all with the help and guidance of your presentation – thank you. I would now like to monitor the depth of a tank of fluids (coolant tank) that prints out the measurement to an lcd screen and the levels change. Could you advise please? Or could you… Read more »
Hey Paul, I’m looking to do something similar did you ever get it working?
great project, i’m interested in your project, i will make it
Very useful for drones!!
Can you make provide me codes for my arduino project?
it is a arduino nano based bluetooth drone
Components:
arduino nano with Atmega 328p running at 5v
hm-10 bluetooth module
hc-sr04 ultrasonic sensor module for avoiding collisions during flight
4 coreless dc motors 3.7v each
mpu-6050 sensor as a gyro and accelerometer
by the way,also please provide the code for programming the nano as a flight controller with all the rest of the components.Please provide the code.
this is my first project in arduino and i don’t want it to fail!!
I realize I’m replying to a very old post, but when I see one like this, I simply cannot ignore it! That’s because I see them all the time. This is NOT an uncommon occurrence. When I began working with Arduinos, like most people, I roamed the Internet looking for information, and code I could download and study to LEARN from. And, like most people, I have often used others’ code in projects of my own, sometimes intact, and sometimes modified so much the O.P. might not recognize it. In the process, I have learned from other’s work to the… Read more »
Great tutorial, very complete, well written and full of things to try. One request: make the entire tutorial a PDF so we can download it and read it in the reading room (you know where…). Yeah I could read it on my ipad but hardcopy is best: can highlight, underline, cross-out stuff.
I’m working on a car-counter and 13 feet (400 cm) is not quite enough so I’m looking to boost the signal, likely having to use other transducers (I have some 2 wire devices in stock). Maybe someone has done this already? Save me lots of grief?
Hi Bob Thanks so much for your kind words. I’m planning some updates to this website in about 2 weeks (mid September), testing it now on a staging server before I put it into production. One of the updates is indeed the ability to download PDF versions of all the articles. So if you can wait a couple of weeks you’ll have your first request fullfilled! I also like printing things out, for the same reasons you have mentioned. As for an ultrasonic sensor with a longer range I’m not aware of one but perhaps someone else is. I think,… Read more »
Hello
I am working on a project where the amplitude of the echo, pulse duration and time of the echo has to be measures as well as the amplitude of trigger i.e. the ultrasound emitted has to be varied. Is this possible with arduino sensors? If not, can you let me know the details of using alternatives
Using HC-SR04 to measure pool water level Great tutorial, very nicely done. I read this tutorial last week and am using the HC-SR04 now to measure the water level in my pool. Once the water level gets too low, I switch on a relay that controls a water-valve and fills the pool-water. This works very well. I am using a sonoff basic with GPIO14 that is used for both the trigger and echo (that was actually a really good tip to use only one pin that connects to echo and trigger). I use two resisters to do a voltage level… Read more »
Wow Johan, that’s excellent! Thanks for providing the code, I had someone email me recently asking about controlling the level of water in a water tank, essentially the same application.
I really appreciate your comment.
Hi, I am working on one of my project in which I want to use 12 HC-SR04 at a time,I tried to code it but am not able to, so can you help me out by providing the code or any logic?
I will appreciate it.
And by the way I love your content keep doing.
Hi, I am going to try to do the same and publish to mqtt using esp8266, would you mind sharing your entire code.
And thanks for all the great info on this site, really enjoy your way of speaking 👍
Hello, thank you for this tutorial, now I understand this ultrasonic module. Please note that your third link : “NewPing Library on GitHub The NewPing Library repository on GitHub. Goe here for the latest version.” is now invalid. Is it possible to make it available?
Hi Daniel
Thanks for the heads-up on the bad link. I’ve changed it to the library on BitBucket, should be good now.
Thank you for the updating. However, the link itself is the same and does not reflect your update.
Oops, my bad! Give it a try now Daniel, it should work this time.
I suggest to recheck the recommended library to be included (re: #include “DHT.h”) because I had to install few similar others (also Adafruit – shown in Manage Library) in order to get a compilation (with no more error: was reporting “not able to find DHT.h”). And I was not yet able to figure out which of 4 similar (3 newer that the date of you video) – really helped (because I did not had enough time to successively eliminate combination of them – to find the -new – good one).
great project, i’m interested in your project, i will make it the same .
Hi, Thanks for the great tutorials! Great job you are doing, Bob.
I have a problem with the 4-wire SR04. It seems that the sketch works perfectly, if I do not use the “NewPing Library. If I do, I get the out of range comment. I have looked everywhere for possible errors, but I cannot find anything. Any suggestions?
Thanks very much
John
Thanks for the video and the detailed website. Everything is working A1. I had the HC-SR04 working previously but struggled with the DHT22. Turned out the two additional Afafruit libraries had to be installed. I watched your video and my mistake became crystal clear. You take a somewhat complex project and make it simple. You are an amazing instructor, and I appreciate the effort. Keep up the great work. Thank YOU!
Great informative ultrasonic video, I am using EZ-Builder which utilizes blocky, EZ-script
I have a 3 pin connector ultrasonic distance sensor on my robot
How can I utilize, write blocky, EZ-script code to imitate your, I think, python code?
Thanks
great tutorial, thanks!
What sensor do we use to stop a robot car from falling off a platform?
Using the DHT-22 to compensate for speed of sound variation with temperature and humidity seems to work well, but could the system be improved further by altitude compensation?
If so, how would this be done?
good night friend how can i do this 2 sensor ultrasonic code to turn on 1 led at the time that sensor reaches end of reading
and another sensor also
ti Agradeco
Hi there, I,m Getting Some Error while Uploading the above codes. I thought that it was library problem but i have aldready installed the both libraries such as DHT.h and also the NewPing.h but i cant able to upload to my Arduino UNO Board. It shows me the error of ” exit status 1
Error compiling for board Arduino/Genuino Uno.
” Kindly Fix this up……
Thank you, Have a Nice Day 🙂
Hai Sir, As we know ultrasonic sensor range is aout 2cm to 400cm.
But I want to measure the distance which is greater than 400cm.
Is there any possible way for increasing the range of HC-SR04 Circuit or Is there any sensor which measuring range is greater than 400cm.
I’m not getting the stable values around the range of 400cm with HC05 Sensor.
Thanks in Advance.
http://uitechies.co.in/BBBcircuits/product.php?product=ultrasonic-range-finder-module-sensor-distance-measuring-transducer
i need help im trying to use ping sensor to activate a function which is make my robot do a right turn please help
Wow! Fantastic video!
I’d like to incorporate a pair of these HC-SR04 Ultrasonic sensors on a future 1/100th scale Saturn V model build. I say a pair because I’d like the redundancy and by mounting 2 of these, I’d keep the rocket balanced. I’d mount then near the bottom of the lower stage but just above the bottom tucked in between the fins and away from the rocket motor blast.
Do you think this is a good idea?
Hello
I’m Ali and one of your followers on YouTube.
In fact, I am a mechanic and an industrial machine designer and I am very interested in electronics. I make all kinds of industrial robots, but with PLC.
During Arduino’s training on YouTube, I had a lot of questions. I want to know if you have time to guide me.
And the other question is, can Arduino be used for industrial work as well?
Thanks & Regards
ALI
Hi
Your explanation was really good for me as an amateur, thanks.
Looking forward for your support in programming an IC HEF4093 or LM324 with one SR04 and 4 different distance identified by 4 LED output.
thanks alot for your article and your videos it is all more than amazing and helpful
but please in Getting Improved Accuracy sketch it doesn’t work even i did all what you said and the sketch is right and i use HC-SR04 and it always say out of rang !!
even i check the connections many times
I just love your vidoes. Very well explained. Thanks for the uploads.
One of the my see first site.
A great tutorial!
Far more in depth, more complete and also more practical than any other information I have found on the web in regard to interfacing an HCSR04 to an Arduino.
Not working. Always “out of Range” distance=0
Ciao and thanks for your video,
on my arduino robot i need to put six of these sensor. I use an ESP32 3,3V powered so I have to use shift level boards. It work fine but only with 4 wires. In three wires way it doesn’t work. Can I use the same trigger pin and six different echo pins? I’ve not onought resources on ESP32. Thanks in advance for you help.
Carlo
As usual, a great and thorough write up. For lack of other more relevant suggestions, I would only mention stating the units of measurements or variables in the code as comments, such as milliseconds, microseconds, meters, centimeters. Most people will be able to find out, but may help some less experienced.
Thanks for the great videos.
I just finished reading this whole tutorial. Thank You So Much! Sir Bill – This is a great help for me.
i am going to use the sensors to find a given distance between the model locomotives as they approach the station to trigger departure and arrival stop. of course there will be speakers announcing both events and accompanying noise of a busy rail stop. All this a ‘module’. thanks. ps if you have a better idea{s} and just drop me a line.
Great video. really helpful and understandable. I am currently working on a smart road accident prevention system on curvy roads using two ultrasonic sensors. I am not interested in using the DHT so editing the code is proving very difficult. could you advise me on how to go about the editing or help code if you can. Thanks greatly appreciated.
|!
Thank you for another amazing tutorial!
I used a dht11 sensor that returned nan.
Closer inspection to pins looked suspicous and no conductivity between ground pin and rest of pc. I touched up all visible solder joints which immediately resolved the problem!
Excellent presentaion, great explanations and thank you for the code and using NewPing. I’ve ordered some HC-SR04’s and look forward to testing them.
Bill you are the man. Thanks for your work and thoughtfulness is working us through these projects.
I just wanted you to know that you are my “go to” guy for information on electronic home projects. You constantly provide top quality videos with clear and complete content. Your videos allow me to quickly refresh my knowledge an a particular subject. As I am in my 80’s now, my memory fails me more often, and your excellent presentations offer a fast and enjoyable way to get back up to speed.
Sir, I thank you your effort and willingness to share with others.
Excellent presentation. Thank you.
Hey.
you have very relevant projects. i have learnt a lot.
Kudos
thank you