From 80fcd8bf37591f19d086c2f818e7396b027732aa Mon Sep 17 00:00:00 2001 From: PaulVua Date: Fri, 23 Jan 2026 17:24:51 +0100 Subject: [PATCH] fix(envea): improve serial read timing and frame detection - Increase wait time to 1 second for complete sensor response - Read all available bytes from buffer instead of fixed 32 - Search for frame header (FF 02) anywhere in response data (handles command echo or garbage before actual frame) - Extract frame from header position for correct byte alignment Co-Authored-By: Claude Opus 4.5 --- envea/read_value_v2.py | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/envea/read_value_v2.py b/envea/read_value_v2.py index e5559c0..4ed650d 100755 --- a/envea/read_value_v2.py +++ b/envea/read_value_v2.py @@ -114,18 +114,36 @@ try: serial_connection.write(command) debug_print(f" → Sent command: {command.hex()}") - # Wait for sensor response - time.sleep(0.5) + # Wait for complete sensor response (sensor needs time to process and reply) + time.sleep(1.0) + + # Read all available data from buffer + bytes_available = serial_connection.in_waiting + debug_print(f" ← Bytes available in buffer: {bytes_available}") + + if bytes_available > 0: + data_envea = serial_connection.read(bytes_available) + else: + # Fallback: try reading with timeout + data_envea = serial_connection.read(32) - # Read fixed number of bytes (not readline which stops at 0x0A) - data_envea = serial_connection.read(32) # Read fixed 32 bytes debug_print(f" ← Received {len(data_envea)} bytes: {data_envea.hex() if data_envea else 'empty'}") - # Validate frame: should start with 0xFF 0x02 and have at least 20 bytes - if len(data_envea) >= 20: - # Check frame header (0xFF 0x02 expected for valid CAIRSENS response) - if data_envea[0] == 0xFF and data_envea[1] == 0x02: - byte_20 = data_envea[19] + # Find frame start (0xFF 0x02) in received data - may have echo/garbage before it + frame_start = -1 + for i in range(len(data_envea) - 1): + if data_envea[i] == 0xFF and data_envea[i + 1] == 0x02: + frame_start = i + debug_print(f" → Found frame header at position {i}") + break + + if frame_start >= 0: + # Extract frame from header position + frame_data = data_envea[frame_start:] + debug_print(f" → Frame data ({len(frame_data)} bytes): {frame_data.hex()}") + + if len(frame_data) >= 20: + byte_20 = frame_data[19] raw_value = byte_20 calculated_value = byte_20 * coefficient debug_print(f" → Byte 20 value: {raw_value} (0x{raw_value:02X})") @@ -146,9 +164,9 @@ try: debug_print(f" ✓ {name.upper()} = {calculated_value}") else: - debug_print(f" ✗ Invalid frame header: expected FF 02, got {data_envea[0]:02X} {data_envea[1]:02X}") + debug_print(f" ✗ Frame too short ({len(frame_data)} bytes after header, expected ≥20)") else: - debug_print(f" ✗ Response too short ({len(data_envea)} bytes, expected ≥20)") + debug_print(f" ✗ No valid frame header (FF 02) found in response") except serial.SerialException as e: debug_print(f"✗ Error communicating with {name}: {e}")