TTN payload uplink

hi I am having trouble with a packet decoder in TTN I cannot figure any help would be appreciated. My data is put into a 16-byte message on a LoRaWAN Arduino device
They are all 16-bit uint16_t (temp & hum) I encode them like so:

Decoder(bytes, port) {
  var decoded = {};

  decoded.temperature = ((bytes[0] << 8)| bytes[1]) /100; // temperature ºC
  decoded.humidity = ((bytes[2] << 8) | bytes[3]) /100 ; // humidity %
  return decoded;

I got a different result
Sans titre

It looks like you are putting the bytes in in the payload the other way around (byte 0 low byte of int, byte 1 high byte of int). However it is hard to say without seeing the relevant part of the Arduino sketch.

BTW, you are sending far too often. You are allowed 30 seconds of airtime a day, sending every 15 seconds violates the FUP and might even exceed legal limits (the ones that result in fines or jail time).

1 Like

@kersing thank you for your reply
my data is put into a 16-byte message uint16_t
this is the arduino code

#include "LoRaWANNode.h"

#include <HTS221Sensor.h>
#include <LPS22HBSensor.h>
#include <LSM303AGR_ACC_Sensor.h>
#include <LSM303AGR_MAG_Sensor.h>

#define FRAME_DELAY 10000  // in ms. Every 5 minutes by default.

// Serial port use to communicate with the USI shield.
// By default, use D0 (Rx) and D1(Tx).
// For NUCLEO64, see "Known limitations" chapter in the

HardwareSerial SerialLora(D0, D1);
HardwareSerial Serial1(PA10, PA9);

#define DEV_I2C Wire

// Components.
HTS221Sensor  *HumTemp;
LSM303AGR_ACC_Sensor *Acc;
LSM303AGR_MAG_Sensor *Mag;
LPS22HBSensor *PressTemp;

// AppKey and AppEUI.
const char appKey[] = "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§";
const char appEUI[] = "§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§";

// Data send
struct __attribute__((packed)) frameTx_t {
  int16_t temperature;
  uint8_t humidity;
struct frameTx_t frameTx;

void setupSensors() {
  // Initialize I2C bus.

  // Initlialize components.
  HumTemp = new HTS221Sensor (&DEV_I2C);


void readSensors() {
  // Read humidity and temperature.
  float temp1, hum;

  Serial1.print("HTS221   : ");
  Serial1.print("Hum[%]: ");
  Serial1.print(hum, 0);
  Serial1.print(" | Temp[C]: ");
  Serial1.print(temp1, 2);
  Serial1.println(" |");

frameTx.humidity = hum ;
frameTx.temperature = temp1 * 100;

void setup()
  Serial1.println("\n-- LoRaWAN OTAA sketch --");


  // Enable the USI module and set the radio band.
  while(!loraNode.begin(&SerialLora, LORA_BAND_EU_868)) {
    Serial1.println("Lora module not ready");

  Serial1.println("Joining ...");
  // Send a join request and wait the join accept
  while(!loraNode.joinOTAA(appKey, appEUI)) {
    Serial1.println("joinOTAA failed!!");

  Serial1.println("Lora module ready, OTAA join accepted.\n");

void receive(void) {
  uint8_t frameRx[64];
  uint8_t len;
  uint8_t port;

  // Check if data received from a gateway
  if(loraNode.receiveFrame(frameRx, &len, &port)) {
    uint8_t n = 0;
    Serial1.print("frame received: 0x");
    while(len > 0) {
      Serial1.print(frameRx[n], HEX);
    Serial1.print(" on port "); Serial1.println(port);
  } else {
    Serial1.println("No downlink data");

void transmit(void) {
  // Send unconfirmed data to a gateway (port 1 by default)
  int status = loraNode.sendFrame((char*)&frameTx, sizeof(frameTx),UNCONFIRMED);
  //int status = loraNode.sendFrame(frameTx, sizeof(frameTx), UNCONFIRMED);
  if(status == LORA_SEND_ERROR) {
    Serial1.println("Send frame failed!!!");
  } else if(status == LORA_SEND_DELAYED) {
    Serial1.println("Module busy or duty cycle");
  } else {
    Serial1.println("Uplink frame sent");

void loop()

You may find that we’re very very reluctant to help when you didn’t change your uplink time in the code you posted - please can you reassure us that you have dialled back to ~3 minutes which would be OK(ish) for that size of payload. Note, larger payloads will need longer delays.

I’ve not seen this implementation before - what is the device, firmware, version numbers and why use a packed struct which I’d only use to move data between C & Python. A simple byte array usually does the job - otherwise you’ll need to look at how it’s packed and decode accordingly.

16 bytes? Looks like 3 in the struct …


i’m sorry for my english :cry: !
i’m using P_NUCLEO_LRWAN1 i follow this gethub exemple
GitHub - SylvainMontagny/STM32duino_I-NUCLEO-LRWAN1

i’m using the OTTA exemple and i just add library to calculate the (temp and hum ) After that i send the data usinig fonction loraNode.sendFrame()

about the uplink time i changet to 5 minute and i still get the same result

This does not match your decoder. First of all your humidity is just one byte, not two. Then the next hurdle is the way your compiler packs the structure and the order of bytes used by the controller, all things that you can not control and do not match your (current) assumptions.

I would advice to use a byte array and putting the values ‘manually’ at the position you want them. That way you control what goes where and do not run into issues when you start using another device where the architecture differs and the compiler behaves differently.


That worked like a charm. Problem solved
Thanks a lot sir
solution :

//  global variable dataSender
byte dataSender[4];

uint16_t humidity = hum *100 ;
uint16_t temperature = temp1 * 100;
    dataSender[0] = temperature >> 8;
    dataSender[1] = temperature & 0xFF;
    dataSender[2] = humidity >> 8;
    dataSender[3] = humidity & 0xFF;
1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

You are not dealing with negative temperatures here.

no I am not dealing with a negative temperature sir just positive

Apart from the never say never idiom, there’s also that it’s not much of a solution if it’s not future proof - and with global warming someone else may be helped out if you show how to do that.

ok sir if I find the solution I share it