Interfacing HC-SR04 Ultrasonic Sensor with Raspberry Pi

Interfacing HC-SR04 Ultrasonic Sensor with Raspberry Pi

Contents

HC-SR04 Ultrasonic Sensor
HC-SR04 Ultrasonic Sensor

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

Ultrasonic Module Operation
Ultrasonic Module Operation
  1. Provide trigger signal to TRIG input, it requires a HIGH signal of atleast 10μS duration.
  2. This enables the module to transmit eight 40KHz ultrasonic burst.
  3. If there is an obstacle in-front of the module, it will reflect those ultrasonic waves
  4. 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.
Interfacing Raspberry Pi with HC-SR04
Interfacing Raspberry Pi with HC-SR04

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.


5V to 3.3V Voltage Divider
5V to 3.3V Voltage Divider

The following equation can be used for calculating resistor values,

“Vout = Vin x R2/(R1+R2)”

Connection Diagram

Interfacing Raspberry Pi with HC-SR04 Circuit Diagram
Interfacing Raspberry Pi with HC-SR04 Circuit 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

Ultrasonic distance sensor output
Ultrasonic distance sensor 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.

Share this post

  • 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).

  • 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.

  • but that will require internet connection
    so how to do that??
    internet connection on raspberry pi will u explain.

  • 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.

  • 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.

  • how to get email alert from this sensor?
    i mean do you have code for that

  • 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.

  • I used 470 ohm and 1k resistors in my setup (exactly 1/10th of what you have). It works, but should I anticipate problems?

  • 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 🙂

  • 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.

  • I have this letter all time and it wont go away and stays for very long time.
    Waiting for sensor to settle

    Any suggestions ?

  • Good. But Voltage divider using resistors are not accurate for high speed signals. Better use a 3.3v Zener diodes.


  • >