IEEE-754 Floating Point Converter

You haven't got enough zeros on the mask for the sign bit (it should be 0x8000000000000000) but the more fundamental problem is that the max integer value in js is 2^53-1 so you can't turn it into a 64 bit integer and then extract the sign and exponent. You will have to extract the sign and exponent from the first word and then build the mantissa up from the rest of the first word and the other three.

1 Like

Unless the algorithm is for academic interest... why not use the built in Buffer functions ? readDoubleBE - https://nodejs.org/docs/latest-v8.x/api/buffer.html#buffer_buf_readdoublebe_offset_noassert

[{"id":"bc5b882d.b961d8","type":"function","z":"adc578f5.614308","name":"IEEE-754 to float","func":"\nvar buf = Buffer.from([0x40,0xa6,0x63,0x95,0x33,0x67,0x3,0xe]);\nmsg.payload = buf.readDoubleBE(0);\nreturn msg","outputs":1,"noerr":0,"x":350,"y":1580,"wires":[["61eac4ea.e82a6c"]]},{"id":"61eac4ea.e82a6c","type":"debug","z":"adc578f5.614308","name":"Value","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"payload","x":560,"y":1580,"wires":[]},{"id":"5c471d6a.442cb4","type":"inject","z":"adc578f5.614308","name":"","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":1580,"wires":[["bc5b882d.b961d8"]]}]
2 Likes

Thank you all very much.
The result was the following.

[{"id":"485407f3.a2f768","type":"inject","z":"7b2adc08.02a074","name":"fromeRegesters","topic":"","payload":"{\"data\":[16550,25493,13159,782],\"buffer\":[64,166,99,149,51,103,3,14]}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":80,"wires":[["9dd0a3e6.b9bf9"]]},{"id":"9dd0a3e6.b9bf9","type":"function","z":"7b2adc08.02a074","name":"4words to double","func":"//Total Active Energy Import On Peak Tariff\t2.87 kWh\n// PAC3200 801 register\nvar buf = Buffer.from(msg.payload.buffer);\n\nvar value = buf.readDoubleBE(0)*0.001; // Wh to kWh\nmsg.payload = value.toFixed(2) ;\n\n msg.topic = \"tae\"; //Total Active Energy Import On Peak Tariff\n node.status({fill:\"blue\",shape:\"ring\",text:msg.topic + \":\" + msg.payload});\n\nreturn msg;","outputs":1,"noerr":0,"x":370,"y":80,"wires":[["da09114e.8482a"]]},{"id":"da09114e.8482a","type":"debug","z":"7b2adc08.02a074","name":"Value","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"payload","x":580,"y":80,"wires":[]},{"id":"2dff6e4f.649152","type":"modbus-read","z":"7b2adc08.02a074","name":"","topic":"tap","showStatusActivities":false,"showErrors":false,"unitid":"1","dataType":"HoldingRegister","adr":"801","quantity":"4","rate":"1","rateUnit":"s","delayOnStart":true,"startDelayTime":"5","server":"d0e66f0d.1db13","useIOFile":false,"ioFile":"","useIOForPayload":false,"x":130,"y":140,"wires":[[],["9dd0a3e6.b9bf9"]]},{"id":"d0e66f0d.1db13","type":"modbus-client","z":"","name":"PAC3200","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":false,"tcpHost":"192.168.71.15","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","unit_id":"1","commandDelay":"1","clientTimeout":"1000","reconnectTimeout":"2000"}]

I cant seem to get it to work. I'm trying to read a USB Pressure Sensor from Omega.
Any Suggestions?

Here is one of the buffers. It should be around 14 PSIG

[170,59,160,31,199,62]

Omega

Here is the flow

[{"id":"64790db0.313854","type":"serial in","z":"ff00b690.4e7c68","name":"Pressure Sensor","serial":"6bd65ea6.e09bb","x":430,"y":370,"wires":[["411711e2.2982e8"]]},{"id":"4168cb0.a26ee34","type":"serial out","z":"ff00b690.4e7c68","name":"Pressure Sensor Command Request","serial":"6bd65ea6.e09bb","x":880,"y":420,"wires":[]},{"id":"606c6e75.6521a","type":"inject","z":"ff00b690.4e7c68","name":"Single Sample","topic":"","payload":"[80,13,10]","payloadType":"bin","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":440,"y":420,"wires":[["4168cb0.a26ee34"]]},{"id":"99b77fc8.24ed6","type":"inject","z":"ff00b690.4e7c68","name":"Stop Continuous Sample","topic":"","payload":"[80,83,13,10]","payloadType":"bin","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":480,"y":480,"wires":[["4168cb0.a26ee34"]]},{"id":"36c8c941.b32f6e","type":"inject","z":"ff00b690.4e7c68","name":"Start Continuous Sample","topic":"","payload":"[80,67,13,10]","payloadType":"bin","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":480,"y":540,"wires":[["4168cb0.a26ee34"]]},{"id":"db125b9c.688738","type":"inject","z":"ff00b690.4e7c68","name":"fromeRegesters","topic":"","payload":"{\"data\":[16550,25493,13159,782],\"buffer\":[64,166,99,149,51,103,3,14]}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":450,"y":590,"wires":[["a7fbda.b73c6c28"]]},{"id":"a7fbda.b73c6c28","type":"function","z":"ff00b690.4e7c68","name":"4words to double","func":"//Total Active Energy Import On Peak Tariff\t2.87 kWh\n// PAC3200 801 register\nvar buf = Buffer.from(msg.payload.buffer);\n\nvar value = buf.readDoubleBE(0)*0.001; // Wh to kWh\nmsg.payload = value.toFixed(2) ;\n\n msg.topic = \"tae\"; //Total Active Energy Import On Peak Tariff\n node.status({fill:\"blue\",shape:\"ring\",text:msg.topic + \":\" + msg.payload});\n\nreturn msg;","outputs":1,"noerr":0,"x":680,"y":590,"wires":[["5a1df516.38cea4"]]},{"id":"5a1df516.38cea4","type":"debug","z":"ff00b690.4e7c68","name":"Value","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"payload","x":890,"y":590,"wires":[]},{"id":"411711e2.2982e8","type":"debug","z":"ff00b690.4e7c68","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":800,"y":370,"wires":[]},{"id":"6bd65ea6.e09bb","type":"serial-port","z":"","serialport":"/dev/ttyUSB0","serialbaud":"115200","databits":"8","parity":"none","stopbits":"1","waitfor":"0xAA","dtr":"none","rts":"none","cts":"none","dsr":"none","newline":"6","bin":"bin","out":"count","addchar":"","responsetimeout":"10000"}]

Hi,

looks more like 0.38 to me...

[{"id":"e3a46d9.4a1ea9","type":"function","z":"c4f68fc3.2dd88","name":"IEEE-754 to float","func":"\nvar buf = Buffer.from([170,59,160,31,199,62]);\nmsg.payload = buf.readFloatLE(2);\nreturn msg","outputs":1,"noerr":0,"x":370,"y":640,"wires":[["54f49b8e.c0cd94"]]},{"id":"54f49b8e.c0cd94","type":"debug","z":"c4f68fc3.2dd88","name":"Value","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"payload","x":580,"y":640,"wires":[]},{"id":"c3b9e733.2a7438","type":"inject","z":"c4f68fc3.2dd88","name":"","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":640,"wires":[["e3a46d9.4a1ea9"]]}]

You are right! They snt me the wrong sensor. it was to be PSIA - Absolute but they sent me PSIG - Gauge.

Thank you. Now to get a $600.00 sensor swapped.... Ugh

Got it working but the data is coming in very fast and i'm worried about an overflow condition.

I'm getting this.

{"payload":14.331297874450684,"_msgid":"d5bffa5.f807e08","error":"TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type number"}

[
    {
        "id": "64790db0.313854",
        "type": "serial in",
        "z": "ff00b690.4e7c68",
        "name": "Pressure Sensor",
        "serial": "6bd65ea6.e09bb",
        "x": 100,
        "y": 340,
        "wires": [
            [
                "2bce8846.82789"
            ]
        ]
    },
    {
        "id": "2bce8846.82789",
        "type": "function",
        "z": "ff00b690.4e7c68",
        "name": "IEEE-754 to float",
        "func": "var buf = Buffer.from(msg.payload);\nmsg.payload = buf.readFloatLE(2);\nreturn msg",
        "outputs": 1,
        "noerr": 0,
        "x": 340,
        "y": 340,
        "wires": [
            [
                "131dfaf1.bdb325"
            ]
        ]
    },
    {
        "id": "d5ec99bf.39811",
        "type": "debug",
        "z": "ff00b690.4e7c68",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "x": 720,
        "y": 340,
        "wires": []
    },
    {
        "id": "131dfaf1.bdb325",
        "type": "change",
        "z": "ff00b690.4e7c68",
        "name": "",
        "rules": [
            {
                "t": "delete",
                "p": "port",
                "pt": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 560,
        "y": 340,
        "wires": [
            [
                "d5ec99bf.39811"
            ]
        ]
    },
    {
        "id": "6bd65ea6.e09bb",
        "type": "serial-port",
        "z": "",
        "serialport": "/dev/ttyUSB0",
        "serialbaud": "115200",
        "databits": "8",
        "parity": "none",
        "stopbits": "1",
        "waitfor": "0xAA",
        "dtr": "none",
        "rts": "none",
        "cts": "none",
        "dsr": "none",
        "newline": "6",
        "bin": "bin",
        "out": "count",
        "addchar": "",
        "responsetimeout": "10000"
    }
]

Had to fix the function to guarantee 6 bytes

var buf = Buffer.from([0x0,0x0,0x0,0x0,0x0,0x0]);
buf = msg.payload;
msg.payload = buf.readFloatLE(2);
return msg

That will have absolutely no effect since on the next line you overwright buf.

How can I keep the buffer from dropping to 5 character?

You canā€™t stop it. You can check the length and look for the correct start byte or just reject any of incorrect length

If you end up with a buffer five long then that means there were only five in msg.payload.

Fixed with a delay acting as a message limiter to the dashboard, and log the data as CVS file for high speed capture for millisec times

I also had to add a function to trim spurious readings.

Using this sensor

https://www.omega.com/en-us/sensors-and-sensing-equipment/pressure-and-strain/pressure-transducers/px409-series/p/PX409-1-5KAUSBH

Thanks all....

[{"id":"64790db0.313854","type":"serial in","z":"ff00b690.4e7c68","name":"Pressure Sensor","serial":"6bd65ea6.e09bb","x":110,"y":340,"wires":[["51c57ee2.7609e8"]]},{"id":"4168cb0.a26ee34","type":"serial out","z":"ff00b690.4e7c68","name":"Pressure Sensor Command Request","serial":"6bd65ea6.e09bb","x":1020,"y":600,"wires":[]},{"id":"99b77fc8.24ed6","type":"inject","z":"ff00b690.4e7c68","name":"Stop Continuous Sample","topic":"","payload":"[80,83,13,10]","payloadType":"bin","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":680,"y":460,"wires":[["4168cb0.a26ee34"]]},{"id":"36c8c941.b32f6e","type":"inject","z":"ff00b690.4e7c68","name":"Start Continuous Sample","topic":"","payload":"[80,67,13,10]","payloadType":"bin","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":680,"y":510,"wires":[["4168cb0.a26ee34"]]},{"id":"2bce8846.82789","type":"function","z":"ff00b690.4e7c68","name":"IEEE-754 to float","func":"var buf = Buffer.from([0x0,0x0,0x0,0x0,0x0,0x0]);\nbuf = msg.payload;\nmsg.payload = buf.readFloatLE(2);\nreturn msg","outputs":1,"noerr":0,"x":640,"y":340,"wires":[["269bcc4d.3494f4"]]},{"id":"8b2f0579.8e2b3","type":"change","z":"ff00b690.4e7c68","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"1","fromt":"num","to":"[80,67,13,10]","tot":"bin"},{"t":"change","p":"payload","pt":"msg","from":"0","fromt":"num","to":"[80,83,13,10]","tot":"bin"}],"action":"","property":"","from":"","to":"","reg":false,"x":720,"y":600,"wires":[["4168cb0.a26ee34"]]},{"id":"2f17a650.aa6b62","type":"ui_chart","z":"ff00b690.4e7c68","name":"Combustion Chamber Pressure","group":"ce13473e.f4756","order":2,"width":"38","height":"6","label":"Combustion Chamber Pressure","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"0","ymax":"","removeOlder":"6","removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":1180,"y":340,"wires":[[]]},{"id":"88d5aeb2.9528f8","type":"change","z":"ff00b690.4e7c68","name":"","rules":[{"t":"delete","p":"port","pt":"msg"},{"t":"set","p":"topic","pt":"msg","to":"PSIA","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":340,"wires":[["2bce8846.82789"]]},{"id":"8d9892be.231e38","type":"mqtt in","z":"ff00b690.4e7c68","name":"Reset","topic":"Reset","qos":"2","datatype":"auto","broker":"6b8f56d7.82af78","x":60,"y":600,"wires":[["7da2a1f8.83a178","67e33003.78bcd"]]},{"id":"2b85e6a3.e66a12","type":"calculate","z":"ff00b690.4e7c68","name":"","pauseType":"timed","calculation":"median","timeout":"1","timeoutUnits":"seconds","rate":"10","x":950,"y":340,"wires":[["2f17a650.aa6b62","8047929c.d6c1b"]]},{"id":"51c57ee2.7609e8","type":"delay","z":"ff00b690.4e7c68","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"5","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"x":280,"y":340,"wires":[["88d5aeb2.9528f8"]]},{"id":"269bcc4d.3494f4","type":"function","z":"ff00b690.4e7c68","name":"","func":"if (msg.payload > 1500){\n   msg.payload = \" \"; \n  }\nreturn msg;","outputs":1,"noerr":0,"x":800,"y":340,"wires":[["2b85e6a3.e66a12"]]},{"id":"168e6f77.5d1ec1","type":"function","z":"ff00b690.4e7c68","name":"Push Button","func":"var state = context.get(\"STATE\")||0;\n\n//  Look for a !X message to get values.\nif (msg.payload != \"X\")     //Do this if the message is NOT \"X\"\n{\n    //\n    //  Background colours first.\n    //\n    context.set(\"ABGC\", msg.colourA);\n    context.set(\"BBGC\", msg.colourB);\n    //\n    //  Now do text.\n    //\n    context.set(\"Atxt\", msg.txtA);\n    context.set(\"Btxt\", msg.txtB);\n    //\n    //  Font colours.\n    //\n    context.set(\"AFC\",msg.txtclrA);\n    context.set(\"BFC\",msg.txtclrB);\n    //\n    //  Payloads.\n    //\n    context.set(\"PayloadA\", msg.payloadA);\n    context.set(\"PayloadB\", msg.payloadB);\n    //\n    //  Icons.\n    //\n    context.set(\"icon_on\", msg.icon_on);\n    context.set(\"icon_off\", msg.icon_off);\n    //\n    //  Topic.\n    //\n    if (msg.topicSET !== null)\n    {\n        context.set(\"Topic\",msg.topicSET);\n    } else\n    {\n        context.set(\"Topic\",\"~\");\n    }\n    return;\n}\n//      Now on to the real stuff.\nif (msg.payload == \"X\")\n{\n    state = (state + 1)% 2;\n    //node.warn(state);\n    context.set(\"STATE\",state);\n}\nif (state === 0)\n{\n    //  Condition A\n    msg.payload = context.get(\"PayloadA\");\n    msg.colour = context.get(\"ABGC\");\n    msg.txt = context.get(\"icon_off\")+context.get(\"Atxt\");\n    msg.fontclr = context.get(\"AFC\");\n    msg.icon = context.get(\"icon_off\");\n} else\n{\n    //  Condition B\n    msg.payload = context.get(\"PayloadB\");\n    msg.colour = context.get(\"BBGC\");\n    msg.txt = context.get(\"icon_on\")+context.get(\"Btxt\");\n    msg.fontclr = context.get(\"BFC\");\n    msg.icon = context.get(\"icon_on\");\n}\nif (context.get(\"Topic\") == \"~\")\n{\n    msg.topic = \"\";\n} else\n{\n    msg.topic = context.get(\"Topic\");\n}\nreturn msg;\n","outputs":1,"noerr":0,"x":400,"y":600,"wires":[["701d3c21.e62634","8b2f0579.8e2b3"]]},{"id":"701d3c21.e62634","type":"ui_button","z":"ff00b690.4e7c68","name":"High Speed Sampling","group":"8b254e41.bdbcf","order":4,"width":3,"height":2,"passthru":false,"label":"{{msg.txt}}","tooltip":"","color":"{{msg.fontclr}}","bgcolor":"{{msg.colour}}","icon":"","payload":"X","payloadType":"str","topic":"","x":430,"y":560,"wires":[["168e6f77.5d1ec1"]]},{"id":"67e33003.78bcd","type":"function","z":"ff00b690.4e7c68","name":"Setup","func":"msg = {\n    \"colourA\": \"red\",\n    \"colourB\": \"green\",\n    \"txtA\": \"Off\",\n    \"txtB\": \"On\",\n    \"txtclrA\": \"black\",\n    \"txtclrB\": \"white\",\n    \"payloadA\": \"0\",\n    \"payloadB\": \"1\",\n    \"icon_off\": '<i class=\"fa fa-2x fa-toggle-off\"></i> ',\n    \"icon_on\": '<i class=\"fa fa-2x fa-toggle-on\"></i> ',\n    \"topicSET\": \"HighSpeedSampling\"\n}\nreturn msg;","outputs":1,"noerr":0,"x":240,"y":600,"wires":[["168e6f77.5d1ec1"]]},{"id":"8047929c.d6c1b","type":"ui_level","z":"ff00b690.4e7c68","group":"717868ad.8b7468","order":2,"width":6,"height":24,"name":"Pressure","label":"Pressure","colorHi":"#e60000","colorWarn":"#ff9900","colorNormal":"#00b33c","colorOff":"#595959","min":0,"max":"1500","segWarn":"","segHigh":"","unit":"PSIA","layout":"sv","channelA":"","channelB":"","decimals":"2","animations":"reactive","shape":"1","colorschema":"fixed","textoptions":"custom","colorText":"#ffffff","fontLabel":"1","fontValue":"","fontSmall":"","colorFromTheme":false,"textAnimations":true,"hideValue":false,"tickmode":"auto","peakmode":true,"peaktime":"10000","x":1120,"y":380,"wires":[]},{"id":"6bd65ea6.e09bb","type":"serial-port","z":"","serialport":"/dev/ttyUSB0","serialbaud":"115200","databits":"8","parity":"none","stopbits":"1","waitfor":"0xAA","dtr":"none","rts":"none","cts":"none","dsr":"none","newline":"6","bin":"bin","out":"count","addchar":"","responsetimeout":"10000"},{"id":"ce13473e.f4756","type":"ui_group","z":"","name":"Graphs","tab":"91b245b1.b4ed7","order":11,"disp":true,"width":"38","collapse":true},{"id":"6b8f56d7.82af78","type":"mqtt-broker","z":"","name":"PI","broker":"127.0.0.1","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"home/temperature","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"8b254e41.bdbcf","type":"ui_group","z":"","name":"High Speed Capture","tab":"91b245b1.b4ed7","order":2,"disp":true,"width":"5","collapse":false},{"id":"717868ad.8b7468","type":"ui_group","z":"","name":"Combustion Chamber Level","tab":"91b245b1.b4ed7","order":12,"disp":true,"width":"12","collapse":false},{"id":"91b245b1.b4ed7","type":"ui_tab","z":"","name":"Pump Control Dashboard","icon":"dashboard","order":3,"disabled":false,"hidden":false}]
1 Like