Skip to content

Commit dc6db1c

Browse files
committed
Revert "Change the rangefinder class to be non-blocking"
This reverts commit 34c2347.
1 parent 34c2347 commit dc6db1c

1 file changed

Lines changed: 39 additions & 65 deletions

File tree

XRPLib/rangefinder.py

Lines changed: 39 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import time
2-
from machine import Pin, Timer
1+
import machine, time
2+
from machine import Pin
33

44
class Rangefinder:
55

@@ -16,17 +16,15 @@ def get_default_rangefinder(cls):
1616

1717
def __init__(self, trigger_pin: int|str = "RANGE_TRIGGER", echo_pin: int|str = "RANGE_ECHO", timeout_us:int=500*2*30):
1818
"""
19-
A non-blocking class for using the HC-SR04 Ultrasonic Rangefinder.
19+
A basic class for using the HC-SR04 Ultrasonic Rangefinder.
2020
The sensor range is between 2cm and 4m.
21-
Measurements are taken continuously in the background using a timer
22-
and pin IRQ, so distance() returns immediately with the most recent value.
2321
Timeouts will return a MAX_VALUE (65535) instead of raising an exception.
2422
2523
:param trigger_pin: The number of the pin on the microcontroller that's connected to the ``Trig`` pin on the HC-SR04.
2624
:type trigger_pin: int
2725
:param echo_pin: The number of the pin on the microcontroller that's connected to the ``Echo`` pin on the HC-SR04.
2826
:type echo_pin: int
29-
:param timeout_us: Max microseconds to wait for a response from the sensor before assuming it isn't going to answer. By default set to 30,000 us (0.03 s)
27+
:param timeout_us: Max microseconds seconds to wait for a response from the sensor before assuming it isn't going to answer. By default set to 30,000 us (0.03 s)
3028
:type timeout_us: int
3129
"""
3230
self.timeout_us = timeout_us
@@ -38,80 +36,56 @@ def __init__(self, trigger_pin: int|str = "RANGE_TRIGGER", echo_pin: int|str = "
3836
# Init echo pin (in)
3937
self.echo = Pin(echo_pin, mode=Pin.IN, pull=None)
4038

41-
self.cms = self.MAX_VALUE
42-
self._echo_start = 0
43-
self._waiting_for_echo = False
44-
self._trigger_time = 0
45-
self._first_reading_done = False
39+
self.cms = 0
40+
self.last_echo_time = 0
41+
self.cache_time_us = 3000
4642

47-
# Register echo pin IRQ for both rising and falling edges
48-
self.echo.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=self._echo_handler)
49-
50-
# Start a virtual timer to periodically send trigger pulses
51-
# 60ms period matches the HC-SR04 recommended minimum cycle time
52-
self._timer = Timer(-1)
53-
self._timer.init(period=60, callback=self._trigger_ping)
54-
55-
def _trigger_ping(self, t):
43+
def _send_pulse_and_wait(self):
5644
"""
57-
Timer callback that sends a trigger pulse to the HC-SR04.
58-
Only ~15us of work per call (negligible blocking).
59-
Also detects timeouts from previous measurements.
45+
Send the pulse to trigger and listen on echo pin.
46+
We use the method `machine.time_pulse_us()` to get the microseconds until the echo is received.
6047
"""
61-
if self._waiting_for_echo:
62-
# Check if previous measurement timed out
63-
if time.ticks_diff(time.ticks_us(), self._trigger_time) > self.timeout_us:
64-
self.cms = self.MAX_VALUE
65-
self._waiting_for_echo = False
66-
self._first_reading_done = True
67-
else:
68-
# Still waiting for a valid echo, skip this trigger
69-
return
70-
71-
# Send trigger pulse
72-
self._trigger.value(0)
48+
self._trigger.value(0) # Stabilize the sensor
7349
self._delay_us(5)
7450
self._trigger.value(1)
51+
# Send a 10us pulse.
7552
self._delay_us(10)
7653
self._trigger.value(0)
77-
self._trigger_time = time.ticks_us()
78-
self._waiting_for_echo = True
79-
80-
def _echo_handler(self, pin):
81-
"""
82-
Pin IRQ handler for the echo pin.
83-
Rising edge: record start time.
84-
Falling edge: compute distance from pulse width.
85-
"""
86-
if pin.value() == 1:
87-
# Rising edge - echo pulse started
88-
self._echo_start = time.ticks_us()
89-
else:
90-
# Falling edge - echo pulse ended
91-
if self._waiting_for_echo:
92-
pulse_time = time.ticks_diff(time.ticks_us(), self._echo_start)
93-
if pulse_time > 0:
94-
# Sound speed 343.2 m/s = 0.034320 cm/us = 1cm per 29.1us
95-
# Divide by 2 because pulse travels to target and back
96-
self.cms = (pulse_time / 2) / 29.1
97-
else:
98-
self.cms = self.MAX_VALUE
99-
self._waiting_for_echo = False
100-
self._first_reading_done = True
54+
try:
55+
pulse_time = machine.time_pulse_us(self.echo, 1, self.timeout_us)
56+
return pulse_time
57+
except OSError as exception:
58+
raise exception
10159

10260
def distance(self) -> float:
10361
"""
104-
Get the most recent distance measurement in centimeters.
105-
Blocks until the first measurement is available, then returns
106-
immediately on all subsequent calls.
62+
Get the distance in centimeters by measuring the echo pulse time
10763
"""
108-
while not self._first_reading_done:
109-
pass
64+
if time.ticks_diff(time.ticks_us(), self.last_echo_time) < self.cache_time_us and not (self.cms == 65535 or self.cms == 0):
65+
return self.cms
66+
67+
try:
68+
pulse_time = self._send_pulse_and_wait()
69+
if pulse_time <= 0:
70+
return self.MAX_VALUE
71+
except OSError as exception:
72+
# We don't want programs to crash if the HC-SR04 doesn't see anything in range
73+
# So we catch those errors and return 65535 instead
74+
if exception.args[0] == 110: # 110 = ETIMEDOUT
75+
return self.MAX_VALUE
76+
raise exception
77+
78+
# To calculate the distance we get the pulse_time and divide it by 2
79+
# (the pulse walk the distance twice) and by 29.1 becasue
80+
# the sound speed on air (343.2 m/s), that It's equivalent to
81+
# 0.034320 cm/us that is 1cm each 29.1us
82+
self.cms = (pulse_time / 2) / 29.1
83+
self.last_echo_time = time.ticks_us()
11084
return self.cms
11185

11286
def _delay_us(self, delay:int):
11387
"""
114-
Custom implementation of time.sleep_us(), used to get around the bug in MicroPython where time.sleep_us()
88+
Custom implementation of time.sleep_us(), used to get around the bug in MicroPython where time.sleep_us()
11589
doesn't work properly and causes the IDE to hang when uploading the code
11690
"""
11791
start = time.ticks_us()

0 commit comments

Comments
 (0)