Therma TH 9XRP Modbus register map
Also covers TH 90RP, TH 91RP, TH 92RP, TH 93RP
Programmable temperature controller (ramps and soaks), heating and cooling: process value, set points, alarms, PID settings, control outputs, program execution and serial settings
- Official
- 91 registers
- Modbus RTU
- Revision 1 · 2026-11-10
Official: Written from the manufacturer's documentation, but not tested on a device yet. Check the map against the manufacturer's documentation before you write to a live device. Tested it? Report a test.
Communication
- Protocol
- Modbus RTU
- Unit ID
- 1
- Serial
- 9600 8N1 · 9600 baud, 8 data bits, none parity, 1 stop bit
- Byte / word order
- ABCD · bytes big-endian, words high first
- Addresses
- 1-based · wire address = address − 1
Connection values are defaults: the device may be configured differently.
Map
- Registers
- 91 holding registers
- Groups
- 7
- Translation tables
- 2
- Revision
- 1 · 2026-11-10
- Added
- ()
- File
- maps/therma/th9xrp.mbmap.json · 18 KB · history
- SHA-256
- 43ce0c0ec8ffc47024485a092bd682af1f46935dc4fa3901a5fbd9792be3efce
- Manufacturer
- therma.com.br
Sources and notes
- Controladores Programadores para Aquecimento e Resfriamento, TH 90 RP / 91 RP / 92 RP / 93 RP (Manual de Operação) · version 8ª edição 06/2025, 2025-06 linked in issue #121; table of register addresses, pages 39 to 42
Source: Controladores Programadores para Aquecimento e Resfriamento TH 90 RP, TH 91 RP, TH 92 RP, TH 93 RP (Manual de Operação), 8ª edição 06/2025
- Modbus RTU on the optional RS-485 port (controllers ordered with serial communication). The manual lists registers as 40001 to 40091 (function codes 03, 06 and 16); they are numbered from 1 here, so address 40001 is register 1 and address_base is 1. The manual does not name the factory baud rate, parity or controller number: 9600, no parity and 1 are placeholders. Options are 2400, 4800 or 9600 bit/s, no, odd or even parity, 8 data bits and 1 stop bit.
- Values are 16-bit integers, signed where the range includes negative numbers. The manual does not say how decimals are sent: fields with a decimal point (for example some input types) are probably sent without it, so check against the display before applying a scale.
- Packed BCD registers (ALD, SETi, SETL, CFPR and AL xy) hold one digit per alarm relay (A = AL1, B = AL2, C = AL3, D unused) and are read in hexadecimal. Registers 40035, 40038, 40049, 40050, 40069 and 40070 are internal or reserved and are not listed.
- The serial ID range is 1 to 63 in the register table and 1 to 31 in the parameter description. The parity code order (0 = none, 1 = even, 2 = odd) differs from the TH 9XMP manual.
- Registers 40071 to 40088 apply only to programmable (ramp and soak) controllers. Registers 40083 to 40088 act on the segment chosen with PTN and SEGC.
- Written from the manufacturer's manual; not tested on a device.
| Area | Address | Name | Type | Access | Unit | Scale | Description |
|---|---|---|---|---|---|---|---|
| HR | 1 | int16 | R | Measured value; decimals depend on the input type (see notes) | |||
| HR | 2 | int16 | RW | Active set point, between LSPL and USPL | |||
| HR | 3 | int16 | RW | Alarm 1 set point; the allowed range depends on the alarm mode ALD1 | |||
| HR | 4 | int16 | RW | Alarm 2 set point; the allowed range depends on the alarm mode ALD2 | |||
| HR | 5 | int16 | RW | Alarm 3 set point; the allowed range depends on the alarm mode ALD3 | |||
| HR | 6 | uint16 | RW | 0 to 9999 | |||
| HR | 7 | bool bit 0 | R | ||||
| HR | 7 | bool bit 1 | R | ||||
| HR | 7 | bool bit 2 | R | ||||
| HR | 7 | bool bit 3 | R | ||||
| HR | 7 | bool bit 4 | R | ||||
| HR | 7 | bool bit 5 | R | ||||
| HR | 7 | bool bit 6 | R | ||||
| HR | 8 | uint16 | R | ||||
| HR | 9 | uint16 | R | % | Output level, 0 to 100 % | ||
| HR | 10 | uint16 | RW | Write 1 to store the settings written over Modbus; 0 = do not save | |||
| HR | 11 | uint16 | R | Remote set point, or the current set point of a programmable controller | |||
| HR | 12 | uint16 | R | Minutes left on a timed alarm (ALD = 9) | |||
| HR | 13 | uint16 | R | Minutes left on a timed alarm (ALD = 9) | |||
| HR | 14 | uint16 | R | Minutes left on a timed alarm (ALD = 9) | |||
| HR | 15 | uint16 | RW | ||||
| HR | 16 | uint16 | RW | Control output 1 percentage, 0 to 100 | |||
| HR | 17 | uint16 | RW | ||||
| HR | 18 | uint16 | RW | 0 to 3600 | |||
| HR | 19 | uint16 | RW | 0 to 900 | |||
| HR | 20 | uint16 | RW | ||||
| HR | 21 | uint16 | RW | 5 to 500 | |||
| HR | 22 | uint16 | RW | 0 to 10 | |||
| HR | 23 | uint16 | RW | 0 to 2000 | |||
| HR | 24 | uint16 | RW | 0 to 3600 | |||
| HR | 25 | uint16 | RW | 0 to 900 | |||
| HR | 26 | uint16 | RW | ||||
| HR | 27 | uint16 | RW | 0 to 100, or 0 to 10.0 with a decimal input | |||
| HR | 28 | uint16 | RW | 0 to 100, or 0 to 10.0 with a decimal input | |||
| HR | 29 | uint16 | RW | Control output 2 percentage, 0 to 100 | |||
| HR | 30 | uint16 | R | % | Output 2 level, 0 to 100 % | ||
| HR | 31 | uint16 | RW | ||||
| HR | 32 | int16 | RW | Lower end of the measuring range | |||
| HR | 33 | int16 | RW | Upper end of the measuring range | |||
| HR | 34 | uint16 | RW | ||||
| HR | 36 | uint16 | RW | 0 to 100 | |||
| HR | 37 | uint16 | RW | 0 to 100 | |||
| HR | 39 | uint16 | RW | Packed BCD, read as hex: one digit per alarm relay (A = AL1, B = AL2, C = AL3, D unused) | |||
| HR | 40 | uint16 | RW | Packed BCD, read as hex: one digit per alarm relay (A = AL1, B = AL2, C = AL3, D unused) | |||
| HR | 41 | uint16 | RW | Packed BCD, read as hex: one digit per alarm relay (A = AL1, B = AL2, C = AL3, D unused) | |||
| HR | 42 | uint16 | RW | 0 to 1000 | |||
| HR | 43 | uint16 | RW | 0 to 1000 | |||
| HR | 44 | uint16 | RW | 0 to 1000 | |||
| HR | 45 | uint16 | RW | ||||
| HR | 46 | uint16 | RW | ||||
| HR | 47 | uint16 | RW | ||||
| HR | 48 | int16 | RW | Between LSPL and USPL | |||
| HR | 51 | uint16 | RW | 0 to 5 | |||
| HR | 52 | int16 | RW | -1999 to +9999 | |||
| HR | 53 | int16 | RW | -1999 to +9999 | |||
| HR | 54 | uint16 | R | Ambient temperature reading, 0 to 50 | |||
| HR | 55 | uint16 | RW | 0 to 100 | |||
| HR | 56 | int16 | RW | Start of the analog input signal 1 | |||
| HR | 57 | int16 | RW | End of the analog input signal 1 | |||
| HR | 58 | int16 | RW | Start of the analog input signal 2 (remote) | |||
| HR | 59 | int16 | RW | End of the analog input signal 2 (remote) | |||
| HR | 60 | uint16 | RW | s | Closed-to-open time of the motor, 5 to 200 s | ||
| HR | 61 | uint16 | RW | Start of control analog output 1, 0 to 100 | |||
| HR | 62 | uint16 | RW | End of control analog output 1, 0 to 100 | |||
| HR | 63 | uint16 | RW | Start of control analog output 2, 0 to 100 | |||
| HR | 64 | uint16 | RW | End of control analog output 2, 0 to 100 | |||
| HR | 65 | uint16 | RW | 0 to 4095 | |||
| HR | 66 | uint16 | RW | 0 to 4095 | |||
| HR | 67 | uint16 | RW | ||||
| HR | 68 | uint16 | RW | ||||
| HR | 71 | uint16 | RW | Packed BCD, read as hex; see the manual | |||
| HR | 72 | uint16 | RW | 0 to 8 | |||
| HR | 73 | uint16 | R | ||||
| HR | 74 | uint16 | R | 0 to 8 | |||
| HR | 75 | uint16 | RW | 0 to 9999 | |||
| HR | 76 | uint16 | RW | ||||
| HR | 77 | uint16 | RW | Meaning of the pause function, see the manual | |||
| HR | 78 | uint16 | RW | Segment where the program starts | |||
| HR | 79 | uint16 | RW | ||||
| HR | 80 | uint16 | RW | ||||
| HR | 81 | uint16 | RW | 1 to 8 | |||
| HR | 82 | uint16 | RW | 1 to 8 | |||
| HR | 83 | int16 | RW | Set point of the selected segment | |||
| HR | 84 | uint16 | RW | 0 to 9999 | |||
| HR | 85 | uint16 | RW | 0 to 100 % | |||
| HR | 86 | uint16 | RW | 5 to 9999 | |||
| HR | 87 | uint16 | RW | Packed BCD, read as hex: one digit per alarm relay (A = AL1, B = AL2, C = AL3, D = 0) | |||
| HR | 88 | uint16 | RW | ||||
| HR | 89 | uint16 | RW | Controller number for the serial link; the table says 1 to 63, the text 1 to 31 | |||
| HR | 90 | uint16 | RW | ||||
| HR | 91 | uint16 | RW |
No registers match
Try part of the name, an address (decimal or 0x hex) or clear the filters.
Help improve this map
- I tested it on a deviceReport whether it worked, even if you did not write the map.
- Suggest a correctionEdit the file on GitHub; it opens a pull request.
- Report a problemA wrong address, type, scale or byte order.
- Read the formatWhat each key of the file means (SPEC.md).