Community
OpenEnergyMonitor

Community

Decoding binary packets


(Paul Reed) #1

Anyone know much about the format of RF data received via rfm2pi??
I’m assuming it’s a jeelibs binary packet which needs decoding in a particular way.

A typical packet received is in the format OK 10 27 1 0 0 0 0 94 95 7 5 (-64) I’m just looking at the jeelabs blog and trying to make sense of it…
So far I’ve worked out that OK is the acknowledgement, 10 is the node, and (-64) is the RSSI.
The others are laid out in pairs, ie (27 & 1), (0 & 0), (0 & 0), (94 & 95) etc.
So to decode for example (94 & 95), it’s (94+256)*95 = 24414 (which then divide by 100 gives me my supply voltage of 244.14V).

Is my understanding correct?


(Robert Wall) #2

You’re pretty much there.

The main body of the format is actually defined in the sketch, in the form of “Payload”, with the NodeID prepended and the RSSI appended.

So

is only true for integers (2 bytes). If it’s a long, it is 4 bytes.
But your maths

is wrong. It is 94 + (95 × 256), which does indeed equal 24414.
Remember, if it’s signed - what you actually need is this (pseudo-code). For unsigned, you stop after the first line.

      x= ([1st byte] + ( [2nd byte] * 2^8) )
      if x > (2^15)
            x = (x - (2^16))
      return x

Your ÷ 100 comes from inside the sketch, where the decimal value was multiplied by 100 to be sent as an integer - so you must divide by 100 to restore it.

Had the last 4 bytes been a long, you’d extend the p-code thus:

      x= ([1st byte] + ( [2nd byte] * 2^8) + ( [3rd byte] * 2^16) + ( [4th byte] * 2^24) )
      if x > (2^31)
            x = (x - (2^32))
      return x

except of course, we don’t often use signed longs, so for unsigned, you stop after the first line.


(Paul Reed) #3

Robert, that’s a great explanation, thanks for writing it up.

Paul


(franck102) #4

The math is right but if you program this watch out for the value of x overflowing esp. for longs.
Another way to extract your values is to copy them into variables of the proper type:

byte *payload = getMessage();
int value1 = *((int *)payload);
payload += sizeof(int);
unsigned long value2 = *((unsigned long *)payload);
payload += sizeof(unsigned long);

etc…

Franck


(Robert Wall) #5

I’m pleased that you agree with my maths. Perhaps you didn’t notice this bit:

In other words, that is the outline of the mathematical operations that you need to do, not an exact recipe.


(franck102) #6

I have no doubt you can do this with your eyes closed, I didn’t mean to offend :slight_smile: I thought maybe the issue wouldn’t be obvious to the original poster…

Franck


(Paul Reed) #7

Thank you Franck, all help gratefully received!
I will however be using JavaScript.