Ultrasonic distance sensors
In the lab we have ultrasonic sensors available that measure distance using the time of flight of sound.
These sensors use two pins to communicate, a trigger pin and an echo pin.
A measurement is started by a falling edge on the trigger pin, which triggers the sending of an ultrasonic pulse.
After sending the pulse the echo pin will be high until an echo is received.
The distance to an obstacle can then be calculated from the duration of the echo pulse and the speed of sound in air.
5V ────┐ ┌────────────────────────────
Trigger │ │
0V └───┘
5V ┌────────────────┐
Echo │ │
0V ───────┘ └────────────
To connect the 5V ultrasonic sensor to the 3.3V microcontroller we need basic level shifting.
The following connections need to be made:
- Sensor GND to microcontroller GND
- Sensor VCC to microcontroller 5V
- Sensor TRIG to microcontroller D6
And one of the following to convert voltage levels:
-
Voltage divider
┌──────┐ D5 ┌──────┐ ECHO ───┤ 10kΩ ├────┴─────┤ 15kΩ ├─── GND └──────┘ └──────┘
-
Diode
C A ECHO ───┤⯇├── D5
The code snipped below contains a function that,
when called, performs a single distance measurement
and calls the function passed as the db_done
when the measurement is done.
A single argument is passed to the function:
nil
if no echo was received- A number giving the measured distance in meters
function measure_distance(cb_done)
local timeout = tmr.create()
local echo_start = nil
function on_timeout(t)
-- Stop waiting for an interrupt and
-- report failure
gpio.trig(5)
cb_done(nil)
end
function on_echo(level, when, evcount)
-- Measure the time between the pin going high
-- and going low to calculate time of flight
if level == gpio.HIGH then
echo_start= when
else
timeout:unregister()
gpio.trig(5)
local tof = when - echo_start
local distance = tof / 2 * 343e-6
cb_done(distance)
end
end
-- When the echo ouput does not change
-- for 200ms no echo was detected
timeout:alarm(210, tmr.ALARM_SINGLE, on_timeout)
-- Pin 5 is connected to the echo pin setup
-- interrupts to measure the length of the pulse
gpio.mode(5, gpio.INT, gpio.PULLUP)
gpio.trig(5, "both", on_echo)
gpio.mode(6, gpio.OUTPUT)
-- Trigger a measurement by pulsing
-- pin 6 high and then low for 20us
gpio.serout(6, gpio.HIGH, {20, 20}, 1, 0)
end
Task: Call the function once a second and print
the measured distance
TODO: Actually test this with the required voltage divider resistors/diodes