Hi, experts!

I’m using the code mentioned in the above link for temperature and humidity sensing using the Adafruit feather m0 Lora node with the DHT22 sensor. When I check the payload on TTN it shows inconsistent values for Temperature and Humidity.

Here is the code and payload decoder attached below:

void do_send(osjob_t* j){
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) {
Serial.println(F(“OP_TXRXPEND, not sending”));
} else {
// read the temperature from the DHT22
float temperature = dht.readTemperature();
Serial.print(“Temperature: “); Serial.print(temperature);
Serial.println(” *C”);
// adjust for the f2sflt16 range (-1 to 1)
temperature = temperature / 100;

    // read the humidity from the DHT22
    float rHumidity = dht.readHumidity();
    Serial.print("%RH ");
    // adjust for the f2sflt16 range (-1 to 1)
    rHumidity = rHumidity / 100;

    // float -> int
    // note: this uses the sflt16 datum (
    uint16_t payloadTemp = LMIC_f2sflt16(temperature);
    // int -> bytes
    byte tempLow = lowByte(payloadTemp);
    byte tempHigh = highByte(payloadTemp);
    // place the bytes into the payload
    payload[0] = tempLow;
    payload[1] = tempHigh;

    // float -> int
    uint16_t payloadHumid = LMIC_f2sflt16(rHumidity);
    // int -> bytes
    byte humidLow = lowByte(payloadHumid);
    byte humidHigh = highByte(payloadHumid);
    payload[2] = humidLow;
    payload[3] = humidHigh;

    // prepare upstream data transmission at the next possible time.
    // transmit on port 1 (the first parameter); you can use any value from 1 to 223 (others are reserved).
    // don't request an ack (the last parameter, if not zero, requests an ack from the network).
    // Remember, acks consume a lot of network resources; don't ask for an ack unless you really need it.
    LMIC_setTxData2(1, payload, sizeof(payload)-1, 0);
// Next TX is scheduled after TX_COMPLETE event.


function Decoder(bytes, port) {
var temperature = (bytes[0] << 8) | bytes[1];
var humidity = (bytes[2] << 8) | bytes[3];

return {
temperature: temperature / 100, 
humidity: humidity / 100

Serial console

Payload on TTN

The Ubidot application shows the following information

I would request you if any expert could help me in formatting the payload as it shows inconsistent values.


This is the key comment. The data is being transmitted as a scaled floating point (16-bit) value. You have to do some extra work in your JavaScript decoder. See GitHub - mcci-catena/arduino-lmic: LoraWAN-MAC-in-C library, adapted to run under the Arduino environment for info and decoding scripts.

Dear Sir, Thanks for your kind response. I tried the following decoder copied from your repo. However, it shows the following error attached below in a snapshot.

function sflt162f(rawSflt16)
// rawSflt16 is the 2-byte number decoded from wherever;
// it's in range 0..0xFFFF
// bit 15 is the sign bit
// bits 14..11 are the exponent
// bits 10..0 are the the mantissa. Unlike IEEE format,
// the msb is explicit; this means that numbers
// might not be normalized, but makes coding for
// underflow easier.
// As with IEEE format, negative zero is possible, so
// we special-case that in hopes that JavaScript will
// also cooperate.
// The result is a number in the open interval (-1.0, 1.0);

// throw away high bits for repeatability.
rawSflt16 &= 0xFFFF;

// special case minus zero:
if (rawSflt16 == 0x8000)
    return -0.0;

// extract the sign.
var sSign = ((rawSflt16 & 0x8000) != 0) ? -1 : 1;

// extract the exponent
var exp1 = (rawSflt16 >> 11) & 0xF;

// extract the "mantissa" (the fractional part)
var mant1 = (rawSflt16 & 0x7FF) / 2048.0;

// convert back to a floating point number. We hope
// that Math.pow(2, k) is handled efficiently by
// the JS interpreter! If this is time critical code,
// you can replace by a suitable shift and divide.
var f_unscaled = sSign * mant1 * Math.pow(2, exp1 - 15);

return f_unscaled;

Could you please comment on this error?

Yours sincerely