Controlling modbus rtu relay

My setup:
Raspberry pi cm4 with rs485
Waveshare modbus rtu relay

I have a raspberry pi device with rs 485 connection. My relay has rs 485 as well. I need to send this 01 05 00 00 FF 00 8C 3A to the relay device to control the relay.

I need to send Send: 01 01 00 00 00 08 3D CC and then Receive: 01 01 01 00 51 88

can anyone help me with the nodes i will need and the flow i need to use to control it.

this is a reference to the relay board.
[Modbus RTU Relay (D) - Waveshare Wiki]

Install node-red-contrib-modbus then it will do all the difficult stuff for you.

After I install the modbus nodes what nodes do I need to use? I’ve installed modbus nodes before and know the basic principles of modbus but I do not know how to communicate with the slave devices and how to read and translate back.

What in particular do you not understand? If you do not understand the basics of modbus (registers and so on) then I am sure there are many tutorials available online. If you do already understand modbus then the link you provided contains the register mapping and commands for the device.

I understand the very basics but I do not understand what nodes I need to use from modbus nodes. Is there a tutorial you can point me to so I can learn this. I’ve been trying to figure this out for awhile now. I can do this from plc to plcs but I just don’t understand it enough to do it in node red. So I use a mag payload string to send the hex string?? Does the node get configure with the hex string. How do I decode it to ascii string.

I guess I should replace the word basics with basic principal of modbus. I don’t understand how to do it in node red.

Have a look at the documentation for the node. There are example flows there, a link to the wiki and to youtube videos.

No, you work with the modbus registers, the node will do the hex and CRC stuff for you.
For example, to write to it you could use the modbus write node with the appropriate device number, function code and address.

Is this memory mapping correct? The addressing is really my big question.

1-10000 Coils (1-Relay 1, 2-Relay 2, 3-Relay 3, ... etc)
10001-20000 Inputs (10001-Input1, 10002-Input 2, 10003-Input 3)
30001-40000 Input Registers (Analog Inputs)
40001-50000 Holding Registers (Analog Output).

If I wanted to control relay 1 i would use a write node.
Unit ID: ID of modbus device)
FC: FC 5
Address: 1

I would then use a msg.payload =0 or 1 or true or false to inject into the write node.

Reading Inputs or Coil

If I wanted to read relay 1 i would use a read node.
Unit ID: ID of modbus device)
FC: FC 1
Address: 1

If I wanted to read input 1 i would use a read node.
Unit ID: ID of modbus device)
FC: FC 2
Address: 10001

Use node-red-node-serialport when you need to debug flexibly.


test code here:

[
    {
        "id": "e7e0acf8ed94f75e",
        "type": "tab",
        "label": "鍘嬪姏浼犳劅鍣ㄤ覆鍙d换鎰忔寚浠ゅ疄楠?",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "22f712114a9952dd",
        "type": "serial-port",
        "serialport": "/dev/ttyS4",
        "serialbaud": "9600",
        "databits": "8",
        "parity": "none",
        "stopbits": "1",
        "waitfor": "",
        "dtr": "none",
        "rts": "none",
        "cts": "none",
        "dsr": "none",
        "newline": "50",
        "bin": "bin",
        "out": "interbyte",
        "addchar": "",
        "responsetimeout": "10000"
    },
    {
        "id": "067e0acd2d271669",
        "type": "inject",
        "z": "e7e0acf8ed94f75e",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "03030000000185E8",
        "payloadType": "str",
        "x": 130,
        "y": 160,
        "wires": [
            [
                "0e3b76dd644213b3"
            ]
        ]
    },
    {
        "id": "0e3b76dd644213b3",
        "type": "buffer-maker",
        "z": "e7e0acf8ed94f75e",
        "name": "",
        "specification": "spec",
        "specificationType": "ui",
        "items": [
            {
                "name": "item1",
                "type": "hex",
                "length": 16,
                "dataType": "msg",
                "data": "payload"
            }
        ],
        "swap1": "",
        "swap2": "swap16",
        "swap3": "",
        "swap1Type": "swap",
        "swap2Type": "swap",
        "swap3Type": "swap",
        "msgProperty": "payload",
        "msgPropertyType": "str",
        "x": 330,
        "y": 160,
        "wires": [
            [
                "36921b79db22a4f2"
            ]
        ]
    },
    {
        "id": "b30f1f7458ccaa75",
        "type": "debug",
        "z": "e7e0acf8ed94f75e",
        "name": "debug 14",
        "active": true,
        "tosidebar": true,
        "console": true,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 370,
        "y": 260,
        "wires": []
    },
    {
        "id": "cd4fa16807afa3cd",
        "type": "serial in",
        "z": "e7e0acf8ed94f75e",
        "name": "",
        "serial": "22f712114a9952dd",
        "x": 140,
        "y": 260,
        "wires": [
            [
                "b30f1f7458ccaa75"
            ]
        ]
    },
    {
        "id": "36921b79db22a4f2",
        "type": "serial out",
        "z": "e7e0acf8ed94f75e",
        "name": "",
        "serial": "22f712114a9952dd",
        "x": 560,
        "y": 160,
        "wires": []
    },
    {
        "id": "067f998692c1474d",
        "type": "function",
        "z": "e7e0acf8ed94f75e",
        "name": "浠绘剰16杩涘埗鎸囦护",
        "func": "var buf = Buffer.from([0x03 ,0x03 ,0x00 ,0x00 ,0x00 ,0x01 ,0x85 ,0xE8 ]);\nmsg.payload = buf;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 360,
        "y": 80,
        "wires": [
            [
                "36921b79db22a4f2"
            ]
        ]
    },
    {
        "id": "3a2436d910a2f28b",
        "type": "inject",
        "z": "e7e0acf8ed94f75e",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 150,
        "y": 80,
        "wires": [
            [
                "067f998692c1474d"
            ]
        ]
    }
]

Since the device uses Modbus it would be much better to use the modbus nodes.

I am not a modbus expert but the docs you linked to suggest that address 0 is relay 1 and 7 is relay 8.

Again the docs suggest that 10000 is input 1

I don't see those in the docs at all.

I’m basing the address on traditional modbus addressing and it states that each block is a range of 10,000 addresses. It states that each block starts in 00001,10001,30001,40001. If that is mod bus complaint that should be the mapping correct? I guess I am on the right path either way and I can test the path on the relays with a volt meter.

I don't know enough about modbus to comment further on this.

So it is modbus address 0 for relay 1.

Ok thank you! I will be testing this over the next few days and will let you know. Thanks again!

So I am having a little issue. If i use the serial connection magicfire described I can turn on and off the relay but I cant get it to work with the modbus nodes. From what I read node red uses the decimal address and the instructions are in hex. Is there an easy way to convert 0X0000 1X0000 to decimal?

I spent some time, and I figured it out. It is actually pretty simple. I had to restart node red after disabling the serial connection. Once I did that I just used the 0-7 numbers for each type of function block. I dont have to use the 0-10000, 10000-20000 numbering. I did have issues with addressing the modbus with crc16 check sums, but I used a crc calculator to figure that out. Its pretty interesting. I would like to note that the input side doesn't work well unless you use the quanity of the inputs you have on the device. Example I couldn't use quantity 1 because it would just show reconnecting. Once I put 8 it worked great. I don't know if that is a bug or if Im doing something wrong but I will keep playing with it.

You can convert hex to a decimal with this in a function node:

parseInt(hexValue, 16)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.