Update ports

This commit is contained in:
2026-02-09 16:41:40 +01:00
parent 0f50ddbae3
commit 86bc6505c8
2 changed files with 76 additions and 69 deletions

View File

@@ -2,14 +2,15 @@ import serial
import struct
import time
class HILController:
def __init__(self, emulator_port, target_port, baud=921600):
# Port for the ESP32 acting as the Sensor
self.emulator = serial.Serial(emulator_port, baud, timeout=0.1)
# Port for the ESP32 running your application code
class SCD30_HIL_Lib:
def __init__(self, emulator_port='/dev/i2c_emulator', target_port='/dev/esp_sensor_test', baud=921600):
# High speed for the bridge to minimize I2C latency
self.emulator = serial.Serial(emulator_port, baud, timeout=0.05)
# Standard speed for the Target application logs
self.target = serial.Serial(target_port, 115200, timeout=0.1)
def calculate_scd30_crc(self, data):
def _calculate_crc8(self, data):
"""SCD30 specific CRC-8 (Polynomial 0x31)"""
crc = 0xFF
for byte in data:
crc ^= byte
@@ -21,40 +22,38 @@ class HILController:
crc &= 0xFF
return crc
def pack_float_scd30(self, value):
"""Packs a float into the SCD30 [MSB, LSB, CRC, MSB, LSB, CRC] format"""
b = struct.pack('>f', value)
w1 = [b[0], b[1]]
w2 = [b[2], b[3]]
return w1 + [self.calculate_scd30_crc(w1)] + w2 + [self.calculate_scd30_crc(w2)]
def _pack_float(self, value):
"""Converts float to [MSB, LSB, CRC, MSB2, LSB2, CRC]"""
b = struct.pack('>f', value) # Big-endian IEEE754
w1, w2 = [b[0], b[1]], [b[2], b[3]]
return w1 + [self._calculate_crc8(w1)] + w2 + [self._calculate_crc8(w2)]
def set_emulator_data(self, co2, temp, hum):
"""Prepares the DATA: hex string for the Emulator ESP32"""
# SCD30 Ready Status (0x0001 + CRC)
ready_hex = "000103"
# Build the 18-byte measurement buffer
payload = self.pack_float_scd30(co2) + \
self.pack_float_scd30(temp) + \
self.pack_float_scd30(hum)
data_hex = "".join(f"{b:02X}" for b in payload)
# We check for CMD from emulator and respond
def process_bridge(self, co2_val, temp_val, hum_val):
"""
Listens for 'CMD:' from Emulator and replies with 'DATA:'
Returns True if a measurement was successfully served.
"""
line = self.emulator.readline().decode('utf-8', errors='ignore').strip()
if "CMD:0202" in line: # Master asking if data is ready
self.emulator.write(f"DATA:{ready_hex}\n".encode())
elif "CMD:0300" in line: # Master asking for the 18 bytes
self.emulator.write(f"DATA:{data_hex}\n".encode())
return True
if line.startswith("CMD:"):
cmd = line[4:]
if "0202" in cmd: # Data Ready Status request
resp = [0x00, 0x01, self._calculate_crc8([0x00, 0x01])]
self.emulator.write(f"DATA:{''.join(f'{b:02X}' for b in resp)}\n".encode())
elif "0300" in cmd: # Read Measurement request
payload = self._pack_float(co2_val) + \
self._pack_float(temp_val) + \
self._pack_float(hum_val)
hex_data = "".join(f"{b:02X}" for b in payload)
self.emulator.write(f"DATA:{hex_data}\n".encode())
return True # Measurement cycle complete
return False
def read_target_output(self):
"""Reads the latest print statement from the Test Code ESP32"""
line = self.target.readline().decode('utf-8', errors='ignore').strip()
if "CO2:" in line:
return line
return None
def get_target_reading(self):
"""Captures the output from the Target ESP32 Serial Monitor"""
return self.target.readline().decode('utf-8', errors='ignore').strip()
def close(self):
self.emulator.close()