Modbus 16 bit registers to Float value

I am NOT a javascript programmer, just trying to read a Modbus device and get a value out to inject into a data base. I have been struggling with this for hours and hours reading this forum and others.

I get two 16 bit unsigned integers in the msg.payload from Modbus-Flex-Getter [ 61124, 17011 ] I put them into a function node with the following code:

let pay = msg.payload;

const buf = Buffer.allocUnsafe(4);
buf.writeUInt16BE(pay[0], 2);
buf.writeUInt16BE(pay[1], 0);
msg.payload = buf.readFloatBE(0);

return msg;

The value returned in a debug node from the function node is the correct value, but in hex code (0x3c.fbb1). When I use a change node to create a flow variable from the value, I get a ",undefined) : msg.topic : string[73]" error. How do I get a numeric float value (61.642425537109375) from the hex code returned?

Hi, just use the buffer parser and you´ll get success soon.

edit, I tried:

[
    {
        "id": "11026c1822d2eaa3",
        "type": "inject",
        "z": "9f6752b0.b55988",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "true",
        "payloadType": "bool",
        "x": 1690,
        "y": 140,
        "wires": [
            [
                "9b37eb3980bfca78"
            ]
        ]
    },
    {
        "id": "9b37eb3980bfca78",
        "type": "function",
        "z": "9f6752b0.b55988",
        "name": "Array",
        "func": "msg.payload = [61124,17011];\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1690,
        "y": 200,
        "wires": [
            [
                "81d3c91a381f1cf9"
            ]
        ]
    },
    {
        "id": "97b1d3916ce91a4f",
        "type": "debug",
        "z": "9f6752b0.b55988",
        "name": "debug 2",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 1700,
        "y": 320,
        "wires": []
    },
    {
        "id": "81d3c91a381f1cf9",
        "type": "buffer-parser",
        "z": "9f6752b0.b55988",
        "name": "",
        "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": "keyvalue",
        "resultTypeType": "return",
        "multipleResult": false,
        "fanOutMultipleResult": false,
        "setTopic": true,
        "outputs": 1,
        "x": 1710,
        "y": 260,
        "wires": [
            [
                "97b1d3916ce91a4f"
            ]
        ]
    }
]

and got 61124 :face_with_monocle:

@Steve-Mcl will know

I have tried every possible combination of the buffer-parser without a usable value.

I get an array[1] of 0x0.0f44276 or another useless number.

You dont, you get 60.98316955566406 (you really should be exact when asking for assistance.)

Anyhow, I can see from your function code your data is 32bit, then 16bit swapped then read as a Big Endian value. Which is odd - what writes the values to ModBus registers in the first place?

No-code solution...

Demo flow (use CTRL-I to import)

[{"id":"d91ff976927ea647","type":"buffer-parser","z":"22bb2f33123bf539","name":"swap 32, swap16, BE","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"floatbe","name":"temperature","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":""}],"swap1":"swap32","swap2":"swap16","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":760,"y":260,"wires":[["339f476ae7d0e70e"]]},{"id":"b0d077567a7af96f","type":"inject","z":"22bb2f33123bf539","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[ 61124, 17011 ]","payloadType":"json","x":520,"y":300,"wires":[["d91ff976927ea647","dbccc077e654fd40"]]},{"id":"339f476ae7d0e70e","type":"debug","z":"22bb2f33123bf539","name":"debug 153","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":970,"y":260,"wires":[]},{"id":"dbccc077e654fd40","type":"function","z":"22bb2f33123bf539","name":"function 4","func":"let pay = msg.payload;\n\nconst buf = Buffer.allocUnsafe(4);\nbuf.writeUInt16BE(pay[0], 2);\nbuf.writeUInt16BE(pay[1], 0);\nmsg.payload = buf.readFloatBE(0);\n\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":720,"y":340,"wires":[["67a7553fc6f4235f"]]},{"id":"67a7553fc6f4235f","type":"debug","z":"22bb2f33123bf539","name":"debug 155","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":970,"y":340,"wires":[]}]
1 Like

Thank you for your help. I never would have figured out how exactly to use the buffer-parse node.

To answer your question. The modbus registers are read from the the floating point addresses of a AutomationDirect CLICK PLC and are 4-20ma analog inputs.

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