|
| 1 | +# LHS Hotplate Controller |
| 2 | + |
| 3 | +Open-source Python tooling and reverse-engineering notes for LHS-series digital hotplate / stirrer serial interfaces. This project packages a firmware-derived command set, an interactive REPL, a desktop GUI, protocol documentation, and annotated ROM notes. |
| 4 | + |
| 5 | +The recovered firmware family appears across several rebrands and close variants, including Cole-Parmer Dataplate instruments, Omega LHS units, and Barnstead Thermolyne PMC 700-series hotplate/stirrers. Treat this as alpha-quality reverse-engineering work: verify the serial behavior on the unit in front of you before trusting automation. |
| 6 | + |
| 7 | +## Project Status |
| 8 | + |
| 9 | +- The Python client implements the command families recovered from the HC11 ROM and emulator traces. |
| 10 | +- Live probing of at least one related unit also exposed an older line-oriented protocol family that is not fully reconciled with the recovered ROM path. |
| 11 | +- The documentation includes both the implemented firmware-backed protocol and the remaining reverse-engineering caveats. |
| 12 | +- Heating and stirring commands can create real hazards. Supervise hardware tests and start with read-only probes. |
| 13 | + |
| 14 | +## Features |
| 15 | + |
| 16 | +- Firmware-backed Python client for the complete known SCI command set |
| 17 | +- Interactive REPL with: |
| 18 | + - command help (`help`, `help a`, `help -F`) |
| 19 | + - direct execution of every known protocol command |
| 20 | + - raw ASCII / hex / byte sending |
| 21 | + - COM-port listing and switching |
| 22 | + - interface verification (`F` vs diagnostic `s`) |
| 23 | +- Desktop GUI with: |
| 24 | + - plate temperature, stir, and ramp controls |
| 25 | + - delay-on and off-after timers for plate and stir actions |
| 26 | + - live snapshot polling |
| 27 | + - temperature and stir history graphs |
| 28 | + - start/stop capture logging for snapshot history and command history |
| 29 | + - CSV-backed hotplate programs |
| 30 | + - an integrated REPL pane |
| 31 | +- Clean protocol documentation |
| 32 | +- Annotated disassembly excerpts and a cleaned ROM listing copy |
| 33 | + |
| 34 | +## Installation |
| 35 | + |
| 36 | +```powershell |
| 37 | +python -m venv .venv |
| 38 | +.venv\Scripts\Activate.ps1 |
| 39 | +python -m pip install -e . |
| 40 | +``` |
| 41 | + |
| 42 | +## Supported Variants |
| 43 | + |
| 44 | +This project is aimed at the HC11-based LHS-family controller used in several branded products. Known or likely compatible labels include: |
| 45 | + |
| 46 | +- Cole-Parmer Dataplate |
| 47 | +- Cole-Parmer `04644` |
| 48 | +- Omega LHS |
| 49 | +- Barnstead Thermolyne PMC 700 series |
| 50 | + |
| 51 | +Serial behavior should always be verified on the specific unit in front of you before trusting automation. Hardware options, firmware revisions, and front-panel labeling can differ even when the underlying command set looks similar. |
| 52 | + |
| 53 | +## Electrical Interface |
| 54 | + |
| 55 | +The tested Cole-Parmer `04644` uses a 4-position RJ11 jack on the back panel. With the plate upright and viewed from the rear, the pins run left to right as: |
| 56 | + |
| 57 | +```text |
| 58 | +Rear view, plate upright |
| 59 | +
|
| 60 | ++---RJ11 jack---+ |
| 61 | +| 1 | 2 | 3 | 4 | |
| 62 | ++---+---+---+---+ |
| 63 | + | | | | |
| 64 | + | | | +-- Plate Tx -> connect to controller/driver Rx |
| 65 | + | | +------ GND |
| 66 | + | +---------- GND |
| 67 | + +-------------- Plate Rx <- connect to controller/driver Tx |
| 68 | +``` |
| 69 | + |
| 70 | +The plate-side serial path is electrically inverted relative to a plain TTL UART. In practice you need one of these: |
| 71 | + |
| 72 | +- an inverting RS-232 line driver/receiver such as the onboard `SP232ACP` |
| 73 | +- or a TTL serial adapter with both `Rx` and `Tx` configured as inverted |
| 74 | + |
| 75 | +For the `SP232ACP`, the important operating points are: |
| 76 | + |
| 77 | +- RS-232 receiver input range: `-15 V` to `+15 V` |
| 78 | +- receiver threshold region: roughly `0.8 V` to `2.4 V` |
| 79 | +- typical receiver switching points at `5 V`: about `1.2 V` low and `1.7 V` high |
| 80 | +- typical hysteresis: about `0.5 V` |
| 81 | +- RS-232 transmit swing: about `+/-6.5 V` typical, `+/-5.0 V` minimum into a `3 kOhm` load |
| 82 | + |
| 83 | +That inversion requirement is why an FT232-class adapter may appear to "work" electrically only after enabling inverted `Rx` and `Tx` in its EEPROM settings, or after placing a proper inverting line driver between the adapter and the plate. |
| 84 | + |
| 85 | +## Quick Start |
| 86 | + |
| 87 | +List ports: |
| 88 | + |
| 89 | +```powershell |
| 90 | +lhs-hotplate repl --list-ports |
| 91 | +``` |
| 92 | + |
| 93 | +Run the REPL: |
| 94 | + |
| 95 | +```powershell |
| 96 | +lhs-hotplate repl --port COM3 |
| 97 | +``` |
| 98 | + |
| 99 | +If you are working with a close variant that uses a different clock path, you can override the default `300` baud: |
| 100 | + |
| 101 | +```powershell |
| 102 | +lhs-hotplate repl --port COM3 --baud 600 |
| 103 | +``` |
| 104 | + |
| 105 | +Run the GUI: |
| 106 | + |
| 107 | +```powershell |
| 108 | +lhs-hotplate gui |
| 109 | +``` |
| 110 | + |
| 111 | +## Standalone Windows App |
| 112 | + |
| 113 | +This repo can also produce a standalone Windows GUI bundle that does not require a separate Python installation on the target machine. |
| 114 | + |
| 115 | +Build it from the project root with: |
| 116 | + |
| 117 | +```powershell |
| 118 | +.\packaging\windows\build_windows_app.ps1 |
| 119 | +``` |
| 120 | + |
| 121 | +If `PyInstaller` is not already installed in the selected Python environment, you can let the script install it automatically: |
| 122 | + |
| 123 | +```powershell |
| 124 | +.\packaging\windows\build_windows_app.ps1 -InstallBuildDeps |
| 125 | +``` |
| 126 | + |
| 127 | +The build script creates: |
| 128 | + |
| 129 | +- `release/windows-app/LHS-Dataplate-046440-Hotplate-Control-Panel\` |
| 130 | +- `release/windows-app/LHS-Dataplate-046440-Hotplate-Control-Panel.zip` |
| 131 | +- `release/windows-app/installer/*.msi` |
| 132 | + |
| 133 | +The packaged app entry point is: |
| 134 | + |
| 135 | +```text |
| 136 | +LHS-Dataplate-046440-Hotplate-Control-Panel.exe |
| 137 | +``` |
| 138 | + |
| 139 | +The installer artifact is a normal Windows MSI package that installs the app under `%LOCALAPPDATA%\Programs\LHS-Dataplate-046440-Hotplate-Control-Panel` and creates a Start Menu shortcut. |
| 140 | + |
| 141 | +## REPL Examples |
| 142 | + |
| 143 | +```text |
| 144 | +help |
| 145 | +help F |
| 146 | +help baud |
| 147 | +ports |
| 148 | +open COM3 |
| 149 | +baud |
| 150 | +baud 300 |
| 151 | +verify |
| 152 | +F |
| 153 | +k |
| 154 | +m |
| 155 | +a 100 |
| 156 | +A 50 46 |
| 157 | +hex 46 |
| 158 | +ascii F |
| 159 | +bytes 0x46 |
| 160 | +``` |
| 161 | + |
| 162 | +Inside the REPL, `baud` shows the current rate and `baud 600` changes it. The default remains `300` baud because that is what the tested Cole-Parmer `04644` uses. |
| 163 | + |
| 164 | +## CSV Program Format |
| 165 | + |
| 166 | +Programs are saved as CSV with these columns: |
| 167 | + |
| 168 | +```text |
| 169 | +offset_s,plate_c,probe_c,stir_rpm,ramp_c_per_hour,comment |
| 170 | +``` |
| 171 | + |
| 172 | +See [examples/sample_program.csv](examples/sample_program.csv). |
| 173 | + |
| 174 | +## Documentation |
| 175 | + |
| 176 | +- [Protocol reference](docs/PROTOCOL.md) |
| 177 | +- [Reverse-engineering status](docs/REVERSE_ENGINEERING_STATUS.md) |
| 178 | +- [Annotated ROM notes](docs/disassembly/ANNOTATION_SUMMARY.md) |
| 179 | +- [Annotated ROM listing](docs/disassembly/plate_rom_annotated.DIS) |
| 180 | + |
| 181 | +## Safety |
| 182 | + |
| 183 | +This software can control a heater and stir motor. Review commands carefully, verify limits on your specific instrument, and supervise early tests. This project is not affiliated with or endorsed by the instrument manufacturers. |
0 commit comments