Interfacing HC-SR04 Ultrasonic Sensor with Raspberry Pi
Contents
Ultrasonic distance sensors are designed to measure distance between the source and target using ultrasonic waves. We use ultrasonic waves because they are relatively accurate across short distances and don’t cause disturbances as they are inaudible to human ear.
HC-SR04 is a commonly used module for non contact distance measurement for distances from 2cm to 400cm. It uses sonar (like bats and dolphins) to measure distance with high accuracy and stable readings. It consist of an ultrasonic transmitter, receiver and control circuit. The transmitter transmits short bursts which gets reflected by target and are picked up by the receiver. The time difference between transmission and reception of ultrasonic signals is calculated. Using the speed of sound and ‘Speed = Distance/Time‘ equation, the distance between the source and target can be easily calculated.
HC-SR04 ultrasonic distance sensor module has four pins :
- VCC – 5V, input power
- TRIG – Trigger Input
- ECHO – Echo Output
- GND – Ground
Working of HC-SR04
- Provide trigger signal to TRIG input, it requires a HIGH signal of atleast 10μS duration.
- This enables the module to transmit eight 40KHz ultrasonic burst.
- If there is an obstacle in-front of the module, it will reflect those ultrasonic waves
- If the signal comes back, the ECHO output of the module will be HIGH for a duration of time taken for sending and receiving ultrasonic signals. The pulse width ranges from 150μS to 25mS depending upon the distance of the obstacle from the sensor and it will be about 38ms if there is no obstacle.
Voltage Divider
The ECHO output is of 5v. The input pin of Raspberry Pi GPIO is rated at 3.3v. So 5v cannot be directly given to the unprotected 3.3v input pin. Therefore we use a voltage divider circuit using appropriate resistors to bring down the voltage to 3.3V.
The following equation can be used for calculating resistor values,
“Vout = Vin x R2/(R1+R2)”
Connection Diagram
Distance Calculation
Time taken by pulse is actually for to and fro travel of ultrasonic signals, while we need only half of this. Therefore Time is taken as Time/2.
Distance = Speed * Time/2
Speed of sound at sea level = 343 m/s or 34300 cm/s
Thus, Distance = 17150 * Time (unit cm)
Calibration
For accurate distance readings the output can be calibrated using a ruler. In the below program a calibration of 0.5 cm is added.
Python Programming
import RPi.GPIO as GPIO #Import GPIO library import time #Import time library GPIO.setmode(GPIO.BCM) #Set GPIO pin numbering TRIG = 23 #Associate pin 23 to TRIG ECHO = 24 #Associate pin 24 to ECHO print "Distance measurement in progress" GPIO.setup(TRIG,GPIO.OUT) #Set pin as GPIO out GPIO.setup(ECHO,GPIO.IN) #Set pin as GPIO in while True: GPIO.output(TRIG, False) #Set TRIG as LOW print "Waitng For Sensor To Settle" time.sleep(2) #Delay of 2 seconds GPIO.output(TRIG, True) #Set TRIG as HIGH time.sleep(0.00001) #Delay of 0.00001 seconds GPIO.output(TRIG, False) #Set TRIG as LOW while GPIO.input(ECHO)==0: #Check whether the ECHO is LOW pulse_start = time.time() #Saves the last known time of LOW pulse while GPIO.input(ECHO)==1: #Check whether the ECHO is HIGH pulse_end = time.time() #Saves the last known time of HIGH pulse pulse_duration = pulse_end - pulse_start #Get pulse duration to a variable distance = pulse_duration * 17150 #Multiply pulse duration by 17150 to get distance distance = round(distance, 2) #Round to two decimal points if distance > 2 and distance < 400: #Check whether the distance is within range print "Distance:",distance - 0.5,"cm" #Print distance with 0.5 cm calibration else: print "Out Of Range" #display out of range
Run the above program.
Output
Distance is measured every two seconds and displayed.
Reading accuracy
- For greater accuracy use C over Python as Python on a Linux environment is not good for precise timing. As precise timing is required for accurate distance measurements.
- The sensor has a wide angle of sensitivity. If there are objects near the line of sight it may give shorter readings.
- The ultrasonic sensor touching any surface can give wrong readings.
Any doubts? Comment below.
If you are following the aforementioned circuit diagram, try using different pin numbers (worked for me with pin numbers 16 and 18, instead of 23 and 24 respectively).
how can i put the data on the QT desinger?
using this code can i get continuously the water depth
I am having the same issue, despite checking my circuit diagram. Were you able to resolve your issue? If yes, please let me know how.
Thanks!
when we get out of range can we send that message to our phone?? do we have any code for that??
Thank you I have used your example to build a basic rig, I am planning on coding a C++ version to store values in a database for historic reporting and alerting. You have really helped start me my project.
Yes, for sending emails anyway you need internet connection.
but that will require internet connection
so how to do that??
internet connection on raspberry pi will u explain.
Make sure that you have python gpio library.
It seems like there is some connection mistake.
i have the same problrm :/ nothing seems to work
This program is not working for me..it’s stuck on “Waitng For Sensor To Settle”..
I’ve checked all the wiring and nothing seems to work.. any idea or pre requesit in raspberry configurations that are needeD?
Hi,
I ran the code but it’s not displaying the result. It stucked at a “Waiting for Sensor to settle”.
Checked circuit diagram also, everything seems to be correct.
sorry i put a comma in the multiplier
it works good.
When i run this it says that a in line 32 a float is required. as far as i can tell my code is exactly the same as yours.
You can install some SMTP applications and send mail through it.
how to get email alert from this sensor?
i mean do you have code for that
You can add a calibration to make the results more accurate.
Why 0.5cm calibration?
Vcc and ground putted together to waste only 2 ports. for trigger and echo I suggest you to use 6 wires for 3 sensors and set a delay between triggering them (be aware u mustn’t trigger them all at once, even if they are separed. Ultra sound can quickly come back to the sensor by reflecting from walls and corners giving you wrong calculations) the minimum delay needs to be 38 uS, when i was doing a project with them i putted a delay of 100ms and it was more than enough. i cant help you more, i wasnt using rasperry.
anyone know how to connect 3 ultrasonic sensors to raspberry pi?
anyone know how I can connect 3 HCSR04 type sensors to raspberry pi?
It will increase the current flow 10 times, make sure that it doesn’t exceed the output current limit of SR04.
I used 470 ohm and 1k resistors in my setup (exactly 1/10th of what you have). It works, but should I anticipate problems?
Try to find where program fails by printing comments at different parts of your program.
Hi I really enjoyed your tutorial, thank you for posting. I bought one of these sensors and tried to run the code. However the sen
sor never receives the ultrasound pulse. I tried changing the pulse length, I checked the wiring multiple times, changed the wires and arrangement on the breadboard, and even bought a new sensor module. None of these fixed the problem. My only other thought is that I damaged the GPIO pins. When I first hooked it all up I didn’t use resistors as I thought the new pi could receive 5V input. I checked the pins by trying to read input from an accelerometer, and that still worked but admittedly it used different pins. I was wondering if you had any thoughts on my problem? Thank you for the help 🙂
It is clearly explained above.
Hello
I cannot take 5V from echo pin. What is it reason ? Any suggestions ?
time.time function ??
please can any one help me
i have been trying to use 2 ultra sonic sensors on the pi with one of my robotics projects but i cant seem to get the code to work properly. i cant figure out get a response from the second on i think the problem is with the time.time function
I replaced both while GPIO.input(ECHO)==0: and ==1;
with
GPIO.wait_for_edge(GPIO_ECHO, GPIO.BOTH)
start = time.time()
GPIO.wait_for_edge(GPIO_ECHO, GPIO.BOTH)
stop = time.time()
and initialized with
GPIO.add_event_detect(GPIO_ECHO, GPIO.BOTH)
Reducing CPU load significantly.
I tried using GPIO.RISING the GPIO.FALLING, but some times the device triggers all on its own and can be in the middle of an echo reply.
Verify whether the echo pin of sensor is wired correctly.
I have this letter all time and it wont go away and stays for very long time.
Waiting for sensor to settle
Any suggestions ?
Thanks for your suggestion..
Good. But Voltage divider using resistors are not accurate for high speed signals. Better use a 3.3v Zener diodes.