Distance measurement is vital in many applications like robotics, automation, and security systems. The HC-SR04 is a popular ultrasonic sensor used for non-contact distance measurements. This sensor operates by emitting an ultrasonic sound pulse and measuring the time it takes for the echo to return to calculate the distance to an object.
The HC-SR04 is reliable and accurate over short ranges, typically up to 4 meters. Use cases include parking sensors, obstacle avoidance in robotics, and interactive installations.
HC-SR04 Ultrasonic Distance Measurement Module
The HC-SR04 module includes an ultrasonic transmitter, a receiver, and a control circuit. It emits a high-frequency sound wave and receives the echo reflected from a target object. The distance is calculated based on the time interval between sending the wave and receiving the echo.
This module can be interfaced with microcontrollers (like Arduino or ESP32) using digital I/O pins. The HC-SR04 requires a short trigger pulse to start the measurement and then provides a pulse width output corresponding to the distance. The sensor requires a 5V power source.
The following is Micropython code to read 20 distance (cm) values over 10 seconds with the HC-SR04.
importtime from hcsr04 import HCSR04
sensor = HCSR04(trigger_pin=16, echo_pin=0)
for _ inrange(20): print(f'Distance (mm): {sensor.distance_mm()}') time.sleep(0.5)
class HCSR04: """
Driver to use the untrasonic sensor HC-SR04.
The sensor range is between 2cm and 4m.
The timeouts received listening to echo pin are converted to OSError('Out of range')
""" # echo_timeout_us is based in chip range limit (400cm) def__init__(self, trigger_pin, echo_pin, echo_timeout_us=500*2*30): """
trigger_pin: Output pin to send pulses
echo_pin: Readonly pin to measure the distance. The pin should be protected with 1k resistor
echo_timeout_us: Timeout in microseconds to listen to echo pin.
By default is based in sensor limit range (4m)
""" self.echo_timeout_us= echo_timeout_us # Init trigger pin (out) self.trigger= Pin(trigger_pin, mode=Pin.OUT, pull=None) self.trigger.value(0)
def _send_pulse_and_wait(self): """
Send the pulse to trigger and listen on echo pin.
We use the method maχ≠.timeps̲eus() to get the microseconds until the echo is received.
""" self.trigger.value(0)# Stabilize the sensor
sleep_us(5) self.trigger.value(1) # Send a 10us pulse.
sleep_us(10) self.trigger.value(0) try:
pulse_time = time_pulse_us(self.echo,1,self.echo_timeout_us) # time_pulse_us returns -2 if there was timeout waiting for condition; and -1 if there was timeout during the main measurement. It DOES NOT raise an exception # ...as of MicroPython 1.17: http://docs.micropython.org/en/v1.17/library/machine.html#machine.time_pulse_us if pulse_time <0:
MAX_RANGE_IN_CM = const(500)# it's really ~400 but I've read people say they see it working up to ~460
pulse_time =int(MAX_RANGE_IN_CM * 29.1)# 1cm each 29.1us return pulse_time exceptOSErroras ex: if ex.args[0]==110: # 110 = ETIMEDOUT raiseOSError('Out of range') raise ex
def distance_mm(self): """
Get the distance in milimeters without floating point operations.
"""
pulse_time =self._send_pulse_and_wait()
# To calculate the distance we get the pulse_time and divide it by 2 # (the pulse walk the distance twice) and by 29.1 becasue # the sound speed on air (343.2 m/s), that It's equivalent to # 0.34320 mm/us that is 1mm each 2.91us # pulse_time // 2 // 2.91 -> pulse_time // 5.82 -> pulse_time * 100 // 582
mm = pulse_time * 100 // 582 return mm
def distance_cm(self): """
Get the distance in centimeters with floating point operations.
It returns a float
"""
pulse_time =self._send_pulse_and_wait()
# To calculate the distance we get the pulse_time and divide it by 2 # (the pulse walk the distance twice) and by 29.1 becasue # the sound speed on air (343.2 m/s), that It's equivalent to # 0.034320 cm/us that is 1cm each 29.1us
cms =(pulse_time / 2) / 29.1 return cms
Here are a few applications where the HC-SR04 sensor might be useful:
Robotics: For detecting obstacles and aiding in navigation.
Home Automation: Such as turning lights on/off based on presence.
Security Systems: Detecting movement or presence in a particular area.
Educational Projects: To teach students about sensors and microcontrollers.
Experiment with the HC-SR04 sensor by measuring distances to various objects. Explore how the sensor accuracy varies with different materials and distances. Discuss the findings and the implications for potential applications.
Collect data using the following Python script, which takes 100 samples every 5 seconds. Position an object at a measured distance from the sensor, and move it as prompted, allowing a 5-second interval for repositioning. The data is stored in the dist_hcsr04.csv file on the microcontroller.
importtime from hcsr04 import HCSR04 from machine import Pin,SoftI2C
Compare the results of this test to the VL53L0X Laser Sensor. What are the advantages and disadvantages of using sound versus light to measure distance?
Solution
Import the data and convert distance from inches to millimeters. Remove the Time column to help with plotting the data.
import pandas as pd import matplotlib.pyplotas plt
data = pd.read_csv('http://apmonitor.com/dde/uploads/Main/dist_hcsr04.csv') # convert inches to mm
data['Dist']= data['Dist'].values * 25.4 # remove Time column del data['Time']
The data recorded in this solution likely has errors of +/- 20 mm based on where the object was placed for each measurement along the yard stick. Produce a scatter plot that shows the measured versus recorded distance. The lower limit for the distance sensor is about 40mm. The sensor measures the closest object and sound waves travel outward in a spherical form.
The sensor can be used in applications up to 4 m range and as low as 4 cm. The sample frequency may be high enough so that multiple samples can be used to reduce distance uncertainty or remove outliers. As an example, the median 5 values of 11 samples (eliminate 3 highest and 3 lowest) can be averaged and reported as the measured value. The median values eliminate potential outliers, and the average reduces the random uncertainties in the data.
✅ Activity: Proximity Indicator
Create a proximity indicator with a Red (stop), Yellow (slow), Green (near), Blue (far) light LED. Use the HC-SR04 sensor to determine the distance of the approaching object.
Red: < 20 cm
Yellow: 20-50 cm
Green: 50-80 cm
Blue: >80 cm
Below is code to change the build-in color changing LED of the ESP32 S2 WROVER.
from machine import Pin from neopixel import NeoPixel fromtimeimport sleep
# Define the GPIO pin connected to the RGB LED
LED_PIN =18# Update this to the correct pin for your board
# Initialize the NeoPixel object
np = NeoPixel(Pin(LED_PIN),1)# '1' indicates a single LED
def set_color(r, g, b): """Set the color of the RGB LED."""
np[0]=(r, g, b)
np.write()
# Example usage: cycle through red, green, and blue colors for i inrange(2):
set_color(255,0,0)# Red
sleep(1)
set_color(255,255,0)# Yellow
sleep(1)
set_color(0,255,0)# Green
sleep(1)
set_color(0,0,255)# Blue
sleep(1)
if distance isNone: print("Out of range")
set_color(0,0,255)# Turn off LED else: print("Distance: {:.2f} cm".format(distance))
if distance <= RED_THRESHOLD:
set_color(255,0,0)# Red elif distance <= YELLOW_THRESHOLD:
set_color(255,255,0)# Yellow elif distance <= GREEN_THRESHOLD:
set_color(0,255,0)# Green else:
set_color(0,0,255)# Blue (object is far away)