How to read a 33-bit field with "node-red-contrib-binary"?

Hi there,

I'm currently using the node-red-contrib-binary, but I'm facing an issue whereby I can't seem to be able to read a 33-bit field.

No issue at all for 1-32 bit, but for 33, I have no clue... Has anybody been able to do so ?

Easy enough with buffer parser node.

[{"id":"af1d307c4cb20277","type":"buffer-parser","z":"85e1791bc0cd6285","name":"","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"bigint64be","name":"MASK_00000001FFFFFFFF","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":"0x00000001FFFFFFFF"},{"type":"bigint64be","name":"MASK_000001FFFFFFFFFF","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":"0x000001FFFFFFFFFF"},{"type":"bigint64be","name":"MASK_0001FFFFFFFFFFFF","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":"0x0001FFFFFFFFFFFF"},{"type":"bigint64be","name":"MASK_000FFFFFFFFFFFFF","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":"0x000FFFFFFFFFFFFF"},{"type":"bigint64be","name":"NO_MASK","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":2170,"y":140,"wires":[["8c178d9160e32087"]]},{"id":"9f6b3d376054a695","type":"inject","z":"85e1791bc0cd6285","name":"0x000FFFFFFFFFFFFF (4503599627370495)","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[0,15,255,255,255,255,255,255, 0,0,0,128,0,0,51  ,  0,0,0,0,129,5,5,1]","payloadType":"bin","x":2070,"y":80,"wires":[["af1d307c4cb20277"]]},{"id":"8c178d9160e32087","type":"debug","z":"85e1791bc0cd6285","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":2170,"y":200,"wires":[]}]

NOTE: This makes use of BigInt type. Your node-js version must be V10.4.0 or greater.
NOTE2: As the result is a BigInt, you might need to change it to a number type (easy in a function node with msg.payload.NO_MASK = Number(msg.payload.NO_MASK);)

Thanks a lot @Steve-Mcl !

While I understand how to navigate through the whole buffer with "node-red-contrib-binary" (My buffer total length is 320 bits), I am not sure to know how to use buffer-parser to do the same.

Would you be able to briefly give me an example over the first say, 16 bits ?

Simply add entrys that relate to the byte offset in the incoming data.
Read the readme and built in help particularly this bit...

Sure, but firstly, have you looked at the built in demos?
CTRL+I → examples → node-red-contrib-buffer-parser
Give them a go to see if it clears things up

Thank you very much, @Steve-Mcl !

I'm able to progress but now I'm stuck with the Mask usage:

  • The 33-bit value I need to read starts at offset 175 (bits)
  • So I need to start reading the bigInt64 at offset 168 (bits), in another word offset 21 (bytes).

But how to extract the right 33 bit ?

Can you provide sample data (use the copy value button in debug sidebar) and what bytes contain what values (and the value you expect it to be)

PS, are you mixing up bits and bytes ?

Hi @Steve-Mcl here it is. The 33-bit long value I need to extract is positioned at the 175th bit (offset), and the integer value is as follows:

Sample data 1:

[252,48,32,0,0,0,0,0,0,0,255,240,15,5,0,15,168,66,127,79,254,50,172,56,15,0,0,0,0,0,0,148,70,103,218]

image

Sample data 2:

[252,48,37,0,0,0,0,0,0,0,255,240,20,5,0,15,168,64,127,239,254,50,196,213,188,254,0,247,49,64,0,0,0,0,0,0,6,231,201,95]

image

PS: Not mixing up bits and bytes, just that Node-RED Buffer parser offset is in bytes, but on the other app I'm using, the offset is expressed in bits :slight_smile:

By the way @Steve-Mcl

Every time I'm trying to use Mask, I keep getting the following error:

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

I really got no idea how to use the mask, even after reading the readme and all... Would you be able to help?

You possibly have an older version (it was a bug)

check you have V3.2.1 installed.

Hi @Steve-Mcl

Which version ?

I installed the latest nodeJS (17.4.0) today morning as well as NodeRED 2.2.0, same problem.

node-red-contrib-buffer-parser v3.2.1

I would suggest sticking with node v16 LTS

@Steve-Mcl

I was running v3.2.0, now running 3.2.1. Will check if I still get the error or not.

In the meanwhile, would you mind helping me understand how the mask would work in my case, and how to apply it?

I'm still facing the issue as shown in the screenshot.

Am I using Mask wrongly ?

Yes, you found a bug :slight_smile: (its the UInt64 type mask isnt parsed correctly)

i have fixed it and released V3.2.2 - it will take 10m or so for the flows lib to become avaiable on your node-red palette manager.

Refresh node-red and see if 3.2.2 is available to update (or use NPM on the terminal if you know how)

Alright, thanks a lot !

Sorry for asking again about the Mask, how can I use it to extract only the 33-bit that I am interested in ?

You have to find the right position in the byte stream. then use a 33 bit mask based on the data. If necessary, you might have to shift the data to right align. Depending on the data format, you may also need to byteswap

PS: 33 bit mask would be 0x00000001FFFFFFFF assuming the data is starting in a sensible position
Another 33 bit mask would be 0x000001FFFFFFFF00 if it was left shifted 1 digit/nibble (4 bits) etc
And IF the data is misaligned then after getting the value you would need to right shift it to correct it e.g. value = (value >> 4);



Are you certain those 2 sample data, 33 bits from bit 175 have the value 2653870640? The sample data is completely different!

If you can provide sample data and the actual expected value, I'll help you solve this.

Hi @Steve-Mcl

I just got it working, but what a mess ! I literally had to do trial and errors, and had to do three things:

  • enabled swap64
  • used bigint64 (LE)
  • and used your magical Mask

And obviously, I'm using the v3.2.2 :slight_smile:

Thank you so much !!

2 Likes

Hi @Steve-Mcl

Little up :slight_smile:

Hi.

I cant really make head nor sense of the data layout. I do know if you choose offset 17 you can read the 45000 value you are expecting.

I wonder if the data is out by 1 byte or the details are incorrect or the data is double swapped?

I say that because bit 175 is actually the last bit (first bit LSB) of byte 21.
Assuming the 33 bit value is packed in 64 bits then the data would layout as follows...

byte 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
value 252 48 32 0 0 0 0 0 0 0 255 240 15 5 97 211 135 180 127 255 126 0 6 221 208 0 56 0 0 0 0 12 195 15 166
1st bit 0 8 16 24 32 40 48 56 64 72 80 88 96 104 112 120 128 136 144 152 160 168 176 184 192 200 208 216 224 232 240 248 256 264 272
last bit 7 15 23 31 39 47 55 63 71 79 87 95 103 111 119 127 135 143 151 159 167 175 183 191 199 207 215 223 231 239 247 255 263 271 279
byte 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
MASK 00 00 00 01 FF FF FF FF

Dont you have any more detailed documentation - often manuals have a sample data, data type descriptions and a worked example showing raw data + final value.

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