Introduction
In this tutorial, we will learn how to interface the HC-SR04 ultrasonic sensor with an ESP32 microcontroller using MicroPython. The HC-SR04 sensor is used to measure distances accurately by sending out ultrasonic pulses and measuring the time it takes for the echo to return.
Prerequisites
Before we dive into the code, ensure you have the following:
- ESP32 microcontroller
- HC-SR04 ultrasonic sensor
- Breadboard and jumper wires
- MicroPython installed on the ESP32
- Thonny IDE or any other suitable IDE for writing and uploading MicroPython code
Code Explanation
We will use two scripts: hcsr04.py
(a module for the HC-SR04 sensor) and main.py
(the main script to read and display distance measurements).
hcsr04.py Module Code
This module handles the low-level operations of the HC-SR04 sensor. It initializes the trigger and echo pins, sends out ultrasonic pulses, and measures the time it takes for the echo to return. This time is then converted to distance.
import machine, time
from machine import Pin
__version__ = '0.2.0'
__author__ = 'Roberto Sánchez'
__license__ = "Apache License 2.0. https://www.apache.org/licenses/LICENSE-2.0"
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)
# Init echo pin (in)
self.echo = Pin(echo_pin, mode=Pin.IN, pull=None)
def _send_pulse_and_wait(self):
"""
Send the pulse to trigger and listen on echo pin.
We use the method `machine.time_pulse_us()` to get the microseconds until the echo is received.
"""
self.trigger.value(0) # Stabilize the sensor
time.sleep_us(5)
self.trigger.value(1)
# Send a 10us pulse.
time.sleep_us(10)
self.trigger.value(0)
try:
pulse_time = machine.time_pulse_us(self.echo, 1, self.echo_timeout_us)
return pulse_time
except OSError as ex:
if ex.args[0] == 110: # 110 = ETIMEDOUT
raise OSError('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
main.py Code
The main script imports the HCSR04
class from the hcsr04.py
module and uses it to continuously read and display distance measurements.
# code written by Shemanto Sharkar (let's connect on LinkedIn: https://www.linkedin.com/in/shemanto/)
# step-1: importing necessary modules
from hcsr04 import HCSR04
from time import sleep
# step-2: telling ESP32 where our sensor's pins are connected
sensor = HCSR04(trigger_pin=5, echo_pin=18, echo_timeout_us=10000)
# step-3: reading data continuously inside loop
while True:
try:
distance = sensor.distance_cm()
print('Distance:', distance, 'cm')
sleep(1)
except OSError as e: # Error Handling
print("Error Data")
Detailed Code Breakdown
- Importing Necessary Modules: ```python
from hcsr04 import HCSR04
from time import sleep
- `from hcsr04 import HCSR04`: Imports the `HCSR04` class from the `hcsr04` module.
- `from time import sleep`: Imports the `sleep` function from the `time` module for introducing delays.
2. **Setting Up the Sensor:**
```python
sensor = HCSR04(trigger_pin=5, echo_pin=18, echo_timeout_us=10000)
-
sensor = HCSR04(trigger_pin=5, echo_pin=18, echo_timeout_us=10000)
: Initializes the HC-SR04 sensor with the trigger pin connected to GPIO 5 and the echo pin connected to GPIO 18. Theecho_timeout_us
parameter sets the timeout for listening to the echo signal.
- Reading Data Continuously: ```python
while True:
try:
distance = sensor.distance_cm()
print('Distance:', distance, 'cm')
sleep(1)
except OSError as e:
print("Error Data")
- `while True`: Starts an infinite loop to continuously read data from the sensor.
- `distance = sensor.distance_cm()`: Reads the distance measurement from the sensor in centimeters.
- `print('Distance:', distance, 'cm')`: Prints the distance measurement to the console.
- `sleep(1)`: Introduces a delay of 1 second before the next reading.
- `except OSError as e`: Catches any errors that occur during the reading process and prints an error message.
### Diagram
Here’s a diagram illustrating the connections:
ESP32 Microcontroller:
___________
| |
| |
| |
| 5 |--------> HC-SR04 (Trigger Pin)
| |
| 18 |--------> HC-SR04 (Echo Pin)
|___________|
|
|
GND
VCC (5V)
**Connections:**
- Connect the VCC pin of the HC-SR04 to the 5V pin of the ESP32.
- Connect the GND pin of the HC-SR04 to the GND pin of the ESP32.
- Connect the Trigger pin of the HC-SR04 to GPIO pin 5 of the ESP32.
- Connect the Echo pin of the HC-SR04 to GPIO pin 18 of the ESP32.
### Conclusion
By following this tutorial, you will be able to measure distances using an HC-SR04 ultrasonic sensor with an ESP32 microcontroller running MicroPython. This basic setup can be extended for various applications like obstacle detection, distance measurement, and more. Happy coding!
If you have any questions or need further assistance, feel free to reach out on LinkedIn: [Shemanto Sharkar](https://www.linkedin.com/in/shemanto/).