Modbus Server not working

I am using the Modbus Flex Server from node-red-contrib-modbus. I want to create a modbus client so an industrial PLC can read a Zigbee device.
I can see some topic about this back in 2019, I am not sure if anyone if using it nowadays.

I imported the example and it works. Next I created my own Flex Server node, configured it to 127.0.0.1 port: 505, unit-id: 1. I am only setting holding registers.
Next I created a Flex getter to read the holding registers.
Everything is active, green, the server accepts updates, but when I trigger the flex getter nothing happens. Nothing is returned, no errors. I also have a catch node and Queue info as well, and they are all dead. Like the inject message is just lost.

Any ideas?

Hi .. can you try a Bind Address 0.0.0.0 instead of 127.0.0.1 for the server ?

Unfortunately did not help.

What is also strange, that I update registers with the top message (holding register 4 with a value of 150), but when I look at the register dump on the output, the registers are still all zero:

Seems to be working fine for me .. here is an example Flow i just tested

Flow : (credit for the subroutine call part goes to Steve-Mcl)
** you need to change the Modbus Read Config to match your IP

[{"id":"937cb040.d8e16","type":"tab","label":"Modbus Buffer Servers","disabled":false,"info":"simple flows to show what you \ncan do with the package\n\nthink about organization of reads and \nwrites and try to simplify these flows"},{"id":"2e869ad80ee4016b","type":"group","z":"937cb040.d8e16","name":"SUBROUTINE: Convert 1 Float to a UINT value for ModBus","style":{"stroke":"#0070c0","fill":"#bfdbef","label":true,"color":"#000000"},"nodes":["06e8463bb48c80ad","ba82d013eccbe4fc","651d03f969ae5789","ac4640d4f6ddc59c"],"x":114,"y":639,"w":782,"h":82},{"id":"a58ce8e2.9210d8","type":"debug","z":"937cb040.d8e16","name":"coils Buffer","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":760,"y":140,"wires":[]},{"id":"c45f9a38fafeea33","type":"debug","z":"937cb040.d8e16","name":"holding Buffer","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":770,"y":100,"wires":[]},{"id":"3ebf4334ff738f57","type":"debug","z":"937cb040.d8e16","name":"discrete inputs Buffer","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":790,"y":220,"wires":[]},{"id":"c85cf54d3f04b905","type":"debug","z":"937cb040.d8e16","name":"input Buffer","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":760,"y":180,"wires":[]},{"id":"67da3b9c4e798a0b","type":"debug","z":"937cb040.d8e16","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":705,"y":280,"wires":[],"l":false},{"id":"2027c3dacc40fb15","type":"inject","z":"937cb040.d8e16","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"-123","payloadType":"num","x":190,"y":160,"wires":[["9cecfc46858d01f2"]]},{"id":"6ef8309b782c54cb","type":"debug","z":"937cb040.d8e16","name":"debug 35","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":315,"y":140,"wires":[],"l":false},{"id":"06e8463bb48c80ad","type":"link in","z":"937cb040.d8e16","g":"2e869ad80ee4016b","name":"Float to UINT","links":[],"x":155,"y":680,"wires":[["651d03f969ae5789"]]},{"id":"ba82d013eccbe4fc","type":"link out","z":"937cb040.d8e16","g":"2e869ad80ee4016b","name":"link out 41","mode":"return","links":[],"x":855,"y":680,"wires":[]},{"id":"651d03f969ae5789","type":"buffer-maker","z":"937cb040.d8e16","g":"2e869ad80ee4016b","name":"Convert 1 float to a buffer","specification":"spec","specificationType":"ui","items":[{"name":"item1","type":"int32be","length":1,"dataType":"msg","data":"payload"}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","x":330,"y":680,"wires":[["ac4640d4f6ddc59c"]]},{"id":"ac4640d4f6ddc59c","type":"buffer-parser","z":"937cb040.d8e16","g":"2e869ad80ee4016b","name":"Buffer to UINT","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"uint8","name":"item1","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"uint8","name":"item2","offset":1,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"uint8","name":"item3","offset":2,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"uint8","name":"item4","offset":3,"length":1,"offsetbit":0,"scale":"1","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"value","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":true,"setTopic":false,"outputs":1,"x":640,"y":680,"wires":[["ba82d013eccbe4fc"]]},{"id":"f594dc8cbd89b61e","type":"modbus-read","z":"937cb040.d8e16","name":"","topic":"","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"showWarnings":true,"unitid":"1","dataType":"HoldingRegister","adr":"0","quantity":"10","rate":"3","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"644cb5f29bb9a4f8","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":210,"y":460,"wires":[["6f86aebe1f9f82e9"],[]]},{"id":"4295ae7bfd9a13a8","type":"debug","z":"937cb040.d8e16","name":"debug 63","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":600,"y":480,"wires":[]},{"id":"a3172ada7e689fc0","type":"modbus-server","z":"937cb040.d8e16","name":"","logEnabled":false,"hostname":"0.0.0.0","serverPort":"502","responseDelay":100,"delayUnit":"ms","coilsBufferSize":10000,"holdingBufferSize":10000,"inputBufferSize":10000,"discreteBufferSize":10000,"showErrors":false,"x":540,"y":200,"wires":[["c45f9a38fafeea33"],["a58ce8e2.9210d8"],["c85cf54d3f04b905"],["3ebf4334ff738f57"],["67da3b9c4e798a0b"]]},{"id":"6f86aebe1f9f82e9","type":"buffer-parser","z":"937cb040.d8e16","name":"","data":"responseBuffer.buffer","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"int32be","name":"item1","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":410,"y":480,"wires":[["4295ae7bfd9a13a8"]]},{"id":"9cecfc46858d01f2","type":"link call","z":"937cb040.d8e16","name":"","links":["06e8463bb48c80ad"],"linkType":"static","timeout":"30","x":295,"y":200,"wires":[["6ef8309b782c54cb","ed4b47b45d78c3cc"]],"l":false},{"id":"ed4b47b45d78c3cc","type":"function","z":"937cb040.d8e16","name":"","func":"\nmsg.payload = {\n    'value': msg.payload,\n    'register': 'holding',\n    'address': 0,\n    'disableMsgOutput': 0\n};\n\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":355,"y":200,"wires":[["a3172ada7e689fc0"]],"l":false},{"id":"b83ead4a63c6fe76","type":"inject","z":"937cb040.d8e16","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"456","payloadType":"num","x":190,"y":240,"wires":[["9cecfc46858d01f2"]]},{"id":"644cb5f29bb9a4f8","type":"modbus-client","name":"","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":false,"queueLogEnabled":false,"failureLogEnabled":true,"tcpHost":"192.168.0.7","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}]

Can you share your flow to test ??

[EDIT]
I think you are right .. something is wrong with the Server nodes .. i tested again but this time i wrote to Register 4 instead of 0 as the above test and the values are not written to the correct address.

[EDIT2]
Found a related Issue open on the node's Github, in case you want to drop a line to the developer confirming the bug (link)

Instead of sending values to the server, use modbus write/setter nodes to set the registers of your server - it works. I did a post some time ago but can't find it.

2 Likes

Steve's method works :+1:

Updated the Test Flow to include a Modbus Write node instead

[{"id":"a58ce8e2.9210d8","type":"debug","z":"937cb040.d8e16","name":"coils Buffer","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":900,"y":100,"wires":[]},{"id":"c45f9a38fafeea33","type":"debug","z":"937cb040.d8e16","name":"holding Buffer","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":910,"y":60,"wires":[]},{"id":"3ebf4334ff738f57","type":"debug","z":"937cb040.d8e16","name":"discrete inputs Buffer","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":930,"y":180,"wires":[]},{"id":"c85cf54d3f04b905","type":"debug","z":"937cb040.d8e16","name":"input Buffer","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":900,"y":140,"wires":[]},{"id":"67da3b9c4e798a0b","type":"debug","z":"937cb040.d8e16","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":845,"y":240,"wires":[],"l":false},{"id":"2027c3dacc40fb15","type":"inject","z":"937cb040.d8e16","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"-123","payloadType":"num","x":130,"y":240,"wires":[["9cecfc46858d01f2"]]},{"id":"6ef8309b782c54cb","type":"debug","z":"937cb040.d8e16","name":"debug 35","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":285,"y":220,"wires":[],"l":false},{"id":"f594dc8cbd89b61e","type":"modbus-read","z":"937cb040.d8e16","name":"","topic":"","showStatusActivities":true,"logIOActivities":false,"showErrors":true,"showWarnings":true,"unitid":"1","dataType":"HoldingRegister","adr":"4","quantity":"2","rate":"3","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"644cb5f29bb9a4f8","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":210,"y":440,"wires":[["6f86aebe1f9f82e9"],[]]},{"id":"4295ae7bfd9a13a8","type":"debug","z":"937cb040.d8e16","name":"debug 63","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":600,"y":460,"wires":[]},{"id":"6f86aebe1f9f82e9","type":"buffer-parser","z":"937cb040.d8e16","name":"","data":"responseBuffer.buffer","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"int16be","name":"item1","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":410,"y":460,"wires":[["4295ae7bfd9a13a8"]]},{"id":"9cecfc46858d01f2","type":"link call","z":"937cb040.d8e16","name":"","links":["06e8463bb48c80ad"],"linkType":"static","timeout":"30","x":255,"y":280,"wires":[["6ef8309b782c54cb","ed4b47b45d78c3cc"]],"l":false},{"id":"ed4b47b45d78c3cc","type":"function","z":"937cb040.d8e16","name":"","func":"\nmsg.payload = {\n    value: msg.payload,\n    'fc': 6,\n    'unitid': 1,\n    'address': 4,\n    'quantity': 1\n}\n\nreturn msg","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":355,"y":280,"wires":[["6985a227346dfea0"]],"l":false},{"id":"b83ead4a63c6fe76","type":"inject","z":"937cb040.d8e16","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"252","payloadType":"num","x":130,"y":320,"wires":[["9cecfc46858d01f2"]]},{"id":"6985a227346dfea0","type":"modbus-flex-write","z":"937cb040.d8e16","name":"","showStatusActivities":true,"showErrors":true,"showWarnings":true,"server":"644cb5f29bb9a4f8","emptyMsgOnFail":false,"keepMsgProperties":false,"delayOnStart":false,"startDelayTime":"","x":510,"y":280,"wires":[[],[]]},{"id":"f498667f45ddcea6","type":"modbus-flex-server","z":"937cb040.d8e16","name":"","logEnabled":false,"serverAddress":"0.0.0.0","serverPort":"10502","responseDelay":100,"unitId":1,"delayUnit":"ms","coilsBufferSize":"200","registersBufferSize":"200","minAddress":0,"splitAddress":"100","funcGetCoil":"function getFlexCoil(addr, unitID) {\n\tif (unitID === node.unitId && \n\t\taddr >= node.minAddress && \n\t\taddr <= node.splitAddress) { \n\n\t\treturn node.coils.readUInt8(addr * node.bufferFactor) \n\t}  \n}","funcGetDiscreteInput":"function getFlexDiscreteInput(addr, unitID) {\n\taddr += node.splitAddress\n\tif (unitID === node.unitId && \n\t\taddr >= node.splitAddress && \n\t\taddr <= node.splitAddress * 2) { \n\n\t\treturn node.coils.readUInt8(addr * node.bufferFactor) \n\t}  \n}","funcGetInputRegister":"function getFlexInputRegister(addr, unitID) { \n\tif (unitID === node.unitId && \n\t\taddr >= node.minAddress && \n\t\taddr <= node.splitAddress) { \n\n\t\treturn node.registers.readUInt16BE(addr * node.bufferFactor)  \n\t} \n}","funcGetHoldingRegister":"function getFlexHoldingRegsiter(addr, unitID) { \n\taddr += node.splitAddress\n\tif (unitID === node.unitId && \n\t\taddr >= node.splitAddress && \n\t\taddr <= node.splitAddress * 2) { \n\n\t\treturn node.registers.readUInt16BE(addr * node.bufferFactor)  \n\t} \n}","funcSetCoil":"function setFlexCoil(addr, value, unitID) { \n\tif (unitID === node.unitId && \n\t\taddr >= node.minAddress && \n\t\taddr <= node.splitAddress) { \n\n\t\tnode.coils.writeUInt8(value, addr * node.bufferFactor)  \n\t} \n}","funcSetRegister":"function setFlexRegister(addr, value, unitID) { \n\taddr += node.splitAddress\n\tif (unitID === node.unitId && \n\t\taddr >= node.splitAddress && \n\t\taddr <= node.splitAddress * 2) { \n\n\t\tnode.registers.writeUInt16BE(value, addr * node.bufferFactor)  \n\t} \n}","showErrors":false,"x":640,"y":120,"wires":[["c45f9a38fafeea33"],["a58ce8e2.9210d8"],["c85cf54d3f04b905"],["3ebf4334ff738f57"],["67da3b9c4e798a0b"]]},{"id":"2e869ad80ee4016b","type":"group","z":"937cb040.d8e16","name":"SUBROUTINE: Convert to a UINT value for ModBus","style":{"stroke":"#0070c0","fill":"#bfdbef","label":true,"color":"#000000"},"nodes":["06e8463bb48c80ad","ba82d013eccbe4fc","651d03f969ae5789","ac4640d4f6ddc59c"],"x":44,"y":619,"w":782,"h":82},{"id":"06e8463bb48c80ad","type":"link in","z":"937cb040.d8e16","g":"2e869ad80ee4016b","name":"Float to UINT","links":[],"x":85,"y":660,"wires":[["651d03f969ae5789"]]},{"id":"ba82d013eccbe4fc","type":"link out","z":"937cb040.d8e16","g":"2e869ad80ee4016b","name":"link out 41","mode":"return","links":[],"x":785,"y":660,"wires":[]},{"id":"651d03f969ae5789","type":"buffer-maker","z":"937cb040.d8e16","g":"2e869ad80ee4016b","name":"Convert 1 int to a buffer","specification":"spec","specificationType":"ui","items":[{"name":"item1","type":"int16be","length":1,"dataType":"msg","data":"payload"}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","x":260,"y":660,"wires":[["ac4640d4f6ddc59c"]]},{"id":"ac4640d4f6ddc59c","type":"buffer-parser","z":"937cb040.d8e16","g":"2e869ad80ee4016b","name":"Buffer to UINT","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"uint16be","name":"item1","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"value","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":true,"setTopic":false,"outputs":1,"x":570,"y":660,"wires":[["ba82d013eccbe4fc"]]},{"id":"644cb5f29bb9a4f8","type":"modbus-client","name":"","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":false,"queueLogEnabled":false,"failureLogEnabled":true,"tcpHost":"127.0.0.1","tcpPort":"10502","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":false,"reconnectTimeout":"2000","parallelUnitIdsAllowed":true,"showErrors":false,"showWarnings":true,"showLogs":true}]

The Subroutine part may not be needed if you are not planning to send negative values

1 Like

Thanks a lot, this seems to be working for me as well. Let me play around with it a bit more...

When I read the documentation of the Flex Server node it says it is for testing. But I assume it is working as a proper modbus client and could be used in production setting as well.

Also want to test if it works fine by having multiple Flex Servers on the same port with different unit IDs.