Encoding and Decoding Payloads on The Things Network

Stephen just shared a new tutorial: "Encoding and Decoding Payloads on The Things Network"



Sending data to the cloud is great! You’ve followed our Getting Started on The Things Network Tutorial and you have data streaming out of your Pycom Lopy4 and into your TTN account. There is just one problem, it’s all bytes! How do we get…

Read more

there’s a small error in the code posted for decoding a float. One of the bit shift “>” is reversed. I think there’s something else wrong too, but didn’t track it down.

This version from a TTN forum works:-

function Decoder(bytes, port) {

  // Based on https://stackoverflow.com/a/37471538 by Ilya Bursov
  function bytesToFloat(bytes) {
    // JavaScript bitwise operators yield a 32 bits integer, not a float.
    // Assume LSB (least significant byte first).
    var bits = bytes[3]<<24 | bytes[2]<<16 | bytes[1]<<8 | bytes[0];
    var sign = (bits>>>31 === 0) ? 1.0 : -1.0;
    var e = bits>>>23 & 0xff;
    var m = (e === 0) ? (bits & 0x7fffff)<<1 : (bits & 0x7fffff) | 0x800000;
    var f = sign * m * Math.pow(2, e - 150);
    return f;
  }  

  // Test with 0082d241 for 26.3134765625
  return {
    // Take bytes 0 to 4 (not including), and convert to float:
    temp: bytesToFloat(bytes.slice(0, 4))
  };
}
2 Likes

Thanks Andrew!

This is the code that I was pasting in for the example, but it turns out our web platform can’t handle it and it gets corrupted when I upload it. Not too surprising when you think about it. I’ll see if I can work out a fix! In the meantime, thanks for posting the correct code!

glad to help.

Any chance of posting a tutorial that say - takes a temperature reading with the LoPy4 once an hour, sends it to TTN and then sleeps the board to conserve power? I am finding the changeover from Arduino and C++ a bit of a struggle and am limping along, but it would save me a bit of time.

cheers Andrew

Andrew,

Great suggestion! The deep sleep mode is one of the best features of Pycom boards. It would be good to make a tutorial on it. I’ll add it to my list!

Hey Andrew,

Check out this tutorial:

It takes a temperature reading and sends it to TTN every ten seconds. You could easily adapt this to work for your purpose though!

Hi !
I work on aproject with a raspberry and an humidity and temprature sensor DHT11.
I send the value on TTN but I need a decoder code to trnaslate the value of humity into reel value. but I don’it know what to write.

Now I send 32 it receive 22000, or 95 ->29000 or 30 -> 21000
can someone give my the decoder code ?

thanks

Hi K,

There are examples of decoder code in this tutorial. Have you followed the steps in the tutorial?

Here’s an example Encoder() for downlink control of a Dragino I/O Controller

// Decodes the value to either 1 or 0
function onoff(val) {
// Non-strict equals: return 1 for the number 1 or the string “1”
if (val == 1) {
return 1;
}
// Default all missing or invalid values to 0
return 0;
}

function Encoder(object, port) {

var bytes = [];

if (object.Control == “DO”)
{
//test with: {“Control”: “DO”, “DO1”:1 , “DO2”:1, “DO3”:1} => 02 01 01 01 (where 1 = on, 0 = off)

bytes[0] = 0x02;
bytes[1] = onoff(object.DO1);
bytes[2] = onoff(object.DO2);
bytes[3] = onoff(object.DO3);

}

if (object.Control == “RELAY”)
{
//test with: {“Control”: “RELAY”, “RO1”:1 , “RO2”:1} => 03 01 01 (where 1 = close, 0 = open)
//test with: {“Control”: “RELAY”, “RO1”:0 , “RO2”:1} => 03 00 01 (where 1 = close, 0 = open)
//test with: {“Control”: “RELAY”, “RO1”:1 , “RO2”:0} => 03 01 00 (where 1 = close, 0 = open)
bytes[0] = 0x03;
bytes[1] = onoff(object.RO1);
bytes[2] = onoff(object.RO2);
}

if (object.Control == “RESET”)
{
//test with: {“Control”: “RESET”} => 04 FF
bytes[0] = 0x04;
bytes[1] = 0xFF;
}

if (object.Control == “PERIOD”)
{
//test with: {“Control”: “PERIOD”, “Seconds”:60} => 01 00 3C
bytes[0] = 0x01;

// in seconds byte[1]..byte[2] eg.     

bytes[1] = object.Seconds >> 16;
bytes[2] = object.Seconds >> 8 & 0xFF;
bytes[3] = object.Seconds & 0xFF;
}

return bytes;
}

1 Like

Can you please share any code for decoding two variables -one integer and one float that are being sent from the LORA Node? Would be glad to receive any advise or help.
Thank you!

Hi Shivani,

It would depend on how you are encoding those variables. You should be able to solve this problem by sending it all in one string of bytes, and using the shared int decoder and float decoder with a bit-shift to only decode the appropriate bits.

Hi Stephen,

I’m looking to decode a payload into text for 4 different ‘values.’
For example, a payload of 01 94 04 85 should give me
“Insight 1 corresponding to what I’ve assigned 01 to mean”
“94% confidence of the first insight”
“Insight 2 corresponding to what I’ve assigned 03 to mean”
“85% confidence of the second insight”

What would the code look like for this example? I’m guessing that I’m dealing with a float payload.

Many thanks

Hello Stephen

Thanks for the clear tutorial , i’m facing an issue when i try to send couple of data using the ustruct , the 1st value is transmitted correctly to the TTN server but the second not correct :

using the same decoder , but as you can see the 2nd and the 3rd bytes are Zeros (i copied this payload from TTN application )

Kindly , what have i done wrong ?

You are only showing the payload as being 2 bytes, and there is no byte 2 and 3.

You can’t decode what isn’t there. Check the encoding of the data. Should the ustruct.pack format string be ‘hh’?

1 Like