From fe9ced5f5b20b12c7aba5b9025de476d5e27749b Mon Sep 17 00:00:00 2001 From: grabowski Date: Thu, 5 Feb 2026 10:04:47 +0700 Subject: [PATCH] Send test config (8C 2B) before single-shot measurement The device needs the test config commands to enter single-test mode. Without them it behaves as continuous start+stop. Supports auto_psu flag so the device can handle PSU on/off automatically. Co-Authored-By: Claude Opus 4.5 --- hpcs6500.py | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/hpcs6500.py b/hpcs6500.py index bb5ee44..0a17620 100644 --- a/hpcs6500.py +++ b/hpcs6500.py @@ -39,6 +39,19 @@ CMD_SET_AC = 0x78 CMD_READ_PSU = 0x79 CMD_PSU_OUTPUT = 0x72 CMD_SET_MODE = 0x7A +CMD_TEST_CONFIG = 0x2B + +# Single-test config payloads captured from vendor software. +# Sub 00: test parameters, sub 01: test config with auto-PSU flag at byte 37. +_TEST_CONFIG_SUB0 = bytes.fromhex( + "00003c00000001008813037c011a04000000484200000208" + "000000000001060000000000803f0000803f0000803f0000" + "803f0000803f00000000003f" +) +_TEST_CONFIG_SUB1_BASE = bytes.fromhex( + "017c010c037c010c037c010c030000803f000000000000000000000000" + "00000000000000000001000000400000803f" +) # State polling byte[5] values STATE_IDLE = 0x04 @@ -268,6 +281,23 @@ class HPCS6500: state = resp[5] return data_available, state + def send_test_config(self, auto_psu=False): + """Send single-test configuration (8C 2B sub 00 + sub 01). + If auto_psu=True, device handles PSU on/off automatically.""" + self.ser.reset_input_buffer() + self.ser.write(bytes([SYNC, CMD_TEST_CONFIG]) + _TEST_CONFIG_SUB0) + resp = self._recv(2, timeout=2.0) + if resp != bytes([SYNC, CMD_TEST_CONFIG]): + return False + + sub1 = bytearray(_TEST_CONFIG_SUB1_BASE) + if auto_psu: + sub1[37] = 0x01 + self.ser.reset_input_buffer() + self.ser.write(bytes([SYNC, CMD_TEST_CONFIG]) + bytes(sub1)) + resp = self._recv(2, timeout=2.0) + return resp == bytes([SYNC, CMD_TEST_CONFIG]) + def start_measurement(self): """Send 8C 0E 01 to start measurement.""" self.ser.reset_input_buffer() @@ -426,10 +456,12 @@ class HPCS6500: return result - def take_single_reading(self): - """Trigger a single measurement (no PSU control). - Sends stop to trigger a one-shot reading, waits for data, reads it, - then resets. This matches the vendor software's single-test flow.""" + def take_single_reading(self, auto_psu=False): + """Trigger a single measurement matching the vendor's single-test flow. + Sends test config, then stop to trigger a one-shot reading, waits for + data, reads it, then resets. + If auto_psu=True, the device handles PSU on/off automatically.""" + self.send_test_config(auto_psu=auto_psu) self.stop_measurement() if not self.wait_for_data(timeout=30.0):