Writing to Data Block in S7 1200 PLC via node-red-contrib-s7

Hello,
I am trying to read and write to a s7 1200 PLC Datablock.
I have sucessfully able to read the content of DB1 which contains a array "Test" which contains 20 String variabvles. See the image.


Folowing is the json for reading

[
    {
        "id": "defa031d7223bc60",
        "type": "s7 in",
        "z": "4606f8b0d0a8d4e9",
        "endpoint": "2f70a4039f09ee82",
        "mode": "single",
        "variable": "Andon Call Test",
        "diff": false,
        "name": "Andon Call Block Read",
        "x": 280,
        "y": 1020,
        "wires": [
            [
                "a35cfb21a3a49967",
                "3c06c3e94034441b"
            ]
        ]
    },
    {
        "id": "78b3252143da9aad",
        "type": "debug",
        "z": "4606f8b0d0a8d4e9",
        "name": "debug 60",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 740,
        "y": 1020,
        "wires": []
    },
    {
        "id": "a35cfb21a3a49967",
        "type": "function",
        "z": "4606f8b0d0a8d4e9",
        "name": "function 8",
        "func": "const buf = msg.payload;\nconst totalStrings = 21;  // Number of strings\nconst stringSize = 256;   // Size of each string (padded to 256 bytes)\n\nconst parsedStrings = [];\n\nfor (let i = 0; i < totalStrings; i++) {\n    const offset = i * stringSize;  // Get the offset for the current string\n    const actualLen = buf[offset + 1];  // Byte 1 is the actual length of the string\n\n    if (actualLen > 0) {\n        // Extract the byte array for the string data\n        const stringBytes = buf.slice(offset + 2, offset + 2 + actualLen);\n\n        // Convert the byte array into a string using ASCII encoding\n        let str = '';\n        for (let byte of stringBytes) {\n            str += String.fromCharCode(byte);\n        }\n\n        parsedStrings.push(str);  // Push the string into the parsedStrings array\n    } else {\n        parsedStrings.push('');  // Empty string if actual length is 0\n    }\n}\n\nmsg.payload = parsedStrings;  // Set the parsed strings as payload\nreturn msg;\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 500,
        "y": 1020,
        "wires": [
            [
                "78b3252143da9aad"
            ]
        ]
    },
    {
        "id": "3c06c3e94034441b",
        "type": "debug",
        "z": "4606f8b0d0a8d4e9",
        "name": "debug 65",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 520,
        "y": 980,
        "wires": []
    },
    {
        "id": "2f70a4039f09ee82",
        "type": "s7 endpoint",
        "transport": "iso-on-tcp",
        "address": "10.243.13.61",
        "port": "102",
        "rack": "0",
        "slot": "1",
        "localtsaphi": "01",
        "localtsaplo": "00",
        "remotetsaphi": "01",
        "remotetsaplo": "00",
        "connmode": "rack-slot",
        "adapter": "",
        "busaddr": 2,
        "cycletime": "1000",
        "timeout": 2000,
        "name": "",
        "vartable": [
            {
                "addr": "DB1,B0.5375",
                "name": "Andon Call Test"
            },
            {
                "addr": "DB1,B5376.100",
                "name": "Andon Call Test 1"
            }
        ]
    }
]

Now I am trying to write but Cant figure out why S7 Out node Saying

msg : error
"Error: Expected [5375] values for this item"
Incomming msg for S7 Out looks like this
msg : Object

object

payload: buffer[5376]

[0 … 9]

0: 0x0

1: 0x13

2: 0x53

3: 0x65

4: 0x6e

5: 0x73

6: 0x6f

7: 0x72

8: 0x20

9: 0x44

[10 … 19]

10: 0x69

11: 0x73

12: 0x63

13: 0x6f

14: 0x6e

15: 0x6e

16: 0x65

17: 0x63

18: 0x74

19: 0x65

Folowing is the code

[
    {
        "id": "e5cb46dbef0bcd4e",
        "type": "s7 out",
        "z": "4606f8b0d0a8d4e9",
        "endpoint": "2f70a4039f09ee82",
        "variable": "Andon Call Test",
        "name": "Andon Call Write",
        "x": 810,
        "y": 840,
        "wires": []
    },
    {
        "id": "5d183a28c9ef8549",
        "type": "MSSQL",
        "z": "4606f8b0d0a8d4e9",
        "mssqlCN": "814fd0e4912a79ae",
        "name": "LKEK1DB01",
        "outField": "payload",
        "returnType": "1",
        "throwErrors": "0",
        "query": "INSERT INTO [NodeRed].[dbo].[EventCall]\r\n  (MachineID, ErrorID, UserID, RecordTime, Status, Shift, Comments, Severity)\r\nVALUES\r\n  (\r\n    {{payload.MachineID}},\r\n    {{payload.ErrorID}},\r\n    {{payload.UserID}},\r\n    '{{payload.RecordTime}}',\r\n    '{{payload.Status}}',\r\n    '{{payload.Shift}}',\r\n    '{{payload.Comments}}',\r\n    '{{payload.Severity}}'\r\n  )\r\n",
        "modeOpt": "",
        "modeOptType": "query",
        "queryOpt": "payload",
        "queryOptType": "msg",
        "paramsOpt": "",
        "paramsOptType": "none",
        "rows": "rows",
        "rowsType": "msg",
        "parseMustache": true,
        "params": [
            {
                "output": false,
                "name": "param1",
                "type": "int",
                "valueType": "num",
                "value": "0",
                "options": {
                    "nullable": true,
                    "primary": false,
                    "identity": false,
                    "readOnly": false
                }
            }
        ],
        "x": 370,
        "y": 840,
        "wires": [
            [
                "51ba80916f44af68",
                "a75ed45029b6f074"
            ]
        ]
    },
    {
        "id": "e43002f3de7f33bf",
        "type": "function",
        "z": "4606f8b0d0a8d4e9",
        "name": "function 9",
        "func": "msg.payload = `SELECT [ErrorName]\n  FROM [ETD1 Andon Call System].[dbo].[ErrorType]`\n  return msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 220,
        "y": 840,
        "wires": [
            [
                "5d183a28c9ef8549"
            ]
        ]
    },
    {
        "id": "aa034cc6676389d8",
        "type": "inject",
        "z": "4606f8b0d0a8d4e9",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 80,
        "y": 840,
        "wires": [
            [
                "e43002f3de7f33bf"
            ]
        ]
    },
    {
        "id": "51ba80916f44af68",
        "type": "debug",
        "z": "4606f8b0d0a8d4e9",
        "name": "debug 61",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 540,
        "y": 800,
        "wires": []
    },
    {
        "id": "a75ed45029b6f074",
        "type": "function",
        "z": "4606f8b0d0a8d4e9",
        "name": "function 10",
        "func": "var Output = {};\nconst errorMessages = msg.payload.recordsets[0].map(item => item.ErrorName);\n\n// Config\nconst totalStrings = 21;\nconst stringSize = 256;\nconst totalSize = totalStrings * stringSize; // 5376\nconst buffer = Buffer.alloc(totalSize); // Full buffer\n\nfor (let i = 0; i < totalStrings; i++) {\n    const offset = i * stringSize;\n    const message = errorMessages[i] || \"\";\n    const len = Math.min(message.length, stringSize - 2);\n\n    buffer.writeUInt8(0, offset);           // Byte 0: unused/reserved\n    buffer.writeUInt8(len, offset + 1);     // Byte 1: string length\n\n    for (let j = 0; j < len; j++) {\n        buffer.writeUInt8(message.charCodeAt(j), offset + 2 + j);\n    }\n}\n\n// ✅ Send exactly 5376 bytes\nOutput.payload = buffer;\nOutput.variable = \"Andon Call\";\nreturn Output;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 590,
        "y": 840,
        "wires": [
            [
                "59a8b52b9686d3c9",
                "e5cb46dbef0bcd4e"
            ]
        ]
    },
    {
        "id": "59a8b52b9686d3c9",
        "type": "debug",
        "z": "4606f8b0d0a8d4e9",
        "name": "debug 62",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 740,
        "y": 800,
        "wires": []
    },
    {
        "id": "2f70a4039f09ee82",
        "type": "s7 endpoint",
        "transport": "iso-on-tcp",
        "address": "10.243.13.61",
        "port": "102",
        "rack": "0",
        "slot": "1",
        "localtsaphi": "01",
        "localtsaplo": "00",
        "remotetsaphi": "01",
        "remotetsaplo": "00",
        "connmode": "rack-slot",
        "adapter": "",
        "busaddr": 2,
        "cycletime": "1000",
        "timeout": 2000,
        "name": "",
        "vartable": [
            {
                "addr": "DB1,B0.5375",
                "name": "Andon Call Test"
            },
            {
                "addr": "DB1,B5376.100",
                "name": "Andon Call Test 1"
            }
        ]
    },
    {
        "id": "814fd0e4912a79ae",
        "type": "MSSQL-CN",
        "tdsVersion": "7_4",
        "name": "SQL LKEK1DB01",
        "server": "LKEK1DB01.CSL.LOCAL\\ETD1_ANDON_CALL",
        "port": "1443",
        "encyption": false,
        "trustServerCertificate": true,
        "database": "ETD1 Andon Call System",
        "useUTC": false,
        "connectTimeout": "1500",
        "requestTimeout": "1500",
        "cancelTimeout": "5000",
        "pool": "5",
        "parseJSON": false,
        "enableArithAbort": true,
        "readOnlyIntent": false
    }
]

It looks like the error message is indicating a mismatch between the expected size of the buffer and what is being sent:

Error: Expected [5375] values for this item

This usually happens when the S7 Out node expects an exact number of bytes (5375 in this case) but receives 5376. You're likely sending 1 extra byte in the buffer. Make sure the buffer size matches exactly what the node expects.

Also, for more insights into working with S7 PLCs in Node-RED, I’ve written a blog that might help with related issues: Getting Started: Integrating Siemens S7 PLCs with Node-RED • FlowFuse

Hope this helps!

2 Likes

Hello Sumitshinde,
Thanks you for replying.I've read your article several times before. It was very helpful. I did try the suggestions you mentioned earlier, but unfortunately, they didn't work in my case. I experimented with flat arrays, buffers, and regular arrays, but none of them seemed to resolve the issue.

Do you have any other ideas or suggestions I could try?