Chatham Rabbit Hole Logo

Using the HC-SR04 Ultrasound Distance Sensor

The HC-SR04 Ultrasound Sensor can measure distance measurement at short ranges up to ~1m

The interface is simple and straightforward with four pins:

  • Vcc (5 volts)
  • Ground
  • Trigger Pulse (activates the sensor’s sound transmitter)
  • Echo (the receiver output, nominally at the Vcc voltage, when sound is received.)

 


NOTE: The Echo output from the HC-SR04 sensor has a maximum voltage of 5v, and cannot be connected directly to a RaspberryPi GPIO input pin that requires an input no greater than 3.5v.

Typical solutions to this mismatch use a pair of resistors as a voltage divider, nominally in a 2:3 ratio; the most common selections using standard resistors are 330 and 470 ohms.

A newer version, the HC-SR04P, generates a 3.5v RaspberryPi-compatible Echo output, and does not require the voltage divider.

HC-SR04 Voltage Divider

Coding Examples

Code examples for Arduino, RaspberryPi, and other projects using the HC-SR04 are readily found. They share a common structure that sets a timer to generate a short pulse, sets a second timer to measure the interval when the return pulse is detected, and calculates resulting distance. Differences in the examples depend on the computer hardware, operating system, and programming language.

Ultrasound sensors are more suitable than LiDAR for measuring short ranges in low-cost systems because sound’s slower speed produces longer round-trip delays than a laser and are thus easier to measure with low-cost computers.

 Here’s a code example in Python for measuring distance with a RaspberryPi and the ‘SR-04 connected via GPIO.

				
					import RPi.GPIO as GPIO
import time


GPIO.setmode(GPIO.BOARD)

TRIG = 16
ECHO = 18
i=0

GPIO.setup(TRIG,GPIO.OUT)
GPIO.setup(ECHO,GPIO.IN)

GPIO.output(TRIG, False)
print "Calibrating....."
time.sleep(2)

print "Place the object......"


try:
    while True:
       GPIO.output(TRIG, True)
       time.sleep(0.00001)
       GPIO.output(TRIG, False)

       while GPIO.input(ECHO)==0:
          pulse_start = time.time()

       while GPIO.input(ECHO)==1:
          pulse_end = time.time()

       pulse_duration = pulse_end - pulse_start

       distance = pulse_duration * 17150

       distance = round(distance+1.15, 2)
  
       if distance<=20 and distance>=5:
          print "distance:",distance,"cm"
          i=1
          
       if distance>20 and i==1:
          print "place the object...."
          i=0
       time.sleep(2)

except KeyboardInterrupt:
     GPIO.cleanup()

				
			

Using the GPIOZERO API

Your Python code can be simplified considerably using the standardized GPIOZERO Library’s Application Programmer’s Interface for  the  HR-SR04 Distance Sensor. Interface details are at the online library documentation  here.

				
					#Code example using the gpiozero library
class gpiozero.DistanceSensor(echo, trigger, *, 
    queue_len=30, max_distance=1, threshold_distance=0.3, 
    partial=False, pin_factory=None)

##########################################################
# The following code will periodically report the distance 
#   measured by the sensor in cm assuming the TRIG pin is
#   connected to GPIO17, and the ECHO pin to GPIO18:

from gpiozero import DistanceSensor
from time import sleep

sensor = DistanceSensor(echo=18, trigger=17)
while True:
    print('Distance: ', sensor.distance * 100)
    sleep(1)