How Decoders Work
Decoders (also known as payload formatters) convert raw binary data from LoRaWAN devices into human-readable values.
Why Decoders Are Needed
LoRaWAN devices transmit data as bytes to minimize payload size and conserve battery life. For example:
- Raw bytes:
01 67 01 88 05 - Decoded data:
{"temperature": 35.9, "humidity": 64.8}
Decoder Types
JavaScript Decoders
The most common format, used by Helium Console and ChirpStack:
function Decoder(bytes, port) {
var temperature = ((bytes[0] << 8) | bytes[1]) / 10;
var humidity = ((bytes[2] << 8) | bytes[3]) / 10;
return {
temperature: temperature,
humidity: humidity,
battery: bytes[4] / 10
};
}CayenneLPP
A standardized format for common sensor types:
- Pre-defined data types
- No custom decoder required
- Limited flexibility
Writing a Decoder
Step 1: Understand the Payload Format
Refer to your device’s datasheet or manufacturer documentation for the payload structure.
Example: Dragino LHT65 sends 11 bytes:
Byte 0-1: Temperature (signed, divide by 100)
Byte 2-3: Humidity (unsigned, divide by 10)
Byte 4-5: Battery voltage (unsigned, in mV)
...Step 2: Extract Values
Use bitwise operations to extract multi-byte values:
// Big-endian (most significant byte first)
var temp = (bytes[0] << 8) | bytes[1];
// Handle signed values
if (temp > 32767) {
temp = temp - 65536;
}
temp = temp / 100;Step 3: Return JSON Object
return {
temperature: temp,
humidity: humidity,
battery: battery,
timestamp: Date.now()
};Common Pitfalls
Endianness
- Big-endian: Most significant byte first
[0x01, 0x67]= 359 - Little-endian: Least significant byte first
[0x67, 0x01]= 359
Signed vs Unsigned
- Unsigned: 0 to 65535
- Signed: -32768 to 32767
Data Types
// Correct: JavaScript handles division as floats
var value = bytes[0] / 10;
// Be explicit with bit operations for multi-byte values
var value = (bytes[0] << 8 | bytes[1]) / 100;Testing Your Decoder
- Obtain a sample payload from the device datasheet
- Test with known values
- Verify edge cases (e.g., negative temperatures, maximum values)
- Check decimal precision
Example test:
// Test payload: 01 67 01 88 0F A0
var testBytes = [0x01, 0x67, 0x01, 0x88, 0x0F, 0xA0];
console.log(Decoder(testBytes, 1));
// Expected: {temperature: 35.9, humidity: 64.8, battery: 4000}Finding Existing Decoders
- Manufacturer documentation
- The Things Network Device Repository
- GitHub repositories (e.g., Helium Console Decoders )
- Community forums