Ultrasonic Distance Sensor with Python and the micro:bit
This installment of our micro:bit peripherals in Python series focuses on the HC-SR04 “Ultrasonic Distance Sensor”. This sensor detects objects using reflected sound waves, so you can add a “sonar” capability to your next project! It’s widely available, reasonably accurate, and only costs about $2.
Check out the video demo here:
Ultrasonic means that these sensors work with sound waves at a higher frequency than the human ear can detect. In this case it’s about 40kHz, which is twice as high as the 20kHz limit of normal hearing. If you’re thinking that’s just like a bat’s echolocation ability, you’d be right!
Triggering and Echo
As you can see from the picture, the sensor has 4 pins we can connect to. When you want to start a “ranging” cycle, just pulse the TRIG pin and then measure the duration of the return pulse on the ECHO pin. That duration is the time elapsed between an ultrasonic burst being transmitted and the echo being received.
Note: It may seem a little odd that you measure the duration of the ECHO pulse rather than the time delay between TRIG and ECHO. The reason for this is that the HC-SR04 has its own microcontroller (software inside!) that waits for your TRIG pulse, generates the "call" and measures the time before hearing the "echo". After it does its own software calculation, it relays the information to you by asserting the ECHO pin for the precise duration it measured.
The Speed of Sound
At room temperature the speed of sound in air is about 343 meters per second. So, to calculate the distance, just multiply the time “t” by 343. That gives you the total distance traveled by the sound wave, from the sensor out to the reflecting object and back again! We need only the distance to the object which is half of that amount. The equation we can use to measure distance to an object is:
distance = (t / 2) * 343 meters
Measuring Pulses with the Micro:bit
The HC-SR04 works for distances from 2 cm up to about 4 meters. So, we’ll need to measure some pretty short pulses! Take the 2 cm case:
t = 0.02 / 343 = 0.0000583 seconds
That’s about 58.3 microseconds! Can the micro:bit measure pulses that fast? You bet!
You’ll need to import a function from the “machine” library like so:
from machine import time_pulse_us
# Measure the echo pulse
micros = time_pulse_us(pin1, 1)
This function waits for the pin to go from ‘0’ to ‘1’ (that’s what the 2nd parameter indicates) and then returns the duration of the measured pulse in microseconds. Exactly what we need!
Powering the Sensor - Simple connection
The HC-SR04 is powered by the two pins labeled VCC and GND. VCC is the (+) side of power and as always GND is (-). You can connect these pins to your micro:bit’s 3V and GND pins as shown below, but be warned this might not work well with some HC-SR04 sensors! The datasheet of this sensor states that it needs 5V to operate properly. There are a few variations of the sensor on the market, and some of them can work at the micro:bit’s 3V… but some may not work, or may have poor performance with the lower voltage supply.
This configuration might work
Better Power - 5V Supply or 3-Cell Pack
The following is a better connection method. An external battery pack (warning: 4-cell packs are too high voltage for this) that gets the voltage to the 4-5 Volt range, or a 5V power supply will give the best performance.
Since the sensor will be running with a higher voltage than the micro:bit in this case, you’ll need to protect the micro:bit’s input circuit from the higher voltage of the ECHO pulse. Like most microcontrollers, the micro:bit has built-in protection circuits (clamping diodes) to prevent excessive voltages from damaging the part. But you should add a resistor in series with the input, to limit the current so the micro:bit can clamp the input voltage without breaking a sweat! A 1kΩ resistor will do nicely here.
External 5 Volt Power is Recommended
Fancy Some Hardware Hacking?
If you don’t mind getting the soldering iron out and making a little mod to your micro:bit, you can tap into the 5 Volts supplied by the USB port. It’s available on a test-pad on the micro:bit. Use a voltmeter to confirm you’ve found the right spot, and solder a wire as shown to access the power.
Caution: If you miswire this you can damage your micro:bit and/or the device at the other end of the USB cable! If you’re uncertain, consider testing with a cheap USB power adapter rather than plugging it into your PC the first time!
How to Run this Example:
When running any of the code samples below you should:
- Connect the HC-SR04 as shown above.
- Type one of the code examples below into https://makebit.firialabs.com (opens in a new tab).
- Run the example - display the distance in cm on the micro:bit.
If you haven't tried CodeSpace with the micro:bit, you're missing out on a FANTASTIC coding experience! Give it a try!
Code Example: Ranging Loop
"""HC-SR04 Ultrasonic Ranger"""
from microbit import *
from maching import time_pulse_us
#Choose I/O pins based on wiring
trig = pin0
echo = pin1
# Set up I/O
trig.write_digital(0)
echo.read_digital()
# Continuous Ultrasonic Ranging!
while True:
# Output a pulse to trigger ultrasonic burst
trig.write_digital(1)
trig.write_digital(0)
# Meausre the input echo pulse in microseconds, convert to seconds
micros = time_pulse_us(echo, 1)
t_echo = micros / 1000000
# Calculate distance in cm and display on micro:bit
dist_cm = (t_echo / 2) * 34300
display.scroll(str(int(dist_cm)))
# Must pause between measurements (superfluous due to scroll)
sleep(100)