diff --git a/modules/app_obd.py b/modules/app_obd.py index 181b147..1c8b94f 100644 --- a/modules/app_obd.py +++ b/modules/app_obd.py @@ -11,6 +11,9 @@ from modules import app_events, app_gps RECONNECT_INTERVAL = 10 SENSOR_POLL_INTERVAL = 5 +# Speed poll is every 2s; if the adapter returns null for this many consecutive +# polls (~20s) the ELM327 is usually stalled — force a reconnect. +STALE_SPEED_RECONNECT_THRESHOLD = 10 status = None speed = 0 @@ -357,14 +360,25 @@ def get_fresh_dtc_codes(max_age=SENSOR_POLL_INTERVAL * 3): def obd_speed(): global speed, speed_updated_at with obd_speed_lock: + null_streak = 0 while not stop_speed.is_set() and _is_car_connected(): response = _query(obd.commands.SPEED) if response is None: break if response.is_null(): + null_streak += 1 print("No speed data received. #" + str(get_speedtime())) print(app_gps.get_gps()) + # A stalled ELM327 keeps the connection "alive" but returns + # null for speed forever. Force a reconnect after ~20s of null + # reads instead of flatlining until the next ignition cycle. + if null_streak >= STALE_SPEED_RECONNECT_THRESHOLD: + with _connection_lock: + candidate = connection + _mark_connection_lost(candidate, "speed", "stale null speed") + break else: + null_streak = 0 speed = round(response.value.to("kph").magnitude, 1) speed_updated_at = time.monotonic() print("Speed:", speed, "kph")