@@ -290,10 +290,9 @@ def __init__(self, trig_pin, echo_pin):
290290 self .trig_pin .off ()
291291
292292 # Sensor configuration
293- self .sound_speed_mm_us = 0.343 # Speed of sound in mm/μs
294293 self .max_distance_mm = 2000 # Max sensor range in mm
295- # Calculate timeout based on max distance
296- self .timeout_us = int ( self . max_distance_mm * 2.5 / self . sound_speed_mm_us )
294+ # Timeout: 30,000μs allows ~2x longer echo wait (500 * 2 * 30)
295+ self .timeout_us = 30000
297296
298297 def read_distance_mm (self ):
299298 """
@@ -302,46 +301,69 @@ def read_distance_mm(self):
302301 Returns:
303302 int: Distance in millimeters, or -1 if the reading is out of range or fails.
304303 """
305- # Add a delay to allow the sensor to settle between readings.
306- sleep_ms (30 )
304+ # Pre-check: ensure echo pin is LOW (not stuck high from wiring issue)
305+ if self .echo_pin .value () != 0 :
306+ _ultrasonic_warn_inline ("Echo pin stuck HIGH – check wiring" )
307+ if _ultrasonic_fail_count <= 3 and eventlog is not None :
308+ try :
309+ eventlog .log_event ("ultrasonic echo pin stuck high" )
310+ except Exception :
311+ pass
312+ return - 1
307313
308- # Send a 10μs trigger pulse
314+ # Send a 10μs trigger pulse with 5μs stabilization
309315 self .trig_pin .off ()
310- sleep_us (2 )
316+ sleep_us (5 )
311317 self .trig_pin .on ()
312318 sleep_us (10 )
313319 self .trig_pin .off ()
314320
315321 try :
316- # Measure the duration of the echo pulse
322+ # Measure the duration of the echo pulse (with retry on failure)
317323 duration = time_pulse_us (self .echo_pin , 1 , self .timeout_us )
318324
319325 # time_pulse_us returns -1 on timeout and -2 on invalid state
320326 if duration < 0 :
321- _ultrasonic_warn_inline ("Sensor error – check wiring" )
322- # Only log to eventlog on first few failures to avoid log spam
323- if _ultrasonic_fail_count <= 3 and eventlog is not None :
324- try :
325- eventlog .log_event ("ultrasonic timeout or invalid echo" )
326- except Exception :
327- pass
328- return - 1
329-
330- # Calculate distance in mm: (duration * speed_of_sound) / 2
331- distance_mm = (duration * self .sound_speed_mm_us ) / 2
327+ # Retry once after brief delay to handle transient issues
328+ sleep_ms (20 ) # Let sensor settle
329+ self .trig_pin .off ()
330+ sleep_us (5 )
331+ self .trig_pin .on ()
332+ sleep_us (10 )
333+ self .trig_pin .off ()
334+ duration = time_pulse_us (self .echo_pin , 1 , self .timeout_us )
335+
336+ # If still failing after retry, report error
337+ if duration < 0 :
338+ _ultrasonic_warn_inline ("Sensor error – check wiring" )
339+ # Only log to eventlog on first few failures to avoid log spam
340+ if _ultrasonic_fail_count <= 3 and eventlog is not None :
341+ try :
342+ eventlog .log_event ("ultrasonic timeout or invalid echo" )
343+ except Exception :
344+ pass
345+ return - 1
346+
347+ # Calculate distance in mm using integer math (avoids floating point)
348+ # Sound speed: 343.2 m/s = 0.3432 mm/μs
349+ # distance = (time * speed) / 2, so: time * 100 // 582
350+ distance_mm = duration * 100 // 582
332351
333352 # Check if the reading is within the valid range (20mm to 2000mm)
334353 if 20 <= distance_mm <= self .max_distance_mm :
335354 # Clear any inline warning since we got a good reading
336355 _ultrasonic_warn_clear ()
356+ result = int (distance_mm )
357+
358+ # Log AFTER timing-sensitive measurement is complete
337359 if eventlog is not None :
338360 try :
339361 eventlog .log_event (
340- "distance reading: {} mm" .format (int ( distance_mm ) )
362+ "distance reading: {} mm" .format (result )
341363 )
342364 except Exception :
343365 pass
344- return int ( distance_mm )
366+ return result
345367
346368 # Out of range – likely too close, too far, or pointing into open space
347369 _ultrasonic_warn_inline ("Out of range ({}mm)" .format (int (distance_mm )))
@@ -467,26 +489,26 @@ class AIDriver:
467489
468490 def __init__ (
469491 self ,
470- right_speed_pin = 3 , # GP2 (PWM capable)
471- left_speed_pin = 11 , # GP3 (PWM capable)
472- right_dir_pin = 12 , # GP4
473- right_brake_pin = 9 , # GP5
474- left_dir_pin = 13 , # GP6
475- left_brake_pin = 8 , # GP7
476- trig_pin = 6 , # GP8
477- echo_pin = 7 , # GP9
492+ right_speed_pin = 3 , # GP3 (PWM capable)
493+ left_speed_pin = 11 , # GP11 (PWM capable)
494+ right_dir_pin = 12 , # GP12
495+ right_brake_pin = 9 , # GP9
496+ left_dir_pin = 13 , # GP13
497+ left_brake_pin = 8 , # GP8
498+ trig_pin = 6 , # GP6
499+ echo_pin = 7 , # GP7
478500 ):
479501 """Initialize RP2040 based AIDriver differential drive robot.
480502
481503 Args:
482- right_speed_pin: PWM pin for right motor speed (default GP2 )
483- left_speed_pin: PWM pin for left motor speed (default GP3 )
484- right_dir_pin: Digital pin for right motor direction (default GP4 )
485- right_brake_pin: Digital pin for right motor brake (default GP5 )
486- left_dir_pin: Digital pin for left motor direction (default GP6 )
487- left_brake_pin: Digital pin for left motor brake (default GP7 )
488- trig_pin: Ultrasonic sensor trigger pin (default GP8 )
489- echo_pin: Ultrasonic sensor echo pin (default GP9 )
504+ right_speed_pin: PWM pin for right motor speed (default GP3 )
505+ left_speed_pin: PWM pin for left motor speed (default GP11 )
506+ right_dir_pin: Digital pin for right motor direction (default GP12 )
507+ right_brake_pin: Digital pin for right motor brake (default GP9 )
508+ left_dir_pin: Digital pin for left motor direction (default GP13 )
509+ left_brake_pin: Digital pin for left motor brake (default GP8 )
510+ trig_pin: Ultrasonic sensor trigger pin (default GP6 )
511+ echo_pin: Ultrasonic sensor echo pin (default GP7 )
490512 """
491513
492514 # Library-side preflight: log pin config and attempt a quick sensor ping
0 commit comments