Skill Level: Intermediate
Table Of Contents
- Introduction
- What Is Needed
- Background Information
- Building The Circuit
- Writing The Software
- Running And Testing The System
- Detecting An Object
- Summary
Introduction
This tutorial will teach you how to interface HC-SR04, and compatible, ultrasonic distance sensors with a Raspberry Pi. A basic understanding of electronics and programming is expected along with some familiarity with the Raspberry Pi platform. If you are new to Raspberry Pi or would just like to refresh your knowledge, please see our Blink: Making An LED Blink On A Raspberry Pi tutorial before proceeding with this one.
The resources created for this tutorial are available on GitHub for your reference.
What Is Needed
- Raspberry Pi Running Raspbian Or Similar Linux Based OS (available on Raspberry Pi Foundation and Adafruit)
- One Or More HC-SR04 Compatible Ultrasonic Distance Sensors (available on Adafruit [RCWL-1601], Adafruit [HC-SR04], and SparkFun)
- 2 x 10 KΩ Resistors (available on SparkFun and Amazon)
Background Information
Distance sensors come in a variety of types and form factors for use in a wide range applications. They differ greatly in the range of distances they detect and the resolution of the distances measured. SparkFun provides a good overview of these differences in their Distance Sensing guide that also contains a link to their Distance Sensor Comparison Guide that provides many technical specifications for the different types of distance sensors available.
This tutorial will focus on the HC-SR04, or compatible, ultrasonic distance sensor. It is a very popular and inexpensive sensor used in small to medium range applications such as general distance measurement, proximity detection, and robotics. The HC-SR04 requires a 5 V supply, consumes 15 mA during reads, and can read distances between 2 and 400 cm. Specifically, I will be using the compatible RCWL-1601 sensor since it allows for 3-5 V operation, uses less current (2.2 mA), and provides a little longer range (2-450 cm) than the HC-SR04.
My development board is the Raspberry Pi 3 Model B running the Raspbian operating system. If you are using a different Raspberry Pi model or a different OS that is similar to Raspbian, the vast majority of this tutorial should still apply, however, some minor changes may be necessary.
If you need assistance with your particular setup, post a question in the comments section below and I, or someone else, can try to help you.
Building The Circuit
Before connecting any circuitry to your Raspberry Pi, shutdown and disconnect it from power. This avoids accidental damage during wiring.
Each HC-SR04 sensor will use two pins on your Raspberry Pi, for Trigger (output) and Echo (input), along with power and ground connections.
If you are using a 3.3 V compatible sensor, such as the RCWL-1601 mentioned above, connect the sensor’s Gnd and Vcc pins to your Raspberry Pi’s GND and 3V3 pins respectively. Then connect GPIO pins BCM 24 (physical pin 18) and BCM 23 (physical pin 16) on your Raspberry Pi to the sensor’s Trig and Echo pins respectively.
If you are using a 5 V only sensor, such as the original HC-SR04, we need to use a resistive voltage divider on the sensor’s Echo pin so as not to damage the 3.3 V GPIO of the Raspberry Pi. Connect the sensor’s Gnd and Vcc pins to your Raspberry Pi’s GND and 5V pins respectively. Connect GPIO pin BCM 24 (physical pin 18) on your Raspberry Pi to the sensor’s Trig pin. Now we create the voltage divider for the Echo pin. Connect one end of a 10 KΩ resistor to GND. Connect one end of another 10 KΩ resistor to the sensor’s Echo pin. Then connect the two open ends of both resistors together along with the Raspberry Pi’s GPIO BCM 23 pin (physical pin 16). See the schematic below for a visual.
Once the circuit is built, you can connect power to your Raspberry Pi and boot it up.
Writing The Software
We are going to take advantage of the DistanceSensor class included in the GPIO Zero library.
Open your favorite text editor on the Raspberry Pi and create a Python program named hcsr04_simple.py with the code shown below.
#!/usr/bin/env python3 from time import sleep from gpiozero import DistanceSensor dist_sensor = DistanceSensor(echo=23, trigger=24, max_distance=4) print("Press CTRL-C to exit.\n") while True: print("Distance sensor read %.1f cm." % (dist_sensor.distance * 100)) sleep(1)
This is a rather simple program since the DistanceSensor
class takes care of all of the communication with the distance sensor for us. I would like to mention a few things however. The max_distance
parameter used in the class instantiation defines the maximum distance, in meters, that can be read from the sensor. The default is 1 meter. I have specified 4 meters since that is the rated maximum distance for the HC-SR04 sensor. The RCWL-1601 compatible sensor I am using has a rated range of up to 4.5 m (450 cm). In the while
loop, I am converting the distance retrieved from the sensor in meters to centimeters for printing since most of these types of sensors are rated in cm.
Save the program when you are done editing.
Running And Testing The System
Now that our circuit is built and our software is written, it is time to run and test our project.
In a terminal window on the Raspberry Pi, run the following command to make the Python program an executable
$ chmod a+x hcsr04_simple.py
and then run the program.
$ ./hcsr04_simple.py
You should see something like the following being printed to the screen.
Distance sensor read 138.5 cm. Distance sensor read 139.4 cm.
Place your hand or another object at varying distances from the sensor and watch the distances being reported. If you grab a ruler, you can even test the accuracy of your sensor. The resolution and accuracy for the HC-SR04 are both rated at 3 mm. That is very good for an inexpensive distance sensor.
Adafruit, where I obtained my sensors, states on their product pages that although the distance sensors work across their rated ranges, the best results are achieved in the 10-250 cm range.
Press CTRL-C to exit the program when you are done.
That covers the basics for connecting ultrasonic distance sensors to your Raspberry Pi.
Detecting An Object
One very nice feature of the DistanceSensor
class is the ability to conditionally execute code based on whether the measured distance is within or outside of a particular range. Let’s create a new program named hcsr04_range.py to explore this feature.
#!/usr/bin/env python3 from signal import pause from gpiozero import DistanceSensor dist_sensor = DistanceSensor(echo=23, trigger=24, max_distance=4, threshold_distance=0.3) def object_in_range(sensor): print("Object detected in range (%.1f cm)." % (sensor.distance * 100)) def object_out_of_range(sensor): print("Object detected out of range (%.1f cm)." % (sensor.distance * 100)) print("Press CTRL-C to exit.\n") dist_sensor.when_in_range = object_in_range dist_sensor.when_out_of_range = object_out_of_range pause()
The when_in_range
and when_out_of_range
methods of the DistanceSensor
class are used to specify the local functions, object_in_range()
and object_out_of_range()
functions in this case, that will be called when the distance sensor detects an object that is within or outside of a specified threshold distance. The threshold_distance
parameter used in the class instantiation defines this distance. The default value is 0.3 m (about a foot) and I left it the same for this example.
Save the program, make it an executable, and run it like we did for the previous program.
Place your hand in front of the sensor and then remove it. You should see something like the following printed to the screen.
Object detected in range (10.2 cm). Object detected out of range (251.6 cm).
Press CTRL-C to exit the program when you are done.
Try changing the threshold_distance
value to something else, like 1 or 2 for instance, and see how that affects the object detection. Just make sure that the threshold_distance
value is less than the max_distance
value.
Summary
In this tutorial, we learned how to connect and read HC-SR04, and compatible, ultrasonic distance sensors with a Raspberry Pi using the DistanceSensor class of the GPIO Zero library. We also learned how to conditionally execute code based on whether an object was detected or not. These types of distance sensors can be a valuable component to add to your electronics toolbox.
The final commented source code used for this tutorial, hcsr04_simple.py and hcsr04_range.py, is available on GitHub.
I also wrote a program, named hcsr04_array.py, that extends the simple program demonstrated here by incorporating an array of sensors and providing the ability to specify the sensor sampling rate. It could be used as the basis for an object avoidance program for a robotics project. This program is also available in the GitHub repository.
If there is something that needs further explanation, please let me know in the comment section and I will try to answer your question.
Thank you for joining me in this journey and I hope you enjoyed the experience.
Two questions
1. Will this work with long wires between the lines and the sensor, maybe 10 meters?
Can the script be modified to write the readings to a text file?
Thanks
I believe that longer wires would definitely make it more difficult to read the sensors, but I don’t know how long they can be. It also greatly depends on the type of wire or cable you are using.
Writing data to a file is fairly simple in Python, check out the following links for more information.
https://www.w3schools.com/python/python_file_write.asp
https://www.geeksforgeeks.org/writing-to-file-in-python/