Skip to content

Latest commit

 

History

History
191 lines (136 loc) · 4.77 KB

PROTOCOL.md

File metadata and controls

191 lines (136 loc) · 4.77 KB

LHS Hotplate Serial Protocol

This protocol description is based on the recovered HC11 ROM and pin-level emulation. Some live hardware probing has shown related line-oriented command families that are not fully reconciled with this ROM-visible parser, so verify the protocol on your unit before using write commands.

Transport

  • MCU SCI on PD0/PD1
  • default 300 baud
  • 8N1
  • No checksum
  • Immediate commands are a single byte
  • Decimal setters use CR as the terminator
  • Raw setters use binary little-endian payload bytes

The packaged client and REPL default to 300 baud. The REPL also supports baud <rate> for close variants that use a different crystal or divider.

Electrical Interface

The observed LHS-family hardware exposes the serial interface on a 4-position RJ11 jack. Viewed from the back of the unit with the plate upright, the pins run left to right as:

Rear view, plate upright

+---RJ11 jack---+
| 1 | 2 | 3 | 4 |
+---+---+---+---+
  |   |   |   |
  |   |   |   +-- Plate Tx  -> controller/driver Rx
  |   |   +------ GND
  |   +---------- GND
  +-------------- Plate Rx  <- controller/driver Tx

The plate-side signaling is inverted relative to a plain TTL UART. Use either:

  • an inverting RS-232 transceiver path, such as an SP232ACP
  • or a TTL adapter with both Rx and Tx explicitly configured as inverted

Relevant SP232ACP electrical points:

  • RS-232 receiver input range: -15 V to +15 V
  • receiver threshold region: about 0.8 V to 2.4 V
  • typical receiver thresholds at 5 V: 1.2 V low and 1.7 V high
  • typical hysteresis: 0.5 V
  • RS-232 transmit swing: about ±6.5 V typical, ±5.0 V minimum into 3 kΩ

If F and the rest of the known command set appear silent on an otherwise valid wiring setup, inversion is the first thing to check.

Command Families

Immediate:
  C e F G i j k l m n o p

Raw setters:
  A B D E <lo> <hi>

Decimal setters:
  a b c d f g h <ascii-digits> <CR>

Immediate Commands

  • C, e: clear active probe/plate target mode bits
  • F: return a 10-byte binary snapshot
  • G, p: trigger the 3-chirp alarm pattern used at timer expiry
  • i: query probe temperature in C
  • j: query probe temperature in F
  • k: query plate temperature in C
  • l: query plate temperature in F
  • m: query measured stir speed in RPM
  • n: query ramp in C/hour
  • o: query ramp in F/hour

Query replies are ASCII digits followed by CR LF. i and j return blank CR LF when no probe is connected.

Raw Setters

  • A <lo> <hi>: set probe target raw
  • B <lo> <hi>: set plate target raw
  • D <lo> <hi>: set stir target raw, low byte only is meaningful
  • E <lo> <hi>: set ramp raw

Examples:

  • 41 50 46 -> A 0x4650
  • 42 BC 34 -> B 0x34BC
  • 44 1E 00 -> D 0x001E
  • 45 5A 00 -> E 0x005A

Decimal Setters

  • a<digits><CR>: set probe target in C
  • b<digits><CR>: set probe target in F
  • c<digits><CR>: set plate target in C
  • d<digits><CR>: set plate target in F
  • f<digits><CR>: set stir target in RPM
  • g<digits><CR>: set ramp in C/hour
  • h<digits><CR>: set ramp in F/hour

Units And Conversion

Temperature

raw = (degC + 100) * 90
raw = (degF + 148) * 50
degC = raw / 90 - 100
degF = raw / 50 - 148

Validated examples:

  • a100<CR> == b212<CR> == raw 0x4650
  • c50<CR> == d122<CR> == raw 0x34BC

Stir

raw = rpm / 10
rpm = raw * 10

Validated example:

  • f300<CR> stores raw 0x1E

Ramp

Ramp is expressed in degrees per hour.

raw = degC_per_hour * 9
raw = degF_per_hour * 5
degC_per_hour = raw / 9
degF_per_hour = raw / 5

Validated example:

  • g10<CR> == h18<CR> == raw 0x005A

Snapshot Frame

F returns 10 bytes with no terminator:

byte 0: status_b1
byte 1: stir_measured_raw
byte 2: probe_temp_raw low
byte 3: probe_temp_raw high
byte 4: plate_temp_raw low
byte 5: plate_temp_raw high
byte 6: active_setpoint_raw low
byte 7: active_setpoint_raw high
byte 8: ramp_raw low
byte 9: ramp_raw high

The wire format is little-endian for all 16-bit fields.

Known status bits:

  • 0x08: probe target mode active
  • 0x10: plate target mode active

Observed first-byte values in live testing:

  • 0x00: no active temperature target mode
  • 0x08: probe target mode active
  • 0x10: plate target mode active

Live stir validation:

recv: 00 6D 00 00 4D 38 50 46 00 00

Decoded:

  • measured stir raw = 0x6D -> 1090 RPM
  • plate temp raw = 0x384D
  • active setpoint raw = 0x4650

Useful API Mapping

The Python client exposes:

  • low-level transport: immediate(), raw16le(), decimal(), send_ascii(), send_hex(), send_bytes()
  • semantic helpers: set_plate_temp_c(), set_probe_temp_c(), set_stir_rpm(), set_ramp_c(), query helpers, and snapshot()
  • interface verification: verify_interface()