Skip to content

Commit 4352c5c

Browse files
Prepare open-source release
0 parents  commit 4352c5c

22 files changed

Lines changed: 6038 additions & 0 deletions

‎.gitattributes‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
* text=auto eol=lf
2+
*.ps1 text eol=crlf

‎.github/workflows/tests.yml‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: tests
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
python:
9+
runs-on: ubuntu-latest
10+
strategy:
11+
fail-fast: false
12+
matrix:
13+
python-version: ["3.11", "3.12", "3.13"]
14+
steps:
15+
- uses: actions/checkout@v4
16+
- uses: actions/setup-python@v5
17+
with:
18+
python-version: ${{ matrix.python-version }}
19+
- run: python -m pip install --upgrade pip
20+
- run: python -m pip install -e . pytest
21+
- run: python -m pytest

‎.gitignore‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
__pycache__/
2+
*.pyc
3+
.venv/
4+
.pytest_cache/
5+
.ruff_cache/
6+
.mypy_cache/
7+
dist/
8+
build/
9+
release/
10+
*.egg-info/
11+
*.log
12+
*.jsonl
13+
*.tmp

‎LICENSE‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

‎README.md‎

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
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

Comments
 (0)