Errors in MODBUS RTU communication

Hello,

I have problems with reading data from 5 meters on the same modbus RTU databus in a Node-RED flow.

As a newbie in modbus and Node-RED I try setting up MODBUS RTU communication with 5 ABB energy meters connected to a UniPI.
Setup:

  • Modbus master UniPI Patron S117
  • Node-RED 2.2.2 (UniPI Node-RED image Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-43-generic x86_64))
  • node-red-contrib-modbus 5.22.0

I got a working setup tested with mbpoll. I used mbpoll to monitor the bus. At the same time I had Node-RED with one modbus-read node polling the same meter on another address. There where errors and lost packets, 5-10% loss. After adding a second modbus-read node for meter 2 problems started really with 20-30% errors and lost packets.

Now I think this was a problem: I created 2 (and even 3) modbus RTU servers on one RS485 bus. I got same errors in Node-RED and with mbpoll. These where the errors:

$ mbpoll -b 19200 -P none -l 6000 -a 3 -t 4 -c 1 -r 23341 /dev/ttyNS0

Read output (holding) register failed: Connection timed out
Read output (holding) register failed: Invalid data

I created this Flow in Node-RED with modbus-read, to read 5 meters but this does not work for more than one meter active at a time:

[
    {
        "id": "53429a3ba2715def",
        "type": "tab",
        "label": "Flow 3",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "9bcd90d2bc9a4618",
        "type": "modbus-read",
        "z": "53429a3ba2715def",
        "name": "meter 1",
        "topic": "",
        "showStatusActivities": true,
        "logIOActivities": false,
        "showErrors": true,
        "unitid": "3",
        "dataType": "HoldingRegister",
        "adr": "20480",
        "quantity": "32",
        "rate": "10",
        "rateUnit": "s",
        "delayOnStart": false,
        "startDelayTime": "",
        "server": "35802f02075a2a9a",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "x": 90,
        "y": 160,
        "wires": [
            [
                "4268dbfd68993c33"
            ],
            [
                "b61eda5a434fbaa7",
                "0c391b85dbabcb35"
            ]
        ],
        "info": "UniPI meter\n"
    },
    {
        "id": "b61eda5a434fbaa7",
        "type": "function",
        "z": "53429a3ba2715def",
        "name": "",
        "func": "//--KwH verbruik/levering----------------------------------------------\n\nlet VerbruikKWH = msg.payload.buffer.readUInt32BE(4,4)/10\n\n//--payload----------------------------------------------\nmsg.payload = [\n    {\n        VerbruikKWH: VerbruikKWH,\n    },\n    {\n        MeterId: 'meter 1',\n        Locatie: 'pump 1',\n        Locatiegroep: 'Huis'\n    },\n    { timestamp: Date.now()}\n];\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 460,
        "y": 140,
        "wires": [
            [
                "667c7527d88c4789",
                "de1767c1ba6dd238"
            ]
        ]
    },
    {
        "id": "667c7527d88c4789",
        "type": "influxdb out",
        "z": "53429a3ba2715def",
        "influxdb": "f95e408fa8fecc72",
        "name": "testdatabase",
        "measurement": "verbruik",
        "precision": "",
        "retentionPolicy": "",
        "database": "database",
        "precisionV18FluxV20": "ms",
        "retentionPolicyV18Flux": "",
        "org": "organisation",
        "bucket": "metingen",
        "x": 850,
        "y": 140,
        "wires": []
    },
    {
        "id": "0c391b85dbabcb35",
        "type": "debug",
        "z": "53429a3ba2715def",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 470,
        "y": 180,
        "wires": []
    },
    {
        "id": "de1767c1ba6dd238",
        "type": "debug",
        "z": "53429a3ba2715def",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 670,
        "y": 180,
        "wires": []
    },
    {
        "id": "744d1fbf533db838",
        "type": "comment",
        "z": "53429a3ba2715def",
        "name": "meters on RS485 ",
        "info": "",
        "x": 100,
        "y": 60,
        "wires": []
    },
    {
        "id": "068c8e79060ff51e",
        "type": "modbus-read",
        "z": "53429a3ba2715def",
        "name": "meter 2",
        "topic": "",
        "showStatusActivities": true,
        "logIOActivities": false,
        "showErrors": true,
        "unitid": "4",
        "dataType": "HoldingRegister",
        "adr": "20480",
        "quantity": "32",
        "rate": "10",
        "rateUnit": "s",
        "delayOnStart": false,
        "startDelayTime": "",
        "server": "35802f02075a2a9a",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "x": 90,
        "y": 320,
        "wires": [
            [],
            [
                "117d2ee4584929ed",
                "24a11a2b0b0d7901"
            ]
        ],
        "info": "UniPI meter woonhuis\n"
    },
    {
        "id": "117d2ee4584929ed",
        "type": "function",
        "z": "53429a3ba2715def",
        "name": "",
        "func": "//--KwH verbruik/levering----------------------------------------------\n\nlet VerbruikKWH = msg.payload.buffer.readUInt32BE(4,4)/10\n\n//--payload----------------------------------------------\nmsg.payload = [\n    {\n        VerbruikKWH: VerbruikKWH,\n    },\n    {\n        MeterId: 'meter 2',\n        Locatie: 'meter 2',\n        Locatiegroep: 'Huis'\n    },\n    { timestamp: Date.now()}\n];\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 460,
        "y": 300,
        "wires": [
            [
                "e4a75cb7c87718c8",
                "8e885febd8d13323"
            ]
        ]
    },
    {
        "id": "e4a75cb7c87718c8",
        "type": "influxdb out",
        "z": "53429a3ba2715def",
        "influxdb": "f95e408fa8fecc72",
        "name": "testdatabase",
        "measurement": "verbruik",
        "precision": "",
        "retentionPolicy": "",
        "database": "database",
        "precisionV18FluxV20": "ms",
        "retentionPolicyV18Flux": "",
        "org": "organisation",
        "bucket": "metingen",
        "x": 850,
        "y": 300,
        "wires": []
    },
    {
        "id": "24a11a2b0b0d7901",
        "type": "debug",
        "z": "53429a3ba2715def",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 465,
        "y": 345,
        "wires": []
    },
    {
        "id": "8e885febd8d13323",
        "type": "debug",
        "z": "53429a3ba2715def",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 670,
        "y": 340,
        "wires": []
    },
    {
        "id": "9be7f137e1a54d28",
        "type": "modbus-read",
        "z": "53429a3ba2715def",
        "name": "meter 3",
        "topic": "",
        "showStatusActivities": true,
        "logIOActivities": false,
        "showErrors": true,
        "unitid": "5",
        "dataType": "HoldingRegister",
        "adr": "20480",
        "quantity": "32",
        "rate": "10",
        "rateUnit": "s",
        "delayOnStart": false,
        "startDelayTime": "",
        "server": "35802f02075a2a9a",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "x": 90,
        "y": 500,
        "wires": [
            [],
            [
                "619ce5b0379bf3bc",
                "ca85091bc6f36065"
            ]
        ],
        "info": "UniPI meter woonhuis\n"
    },
    {
        "id": "619ce5b0379bf3bc",
        "type": "function",
        "z": "53429a3ba2715def",
        "name": "",
        "func": "//--KwH verbruik/levering----------------------------------------------\n\nlet VerbruikKWH = msg.payload.buffer.readUInt32BE(4,4)/10\n\n//--payload----------------------------------------------\nmsg.payload = [\n    {\n        VerbruikKWH: VerbruikKWH,\n    },\n    {\n        MeterId: 'meter 3',\n        Locatie: 'meter 3',\n        Locatiegroep: 'Huis'\n    },\n    { timestamp: Date.now()}\n];\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 380,
        "y": 460,
        "wires": [
            [
                "12db1e09e708af9e",
                "bb28e4fbc60231b9"
            ]
        ]
    },
    {
        "id": "12db1e09e708af9e",
        "type": "influxdb out",
        "z": "53429a3ba2715def",
        "influxdb": "f95e408fa8fecc72",
        "name": "testdatabase",
        "measurement": "verbruik",
        "precision": "",
        "retentionPolicy": "",
        "database": "database",
        "precisionV18FluxV20": "ms",
        "retentionPolicyV18Flux": "",
        "org": "organisation",
        "bucket": "metingen",
        "x": 765,
        "y": 465,
        "wires": []
    },
    {
        "id": "ca85091bc6f36065",
        "type": "debug",
        "z": "53429a3ba2715def",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 390,
        "y": 520,
        "wires": []
    },
    {
        "id": "bb28e4fbc60231b9",
        "type": "debug",
        "z": "53429a3ba2715def",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 590,
        "y": 520,
        "wires": []
    },
    {
        "id": "33f0140fe01e3a4c",
        "type": "modbus-read",
        "z": "53429a3ba2715def",
        "name": "meter 4",
        "topic": "",
        "showStatusActivities": true,
        "logIOActivities": false,
        "showErrors": true,
        "unitid": "6",
        "dataType": "HoldingRegister",
        "adr": "20480",
        "quantity": "32",
        "rate": "10",
        "rateUnit": "s",
        "delayOnStart": false,
        "startDelayTime": "",
        "server": "35802f02075a2a9a",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "x": 90,
        "y": 640,
        "wires": [
            [],
            [
                "72701aafbecfae83",
                "79d6ce1b01774bb0"
            ]
        ],
        "info": "UniPI meter woonhuis\n"
    },
    {
        "id": "72701aafbecfae83",
        "type": "function",
        "z": "53429a3ba2715def",
        "name": "",
        "func": "//--KwH verbruik/levering----------------------------------------------\n\nlet VerbruikKWH = msg.payload.buffer.readUInt32BE(4,4)/10\n\n//--payload----------------------------------------------\nmsg.payload = [\n    {\n        VerbruikKWH: VerbruikKWH,\n    },\n    {\n        MeterId: 'meter 4',\n        Locatie: 'meter 4',\n        Locatiegroep: 'Huis'\n    },\n    { timestamp: Date.now()}\n];\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 380,
        "y": 620,
        "wires": [
            [
                "25c212ade6b7a671",
                "9867645d64c2761d"
            ]
        ]
    },
    {
        "id": "25c212ade6b7a671",
        "type": "influxdb out",
        "z": "53429a3ba2715def",
        "influxdb": "f95e408fa8fecc72",
        "name": "testdatabase",
        "measurement": "verbruik",
        "precision": "",
        "retentionPolicy": "",
        "database": "database",
        "precisionV18FluxV20": "ms",
        "retentionPolicyV18Flux": "",
        "org": "organisation",
        "bucket": "metingen",
        "x": 765,
        "y": 625,
        "wires": []
    },
    {
        "id": "79d6ce1b01774bb0",
        "type": "debug",
        "z": "53429a3ba2715def",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 390,
        "y": 680,
        "wires": []
    },
    {
        "id": "9867645d64c2761d",
        "type": "debug",
        "z": "53429a3ba2715def",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 590,
        "y": 680,
        "wires": []
    },
    {
        "id": "c6af83ae70e3ba65",
        "type": "modbus-read",
        "z": "53429a3ba2715def",
        "name": "meter 5",
        "topic": "",
        "showStatusActivities": true,
        "logIOActivities": false,
        "showErrors": true,
        "unitid": "10",
        "dataType": "HoldingRegister",
        "adr": "20480",
        "quantity": "32",
        "rate": "10",
        "rateUnit": "s",
        "delayOnStart": false,
        "startDelayTime": "",
        "server": "35802f02075a2a9a",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "x": 90,
        "y": 780,
        "wires": [
            [],
            [
                "ab3e374dbd99d2cb",
                "fcbf47a60c9fa3ba"
            ]
        ],
        "info": "UniPI meter woonhuis\n"
    },
    {
        "id": "ab3e374dbd99d2cb",
        "type": "function",
        "z": "53429a3ba2715def",
        "name": "",
        "func": "//--KwH verbruik/levering----------------------------------------------\n\nlet VerbruikKWH = msg.payload.buffer.readUInt32BE(4,4)/10\n\n//--payload----------------------------------------------\nmsg.payload = [\n    {\n        VerbruikKWH: VerbruikKWH,\n    },\n    {\n        MeterId: 'meter 5',\n        Locatie: 'meter 5',\n        Locatiegroep: 'Huis'\n    },\n    { timestamp: Date.now()}\n];\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 380,
        "y": 760,
        "wires": [
            [
                "a272b3de45526689",
                "8671056946a266e7"
            ]
        ]
    },
    {
        "id": "a272b3de45526689",
        "type": "influxdb out",
        "z": "53429a3ba2715def",
        "influxdb": "f95e408fa8fecc72",
        "name": "testdatabase",
        "measurement": "verbruik",
        "precision": "",
        "retentionPolicy": "",
        "database": "database",
        "precisionV18FluxV20": "ms",
        "retentionPolicyV18Flux": "",
        "org": "organisation",
        "bucket": "metingen",
        "x": 765,
        "y": 765,
        "wires": []
    },
    {
        "id": "fcbf47a60c9fa3ba",
        "type": "debug",
        "z": "53429a3ba2715def",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 390,
        "y": 820,
        "wires": []
    },
    {
        "id": "8671056946a266e7",
        "type": "debug",
        "z": "53429a3ba2715def",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 590,
        "y": 820,
        "wires": []
    },
    {
        "id": "4268dbfd68993c33",
        "type": "modbus-response",
        "z": "53429a3ba2715def",
        "name": "",
        "registerShowMax": 20,
        "x": 470,
        "y": 80,
        "wires": []
    },
    {
        "id": "81ae7356b4f468d0",
        "type": "comment",
        "z": "53429a3ba2715def",
        "name": "Question method 1",
        "info": "",
        "x": 110,
        "y": 400,
        "wires": []
    },
    {
        "id": "73bb35cef124068f",
        "type": "comment",
        "z": "53429a3ba2715def",
        "name": "Question method 1",
        "info": "",
        "x": 110,
        "y": 20,
        "wires": []
    },
    {
        "id": "35802f02075a2a9a",
        "type": "modbus-client",
        "name": "",
        "clienttype": "simpleser",
        "bufferCommands": true,
        "stateLogEnabled": false,
        "queueLogEnabled": false,
        "failureLogEnabled": false,
        "tcpHost": "127.0.0.1",
        "tcpPort": "502",
        "tcpType": "TPC-RTU-BUFFERED",
        "serialPort": "/dev/ttymxc2",
        "serialType": "RTU-BUFFERD",
        "serialBaudrate": "19200",
        "serialDatabits": "8",
        "serialStopbits": "1",
        "serialParity": "none",
        "serialConnectionDelay": "100",
        "serialAsciiResponseStartDelimiter": "",
        "unit_id": "",
        "commandDelay": "1",
        "clientTimeout": "1000",
        "reconnectOnTimeout": true,
        "reconnectTimeout": "2000",
        "parallelUnitIdsAllowed": true
    },
    {
        "id": "f95e408fa8fecc72",
        "type": "influxdb",
        "hostname": "127.0.0.1",
        "port": "8086",
        "protocol": "http",
        "database": "database",
        "name": "Influxtestomgeving",
        "usetls": false,
        "tls": "",
        "influxdbVersion": "2.0",
        "url": "http://192.168.1.18:8086",
        "rejectUnauthorized": false
    }
]

Should this methode work? Is there an error in the flow?

I red every nodeRED forum question about modbus, searched on Youtube, on Stevesnoderedguide website. Lots of info about Modbus TCP, not very much to find about MODBUS RTU reading addresblocks on more than one modbus machine.

Most promising solution I found was on Stevesnoderedguide website. It`s this flow based on modbus-getter (I changed it to my situation but it doesn't work well). :

The flow:

[
    {
        "id": "ee3039d35ce6bda2",
        "type": "tab",
        "label": "Flow 4",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "abbeef16e43afeaf",
        "type": "comment",
        "z": "ee3039d35ce6bda2",
        "name": "Question method 2",
        "info": "",
        "x": 130,
        "y": 40,
        "wires": []
    },
    {
        "id": "fca3f10dc117d659",
        "type": "inject",
        "z": "ee3039d35ce6bda2",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": "2",
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 130,
        "y": 160,
        "wires": [
            [
                "6088b438b44933f3"
            ]
        ]
    },
    {
        "id": "6088b438b44933f3",
        "type": "modbus-getter",
        "z": "ee3039d35ce6bda2",
        "name": "",
        "showStatusActivities": false,
        "showErrors": false,
        "logIOActivities": false,
        "unitid": "3",
        "dataType": "HoldingRegister",
        "adr": "20480",
        "quantity": "8",
        "server": "bb5a04411cd75771",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "keepMsgProperties": false,
        "x": 320,
        "y": 160,
        "wires": [
            [
                "0b15cad3ad878289",
                "78d7eadd4558c3f5"
            ],
            [
                "44ecd192c08bb8e4"
            ]
        ]
    },
    {
        "id": "78d7eadd4558c3f5",
        "type": "switch",
        "z": "ee3039d35ce6bda2",
        "name": "Pull next data?",
        "property": "payload[0]",
        "propertyType": "msg",
        "rules": [
            {
                "t": "gt",
                "v": "0",
                "vt": "num"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 140,
        "y": 280,
        "wires": [
            [
                "956487fef4b0bb29"
            ]
        ]
    },
    {
        "id": "956487fef4b0bb29",
        "type": "modbus-getter",
        "z": "ee3039d35ce6bda2",
        "name": "",
        "showStatusActivities": false,
        "showErrors": false,
        "logIOActivities": false,
        "unitid": "6",
        "dataType": "HoldingRegister",
        "adr": "20480",
        "quantity": "8",
        "server": "bb5a04411cd75771",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "keepMsgProperties": false,
        "x": 320,
        "y": 280,
        "wires": [
            [
                "acdd320a145d31bf",
                "07413b42df7a11bf"
            ],
            [
                "500a0084370417be"
            ]
        ]
    },
    {
        "id": "44ecd192c08bb8e4",
        "type": "function",
        "z": "ee3039d35ce6bda2",
        "name": "",
        "func": "//--KwH verbruik/levering----------------------------------------------\n\nlet VerbruikKWH = msg.payload.buffer.readUInt32BE(4,4)/10\n\n//--payload----------------------------------------------\nmsg.payload = [\n    {\n        VerbruikKWH: VerbruikKWH,\n    },\n    {\n        MeterId: 'meter 1',\n        Locatie: 'meter 1',\n        Locatiegroep: 'Huis'\n    },\n    { timestamp: Date.now()}\n];\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 660,
        "y": 160,
        "wires": [
            [
                "e1166a7b054acd70",
                "b5c1d62a92aad00a"
            ]
        ]
    },
    {
        "id": "e1166a7b054acd70",
        "type": "influxdb out",
        "z": "ee3039d35ce6bda2",
        "influxdb": "749ea570d74a9941",
        "name": "testdatabase",
        "measurement": "verbruik",
        "precision": "",
        "retentionPolicy": "",
        "database": "database",
        "precisionV18FluxV20": "ms",
        "retentionPolicyV18Flux": "",
        "org": "organisation",
        "bucket": "metingen",
        "x": 870,
        "y": 160,
        "wires": []
    },
    {
        "id": "500a0084370417be",
        "type": "function",
        "z": "ee3039d35ce6bda2",
        "name": "",
        "func": "//--KwH verbruik/levering----------------------------------------------\n\nlet VerbruikKWH = msg.payload.buffer.readUInt32BE(4,4)/100\n\n//--payload----------------------------------------------\nmsg.payload = [\n    {\n        VerbruikKWH: VerbruikKWH,\n    },\n    {\n        MeterId: 'meter 2',\n        Locatie: 'meter 2',\n        Locatiegroep: 'Huis'\n    },\n    { timestamp: Date.now()}\n];\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 660,
        "y": 280,
        "wires": [
            [
                "f6bc8fa8d49a0e66",
                "2464c4400dd8c77a"
            ]
        ]
    },
    {
        "id": "f6bc8fa8d49a0e66",
        "type": "influxdb out",
        "z": "ee3039d35ce6bda2",
        "influxdb": "749ea570d74a9941",
        "name": "testdatabase",
        "measurement": "verbruik",
        "precision": "",
        "retentionPolicy": "",
        "database": "database",
        "precisionV18FluxV20": "ms",
        "retentionPolicyV18Flux": "",
        "org": "organisation",
        "bucket": "metingen",
        "x": 870,
        "y": 280,
        "wires": []
    },
    {
        "id": "b5c1d62a92aad00a",
        "type": "debug",
        "z": "ee3039d35ce6bda2",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 870,
        "y": 120,
        "wires": []
    },
    {
        "id": "2464c4400dd8c77a",
        "type": "debug",
        "z": "ee3039d35ce6bda2",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 870,
        "y": 320,
        "wires": []
    },
    {
        "id": "0b15cad3ad878289",
        "type": "modbus-response",
        "z": "ee3039d35ce6bda2",
        "name": "",
        "registerShowMax": 20,
        "x": 570,
        "y": 60,
        "wires": []
    },
    {
        "id": "acdd320a145d31bf",
        "type": "modbus-response",
        "z": "ee3039d35ce6bda2",
        "name": "",
        "registerShowMax": 20,
        "x": 570,
        "y": 220,
        "wires": []
    },
    {
        "id": "a21cd6b05bdb2181",
        "type": "modbus-getter",
        "z": "ee3039d35ce6bda2",
        "name": "",
        "showStatusActivities": false,
        "showErrors": false,
        "logIOActivities": false,
        "unitid": "5",
        "dataType": "HoldingRegister",
        "adr": "20480",
        "quantity": "8",
        "server": "bb5a04411cd75771",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "keepMsgProperties": false,
        "x": 320,
        "y": 360,
        "wires": [
            [
                "84e94e670bc14df8"
            ],
            [
                "56f98457c26c5626"
            ]
        ]
    },
    {
        "id": "84e94e670bc14df8",
        "type": "modbus-response",
        "z": "ee3039d35ce6bda2",
        "name": "",
        "registerShowMax": 20,
        "x": 570,
        "y": 340,
        "wires": []
    },
    {
        "id": "56f98457c26c5626",
        "type": "function",
        "z": "ee3039d35ce6bda2",
        "name": "",
        "func": "//--KwH verbruik/levering----------------------------------------------\n\nlet VerbruikKWH = msg.payload.buffer.readUInt32BE(4,4)/10\n\n//--payload----------------------------------------------\nmsg.payload = [\n    {\n        VerbruikKWH: VerbruikKWH,\n    },\n    {\n        MeterId: 'meter 3',\n        Locatie: 'meter 3',\n        Locatiegroep: 'Huis'\n    },\n    { timestamp: Date.now()}\n];\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 660,
        "y": 420,
        "wires": [
            [
                "b4cc875df990a821",
                "0fed58d8d1ab02cc"
            ]
        ]
    },
    {
        "id": "b4cc875df990a821",
        "type": "influxdb out",
        "z": "ee3039d35ce6bda2",
        "influxdb": "749ea570d74a9941",
        "name": "testdatabase",
        "measurement": "verbruik",
        "precision": "",
        "retentionPolicy": "",
        "database": "database",
        "precisionV18FluxV20": "ms",
        "retentionPolicyV18Flux": "",
        "org": "organisation",
        "bucket": "metingen",
        "x": 870,
        "y": 420,
        "wires": []
    },
    {
        "id": "0fed58d8d1ab02cc",
        "type": "debug",
        "z": "ee3039d35ce6bda2",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 870,
        "y": 460,
        "wires": []
    },
    {
        "id": "07413b42df7a11bf",
        "type": "switch",
        "z": "ee3039d35ce6bda2",
        "name": "Pull next data?",
        "property": "payload[0]",
        "propertyType": "msg",
        "rules": [
            {
                "t": "gt",
                "v": "0",
                "vt": "num"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 1,
        "x": 140,
        "y": 360,
        "wires": [
            [
                "a21cd6b05bdb2181"
            ]
        ]
    },
    {
        "id": "bb5a04411cd75771",
        "type": "modbus-client",
        "name": "",
        "clienttype": "simpleser",
        "bufferCommands": true,
        "stateLogEnabled": false,
        "queueLogEnabled": false,
        "failureLogEnabled": true,
        "tcpHost": "127.0.0.1",
        "tcpPort": "502",
        "tcpType": "DEFAULT",
        "serialPort": "/dev/ttymxc2",
        "serialType": "RTU-BUFFERD",
        "serialBaudrate": "19200",
        "serialDatabits": "8",
        "serialStopbits": "1",
        "serialParity": "none",
        "serialConnectionDelay": "100",
        "serialAsciiResponseStartDelimiter": "0x3A",
        "unit_id": "",
        "commandDelay": 1,
        "clientTimeout": 1000,
        "reconnectOnTimeout": true,
        "reconnectTimeout": 2000,
        "parallelUnitIdsAllowed": true
    },
    {
        "id": "749ea570d74a9941",
        "type": "influxdb",
        "hostname": "127.0.0.1",
        "port": "8086",
        "protocol": "http",
        "database": "database",
        "name": "Influxtestomgeving",
        "usetls": false,
        "tls": "",
        "influxdbVersion": "2.0",
        "url": "http://192.168.1.18:8086",
        "rejectUnauthorized": false
    }
]

These flow works only for the the first 2 meters, not clear why meter 3 never was started. For meter 3 no modbus response and no msg.payload...

And more important what to do if payload[0] is really 0? Readings simply stop?

Will this setup work with 15 modbus meters? Is it fast enough to cycle through 15 meters in a second or 2?

Is this second method the best way to read these meters or is there a much better/simpler way?

The second method is the best. Start by making the inject node manual rather than repeating to make sure you are not driving it too faset. If that doesn't get it going then add a 1 second Delay node between the getters and see if that sorts it. Once you get it going then you can run it faster and find how fast it will go reliably.

I don't know which msg.payload you are referring to.

Thank you Colin for your answer. So al lot of prototyping and testing is needed...

I was referring to the condition used to determine if data is collected. This works for first and second modbus getter nodes but not in the third node. That one did not start...

as can be seen from this screenshot with live data:

payload[0] is indeed 0 here, but I used payload[6] and it did not work too. It seems error-prone to me. Is there a better way?

Add debug nodes to check the trigger is actually getting to the last getter. Why have you got the Switch nodes there? I would have thought you want to trigger the next one even if the previous one fails.

In addition did you see the comment at the start of the help text for the getter node?

If you have more than 10 nodes on one communication configuration, use the Modbus-Flex-Getter or think about multiple connections to your Modbus Device, please!

Which suggests that since you eventually want 15 you would be better to use the flex-getter.

I think this switch node is to be sure the read action is ready, to protect from collisions. If you don't do that you have possibly more than one modbus server chatting like in method 1 I tested.

I think the node won't send a message until it is complete. It doesn't make any mention in the help text that it may send a message before it is finished.

1 Like

I red it. In my setup the 15 components will be split in 3 separate RS485 modbus lines (This UniPI has 4 isolated lines).

I did not try the mobus-flex-getter because I need to add 1 extra functionnode for eacht node for the modbus parameters. Would it work better?

I made a now flow without the switch nodes, in a couple of days I'm on location and test this:

1 Like

im no expert in Modbus but you could try increasing the ms delay in the Modbus Config node
instead of 1ms that you had to 50ms or 100ms .. gradually increase it to see if it helps

image

possibly this will give some breathing space between the reads from the previous device to the next (like a pre-delay) ?

ps. that third device .. if you poll it by itself in Node-red .. does it reply without issues ?

Thank you @ UnborN. I take a look at these very usefull hints when I'm back, can't try them from here.

I prepared some tests with the third node, there was no poweruse on it but I'll take a look at voltages or frequency.

Just to share my own experience with the Modbus Read nodes...

We have 5 controllers enabled with 2-wire Modbus. All 5 controllers are daisy-chained together and each has its own Slave address (1, 2, 3, 4, 5). Here is what I have found:

  • If all 5 controllers are polling data once per second, we get errors. Solution: have each controller poll at a slightly different rate (1.43 seconds, 2.14 seconds, etc.)

  • If one of the 5 controllers is turned off, we get errors. Solution: If any controller gets turned off, we disable the node that corresponds to that controller.

Hello Grant1,
Thanks for your sharing your setup.

I am very interested in the flow you use. Do you have a modbus read node for each of the controllers like in my first try?
Could you share your flow if possible?

How have you ensured that two do not poll at the same time?

Do you mean you get errors that would be expected if you attempt to poll a device that does not respond, or do you mean unexpected errors?

We have 3 controllers in place at the moment (not 5), but I can still illustrate the setup, errors, and fixes...

First, here is what I am using in this particular setup:

  • groov EPIC running Node-RED v2.2.2
  • node-red-contrib-modbus v5.21.2
  • this serial to USB adapter (that takes the end of the daisy chained units)
  • these controllers (here is the Modbus manual) labeled #301, #303 and #305 in the flow below. #301 is polling every 4000 ms, #303 is polling every 7652 ms, and #305 is polling every 5314 ms (I made these values up...just wanted them to be different "enough" so they did not overlap. But to answer the first question by @Colin , I cannot 100% ensure that they do not poll at the same time, as the polling interval could theoretically overlap, although it has not happened to my knowledge).

Currently, #303 is switched off, so I disabled the flow. The output is shown in the debug pane (no errors).

As soon as I enable #303, this is what I get:

After a minute or so, it will work again, but will then produce errors (this next screenshot was taken ~30 min. later because I got interrupted):

To answer the second question from @Colin , I do not even understand the above errors, but it seems the error above which causes everything to go wrong is

Client -> fsm failed state after sending Get More About It By Logging Serial@/dev/ttySer0:19200bit/s default Unit-Id: 1

In case it helps, here are the settings pages from the Modbus node. I set this up several years ago so it's not all fresh in my mind, but I recall needing the "UnitID's in parallel" box needing to be ticked.

FSM == finite state machine

I believe the modbus nodes internally use an FSM to control the sequence of events. It sends out a request & expects a matching response and then the state machine moves on to the next stage.

That kinda suggests you have overlapping comms

The better way of dealing with this is to ensure they are not operating while another is requesting (not via random timer values that will eventually coalesce).

You can achieve this interlocking in several ways. The most obvious is to wire your read nodes in series one after the other. Another way could be to use a Boolean flag to mark when a read in process & block others & plenty other ways too.


Forgive any nonsense :point_up: This was written on mobile with autocorrect

Use the Getter node with the nodes wired in series as shown in post #8 above. Then the comms will not collide.

.. also try decreasing the Timeout from 3 seconds to 1 sec (or less). If a device didnt reply in 1 sec then most probably it will never will (for that request) and that may lead to additional blocking of the queue ..
by the time a failed device times out in 3 seconds the next poll will follow and the polls will pile up resulting to further fails.

ps. does anyone know why the device 303 (from screenshot) is being polled even if the Node is disabled ?
Is this normal ?

image

@UnborN Thanks for the suggestion, but changing this did not have any effect on the errors produced. I will try to implement the other solutions proposed and report back.

I found in this issue more info about "unitid's in parallel"