Problem writing into register (address invalid)

Hi,

I'm a Modbus newbie, who is trying to control a heating device remotely with a Python script. The device is connected via RS485 to an Elfin EE11, which acts as a Modbus server. I can connect to the server and read the necessary register values for example with this:

Code:
from pyModbusTCP.client import ModbusClient
c = ModbusClient(host="192.168.0.11", port=8899, auto_open=True)
regs = c.read_holding_registers(502, 2)
print (regs)
which returns [39, 65535]. The data type of the registers I'm trying to adjust is S32 so I figured that I would have to fetch two registers from the starting address.

However, I cannot write a new value to the register with
Code:
c.write_multiple_registers(502, [41, 65535])
which returns me an exception 2, which I've now understood is "invalid address".
I'm quite confused why the address is invalid as reading is successful. Can anyone help me out a bit?
 
What is the heating device you're trying to control? Do you have any Modbus documentation for it that you can share?

It's possible this could be due to an "off-by-one" issue with the register address you're trying to access, especially since it's a 32-bit register that you're trying to access. The device may not care if you read across two 32-bit registers, but when writing a 32-bit register it might return an error if you try to write across two 32-bit registers.

Standard Modbus notation uses 1-based register numbers, but what gets encoded into the Modbus packet is a 0-based register address. Because of this, some vendors use 1-based register numbers and others use 0-based register addresses.

Looking at the documenation, it appears that the pyModbusTCP library uses 0-based addressing. So if your heating device uses 1-based register numbers, you need to subtract 1 from the register number you're targeting.
 
The device is a district heat exchanger (Ouman H23) with two separate circuits for heating and warm water supply in my house. What I'm looking for is integrating it into my existing home-made home automation script to adjust the heating curve and circulated warm water temperature as needed.

This is the Modbus documentation I got from the manufacturer. The ones I know I need to adjust for heating are at 502, 506, 510, 514 and 516 and the warm water supply is controlled by 593.

https://drive.google.com/file/d/14OxhHWz7HI3RfpQFMIADC68gckGX7jAY/view?usp=sharing
 
Subtracting the register value by 1 causes an exception 3 instead of 2.
Code:
print (c.read_holding_registers(502, 2))
c.write_multiple_registers(501, [41, 65535])
print (c.read_holding_registers(502, 2))
This is the debug output from the Python shell for that script:
Code:
Tx
[E7 13 00 00 00 06 01] 03 01 F6 00 02
Rx
[E7 13 00 00 00 07 01] 03 04 00 27 FF FF

[39, 65535]

Tx
[43 72 00 00 00 0B 01] 10 01 F5 00 02 04 00 29 FF FF
Rx
[43 72 00 00 00 03 01] 90 03

except (code 3)

Tx
[33 04 00 00 00 06 01] 03 01 F6 00 02
Rx
[33 04 00 00 00 07 01] 03 04 00 27 FF FF

[39, 65535]
Writing into 502 shows this for that part:
Code:
Tx
[5F B1 00 00 00 0B 01] 10 01 F6 00 02 04 00 29 FF FF 
Rx
[5F B1 00 00 00 03 01] 90 02 
except (code 2)
 
Exception 3 is Illegal Data Value. The value you're writing is outside of the allowable range for that register.

According to your documentation, register 502 has a range from 0 - 99.

Try reading address 501 first, you will likely see [0, 39] for the values returned. Then if you write [0, 41], I suspect it will work.
 
Top