Skip to content

Add Eurotherm 2200, 2400, 3216, 3500 and EPC3000 temperature controllers - #5

Open
seb5g wants to merge 10 commits into
masterfrom
feature/eurotherm-drivers
Open

seb5g wants to merge 10 commits into
masterfrom
feature/eurotherm-drivers

Conversation

@seb5g

@seb5g seb5g commented Oct 12, 2026 •

Copy link
Copy Markdown

Before: Eurotherm controllers were only usable through the nupylab drivers (GitHub only, built on minimalmodbus, GPLv3), which pymodaq_plugins_eurotherm depends on, or through ad-hoc pymodbus code for the EPC3008.

After: from pymeasure.instruments.eurotherm import Eurotherm2200, Eurotherm2400, Eurotherm3216, Eurotherm3500, EurothermEPC3000 gives pymeasure-native drivers, usable with any pymeasure adapter and testable with expected_protocol. Serial links use Modbus RTU, Ethernet (TCPIP::<ip>::502::SOCKET) uses Modbus TCP.

How: EurothermBase(Instrument) implements Modbus (functions 0x03 and 0x10) over write_bytes/read_bytes, with RTU framing (CRC16) or TCP framing (MBAP header), chosen from the resource string or the tcp argument. Commands are "<kind>,<address>[,<value>]" with kind I (16-bit register), F (float) or T (time in s); floats and times go to the IEEE region (0x8000 + 2*address). Properties are regular Instrument.control/measurement. 3216 program segments, 2400 setpoints, programs and their segments, and the two 3500 loops are Channels whose address offset is applied in insert_id (nested for program → segment).

Adélaïs Bruel (PID registers, plugin logic) and Pierre-Anne Bausson (3500 register map) are added to AUTHORS.txt.

Setpoints and EEPROM: the Eurotherm manuals limit the non-volatile memory to about 100,000 writes and recommend the remote (comms) setpoint for changing values. The docstrings say so, and remote_setpoint is available on the 2200, 2400, 3216 and EPC3000 (alternative_setpoint on the 3500 loops). Its address is confirmed for the 3216 (26, rewrite within 5 s) and the EPC3000 (277, rewrite every second); for the 2200, 2400 and 3500 it is inferred and marked as such.

Notes:

  • Code was written from scratch (nupylab is GPLv3, pymeasure is MIT); only the register map / parameter selection follows nupylab, credited in the docstring. The EPC3000 register map follows the MIT-licensed EPC3008 plugin of LNicolasOnera/pymodaq_plugins_eurotherm, also credited. The 3500 register map (loop 2 at loop 1 + 1024) follows the MIT-licensed 3500 driver of PABausson/pymodaq_plugins_eurotherm, also credited.
  • RTU test frames were generated with minimalmodbus, TCP test frames with pymodbus. Not yet tested on hardware.
  • The EPC3000 driver reads floats from the IEEE region, whereas the EPC3008 plugin read scaled 16-bit integers; to check on hardware.
  • 2400 program_status: nupylab uses 1 reset, 2 run, 4 hold, 8 holdback, 16 complete, while lapkindm/eurotherm2000 uses 0 reset, 1 run, 2 hold, 3 complete for the same register. The driver follows nupylab; which one is right is not confirmed and could not be tested, as the docstring warns.
  • The 3500 driver reads floats from the IEEE region instead of scaled integers; manual_output (3) and the loop 2 rate limit disable (1102) are inferred.
  • 2400 programs/segments are created statically (programs 0-20, 16 segments each) instead of being discovered from the instrument at init, to keep the constructor communication-free.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DEVtMjKj8sTCBv7uiR4gzQ


Generated by Claude Code

seb5g and others added 3 commits October 12, 2026 12:45
Modbus RTU drivers built on Instrument, with a shared EurothermBase
handling framing, CRC and the IEEE register region for floats and times.
Segments, programs and setpoints are exposed as channels.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DEVtMjKj8sTCBv7uiR4gzQ
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DEVtMjKj8sTCBv7uiR4gzQ
EurothermBase now frames requests as Modbus TCP when the adapter is a
TCPIP resource (or tcp=True), Modbus RTU otherwise. EurothermEPC3000
uses the register map of the EPC3008 PyMoDAQ plugin by LNicolasOnera.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DEVtMjKj8sTCBv7uiR4gzQ
@seb5g seb5g changed the title Add Eurotherm 2200, 2400 and 3216 temperature controllers Add Eurotherm 2200, 2400, 3216 and EPC3000 temperature controllers Oct 12, 2026

seb5g commented Oct 12, 2026

Copy link
Copy Markdown
Author

"Code Coverage on codecov" fails at the upload step, not in the tests: Codecov answers Token required because branch is protected. This fork has no CODECOV_TOKEN secret, so the upload will fail for any PR here; nothing in this PR can fix it. The test suite itself passed in that job, and Lint/Type Check and Docs are green on the current head. It should pass once the PR is opened against pymeasure/pymeasure, which has the token.


Generated by Claude Code

seb5g and others added 2 commits October 12, 2026 15:09
Proportional band, integral and derivative times, at the addresses used
by the adelaisbruel/pymodaq_plugins_eurotherm plugin.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DEVtMjKj8sTCBv7uiR4gzQ
…s values

The 3500 register map follows PABausson/pymodaq_plugins_eurotherm (MIT).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DEVtMjKj8sTCBv7uiR4gzQ
@seb5g seb5g changed the title Add Eurotherm 2200, 2400, 3216 and EPC3000 temperature controllers Add Eurotherm 2200, 2400, 3216, 3500 and EPC3000 temperature controllers Oct 12, 2026
Co-authored-by: Adélaïs Bruel <adelais.bruel@gmail.com>
Co-authored-by: Pierre-Anne Bausson <bausson.pierreanne@gmail.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DEVtMjKj8sTCBv7uiR4gzQ
@seb5g
seb5g marked this pull request as ready for review October 12, 2026 18:16
claude and others added 4 commits October 12, 2026 18:35
Every test is marked UNVERIFIED (non-strict xfail) until it passed on a real
controller; each file carries a verification record to fill in.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DEVtMjKj8sTCBv7uiR4gzQ
Eurotherm manuals limit non-volatile memory to about 100,000 write cycles and
recommend the remote (communications) setpoint for changing values. Add it
to the 2200, 2400 and EPC3000 and the alternative setpoint to the 3500 loops,
with the addresses not confirmed by a manual marked as such.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DEVtMjKj8sTCBv7uiR4gzQ
- Remove @Unverified from 22 passing tests on EPC3000 controller
- Add hardware verification record: 2026-11-05, Axel, EPC3000, TCP 134.157.58.62
- test_ramp_units remains @Unverified: register 531 is read-only on this model

Co-authored-by: Junie <junie@jetbrains.com>
Verify Eurotherm EPC3000 driver on real hardware (22/23 tests passed)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants