Writing Unsigned 32bit Integers to Modbus TCP Slave

Hi all,

I'm reading modbus registers with U16 (Unsigned integer of 16-bit), U32, U64, S16 (Signed integer of 16-bit) and S32 integers and it's all working pretty well (except U64 ones, but I can deal with those later). The trouble is with writing data to some registers. I can, for example, write U16 registers successfully but am having trouble with U32.

Take register 40036 as an example. It is 2 bytes, Read-Write supported and U32. I can read the value in this register just fine. Home Assistant can write new values to this register just fine too. I just can't seem to write to this register with Node-RED.

An example message is {"value":15300,"fc":6,"unitid":247,"address":40036,"quantity":2}

I've tried sending different values such as "15300", [0,15300], [0,0,59,196] and so on.

The error I get is: Error: Modbus exception 2: Illegal data address (register not supported by device)

I've searched and reviewed various other posts (including Writing 16bit/32 bit Signed Integers to Modbus TCP server on NodeRed) without luck.

[{"id":"2201f0b734fea824","type":"buffer-maker","z":"11d169a832e66cd4","name":"","specification":"spec","specificationType":"ui","items":[{"name":"item1","type":"uint32be","length":1,"dataType":"msg","data":"payload"}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","x":790,"y":3000,"wires":[["43f5d323c10f84df","e1a8d2d69bfd1226"]]},{"id":"e1a8d2d69bfd1226","type":"buffer-parser","z":"11d169a832e66cd4","name":"","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"uint16be","name":"data","offset":0,"length":2,"offsetbit":0,"scale":"1","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"value","resultTypeType":"output","multipleResult":true,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":990,"y":3000,"wires":[["a4e60b16523c27fb","aebe9ede.e25cf"]]},{"id":"2945b34038e247e4","type":"inject","z":"11d169a832e66cd4","name":"15200","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"write","payload":"15200","payloadType":"num","x":610,"y":3000,"wires":[["2201f0b734fea824"]]},{"id":"bd4625724d13ca31","type":"inject","z":"11d169a832e66cd4","name":"15300","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"write","payload":"15300","payloadType":"num","x":610,"y":2960,"wires":[["2201f0b734fea824"]]},{"id":"aebe9ede.e25cf","type":"modbus-write","z":"11d169a832e66cd4","name":"40036","showStatusActivities":false,"showErrors":true,"showWarnings":true,"unitid":"247","dataType":"HoldingRegister","adr":"40036","quantity":"1","server":"6f01e8e3a69bfa2f","emptyMsgOnFail":false,"keepMsgProperties":false,"delayOnStart":false,"startDelayTime":"","x":1170,"y":3000,"wires":[[],[]]},{"id":"6f01e8e3a69bfa2f","type":"modbus-client","name":"SigenStor","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":false,"queueLogEnabled":false,"failureLogEnabled":true,"tcpHost":"192.168.1.33","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","serialAsciiResponseStartDelimiter":"0x3A","unit_id":1,"commandDelay":1,"clientTimeout":1000,"reconnectOnTimeout":true,"reconnectTimeout":2000,"parallelUnitIdsAllowed":true,"showErrors":false,"showWarnings":true,"showLogs":true}]

I need to also write signed 32 bit values, but seeking to resolve this issue first.

Just in case it is helpful, this is how Home Assistant writes to register 40036 (successfully):

      - action: modbus.write_register
        data_template:
          hub: Sigen
          slave: 247
          address: 40036
          value:
            - >-
              {{ (states('input_text.set_sigen_pv_max_power_limit')| float * 1000) |
              round(0) | int // 2**16 }}
            - >-
              {{ (states('input_text.set_sigen_pv_max_power_limit')| float * 1000) |
              round(0) | int % 2**16 }}

Figured it out. I need FC 16.

1 Like