Motion & Autonomy — Day 3 of 4
'F' → Fullscreen
Keep the motor driver wired — session 16 needs both. Create a new MicroPython script named 2-13-distance.
VCC to 3V3, GND to GND, Trig to GPIO 22, Echo to GPIO 20.Trig, then time how long Echo stays HIGH.Power it from 3V3 rather than 5V. These GPIO pins expect 3.3V signals, and the Echo pin answers at whatever voltage the sensor runs on.
from machine import Pin, time_pulse_usimport time
trigger = Pin(22, Pin.OUT)echo = Pin(20, Pin.IN)
while True: trigger.value(0) time.sleep_us(2) trigger.value(1) time.sleep_us(10) trigger.value(0) duration = time_pulse_us(echo, 1, 30000) print("echo lasted", duration, "microseconds") time.sleep(0.5)Work out where 58 comes from before you accept it. Sound covers 0.0343cm per microsecond, and the echo travels the distance twice.
from machine import Pin, time_pulse_usimport time
trigger = Pin(22, Pin.OUT)echo = Pin(20, Pin.IN)
while True: trigger.value(0) time.sleep_us(2) trigger.value(1) time.sleep_us(10) trigger.value(0) duration = time_pulse_us(echo, 1, 30000) print(duration // 58, "cm") time.sleep(0.5)read_distance(), and return -1 when the timer gives up.from machine import Pin, time_pulse_usimport time
trigger = Pin(22, Pin.OUT)echo = Pin(20, Pin.IN)
TIMEOUT_US = 30000
def read_distance(): trigger.value(0) time.sleep_us(2) trigger.value(1) time.sleep_us(10) trigger.value(0) duration = time_pulse_us(echo, 1, TIMEOUT_US) if duration < 0: return -1 return duration // 58
while True: cm = read_distance() if cm < 0: print("nothing in range") else: print(cm, "cm") time.sleep(0.5)read_average_distance(samples) that takes several readings and averages the good ones.-1 drag the average down.-1 only if every reading failed.Same idea as the temperature sensor in 2.9, with one new wrinkle: here some readings are not merely noisy but entirely absent, so you have to count how many were usable.
from machine import Pin, time_pulse_usimport time
trigger = Pin(22, Pin.OUT)echo = Pin(20, Pin.IN)
TIMEOUT_US = 30000
def read_distance(): trigger.value(0) time.sleep_us(2) trigger.value(1) time.sleep_us(10) trigger.value(0) duration = time_pulse_us(echo, 1, TIMEOUT_US) if duration < 0: return -1 return duration // 58
def read_average_distance(samples): total = 0 good = 0 for i in range(samples): cm = read_distance() if cm > 0: total = total + cm good = good + 1 time.sleep(0.02) if good == 0: return -1 return total // good
while True: cm = read_average_distance(5) if cm < 0: print("nothing in range") else: print(cm, "cm") time.sleep(0.3)show() back from Activity 2.11.from machine import Pin, time_pulse_usimport qwiic_large_oledimport time
trigger = Pin(22, Pin.OUT)echo = Pin(20, Pin.IN)
TIMEOUT_US = 30000
oled = qwiic_large_oled.QwiicLargeOled()oled.begin()
def read_distance(): trigger.value(0) time.sleep_us(2) trigger.value(1) time.sleep_us(10) trigger.value(0) duration = time_pulse_us(echo, 1, TIMEOUT_US) if duration < 0: return -1 return duration // 58
def read_average_distance(samples): total = 0 good = 0 for i in range(samples): cm = read_distance() if cm > 0: total = total + cm good = good + 1 time.sleep(0.02) if good == 0: return -1 return total // good
def show(oled, line1, line2): oled.clear(oled.PAGE) oled.print(line1) oled.print(line2) oled.display()
while True: cm = read_average_distance(5) if cm < 0: show(oled, "Distance", "out of range") else: show(oled, "Distance", str(cm) + " cm") time.sleep(0.3)Moving your hand towards and away from the sensor should print something like:
24 cm23 cmnothing in range41 cmAnswer the following questions before submitting your work.
read_average_distance() counts how many readings were usable instead of just dividing by samples. Explain what would go wrong with the simpler version.Submit the required files to the appropriate dropbox.