node-red:modbus协议数据格式转换

news2025/1/20 10:53:28


node-red:MODBUS协议数据格式转换

  • 一、32word无符号转换
    • 1.1 写操作
    • 1.2 读操作
  • 二、字符串转换
    • 2.1 字符串写操作
    • 2.2 字符串读操作
  • 三、有符号整数转换
    • 3.1 `有符号16word转换`
      • 3.1.1 负数 读 操作
      • 3.1.2 负数 写 操作
    • 3.2 `有符号32word转换`
  • 源码

  本文将描述通过node-red采集工业数据时,采集到的数据需要进行转换的操作方法。
  对于运行在RTU或ASCII传输模式下的modbus协议,它接收主设备发送的指令报文,并根据窗口配置的数据返回主设备需要的指令报文。根据Modbus协议的规定,所有的数值都是以16位二进制形式进行存储和运算的。

回到目录

一、32word无符号转换

  Modbus协议中,32位整数的存储格式会因具体的数据类型而有所不同。Modbus协议对32位无符号整数的存储方式是将该整数分解为两个16位的寄存器来处理,第一个元素是高16位,第二个元素是低16位,具体的字节顺序可以有四种选择:无符号整数大端序、无符号整数小端序、无符号整数大端字节交换和无符号整数小端字节交换。例如,一个无符号的32位整数0x12345678在Modbus中的存储形式可能会是:0x12 0x34 0x56 0x78,具体取决于所选择的字节顺序。其中:

  • 大端序Big-Endian(BE):将最高位字节存储在最低的地址位置;
  • 小端序(LE):则是将最高位字节存储在最高的地址位置;
  • 无符号整数大端字节交换和小端字节交换(BIG_ENDIAN和LITTLE_ENDIAN):指将每个字节的顺序颠倒,但不考虑符号位。

1.1 写操作

  1. 将32位整数转换为16位整数数组
  • 使用无符号整数大端序(BE)的转换方式,js代码如下:
/** 使用无符号整数大端序(BE)的转换方式,将一个32位整数,转换为一个包含两个元素的数组,
 * 其中第一个元素是高16位,第二个元素是低16位 */
function int32ToArrayBE(num) {
    const high = (num >> 16) & 0xFFFF;
    const low = num & 0xFFFF;
    return [high, low];
}
  1. 通过modbus节点写入,示例如下
    2
    数据已成功写入:
    2

回到目录

1.2 读操作

实现步骤:

  1. 将一个包含两个元素的数组转换为一个32位整数
  • 使用无符号整数大端序(BE)的转换方式,js代码如下:
//将一个包含两个元素的数组转换为一个32位整数,其中第一个元素是高16位,第二个元素是低16位。
//转换方式是先将第一个元素左移16位,然后与第二个元素进行按位或操作。
function arrayToInt32BE(data) {
    return (data[0] << 16) | data[1];
}
  1. 通过modbus节点读取,示例如下:
    2

回到目录

二、字符串转换

  modbus支持对字符串类型的数据进行读写操作,进行字符串类型数据的操作时,是基于ASCII码格式进行的,一个字符占一个字节,支持字母、中文已经符号。

2.1 字符串写操作

实现步骤:

  1. 将字符串转换成字节数组,函数如下:
/**将一个字符串,获取每个字符的Unicode编码,转换为字节数组 */
function stringToByteArray(str) {
    let byteArray = [];
    for (let i = 0; i < str.length; i++) {
        byteArray.push(str.charCodeAt(i));
    }
    return byteArray;
}
  1. 将字节数组批量写入modbus中 ,示例如下:
    1
    执行后,可以看到对应地址的数据:
    2

回到目录

2.2 字符串读操作

实现步骤:

  1. modbus节点读取起始地址为n,直至字符串字节数组长度的连续地址的数据数组
  2. 将得到到的字节数组转换为字符串,转换函数如下:
//将Unicode编码字节数组转换为对应的字符
msg.payload = String.fromCharCode(...msg.payload.slice(0, 8));
//有需要的话可以去掉字符串中的null和结尾的空字符
msg.payload = msg.payload.trim().replace(/\u0000/g, '');
return msg;

示例如下:
1

回到目录

三、有符号整数转换

  1. 正整数就是正常的读\写,不需要转换。
  2. 对于负数,在计算机和数字系统中,负数通常使用二进制补码形式来表示。这种方法是将负数的绝对值取反后再加一得到的。如’-80’的二进制补码就是’65456’。

如我们在modsim32中输入-55,实际显示在计算机上的是65481
1

3.1 有符号16word转换

3.1.1 负数 读 操作

  有符号16word转换成补码是占一位地址,通过modbus读取过来是十进制整数,我们需要将其通过node-red的modbus协议读取对应地址下的数据,该数据为补码,需要将其转换为实际的有符号16位整数。有两种转换方式,如下示例所示:
1

  1. 通过js函数转换:
/** 有符号整数补码转换转成16位有符号整数:
 * 如-80的补码为65456,读取出来是65456,需要通过该函数转换成-80
 */
function Signed16ToInt16Be(num){
    //32767是16位带符号证书能表示的最大正数,当数值从32767再增加1时,就会上溢变成负数。
    //即mod通信中所有的负数都是用补码形式存储(如‘-80’实际读\写出来是‘65456’)
    //需要检测是否发生了从正数到负数的转换,即是否发生了上溢或下溢,如果有,进行转换
    return num >= 32768 ? num - 65536 : num;
}
  1. 使用parse节点工具转换:
    2

回到目录

3.1.2 负数 写 操作

   直接将负数写入对应地址时,不生效。需要先将其转换成补码,然后再将补码写入地址。js将负数转换成补码的函数如下:

/** 
 * 负数转成对应的补码
 * 在计算机中,负数通常使用补码表示,如'-80'用补码表示为'65456'.
 */
function Int16BeToSigned16(num) {
    //如果数字小于0,将其转换成十进制补码:65536是2的16次幂,也就是2^16
    if(num < 0){
        num += 65536
    }
    return num;
}

实战示例如下:
1

回到目录

3.2 有符号32word转换

回到目录

源码

[
    {
        "id": "1e64108c77baa639",
        "type": "inject",
        "z": "f77425d62009612d",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 130,
        "y": 580,
        "wires": [
            [
                "7dc4362a647fb9f4"
            ]
        ]
    },
    {
        "id": "7dc4362a647fb9f4",
        "type": "modbus-getter",
        "z": "f77425d62009612d",
        "name": "",
        "showStatusActivities": false,
        "showErrors": false,
        "showWarnings": true,
        "logIOActivities": false,
        "unitid": "2",
        "dataType": "HoldingRegister",
        "adr": "99",
        "quantity": "1",
        "server": "e7cbfcc879655084",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "keepMsgProperties": false,
        "delayOnStart": false,
        "startDelayTime": "",
        "x": 300,
        "y": 580,
        "wires": [
            [
                "b156bb1bacfff01f",
                "1b8c974bcad376f7",
                "4ec96886cf6ddcfc"
            ],
            []
        ]
    },
    {
        "id": "b156bb1bacfff01f",
        "type": "buffer-parser",
        "z": "f77425d62009612d",
        "name": "",
        "data": "payload",
        "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": 470,
        "y": 580,
        "wires": [
            [
                "38805fdde3a44395"
            ]
        ]
    },
    {
        "id": "38805fdde3a44395",
        "type": "debug",
        "z": "f77425d62009612d",
        "name": "parse转换",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 620,
        "y": 580,
        "wires": []
    },
    {
        "id": "1b8c974bcad376f7",
        "type": "function",
        "z": "f77425d62009612d",
        "name": "函数转换",
        "func": "msg.payload = Signed16ToInt16Be(msg.payload);\nreturn msg;\n/** 有符号整数补码转换转成16位有符号整数:\n * 如-80的补码为65456,读取出来是65456,需要通过该函数转换成-80\n */\nfunction Signed16ToInt16Be(num){\n    //32767是16位带符号证书能表示的最大正数,当数值从32767再增加1时,就会上溢变成负数。\n    //即mod通信中所有的负数都是用补码形式存储(如‘-80’实际读\\写出来是‘65456’)\n    //需要检测是否发生了从正数到负数的转换,即是否发生了上溢或下溢,如果有,进行转换\n    return num >= 32768 ? num - 65536 : num;\n}",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 460,
        "y": 620,
        "wires": [
            [
                "d76859e443cd98fc"
            ]
        ]
    },
    {
        "id": "d76859e443cd98fc",
        "type": "debug",
        "z": "f77425d62009612d",
        "name": "js函数转换",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 630,
        "y": 620,
        "wires": []
    },
    {
        "id": "769c583e15f9b628",
        "type": "inject",
        "z": "f77425d62009612d",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 110,
        "y": 720,
        "wires": [
            [
                "c69cb082f4d5391f"
            ]
        ]
    },
    {
        "id": "c758cfc4fd1cdcaf",
        "type": "function",
        "z": "f77425d62009612d",
        "name": "(写)有符号数字",
        "func": "msg.payload = Int16BeToSigned16(msg.payload);\nreturn msg;\n/** \n * 负数转成对应的补码\n * 在计算机中,负数通常使用补码表示,如'-80'用补码表示为'65456'.\n */\nfunction Int16BeToSigned16(num) {\n    //如果数字小于0,将其转换成十进制补码:65536是2的16次幂,也就是2^16\n    if(num < 0){\n        num += 65536\n    }\n    return num;\n}",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 430,
        "y": 720,
        "wires": [
            [
                "4d2f5446435e62d1",
                "d5d6bcc7a95cd04b"
            ]
        ]
    },
    {
        "id": "4d2f5446435e62d1",
        "type": "modbus-write",
        "z": "f77425d62009612d",
        "name": "",
        "showStatusActivities": false,
        "showErrors": false,
        "showWarnings": true,
        "unitid": "2",
        "dataType": "MHoldingRegisters",
        "adr": "99",
        "quantity": "1",
        "server": "e7cbfcc879655084",
        "emptyMsgOnFail": false,
        "keepMsgProperties": false,
        "delayOnStart": false,
        "startDelayTime": "",
        "x": 640,
        "y": 720,
        "wires": [
            [
                "b71462a8db1024f6"
            ],
            []
        ]
    },
    {
        "id": "b71462a8db1024f6",
        "type": "debug",
        "z": "f77425d62009612d",
        "name": "debug 55",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 820,
        "y": 720,
        "wires": []
    },
    {
        "id": "d5d6bcc7a95cd04b",
        "type": "debug",
        "z": "f77425d62009612d",
        "name": "补码",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 610,
        "y": 680,
        "wires": []
    },
    {
        "id": "4ec96886cf6ddcfc",
        "type": "debug",
        "z": "f77425d62009612d",
        "name": "直接读取",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 460,
        "y": 540,
        "wires": []
    },
    {
        "id": "c69cb082f4d5391f",
        "type": "function",
        "z": "f77425d62009612d",
        "name": "赋值",
        "func": "msg.payload = -90;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 250,
        "y": 720,
        "wires": [
            [
                "c758cfc4fd1cdcaf",
                "19cc1b023537db9f"
            ]
        ]
    },
    {
        "id": "19cc1b023537db9f",
        "type": "debug",
        "z": "f77425d62009612d",
        "name": "负数",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 370,
        "y": 680,
        "wires": []
    },
    {
        "id": "db6d11e622be6be8",
        "type": "comment",
        "z": "f77425d62009612d",
        "name": "3.1.2  16位负数写操作",
        "info": "",
        "x": 140,
        "y": 680,
        "wires": []
    },
    {
        "id": "cd5db39529d4197c",
        "type": "comment",
        "z": "f77425d62009612d",
        "name": "3.1.1  16位负数读操作",
        "info": "",
        "x": 140,
        "y": 540,
        "wires": []
    },
    {
        "id": "17422aec125ee1e5",
        "type": "comment",
        "z": "f77425d62009612d",
        "name": " 2.1 字符串写操作",
        "info": "",
        "x": 120,
        "y": 320,
        "wires": []
    },
    {
        "id": "5e6d79e257936ac0",
        "type": "inject",
        "z": "f77425d62009612d",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 110,
        "y": 360,
        "wires": [
            [
                "60a74c2ac2108159"
            ]
        ]
    },
    {
        "id": "60a74c2ac2108159",
        "type": "function",
        "z": "f77425d62009612d",
        "name": "赋值",
        "func": "var str ='你好,Marry';\nmsg.payload = stringToByteArray(str);\nreturn msg;\n/**将一个字符串,获取每个字符的Unicode编码,转换为字节数组 */\nfunction stringToByteArray(str) {\n    let byteArray = [];\n    for (let i = 0; i < str.length; i++) {\n        byteArray.push(str.charCodeAt(i));\n    }\n    return byteArray;\n}",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 230,
        "y": 360,
        "wires": [
            [
                "48ccae615ccc0b4c",
                "ab1f56889919d10b"
            ]
        ]
    },
    {
        "id": "48ccae615ccc0b4c",
        "type": "modbus-write",
        "z": "f77425d62009612d",
        "name": "",
        "showStatusActivities": false,
        "showErrors": false,
        "showWarnings": true,
        "unitid": "2",
        "dataType": "MHoldingRegisters",
        "adr": "99",
        "quantity": "8",
        "server": "e7cbfcc879655084",
        "emptyMsgOnFail": false,
        "keepMsgProperties": false,
        "delayOnStart": false,
        "startDelayTime": "",
        "x": 380,
        "y": 360,
        "wires": [
            [],
            []
        ]
    },
    {
        "id": "ab1f56889919d10b",
        "type": "debug",
        "z": "f77425d62009612d",
        "name": "转换后",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 350,
        "y": 320,
        "wires": []
    },
    {
        "id": "3e34769f2f93e394",
        "type": "inject",
        "z": "f77425d62009612d",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 110,
        "y": 460,
        "wires": [
            [
                "2060ceec23e827b0"
            ]
        ]
    },
    {
        "id": "2060ceec23e827b0",
        "type": "modbus-getter",
        "z": "f77425d62009612d",
        "name": "",
        "showStatusActivities": false,
        "showErrors": false,
        "showWarnings": true,
        "logIOActivities": false,
        "unitid": "2",
        "dataType": "HoldingRegister",
        "adr": "99",
        "quantity": "8",
        "server": "e7cbfcc879655084",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "keepMsgProperties": false,
        "delayOnStart": false,
        "startDelayTime": "",
        "x": 280,
        "y": 460,
        "wires": [
            [
                "674886974e9f1f90",
                "b88737723cab66a8"
            ],
            []
        ]
    },
    {
        "id": "674886974e9f1f90",
        "type": "function",
        "z": "f77425d62009612d",
        "name": "函数转换",
        "func": "//将Unicode编码字节数组转换为对应的字符\nmsg.payload = String.fromCharCode(...msg.payload.slice(0, 8));\n//有需要的话可以去掉字符串中的null和结尾的空字符\nmsg.payload = msg.payload.trim().replace(/\\u0000/g, '');\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 460,
        "y": 460,
        "wires": [
            [
                "c6d5115b578ded31"
            ]
        ]
    },
    {
        "id": "b88737723cab66a8",
        "type": "debug",
        "z": "f77425d62009612d",
        "name": "直接读取",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 440,
        "y": 420,
        "wires": []
    },
    {
        "id": "c6d5115b578ded31",
        "type": "debug",
        "z": "f77425d62009612d",
        "name": "js函数转换",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 610,
        "y": 460,
        "wires": []
    },
    {
        "id": "629c93d9a5836ab0",
        "type": "comment",
        "z": "f77425d62009612d",
        "name": " 2.2  字符串读操作",
        "info": "",
        "x": 120,
        "y": 420,
        "wires": []
    },
    {
        "id": "e2b2a3da4860c56b",
        "type": "function",
        "z": "f77425d62009612d",
        "name": "数组转换",
        "func": "msg.payload = int32ToArrayBE(msg.payload);\nreturn msg;\n/** 使用无符号整数大端序(BE)的转换方式,\n * 将一个32位整数,转换为一个包含两个元素的数组,\n * 其中第一个元素是高16位,第二个元素是低16位 */\nfunction int32ToArrayBE(num) {\n    const high = (num >> 16) & 0xFFFF;\n    const low = num & 0xFFFF;\n    return [high, low];\n}",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 360,
        "y": 80,
        "wires": [
            [
                "11e1bfef49c08c4d",
                "54919ad9449f2987"
            ]
        ]
    },
    {
        "id": "2057a2e62539d669",
        "type": "inject",
        "z": "f77425d62009612d",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 110,
        "y": 80,
        "wires": [
            [
                "c858d03ce2f7e8a2"
            ]
        ]
    },
    {
        "id": "11e1bfef49c08c4d",
        "type": "modbus-write",
        "z": "f77425d62009612d",
        "name": "",
        "showStatusActivities": false,
        "showErrors": false,
        "showWarnings": true,
        "unitid": "2",
        "dataType": "MHoldingRegisters",
        "adr": "99",
        "quantity": "2",
        "server": "e7cbfcc879655084",
        "emptyMsgOnFail": false,
        "keepMsgProperties": false,
        "delayOnStart": false,
        "startDelayTime": "",
        "x": 540,
        "y": 80,
        "wires": [
            [],
            []
        ]
    },
    {
        "id": "c858d03ce2f7e8a2",
        "type": "function",
        "z": "f77425d62009612d",
        "name": "赋值",
        "func": "msg.payload = 3276780;\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 230,
        "y": 80,
        "wires": [
            [
                "e2b2a3da4860c56b",
                "1438b02a5f7824dc"
            ]
        ]
    },
    {
        "id": "1438b02a5f7824dc",
        "type": "debug",
        "z": "f77425d62009612d",
        "name": "原始",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 350,
        "y": 40,
        "wires": []
    },
    {
        "id": "54919ad9449f2987",
        "type": "debug",
        "z": "f77425d62009612d",
        "name": "数组",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 510,
        "y": 40,
        "wires": []
    },
    {
        "id": "1da67750bf2f0eb1",
        "type": "comment",
        "z": "f77425d62009612d",
        "name": "1.1  32word写操作",
        "info": "",
        "x": 130,
        "y": 20,
        "wires": []
    },
    {
        "id": "dd7a84e126fda707",
        "type": "inject",
        "z": "f77425d62009612d",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 110,
        "y": 200,
        "wires": [
            [
                "7d73e7b22a1358f0"
            ]
        ]
    },
    {
        "id": "7d73e7b22a1358f0",
        "type": "modbus-getter",
        "z": "f77425d62009612d",
        "name": "",
        "showStatusActivities": false,
        "showErrors": false,
        "showWarnings": true,
        "logIOActivities": false,
        "unitid": "2",
        "dataType": "HoldingRegister",
        "adr": "99",
        "quantity": "2",
        "server": "e7cbfcc879655084",
        "useIOFile": false,
        "ioFile": "",
        "useIOForPayload": false,
        "emptyMsgOnFail": false,
        "keepMsgProperties": false,
        "delayOnStart": false,
        "startDelayTime": "",
        "x": 260,
        "y": 200,
        "wires": [
            [
                "4bf2a9d5169fa147",
                "9908852fe20a2380",
                "58decbf3f6230bed"
            ],
            []
        ]
    },
    {
        "id": "4bf2a9d5169fa147",
        "type": "function",
        "z": "f77425d62009612d",
        "name": "函数转换",
        "func": "/** 使用无符号整数大端序(Big-Endian)的转换方式,将一个一个包含两个元素的数组,转换为一个32位整数 */\nfunction arrayToInt32BE(data) {\n    return (data[0] << 16) | data[1];\n}\nmsg.payload = arrayToInt32BE(msg.payload);\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 440,
        "y": 200,
        "wires": [
            [
                "275aa03cf2080e7d"
            ]
        ]
    },
    {
        "id": "275aa03cf2080e7d",
        "type": "debug",
        "z": "f77425d62009612d",
        "name": "js函数转换",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 590,
        "y": 200,
        "wires": []
    },
    {
        "id": "9908852fe20a2380",
        "type": "debug",
        "z": "f77425d62009612d",
        "name": "直接读取",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 440,
        "y": 160,
        "wires": []
    },
    {
        "id": "58decbf3f6230bed",
        "type": "buffer-parser",
        "z": "f77425d62009612d",
        "name": "",
        "data": "payload",
        "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": 450,
        "y": 240,
        "wires": [
            [
                "342f36c555ec1252"
            ]
        ]
    },
    {
        "id": "342f36c555ec1252",
        "type": "debug",
        "z": "f77425d62009612d",
        "name": "parse转换",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 600,
        "y": 240,
        "wires": []
    },
    {
        "id": "e1215e288585f302",
        "type": "comment",
        "z": "f77425d62009612d",
        "name": "1.2  32word读操作",
        "info": "",
        "x": 130,
        "y": 140,
        "wires": []
    },
    {
        "id": "e7cbfcc879655084",
        "type": "modbus-client",
        "name": "tcp@192.168.2.105:1024",
        "clienttype": "tcp",
        "bufferCommands": true,
        "stateLogEnabled": false,
        "queueLogEnabled": false,
        "failureLogEnabled": true,
        "tcpHost": "192.168.2.105",
        "tcpPort": "1024",
        "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,
        "showWarnings": true,
        "showLogs": true
    }
]

回到目录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1339808.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024年【北京市安全员-B证】证考试及北京市安全员-B证模拟考试题库

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【北京市安全员-B证】证考试及北京市安全员-B证模拟考试题库&#xff0c;包含北京市安全员-B证证考试答案和解析及北京市安全员-B证模拟考试题库练习。安全生产模拟考试一点通结合国家北京市安全员-B证考试最新…

本地部署 text-generation-webui

本地部署 text-generation-webui 0. 背景1. text-generation-webui 介绍2. 克隆代码3. 创建虚拟环境4. 安装 pytorch5. 安装 CUDA 运行时库6. 安装依赖库7. 启动 Web UI8. 访问 Web UI9. OpenAI 兼容 API 0. 背景 一直喜欢用 FastChat 本地部署大语言模型&#xff0c;今天试一…

GitOps实践指南:GitOps能为我们带来什么?

Git&#xff0c;作为开发过程中的核心工具&#xff0c;提供了强大的版本控制功能。即便在写代码的时候稍微手抖一下&#xff0c;我们也能通过 Git 的差异对比&#xff08;diff&#xff09;轻松追踪到庞大工程中的问题&#xff0c;确保代码的准确与可靠。这种无与伦比的自省能力…

python如何通过日志分析加入黑名单

python通过日志分析加入黑名单 监控nginx日志&#xff0c;若有人攻击&#xff0c;则加入黑名单&#xff0c;操作步骤如下&#xff1a; 1.读取日志文件 2.分隔文件&#xff0c;取出ip 3.将取出的ip放入list&#xff0c;然后判读ip的次数 4.若超过设定的次数&#xff0c;则加…

面向对象(高级)知识点强势总结!!!

文章目录 一、知识点复习1-关键字&#xff1a;static1、知识点2、重点 2-单例模式&#xff08;或单子模式&#xff09;1、知识点2、重点 3-理解main()方法1、知识点2、重点 4-类的成员之四&#xff1a;代码块1、知识点2、重点 5-关键字&#xff1a;final1、知识点2、重点 6-关键…

Python 网络编程之搭建简易服务器和客户端

用Python搭建简易的CS架构并通信 文章目录 用Python搭建简易的CS架构并通信前言一、基本结构二、代码编写1.服务器端2.客户端 三、效果展示总结 前言 本文主要是用Python写一个CS架构的东西&#xff0c;包括服务器和客户端。程序运行后在客户端输入消息&#xff0c;服务器端会…

ArcGIS Pro中Conda环境的Scripts文件解读

Scripts中包含的文件如下 1. propy.bat 用于在 ArcGIS Pro 外部运行 Python 脚本&#xff08;扩展名为 .py 的文件&#xff09;。使用的conda环境是与ArcGIS pro环境同步。propy.bat原理是代替各自python环境下的python.exe&#xff0c;主要区别是propy.bat使用的是与Pro同的…

YOLOv8算法优化:解决YOLOv8无法打印计算量(GFLOPs)的问题点

💡💡💡本文内容:解决YOLOv8无法打印计算量的问题点 💡💡💡本文提供:1)训练阶段自动打印计算量;2)提供离线打印计算量的代码; 1.计算量介绍 FLOPS:注意S是大写,是 “每秒所执行的浮点运算次数”(floating-point operations per second)的缩写。它常被用…

JavaScript 工具库 | PrefixFree给CSS自动添加浏览器前缀

新版的CSS拥有多个新属性&#xff0c;而标准有没有统一&#xff0c;有的浏览器厂商为了吸引更多的开发者和用户&#xff0c;已经加入了最新的CSS属性支持&#xff0c;这其中包含了很多炫酷的功能&#xff0c;但是我们在使用的时候&#xff0c;不得不在属性前面添加这些浏览器的…

nodejs业务分层如何写后端接口

这里展示的是在node express 项目中的操作 &#xff0c;数据库使用的是MongoDB&#xff0c;前期关于express和MongoDB的文章可访问&#xff1a; Nodejs后端express框架 server后端接口操作&#xff1a;通过路由匹配——>调用对应的 Controller——>进行 Service调用——&…

基于YOLOv8深度学习的45种交通标志智能检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

TCP的三次握手

TCP 是一种面向连接的单播协议&#xff0c;在发送数据前&#xff0c;通信双方必须在彼此间建立一条连接。所谓的“连接”&#xff0c;其实是客户端和服务器的内存里保存的一份关于对方的信息&#xff0c;如 IP 地址、端口号等。 TCP 可以看成是一种字节流&#xff0c;它…

强化学习与推荐系统结合

强化学习与推荐系统结合&#xff0c;是在智能体的学习过程中&#xff0c;会根据外部反馈信息&#xff0c;改变自身状态&#xff0c;在根据自身状态进行决策&#xff0c;就是行动反馈&#xff0c;状态更新&#xff0c;在行动的循环。 深度强化学习推荐系统框架是基于强化学习的…

【数据结构】顺序表与单链表的增删查改

文章目录 前言顺序表增删查改顺序表的定义与初始化增删查改操作测试代码完整代码 单链表的增删查改数据结构定义动态申请节点单链表的尾插和头插单链表的尾删和头删单链表的查找单链表的插入和删除销毁链表测试代码完整代码 总结 前言 在计算机编程领域&#xff0c;数据结构是…

力扣Hot100——柱状图中最大矩形(单调栈)

题目链接&#xff1a;https://leetcode.cn/problems/largest-rectangle-in-histogram/description/?envTypestudy-plan-v2&envIdtop-100-liked 经典的单调栈问题 思路&#xff1a;考虑单调递增栈&#xff0c;如果说我拿到的数字比栈顶来的要小&#xff0c;那么说明了我前…

geotool解析shp文件org.locationtech.jts.geom.Polygon报错问题

最近在研究利用geotool制作专题图的功能。geotool加载shp文件和sld样式文件&#xff0c;选然后导出图片&#xff0c;发现点没问题&#xff0c;面总会报&#xff1a; 网上搜到类似问题&#xff1a; GIS:shp文件解析相关_org.locationtech.jts.geom.polygon.getexteriorring(-CS…

搭建APP应用程序如何选择服务器

我经常收到许多关于如何搭建 APP 的询问。其中&#xff0c;如何选择服务器是许多初创企业和开发者经常面临的问题。带着这些问题我也通过一些科技手段收集整理了些知识&#xff0c;今天我就和大家来来探讨如何选择服务器&#xff0c;帮助您搭建一个稳定、高效、安全的 APP。 Ap…

javaEE -18(11000字 JavaScript入门 - 3)

一&#xff1a;事件 &#xff08;高级&#xff09; 1.1 注册事件&#xff08;绑定事件&#xff09; 给元素添加事件&#xff0c;称为注册事件或者绑定事件&#xff0c;注册事件有两种方式&#xff1a;传统方式和方法监听注册方式 传统注册方式 &#xff1a; 利用 on 开头的…

模式识别与机器学习-SVM(线性支持向量机)

线性支持向量机 线性支持向量机间隔距离学习的对偶算法算法:线性可分支持向量机学习算法线性可分支持向量机例子 谨以此博客作为复习期间的记录 线性支持向量机 在以上四条线中&#xff0c;都可以作为分割平面&#xff0c;误差率也都为0。但是那个分割平面效果更好呢&#xff1…

你好!Apache Seata

北京时间 2023 年 10 月 29 日&#xff0c;分布式事务开源项目 Seata 正式通过 Apache 基金会的投票决议&#xff0c;以全票通过的优秀表现正式成为 Apache 孵化器项目&#xff01; 根据 Apache 基金会邮件列表显示&#xff0c;在包含 13 个约束性投票 (binding votes) 和 6 个…