Skip to Content
FundamentalsHow Decoders Work

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

  1. Obtain a sample payload from the device datasheet
  2. Test with known values
  3. Verify edge cases (e.g., negative temperatures, maximum values)
  4. 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

Next Steps