Read all value from buffer and convert to decimal

4,791 views
Skip to first unread message

Luiey

unread,
Mar 30, 2016, 5:56:31 AM3/30/16
to Node-RED
How to convert a modbus return value to array and split each of it?

Current modbus node return to debug as:-

(Object) { "result": [ "ffcc", "00fa", "00be", "02bc", "01e1", "0190", "1542", "0064" ], "server": "192.168.1.5" }

How to read all 8 hexadecimal value and convert to integer?

Mark Setrem

unread,
Mar 30, 2016, 6:15:11 AM3/30/16
to Node-RED
If you search the forum you should find a recent post that will help you achieve this (try searching for modbus)


Luiey

unread,
Mar 30, 2016, 6:25:24 AM3/30/16
to Node-RED
Hi Mark,

I already search for it and found some question about power meter things here but can't catch to what I wanna do, trying also here.

Still can't catch this javascript things.

Nathanaël Lécaudé

unread,
Mar 30, 2016, 2:01:27 PM3/30/16
to Node-RED
parseInt(ffff, 16) 

Nathanaël Lécaudé

unread,
Mar 30, 2016, 2:14:53 PM3/30/16
to Node-RED
And if you want to convert he whole array:

object.result.map(x => parseInt(x,16))


Le mercredi 30 mars 2016 06:25:24 UTC-4, Luiey a écrit :

Nicholas O'Leary

unread,
Mar 30, 2016, 2:35:28 PM3/30/16
to Node-RED

Not wanting to confuse matters, but the => syntax in

    object.result.map(x => parseInt(x,16))

will only work in node 4.x or later.

Otherwise...

    object.result.map(function(x) { return parseInt(x,16);});


Nick


--
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+u...@googlegroups.com.
To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.
For more options, visit https://groups.google.com/d/optout.

Luiey

unread,
Mar 30, 2016, 9:48:31 PM3/30/16
to Node-RED
Currently I'm following what you done:
var b = parseInt("00fa",16);
msg
.payload = b;
return msg;

The number return is 250 but how to make it 25? Because the number display on Controller Panel is 25.

So from the msg.payload.result that contain hexdecimal:-

var b = parseInt(msg.payload.result [3],16);
msg
.payload = b;
return msg;

stuck on how to get value of index [1],[3],[5],[7] and remove 1 last number

Luiey

unread,
Mar 30, 2016, 10:40:22 PM3/30/16
to Node-RED
Latest result are retrieve using msg.payload.result.map and return on debug panel:-
(Object){"result": [ "ffcc", "00fa", "00be", "02bc", "01e0", "0190", "1543", "0064" ]}

From using here
var result = msg.payload.result.map(x => parseInt(x,16))
msg
.payload = result;
return msg;

(Array) [ 65484, 250, 190, 700, 480, 400, 5443, 100 ]

Q: How to make 250,190,700 to be 25.0,19.0,70.0 as shown in controller and for 65484 value, in controller, it shows -5

Any hint for me to search for this?

Nicholas O'Leary

unread,
Mar 31, 2016, 3:20:10 AM3/31/16
to Node-RED Mailing List
Can you remind us what is generating these values? The format ought to be well documented, otherwise you're asking us to guess at the encoding scheme.

Hopefully you can see that to get from  250,190,700 to  25.0,19.0,70.0 each value has simply been divided by 10. The question is why ffcc represents -5.

Dave C-J

unread,
Mar 31, 2016, 3:32:20 AM3/31/16
to node...@googlegroups.com

Fadhli Azmin

unread,
Mar 31, 2016, 4:05:17 AM3/31/16
to node...@googlegroups.com
This value is generating from Temperature Controller.  Ok the dividing part was totally my shame question for simple answer.

What weird is the hexadecimal result:-

Object receive:  "result": [ "ffcc", "00fa", "00be", "02bc", "01e1", "0190", "1543", "0064"]

After being "var result = msg.payload.result.map(x => parseInt(x,16))"

Device 1    Device 2     Device 3     Device 4
=================================
5443          481            190             65484
100            400            700             250

The number display on panel:-

Device 1    Device 2     Device 3     Device 4
=================================
544            48              19              -5
10              40              70              25

You received this message because you are subscribed to a topic in the Google Groups "Node-RED" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/node-red/TarEdQ19d1U/unsubscribe.
To unsubscribe from this group and all its topics, send an email to node-red+u...@googlegroups.com.

Nathanaël Lécaudé

unread,
Mar 31, 2016, 2:14:09 PM3/31/16
to Node-RED
var input = [ "ffcc", "00fa", "00be", "02bc", "01e1", "0190", "1543", "0064"];
var output = [];

var buffer = new Buffer(input.map(b => [b.substr(0,2), b.substr(2,2)]).reduce((a,b) => a.concat(b)).map(x => parseInt(x, 16)));

for (var b = 0 ; b < buffer.length/2 ; b++) {
  var value = buffer.readInt16BE(b*2, 2) / 10;
  output.push(value.toFixed(0));
}

console.log(output);

Nathanaël Lécaudé

unread,
Mar 31, 2016, 2:50:35 PM3/31/16
to Node-RED
(I have vastly abused of map and reduce in my solution but it works ;) )


Le jeudi 31 mars 2016 04:05:17 UTC-4, Luiey a écrit :

Luiey

unread,
Apr 1, 2016, 5:31:48 AM4/1/16
to Node-RED
That...was...too...many...formula.does playing with this things need to have knowledge much on formula?

Nathanaël Lécaudé

unread,
Apr 1, 2016, 1:50:21 PM4/1/16
to Node-RED
There's definately a nicer way of doing it but if you just take this code straight it should convert the numbers in the format you need.

The basic idea is that the numbers you receive are encoded as Unsigned bytes (UInt16) and we need to convert them to signed bytes (Int16). 
That's what the buffer.readInt16BE() function does. Then there's the division by 10 and the floating part is truncated.

Luiey

unread,
May 13, 2016, 12:14:23 AM5/13/16
to Node-RED
My function for determine "ffcc" is actually negative value send by PLC:-

function returnval(x){
   
if (x > 6000){
        x
= Math.round((x - 65535) / 10);
   
}else{
        x
= Math.round(x/10);
   
}
   
return x;
}
var result = msg.payload.result.map(x => parseInt(x,16));

//result[0] return 65484 value for -5 PV on Temperature Controller
var dev_1 = returnval(result[0]);

As maximum buffer is 65535. So any value highly than max should be perform as returnval(x) function.

This reply will be a references of solving mystery for me :)

Reply all
Reply to author
Forward
0 new messages