Errors in MODBUS RTU communication

So the value you are getting by setting Active import to biguint64(be) in buffer-parser is wrong ?
The manual just says that its unsigned but doesnt say what kind of unsigned. We were only guessing that its biguint64 because of the gap of registers between the Import and Export.

If that is the case then i think it would be easier to set a Modbus node to read 8 registers from address 20480 (this should cover both active import and export), then wire a complete msg object Debug node to the first output of the Modbus node and use copy value / share the msg by hovering over it in the Debug window.

image

.. and tell us what values you expect for active Import and active Export.

I red more about the modbus flows. I found that there are 2 ways to read the values. The upper exit flow and the lowest exit (flow2).
As far as I can see in the raw data I need 4 values when i read from payload.buffer and 2 values when I read from payload.data[0].
These are the raw values from Node-Red, I used flowexit 2 to generate this.
Do I need the payload.buffer[0] or payload.data[0] values. I do use flowexit 1 at the moment but is this correct?
This is not the complete message object but normal output from flowoutput 2:

msg.payload = {
    value: msg.payload,
    'fc': 3,
    'unitid': 3,
    'address': 23296,
    'quantity': 88
}

return msg

I create the active import object in a moment.

The values are correct at the moment but active import can grow fast, so least significant bit will not be enough and in a year or two it has to bee presented correct too. I need to be sure the right values are safed.

--never mind found the errorsource, didn't change back buffer.payload to msg.payload.

When I use BigInt64BE and I load 8 modbus addresses I get an error:

TypeError: Cannot mix BigInt and other types, use explicit conversions

When I changed it to UInt32BE this is the result:
{"topic":"K03-ID3","messageId":"631339fb9962a9fe8ce0c922","payload":[{"activeimportKWH":112.7},{"MeterId":"K03-ID3","Locatie":"loc1","Locatiegroep":"Huis"},{"timestamp":1662204411665}],"queueLengthByUnitId":{"unitId":3,"queueLength":0},"queueUnitId":3,"unitId":3,"modbusRequest":{"value":1662204411514,"unitid":3,"fc":3,"address":20480,"quantity":4,"emptyMsgOnFail":true,"keepMsgProperties":false,"messageId":"631339fb9962a9fe8ce0c922"},"responseBuffer":{"data":[0,0,0,1127],"buffer":[0,0,0,0,0,0,4,103]},"_msgid":"0e56ea88c50ab3ed","originalPayload":[0,0,0,1127],"specification":{"options":{"byteSwap":[],"resultType":"value","singleResult":true,"msgProperty":"payload","setTopic":true},"items":[{"type":"uint32be","name":"activeimport","offset":4,"length":1,"offsetbit":0,"scale":"/10","mask":"","id":0,"scaler":{"operator":"/","operand":10},"value":112.7}]},"values":[112.7],"objectResults":{"activeimport":{"type":"uint32be","name":"activeimport","offset":4,"length":1,"offsetbit":0,"scale":"/10","mask":"","id":0,"scaler":{"operator":"/","operand":10},"value":112.7}},"keyvalues":{"activeimport":112.7},"arrayResults":[{"type":"uint32be","name":"activeimport","offset":4,"length":1,"offsetbit":0,"scale":"/10","mask":"","id":0,"scaler":{"operator":"/","operand":10},"value":112.7}],"buffer":[0,0,0,0,0,0,4,103]}

I usually link msg.responseBuffer.buffer to the buffer-parser,
as this is the path where the buffer data is using the top output of the Modbus node.

image

With the above buffer that shows in your shared msg i get with biguint64(be)

image

Thanks UnborN,
I see what you mean. I think we're getting close. I use the wrong property as datasource in de buffer-parser node.

msg.responseBuffer.buffer

It takes some time before I can test the new flow but I come back with the results.

Well I have done some tests after the changes in the buffernodes and it works very well. I learned awfully lots about Node-RED and Javscript last weeks. Thank you all!

But there is more. One measurement with strange value, I come to that later.

First a little Modbus RTU RS485 documentation of what I did.

Active import

I had a problem with BigInt, ABB resulst in a number (kWh) with 2 decimals but Javascript BigInt64 refuses to accept this, I decided to convert to number format.

:point_right: Is there a better method?

Edit function Node active use:

// In case of very Big numbers this BigInt64 conversion to Number may be lossy!
// just remove the divide by 100 and drop last 2 digits in BigInt64 number for ActiveImport
ActiveImport = Number(msg.payload[0]) / 100;


msg.payload = [
    {
        VerbruikKWH: ActiveImport
    },
    {
        MeterId: 'K03-ID3',
        Locatie: 'Grnd-Waterpomp Kelder',
        Locatiegroep: 'Huis'
    },
    { timestamp: Date.now()}
];

return msg;

Results in:
activeimportdebug

Voltages

Edit function Node

msg.payload = [
    {
        VoltageL1: msg.payload[0],
        VoltageL2: msg.payload[1],
        VoltageL3: msg.payload[2],
        Frequentie: msg.payload[3]
    },
    {
        MeterId: 'K03-ID3',
        Locatie: 'K03',
        Locatiegroep: 'Huis'
    },
    { timestamp: Date.now()}
];

return msg;

Results in:
voltagedebug

Current/Power

msg.payload = [
    {
        StroomL1:   msg.payload[0],
        StroomL2:   msg.payload[1],
        StroomL3:   msg.payload[2],
//        StroomN:    msg.payload[3],
        VermogenT:  msg.payload[4],
        VermogenL1: msg.payload[5],
        VermogenL2: msg.payload[6],
        VermogenL3: msg.payload[7],
    },
    {
        MeterId: 'K03-ID3',
        Locatie: 'K03',
        Locatiegroep: 'Huis'
    },
    { timestamp: Date.now()}
];

return msg;

results in:
powerdebug

So all seems wel but there is one value which is very unlikely --> StroomN (this means Current) has a value of 42949672.95 Ampere.

:point_right: Does anyone of you have any idea what is going on here? I better do correct this now.

This is the result of my message object:

{"topic":"K03-ID3","messageId":"amessageid","payload":[{"StroomL1":1.04,"StroomL2":1.05,"StroomL3":1.04,"VermogenT":271.75,"VermogenL1":96.36,"VermogenL2":91.89,"VermogenL3":83.5},{"MeterId":"K03-ID3","Locatie":"K03","Locatiegroep":"Huis"},{"timestamp":1662737950647}],"queueLengthByUnitId":{"unitId":3,"queueLength":0},"queueUnitId":3,"unitId":3,"modbusRequest":{"value":[0,2302,0,2347,0,2296,0,4014,0,4011,0,4002,0,104,0,105,0,104,65535,65535,0,27175,0,9636,0,9189,0,8350,32767,65535,32767,65535,32767,65535,32767,65535,32767,65535,32767,65535,32767,65535,32767,65535,5000,32767,32767,32767,32767,32767,32767,32767,65535,65535,65535,32767,32767,32767,375,32767,32767,32767,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535],"unitid":3,"fc":3,"address":23296,"quantity":88,"emptyMsgOnFail":true,"keepMsgProperties":false,"messageId":"631b5e1e1093f9c5335c1472"},"responseBuffer":{"data":[0,2302,0,2347,0,2296,0,4014,0,4011,0,4002,0,104,0,105,0,104,65535,65535,0,27175,0,9636,0,9189,0,8350,32767,65535,32767,65535,32767,65535,32767,65535,32767,65535,32767,65535,32767,65535,32767,65535,5000,32767,32767,32767,32767,32767,32767,32767,65535,65535,65535,32767,32767,32767,375,32767,32767,32767,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535],"buffer":[0,0,8,254,0,0,9,43,0,0,8,248,0,0,15,174,0,0,15,171,0,0,15,162,0,0,0,104,0,0,0,105,0,0,0,104,255,255,255,255,0,0,106,39,0,0,37,164,0,0,35,229,0,0,32,158,127,255,255,255,127,255,255,255,127,255,255,255,127,255,255,255,127,255,255,255,127,255,255,255,127,255,255,255,127,255,255,255,19,136,127,255,127,255,127,255,127,255,127,255,127,255,127,255,255,255,255,255,255,255,127,255,127,255,127,255,1,119,127,255,127,255,127,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]},"_msgid":"e1fae1b7cf82c08c","originalPayload":[0,2302,0,2347,0,2296,0,4014,0,4011,0,4002,0,104,0,105,0,104,65535,65535,0,27175,0,9636,0,9189,0,8350,32767,65535,32767,65535,32767,65535,32767,65535,32767,65535,32767,65535,32767,65535,32767,65535,5000,32767,32767,32767,32767,32767,32767,32767,65535,65535,65535,32767,32767,32767,375,32767,32767,32767,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535],"specification":{"options":{"byteSwap":[],"resultType":"value","singleResult":true,"msgProperty":"payload","setTopic":true},"items":[{"type":"uint32be","name":"StroomL1","offset":24,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":0,"scaler":{"operator":"/","operand":100},"value":1.04},{"type":"uint32be","name":"StroomL2","offset":28,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":1,"scaler":{"operator":"/","operand":100},"value":1.05},{"type":"uint32be","name":"StroomL3","offset":32,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":2,"scaler":{"operator":"/","operand":100},"value":1.04},{"type":"uint32be","name":"StroomN","offset":36,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":3,"scaler":{"operator":"/","operand":100},"value":42949672.95},{"type":"uint32be","name":"VermogenT","offset":40,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":4,"scaler":{"operator":"/","operand":100},"value":271.75},{"type":"uint32be","name":"VermogenL1","offset":44,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":5,"scaler":{"operator":"/","operand":100},"value":96.36},{"type":"uint32be","name":"VermogenL2","offset":48,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":6,"scaler":{"operator":"/","operand":100},"value":91.89},{"type":"uint32be","name":"VermogenL3","offset":52,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":7,"scaler":{"operator":"/","operand":100},"value":83.5}]},"values":[1.04,1.05,1.04,42949672.95,271.75,96.36,91.89,83.5],"objectResults":{"StroomL1":{"type":"uint32be","name":"StroomL1","offset":24,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":0,"scaler":{"operator":"/","operand":100},"value":1.04},"StroomL2":{"type":"uint32be","name":"StroomL2","offset":28,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":1,"scaler":{"operator":"/","operand":100},"value":1.05},"StroomL3":{"type":"uint32be","name":"StroomL3","offset":32,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":2,"scaler":{"operator":"/","operand":100},"value":1.04},"StroomN":{"type":"uint32be","name":"StroomN","offset":36,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":3,"scaler":{"operator":"/","operand":100},"value":42949672.95},"VermogenT":{"type":"uint32be","name":"VermogenT","offset":40,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":4,"scaler":{"operator":"/","operand":100},"value":271.75},"VermogenL1":{"type":"uint32be","name":"VermogenL1","offset":44,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":5,"scaler":{"operator":"/","operand":100},"value":96.36},"VermogenL2":{"type":"uint32be","name":"VermogenL2","offset":48,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":6,"scaler":{"operator":"/","operand":100},"value":91.89},"VermogenL3":{"type":"uint32be","name":"VermogenL3","offset":52,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":7,"scaler":{"operator":"/","operand":100},"value":83.5}},"keyvalues":{"StroomL1":1.04,"StroomL2":1.05,"StroomL3":1.04,"StroomN":42949672.95,"VermogenT":271.75,"VermogenL1":96.36,"VermogenL2":91.89,"VermogenL3":83.5},"arrayResults":[{"type":"uint32be","name":"StroomL1","offset":24,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":0,"scaler":{"operator":"/","operand":100},"value":1.04},{"type":"uint32be","name":"StroomL2","offset":28,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":1,"scaler":{"operator":"/","operand":100},"value":1.05},{"type":"uint32be","name":"StroomL3","offset":32,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":2,"scaler":{"operator":"/","operand":100},"value":1.04},{"type":"uint32be","name":"StroomN","offset":36,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":3,"scaler":{"operator":"/","operand":100},"value":42949672.95},{"type":"uint32be","name":"VermogenT","offset":40,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":4,"scaler":{"operator":"/","operand":100},"value":271.75},{"type":"uint32be","name":"VermogenL1","offset":44,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":5,"scaler":{"operator":"/","operand":100},"value":96.36},{"type":"uint32be","name":"VermogenL2","offset":48,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":6,"scaler":{"operator":"/","operand":100},"value":91.89},{"type":"uint32be","name":"VermogenL3","offset":52,"length":1,"offsetbit":0,"scale":"/100","mask":"","id":7,"scaler":{"operator":"/","operand":100},"value":83.5}],"buffer":[0,0,8,254,0,0,9,43,0,0,8,248,0,0,15,174,0,0,15,171,0,0,15,162,0,0,0,104,0,0,0,105,0,0,0,104,255,255,255,255,0,0,106,39,0,0,37,164,0,0,35,229,0,0,32,158,127,255,255,255,127,255,255,255,127,255,255,255,127,255,255,255,127,255,255,255,127,255,255,255,127,255,255,255,127,255,255,255,19,136,127,255,127,255,127,255,127,255,127,255,127,255,127,255,255,255,255,255,255,255,127,255,127,255,127,255,1,119,127,255,127,255,127,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]}

interesting .. i was wondering about this also about javascript BigInts ..
so you were trying to directly divide the bigInt / 100 and it wasnt working ?
yea .. it seems that bigints can only be divided by another bigInt ?
unless you convert it to a Number as you did but you have to be sure that the Active import value wont exceed the Maximum safe integer ( Number.MAX_SAFE_INTEGER : 9007199254740991n )

There are some interesting examples on the MDN website

const truncated = 5n / 2n
// ↪ 2n, not 2.5n

and also this article to avoid losing that precision that you noticed, which they multiply the bigint by 100n, convert it to a Number and then divide it by 10000 (in your case) to get the float representation of the value.

No it isn't working... This is the error (I had the error on the buffer parser too but dropped the screenprints and function code I tested yesterday):

I tried this thing from your first linked website yesterday too:

var a = 12340000000000000000n;
var b =  1000000000000000000n;

console.log(Number(a * 100n / b) / 100);

I got the same error, this time in the function. Although I'm not sure now if I typed "a * 100n". I think I missed the "n".... Is important as I read on this page.

It costed me already lots of time experimenting so I took the short way to succes: convert to number. Creating an own class was a bridge to far for me. Where do you create such a thing? In the same function node? Are there side effects in the flows or is this local in the used function node?

class BigDecimal {

I tried some other ways:
Convert Bigint to string, remove last 2 digits and concatenate the string together: concatenated_Bigint &"."&"last_two_2_digits".
Last 2 digits could I try to find with Bigint - 100 * (Bigint / 100) which maybe could have worked if I used 100n.

I found the concatenation function "Slice" for this later. Funny, I see now that I tried to reinvent that "class BigDecimal" in a simpler way :slight_smile:. Which is not very easy if you know very little from the basics of Javascript nor Java.

Would that class Bigdecimal be a good way to use here?

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