61 lines
2.2 KiB
Python
61 lines
2.2 KiB
Python
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
|
|
self.target = serial.Serial(target_port, 115200, timeout=0.1)
|
|
|
|
def calculate_scd30_crc(self, data):
|
|
crc = 0xFF
|
|
for byte in data:
|
|
crc ^= byte
|
|
for _ in range(8):
|
|
if crc & 0x80:
|
|
crc = (crc << 1) ^ 0x31
|
|
else:
|
|
crc <<= 1
|
|
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 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
|
|
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
|
|
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 close(self):
|
|
self.emulator.close()
|
|
self.target.close() |