Decoder bytes allocation confusion

Hello all, I am pretty new to The Things Network. I am having a very difficult time figuring out the JavaScript decode uplink function. Before I found out about TTN I was using two LoRa Esp32 nodes. I finally figured out I needed to make a LoRa gateway for consistent communication. I have downloaded the ESP32_LoRaWAN library for Arduino and have edited the sketch for the devices I have connected to my node. I am not asking for someone to rewrite my program for me. I am asking for any documentation to explain how to properly use bytes in the TTN decoder function.

issuesdecode

To be completely honest, Im not really sure what should go in the “(input.bytes[2] << 8) + input.bytes[3];” section of the decoder function and why (as seen below).

data.event = events[input.fPort];
  data.Voltage = (input.bytes[0] << 8) + input.bytes[1];
  data.Perc = (input.bytes[2] << 8) + input.bytes[3];
  data.Lat = (input.bytes[3] << 8) + input.bytes[3];
  data.Lon = (input.bytes[4] << 8) + input.bytes[3];
  data.Alt = (input.bytes[6] << 8) + input.bytes[3];
  data.Hour = (input.bytes[6] << 8) + input.bytes[3];
  data.Min = (input.bytes[7] << 8) + input.bytes[3];
  data.Sec = (input.bytes[8] << 8) + input.bytes[3];
  data.Sensor = (((input.bytes[4] & 0x80 ? input.bytes[4] - 0x100 : input.bytes[4]) << 8) + input.bytes[5]) / 100;

This is the sketch I created for the node

/*
   HelTec Automation(TM) LoRaWAN 1.0.2 OTAA example use OTAA, CLASS A

   Function summary:

   - use internal RTC(150KHz);

   - Include stop mode and deep sleep mode;

   - 15S data send cycle;

   - Informations output via serial(115200);

   - Only ESP32 + LoRa series boards can use this library, need a license
     to make the code run(check you license here: http://www.heltec.cn/search/);

   You can change some definition in "Commissioning.h" and "LoRaMac-definitions.h"

   HelTec AutoMation, Chengdu, China.
   成都惠利特自动化科技有限公司
   https://heltec.org
   support@heltec.cn

  this project also release in GitHub:
  https://github.com/HelTecAutomation/ESP32_LoRaWAN
*/

#include <ESP32_LoRaWAN.h>
#include "Arduino.h"
//Include the needed libraries for the ADS and the GPS module
#include <Wire.h>//I2C library
#include <Adafruit_ADS1X15.h>//ADS library
#include "TinyGPS++.h"//Gps module library

//Define the BAND frequency
#define BAND    915E6//set BAND to US which is 915E6 or 915MHz

//Declare your objects which are the GPS module and the ADS1115 in which we can read the geophone inputs
TinyGPSPlus gps;//This is the GPS object that will pretty much do all the grunt work with the NMEA data
Adafruit_ADS1115 ads;/* Use this for the 16-bit version */

//Declare the global variables
int value = analogRead(A0);
float Voltage;
float Perc;
int16_t SensorRead;
float LatRead;
float LonRead;
float AltRead;
int HourRead;
int MinRead;
int SecRead;




/*license for Heltec ESP32 LoRaWan, quary your ChipID relevant license: http://resource.heltec.cn/search */
uint32_t  license[4] = {0xD5397DF0, 0x8573F814, 0x7A38C73D, 0x48E68607};

/* OTAA para*/
uint8_t DevEui[] = { 0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x04, 0xC7, 0x25 };
uint8_t AppEui[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t AppKey[] = { 0x00, 0x5C, 0xC0, 0x9F, 0x5D, 0x71, 0x4F, 0xE1, 0x0D, 0xAC, 0x21, 0x7D, 0xC4, 0xB3, 0x43, 0x40};

/* ABP para*/
uint8_t NwkSKey[] = { 0x15, 0xb1, 0xd0, 0xef, 0xa4, 0x63, 0xdf, 0xbe, 0x3d, 0x11, 0x18, 0x1e, 0x1e, 0xc7, 0xda, 0x85 };
uint8_t AppSKey[] = { 0x00, 0x5C, 0xC0, 0x9F, 0x5D, 0x71, 0x4F, 0xE1, 0x0D, 0xAC, 0x21, 0x7D, 0xC4, 0xB3, 0x43, 0x40 };
uint32_t DevAddr =  ( uint32_t )0x007e6ae1;

/*LoraWan channelsmask, default channels 0-7*/
uint16_t userChannelsMask[6] = { 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };

/*LoraWan Class, Class A and Class C are supported*/
DeviceClass_t  loraWanClass = CLASS_A;

/*the application data transmission duty cycle.  value in [ms].*/
uint32_t appTxDutyCycle = 15000;

/*OTAA or ABP*/
bool overTheAirActivation = true;

/*ADR enable*/
bool loraWanAdr = true;

/* Indicates if the node is sending confirmed or unconfirmed messages */
bool isTxConfirmed = true;

/* Application port */
uint8_t appPort = 2;

/*!
  Number of trials to transmit the frame, if the LoRaMAC layer did not
  receive an acknowledgment. The MAC performs a datarate adaptation,
  according to the LoRaWAN Specification V1.0.2, chapter 18.4, according
  to the following table:

  Transmission nb | Data Rate
  ----------------|-----------
  1 (first)       | DR
  2               | DR
  3               | max(DR-1,0)
  4               | max(DR-1,0)
  5               | max(DR-2,0)
  6               | max(DR-2,0)
  7               | max(DR-3,0)
  8               | max(DR-3,0)

  Note, that if NbTrials is set to 1 or 2, the MAC will not decrease
  the datarate, in case the LoRaMAC layer did not receive an acknowledgment
*/
uint8_t confirmedNbTrials = 8;

/*LoraWan debug level, select in arduino IDE tools.
  None : print basic info.
  Freq : print Tx and Rx freq, DR info.
  Freq && DIO : print Tx and Rx freq, DR, DIO0 interrupt and DIO1 interrupt info.
  Freq && DIO && PW: print Tx and Rx freq, DR, DIO0 interrupt, DIO1 interrupt and MCU deepsleep info.
*/
uint8_t debugLevel = LoRaWAN_DEBUG_LEVEL;

/*LoraWan region, select in arduino IDE tools*/
LoRaMacRegion_t loraWanRegion = ACTIVE_REGION;

static void prepareTxFrame( uint8_t port )
{
  /*appData size is LORAWAN_APP_DATA_MAX_SIZE which is defined in "commissioning.h".
    appDataSize max value is LORAWAN_APP_DATA_MAX_SIZE.
    if enabled AT, don't modify LORAWAN_APP_DATA_MAX_SIZE, it may cause system hanging or failure.
    if disabled AT, LORAWAN_APP_DATA_MAX_SIZE can be modified, the max value is reference to lorawan region and SF.
    for example, if use REGION_CN470,
    the max value for different DR can be found in MaxPayloadOfDatarateCN470 refer to DataratesCN470 and BandwidthsCN470 in "RegionCN470.h".
  */
  pinMode(Vext, OUTPUT);
  digitalWrite(Vext, LOW);
  float Voltage = value * 5.0 / 1023;
  float Perc = map(Voltage, 3.6, 4.2, 0, 100);
  float LatRead = gps.location.lat();
  float LonRead = gps.location.lng();
  float AltRead = gps.altitude.feet();
  int HourRead = gps.time.hour();
  int MinRead = gps.time.minute();
  int SecRead = gps.time.second();
  int16_t SensorRead = ads.getLastConversionResults();
  digitalWrite(Vext, HIGH);
  unsigned char *puc;

  puc = (unsigned char *)(&Voltage);
  appDataSize = 34;
  appData[0] = puc[0];
  appData[1] = puc[1];
  appData[2] = puc[2];
  appData[3] = puc[3];

  puc = (unsigned char *)(&Perc);
  appData[4] = puc[0];
  appData[5] = puc[1];
  appData[6] = puc[2];
  appData[7] = puc[3];

  puc = (unsigned char *)(&LatRead);
  appData[8] = puc[0];
  appData[9] = puc[1];
  appData[10] = puc[2];
  appData[11] = puc[3];

  puc = (unsigned char *)(&LonRead);
  appData[12] = puc[0];
  appData[13] = puc[1];
  appData[14] = puc[2];
  appData[15] = puc[3];

  puc = (unsigned char *)(&AltRead);
  appData[16] = puc[0];
  appData[17] = puc[1];
  appData[18] = puc[2];
  appData[19] = puc[3];

  puc = (unsigned char *)(&HourRead);
  appData[20] = puc[0];
  appData[21] = puc[1];
  appData[22] = puc[2];
  appData[23] = puc[3];

  puc = (unsigned char *)(&MinRead);
  appData[24] = puc[0];
  appData[25] = puc[1];
  appData[26] = puc[2];
  appData[27] = puc[3];

  puc = (unsigned char *)(&SecRead);
  appData[28] = puc[0];
  appData[29] = puc[1];
  appData[30] = puc[2];
  appData[31] = puc[3];
  
  appData[32] = (uint16_t)(SensorRead >> 8);
  appData[33] = (uint16_t)SensorRead;

  Serial.print("Lat=");
  Serial.print(LatRead);
  Serial.print(", Lon=");
  Serial.print(LonRead);
  Serial.print(", Alt=");
  Serial.println(AltRead);
  Serial.print("Time: ");
  Serial.print(HourRead);
  Serial.print(":");
  Serial.print(MinRead);
  Serial.print(":");
  Serial.println(SecRead);
  Serial.print("Voltage: ");
  Serial.print(Voltage);
  Serial.print(", Percentage: ");  
  Serial.println(Perc);
  Serial.print("Sensor Reading: ");
  Serial.println(SensorRead);
}

// Add your initialization code here
void setup()
{
  Serial.begin(115200);
  while (!Serial);
  SPI.begin(SCK, MISO, MOSI, SS);
  Mcu.init(SS, RST_LoRa, DIO0, DIO1, license);
  deviceState = DEVICE_STATE_INIT;
  Serial2.begin(115200, SERIAL_8N1, 2, 17);
  //serial_connection.begin(115200);//This opens up communications to the GPS
  Serial.println("Hello!");
  Serial.println("Single-ended readings from AIN0 with >3.0V comparator");
  Serial.println("ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)");
  Serial.println("Comparator Threshold: 1000 (3.000V)");
  //                                                                ADS1015  ADS1115
  //                                                                -------  -------
  // ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default)
  //ads.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV
  // ads.setGain(GAIN_TWO);        // 2x gain   +/- 2.048V  1 bit = 1mV      0.0625mV
  // ads.setGain(GAIN_FOUR);       // 4x gain   +/- 1.024V  1 bit = 0.5mV    0.03125mV
  // ads.setGain(GAIN_EIGHT);      // 8x gain   +/- 0.512V  1 bit = 0.25mV   0.015625mV
  //ads.setGain(GAIN_SIXTEEN);    // 16x gain  +/- 0.256V  1 bit = 0.125mV  0.0078125mV
  ads.begin();
  ads.setGain(GAIN_FOUR);
  if (!ads.begin()) {
    Serial.println("Failed to initialize ADS.");
    while (1);
  }
  // Setup 3V comparator on channel 0
  ads.startComparator_SingleEnded(0, 1000);
}

// The loop function is called in an endless loop
void loop()
{
  switch ( deviceState )
  {
    case DEVICE_STATE_INIT:
      {
#if(LORAWAN_DEVEUI_AUTO)
        LoRaWAN.generateDeveuiByChipID();
#endif
        LoRaWAN.init(loraWanClass, loraWanRegion);
        break;
      }
    case DEVICE_STATE_JOIN:
      {
        LoRaWAN.join();
        break;
      }
    case DEVICE_STATE_SEND:
      {
        prepareTxFrame( appPort );
        LoRaWAN.send(loraWanClass);
        deviceState = DEVICE_STATE_CYCLE;
        break;
      }
    case DEVICE_STATE_CYCLE:
      {
        // Schedule next packet transmission
        txDutyCycleTime = appTxDutyCycle + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
        LoRaWAN.cycle(txDutyCycleTime);
        deviceState = DEVICE_STATE_SLEEP;
        break;
      }
    case DEVICE_STATE_SLEEP:
      {
        LoRaWAN.sleep(loraWanClass, debugLevel);
        break;
      }
    default:
      {
        deviceState = DEVICE_STATE_INIT;
        break;
      }
  }
}

Again, I’m not really asking for anyone to rewrite my program, I’m more so looking for any links/articles/ or documentation to explain the bytes and how I can correctly use the decoder function on TTN. Thank you so much in advance.

This may help:

https://www.thethingsnetwork.org/docs/devices/bytes/

For that page, it’s OK to ignore the pink warning.

So I’ve been reading through this document and my apologies for my lack of understanding. In my Arduino sketch I just pasted my old node to node sketch to find (location, time, and a sensor reading) and I inserted it inside of the ESP32_LoRaWAN example sketch (library I got from the Heltec website). Im still unsure if I even programmed the sketch correctly as normally I was just sending messages to another node as integers and strings.

Is this even the correct usage of sending variables via bytes? and if not is there some other documentation that explains how to find how many bytes my particular variable being sent consists of? (again sorry if im asking dumb questions)

  puc = (unsigned char *)(&AltRead);
  appData[16] = puc[0];
  appData[17] = puc[1];
  appData[18] = puc[2];
  appData[19] = puc[3];