RAK4630 not connecting to LoraWan

Hi.
I just star with my first wisblock project with a tracker coinfiguration using:
RAK5005-O
RAK4631-AU915
RAK1904
RAK1910

After loading the Tracker example:

I got this message:
image

All the keys are coorect in the Lorawan server (TTN Server)

The gateway is just a few meters away.,

This is the configuration in the sketch:

bool doOTAA = true; // OTAA is used by default.
#define SCHED_MAX_EVENT_DATA_SIZE APP_TIMER_SCHED_EVENT_DATA_SIZE /< Maximum size of scheduler events. */
#define SCHED_QUEUE_SIZE 60 /
< Maximum number of events in the scheduler queue. /
#define LORAWAN_DATERATE DR_0 /LoRaMac datarates definition, from DR_0 to DR_5/
#define LORAWAN_TX_POWER TX_POWER_5 /LoRaMac tx power definition, from TX_POWER_0 to TX_POWER_15/
#define JOINREQ_NBTRIALS 3 /**< Number of trials for the join request. /
DeviceClass_t gCurrentClass = CLASS_A; /
class definition
/
LoRaMacRegion_t gCurrentRegion = LORAMAC_REGION_AU915; /* Region:EU868*/
lmh_confirm gCurrentConfirm = LMH_UNCONFIRMED_MSG; /* confirm/unconfirm packet definition*/
uint8_t gAppPort = LORAWAN_APP_PORT; /* data port*/

And the KEYS are this:

//OTAA keys !!! KEYS ARE MSB !!!

uint8_t nodeDeviceEUI[8] = {0xAC, 0x1F, 0x09, 0xFF, 0xFE, 0x05, 0x70, 0xFE};
uint8_t nodeAppEUI[8] = {0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x02, 0x01, 0xE1};
uint8_t nodeAppKey[16] = {CORRECT AN VERIFIED};

What is missing? can anybody help me please?

If I am not wrong, TTN uses subband 2 for AU915 (channels 8 to 15).
You need to add

	if (!lmh_setSubBandChannels(2))
	{
		Serial.println("lmh_setSubBandChannels failed. Wrong sub band requested?");
		return -3;
	}

after calling lmh_init()

Thank you Bernd.

I’m using subband 1 (0 to 7) I guess I need to put lmh_setSubBandChannels(1) instead.
But I put this after the band definition and gave me a compilation error.

Wher should I put this code ?

Regards,

If TTN is using subband 2 you have to use lmh_setSubBandChannels(2), not 1 (count starts at 1, not at 0).

Look for the code line with lmh_init() in it and place the lmh_setSubBandChannels(2) after the init command.

e.g.:


	// Initialize LoRaWan
	if (lmh_init(&lora_callbacks, lora_param_init, g_lorawan_settings.otaa_enabled, (eDeviceClass)g_lorawan_settings.lora_class, (LoRaMacRegion_t)g_lorawan_settings.lora_region) != 0)
	{
		Serial.println("Failed to initialize LoRaWAN");
		return -2;
	}

	// For some regions we might need to define the sub band the gateway is listening to
	// This must be called AFTER lmh_init()
	if (!lmh_setSubBandChannels(2))
	{
		Serial.println("lmh_setSubBandChannels failed. Wrong sub band requested?");
		return -3;
	}

Hi Bernd:

The code in the Tracker example is this:

// Initialize LoRaWan
err_code = lmh_init(&lora_callbacks, lora_param_init, doOTAA, gCurrentClass, gCurrentRegion);
if (err_code != 0)
{
Serial.printf(“lmh_init failed - %d\n”, err_code);
return;
}

// Start Join procedure
lmh_join();
}

If I put the code in it like this it gave me a compilation error (I need to use channeles 0 to 7, so I put subchannel 1.

Change the return -3 with just return

	// For some regions we might need to define the sub band the gateway is listening to
	// This must be called AFTER lmh_init()
	if (!lmh_setSubBandChannels(2))
	{
		Serial.println("lmh_setSubBandChannels failed. Wrong sub band requested?");
		return;
	}

Hi Bernd.

Finnaly I can join de Lorawan network but it send no data to the network.
The tracker is outside and it get coorect location but it do not send packets to TTN.

This is the output:

X = 16.01mg Y = -16.01mg Z =-976.79mg
.00,V,N4B
$GPRMC,153025.00,V,070123,N
7A
$GPVTG,N30
$GPGGA,153025.00,0,00,99.99,66
$GPGSA,A,1,99.99,99.99,99.99
30
$GPGSV,1,1,03,08,33,16,37,27,37
70
$GPGLL,153025.00,V,N4A
$GPRMC,153026.00,V,4.61,4.50,1.00
0A
$GPGSV,1,1,03,08,21,229,32,16,63,282,37,27,52,212,3740
$GPGLL,3256.96395,S,07132.01068,W,153034.00,A,A
6C
$GPRMC,153035.00,A,3256.96415,S,07132.01098,W,0.131,070123,A70
$GPVTG,T,M,0.131,N,0.243,K,A
25
$GPGGA,153035.00,3256.96415,S,07132.01098,W,1,03,4.50,-1.2,M,29.0,M,*7F
$GPGSA,A,2,08,16,27,lmh_send ok count 1
Sending frame now…
lmh_send fail count 1
Sending frame now…
lmh_send fail count 2
Sending frame now…
lmh_send fail count 3

And this is waht I get in TTN:

This is the code I’m using:

/**

 * @file GPS_Tracker.ino

 * @author rakwireless.com

 * @brief This sketch demonstrate a GPS tracker that collect location from a uBlox M7 GNSS sensor

 *    and send the data to lora gateway.

 *    It uses a 3-axis acceleration sensor to detect movement of the tracker

 * @version 0.2

 * @date 2021-04-30

 *

 * @copyright Copyright (c) 2020

 *

 * @note RAK4631 GPIO mapping to nRF52840 GPIO ports

   RAK4631    <->  nRF52840

   WB_IO1     <->  P0.17 (GPIO 17)

   WB_IO2     <->  P1.02 (GPIO 34)

   WB_IO3     <->  P0.21 (GPIO 21)

   WB_IO4     <->  P0.04 (GPIO 4)

   WB_IO5     <->  P0.09 (GPIO 9)

   WB_IO6     <->  P0.10 (GPIO 10)

   WB_SW1     <->  P0.01 (GPIO 1)

   WB_A0      <->  P0.04/AIN2 (AnalogIn A2)

   WB_A1      <->  P0.31/AIN7 (AnalogIn A7)

 */

#include <Arduino.h>

#include <LoRaWan-RAK4630.h> //http://librarymanager/All#SX126x

#include <SPI.h>

#include "SparkFunLIS3DH.h" //http://librarymanager/All#SparkFun-LIS3DH

#include "Wire.h"

#include <TinyGPS.h>        //http://librarymanager/All#TinyGPS

LIS3DH SensorTwo(I2C_MODE, 0x18);

TinyGPS gps;

String tmp_data = "";

int direction_S_N = 0;  //0--S, 1--N

int direction_E_W = 0;  //0--E, 1--W

// RAK4630 supply two LED

#ifndef LED_BUILTIN

#define LED_BUILTIN 35

#endif

#ifndef LED_BUILTIN2

#define LED_BUILTIN2 36

#endif

bool doOTAA = true;   // OTAA is used by default.

#define SCHED_MAX_EVENT_DATA_SIZE APP_TIMER_SCHED_EVENT_DATA_SIZE /**< Maximum size of scheduler events. */

#define SCHED_QUEUE_SIZE 60                     /**< Maximum number of events in the scheduler queue. */

#define LORAWAN_DATERATE DR_0                   /*LoRaMac datarates definition, from DR_0 to DR_5*/

#define LORAWAN_TX_POWER TX_POWER_5             /*LoRaMac tx power definition, from TX_POWER_0 to TX_POWER_15*/

#define JOINREQ_NBTRIALS 3                      /**< Number of trials for the join request. */

DeviceClass_t gCurrentClass = CLASS_A;          /* class definition*/

LoRaMacRegion_t gCurrentRegion = LORAMAC_REGION_AU915;    /* Region:AU915*/

lmh_confirm gCurrentConfirm = LMH_UNCONFIRMED_MSG;          /* confirm/unconfirm packet definition*/

uint8_t gAppPort = LORAWAN_APP_PORT;                      /* data port*/

/**@brief Structure containing LoRaWan parameters, needed for lmh_init()

 */

static lmh_param_t lora_param_init = {LORAWAN_ADR_ON, LORAWAN_DATERATE, LORAWAN_PUBLIC_NETWORK, JOINREQ_NBTRIALS, LORAWAN_TX_POWER, LORAWAN_DUTYCYCLE_OFF};

// Foward declaration

static void lorawan_has_joined_handler(void);

static void lorawan_join_failed_handler(void);

static void lorawan_rx_handler(lmh_app_data_t *app_data);

static void lorawan_confirm_class_handler(DeviceClass_t Class);

static void send_lora_frame(void);

/**@brief Structure containing LoRaWan callback functions, needed for lmh_init()

*/

static lmh_callback_t lora_callbacks = {BoardGetBatteryLevel, BoardGetUniqueId, BoardGetRandomSeed,

                                        lorawan_rx_handler, lorawan_has_joined_handler, lorawan_confirm_class_handler, lorawan_join_failed_handler

                                       };

                                       

//OTAA keys !!!! KEYS ARE MSB !!!!

uint8_t nodeDeviceEUI[8] = {0xAC, 0x1F, 0x09, 0xFF, 0xFE, 0x05, 0x70, 0xFE};

uint8_t nodeAppEUI[8] = {0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x02, 0x01, 0xE1};

uint8_t nodeAppKey[16] = {0x49, 0x24, 0x0E, 0xEE, 0xBF, 0xBD, 0x3F, 0x7D, 0x89, 0x8A, 0xA1, 0x15, 0x09, 0x26, 0xAC, 0xFD};

// ABP keys

uint32_t nodeDevAddr = 0x260116F8;

uint8_t nodeNwsKey[16] = {0x7E, 0xAC, 0xE2, 0x55, 0xB8, 0xA5, 0xE2, 0x69, 0x91, 0x51, 0x96, 0x06, 0x47, 0x56, 0x9D, 0x23};

uint8_t nodeAppsKey[16] = {0xFB, 0xAC, 0xB6, 0x47, 0xF3, 0x58, 0x45, 0xC7, 0x50, 0x7D, 0xBF, 0x16, 0x8B, 0xA8, 0xC1, 0x7C};

// Private defination

#define LORAWAN_APP_DATA_BUFF_SIZE 64                     /**< buffer size of the data to be transmitted. */

#define LORAWAN_APP_INTERVAL 10000                        /**< Defines for user timer, the application data transmission interval. 10s, value in [ms]. */

static uint8_t m_lora_app_data_buffer[LORAWAN_APP_DATA_BUFF_SIZE];        //< Lora user application data buffer.

static lmh_app_data_t m_lora_app_data = {m_lora_app_data_buffer, 0, 0, 0, 0}; //< Lora user application data structure.

TimerEvent_t appTimer;

static uint32_t timers_init(void);

static uint32_t count = 0;

static uint32_t count_fail = 0;

void setup()

{

  pinMode(LED_BUILTIN, OUTPUT);

  digitalWrite(LED_BUILTIN, LOW);

  // Initialize Serial for debug output

  time_t timeout = millis();

  Serial.begin(115200);

  while (!Serial)

  {

    if ((millis() - timeout) < 5000)

    {

      delay(100);

    }

    else

    {

      break;

    }

  }

  // Initialize LoRa chip.

  lora_rak4630_init();

  Serial.println("=====================================");

  Serial.println("Welcome to RAK4630 LoRaWan!!!");

  if (doOTAA)

  {

    Serial.println("Type: OTAA");

  }

  else

  {

    Serial.println("Type: ABP");

  }

  switch (gCurrentRegion)

  {

    case LORAMAC_REGION_AS923:

      Serial.println("Region: AS923");

      break;

    case LORAMAC_REGION_AU915:

      Serial.println("Region: AU915");

      break;

    case LORAMAC_REGION_CN470:

      Serial.println("Region: CN470");

      break;

  case LORAMAC_REGION_CN779:

    Serial.println("Region: CN779");

    break;

    case LORAMAC_REGION_EU433:

      Serial.println("Region: EU433");

      break;

    case LORAMAC_REGION_IN865:

      Serial.println("Region: IN865");

      break;

    case LORAMAC_REGION_EU868:

      Serial.println("Region: EU868");

      break;

    case LORAMAC_REGION_KR920:

      Serial.println("Region: KR920");

      break;

    case LORAMAC_REGION_US915:

      Serial.println("Region: US915");

    break;

  case LORAMAC_REGION_RU864:

    Serial.println("Region: RU864");

    break;

  case LORAMAC_REGION_AS923_2:

    Serial.println("Region: AS923-2");

    break;

  case LORAMAC_REGION_AS923_3:

    Serial.println("Region: AS923-3");

    break;

  case LORAMAC_REGION_AS923_4:

    Serial.println("Region: AS923-4");

      break;

  }

  Serial.println("=====================================");

  //lis3dh init

  if (SensorTwo.begin() != 0)

  {

    Serial.println("Problem starting the sensor at 0x18.");

  }

  else

  {

    Serial.println("Sensor at 0x18 started.");

  // Set low power mode

  uint8_t data_to_write = 0;

  SensorTwo.readRegister(&data_to_write, LIS3DH_CTRL_REG1);

  data_to_write |= 0x08;

  SensorTwo.writeRegister(LIS3DH_CTRL_REG1, data_to_write);

  delay(100);

  data_to_write = 0;

  SensorTwo.readRegister(&data_to_write, 0x1E);

  data_to_write |= 0x90;

  SensorTwo.writeRegister(0x1E, data_to_write);

  delay(100);

  }

  //gps init

  pinMode(WB_IO2, OUTPUT);

  digitalWrite(WB_IO2, 0);

  delay(1000);

  digitalWrite(WB_IO2, 1);

  delay(1000);

 

  Serial1.begin(9600);

  while (!Serial1);

  Serial.println("gps uart init ok!");

 

  //creat a user timer to send data to server period

  uint32_t err_code;

  err_code = timers_init();

  if (err_code != 0)

  {

    Serial.printf("timers_init failed - %d\n", err_code);

    return;

  }

  // Setup the EUIs and Keys

  if (doOTAA)

  {

    lmh_setDevEui(nodeDeviceEUI);

    lmh_setAppEui(nodeAppEUI);

    lmh_setAppKey(nodeAppKey);

  }

  else

  {

    lmh_setNwkSKey(nodeNwsKey);

    lmh_setAppSKey(nodeAppsKey);

    lmh_setDevAddr(nodeDevAddr);

  }

  // Initialize LoRaWan

  err_code = lmh_init(&lora_callbacks, lora_param_init, doOTAA, gCurrentClass, gCurrentRegion);

  if (err_code != 0)

  {

    Serial.printf("lmh_init failed - %d\n", err_code);

    return;

  }

  if (!lmh_setSubBandChannels(1))

  {

    Serial.println("lmh_setSubBandChannels failed. Wrong sub band requested?");

    return;

  }

  // Start Join procedure

  lmh_join();

}

void loop()

{

  // Put your application tasks here, like reading of sensors,

  // Controlling actuators and/or other functions.

}

/**@brief LoRa function for handling HasJoined event.

 */

void lorawan_has_joined_handler(void)

{

  if(doOTAA == true)

  {

  Serial.println("OTAA Mode, Network Joined!");

  }

  else

  {

    Serial.println("ABP Mode");

  }

  lmh_error_status ret = lmh_class_request(gCurrentClass);

  if (ret == LMH_SUCCESS)

  {

    delay(1000);

    TimerSetValue(&appTimer, LORAWAN_APP_INTERVAL);

    TimerStart(&appTimer);

  }

}

/**@brief LoRa function for handling OTAA join failed

*/

static void lorawan_join_failed_handler(void)

{

  Serial.println("OTAA join failed!");

  Serial.println("Check your EUI's and Keys's!");

  Serial.println("Check if a Gateway is in range!");

}

/**@brief Function for handling LoRaWan received data from Gateway

 *

 * @param[in] app_data  Pointer to rx data

 */

void lorawan_rx_handler(lmh_app_data_t *app_data)

{

  Serial.printf("LoRa Packet received on port %d, size:%d, rssi:%d, snr:%d, data:%s\n",

          app_data->port, app_data->buffsize, app_data->rssi, app_data->snr, app_data->buffer);

}

void lorawan_confirm_class_handler(DeviceClass_t Class)

{

  Serial.printf("switch to class %c done\n", "ABC"[Class]);

  // Informs the server that switch has occurred ASAP

  m_lora_app_data.buffsize = 0;

  m_lora_app_data.port = gAppPort;

  lmh_send(&m_lora_app_data, gCurrentConfirm);

}

void send_lora_frame(void)

{

  if (lmh_join_status_get() != LMH_SET)

  {

    //Not joined, try again later

    return;

  }

  lmh_error_status error = lmh_send(&m_lora_app_data, gCurrentConfirm);

  if (error == LMH_SUCCESS)

  {

    count++;

    Serial.printf("lmh_send ok count %d\n", count);

  }

  else

  {

    count_fail++;

    Serial.printf("lmh_send fail count %d\n", count_fail);

  }

  TimerSetValue(&appTimer, LORAWAN_APP_INTERVAL);

  TimerStart(&appTimer);

  Serial.println("Sending frame now...");

  send_lora_frame();

}

/**@brief Function for analytical direction.

 */

void direction_parse(String tmp)

{

    if (tmp.indexOf(",E,") != -1)

    {

        direction_E_W = 0;

    }

    else

    {

        direction_E_W = 1;

    }

   

    if (tmp.indexOf(",S,") != -1)

    {

        direction_S_N = 0;

    }

    else

    {

        direction_S_N = 1;

    }

}

/**@brief Function for handling a LoRa tx timer timeout event.

 */

String data = "";

void tx_lora_periodic_handler(void)

{

  float x = 0;

  float y = 0;

  float z = 0;

  bool newData = false;

 

  Serial.println("check acc!");

  x = SensorTwo.readFloatAccelX() * 1000;

  y = SensorTwo.readFloatAccelY() * 1000;

  z = SensorTwo.readFloatAccelZ() * 1000;

  data = "X = " + String(x) + "mg" + " Y = " + String(y) + "mg" + " Z =" + String(z) + "mg";

  Serial.println(data);

  data = "";

  //  if( abs(x-z) < 400)

//  {

    // For one second we parse GPS data and report some key values

    for (unsigned long start = millis(); millis() - start < 1000;)

    {

      while (Serial1.available())

      {

        char c = Serial1.read();

        Serial.write(c); // uncomment this line if you want to see the GPS data flowing

        tmp_data += c;

        if (gps.encode(c))// Did a new valid sentence come in?

          newData = true;

      }

    }

    direction_parse(tmp_data);

    tmp_data = "";

    float flat, flon;

    int32_t ilat, ilon;

    if (newData)

    {

      unsigned long age;  

      gps.f_get_position(&flat, &flon, &age);

      flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat;

      ilat = flat * 100000;

      flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon;

      ilon = flon * 100000;

      memset(m_lora_app_data.buffer, 0, LORAWAN_APP_DATA_BUFF_SIZE);

      m_lora_app_data.port = gAppPort;

      m_lora_app_data.buffer[0] = 0x09;

      //lat data

      m_lora_app_data.buffer[1] = (ilat & 0xFF000000) >> 24;

      m_lora_app_data.buffer[2] = (ilat & 0x00FF0000) >> 16;

      m_lora_app_data.buffer[3] = (ilat & 0x0000FF00) >> 8;

      m_lora_app_data.buffer[4] =  ilat & 0x000000FF;

      if(direction_S_N == 0)

      {

        m_lora_app_data.buffer[5] = 'S';    

      }

      else

      {

        m_lora_app_data.buffer[5] = 'N';    

      }

      //lon data

      m_lora_app_data.buffer[6] = (ilon & 0xFF000000) >> 24;

      m_lora_app_data.buffer[7] = (ilon & 0x00FF0000) >> 16;

      m_lora_app_data.buffer[8] = (ilon & 0x0000FF00) >> 8;

      m_lora_app_data.buffer[9] =  ilon & 0x000000FF;

      if(direction_E_W == 0)

      {

        m_lora_app_data.buffer[10] = 'E';

      }

      else

      {

        m_lora_app_data.buffer[10] = 'W';

      }

      m_lora_app_data.buffsize = 11;

      send_lora_frame();

    }

    else

    {

      TimerSetValue(&appTimer, LORAWAN_APP_INTERVAL);

      TimerStart(&appTimer);

    }

//  }

//  else

//  {

//    TimerSetValue(&appTimer, LORAWAN_APP_INTERVAL);

//    TimerStart(&appTimer);

//  }

}

/**@brief Function for the Timer initialization.

 *

 * @details Initializes the timer module. This creates and starts application timers.

 */

uint32_t timers_init(void)

{

  TimerInit(&appTimer, tx_lora_periodic_handler);

  return 0;

}
1 Like

Hi Alejandro,

Change

to #define LORAWAN_DATARATE DR_3

The data packet might be too large for the max packet size allowed with DR0.

In our docs we have an overview DR - packetsize

Thank you.
Now I receive a packet, but without any location data. Everytime the same packet:

With this details:

{
“name”: “as.up.data.forward”,
“time”: “2023-01-09T04:58:32.558079798Z”,
“identifiers”: [
{
“device_ids”: {
“device_id”: “eui-ac1f09fffe0570fe”,
“application_ids”: {
“application_id”: “lorawan-scanner”
},
“dev_eui”: “AC1F09FFFE0570FE”,
“join_eui”: “70B3D57ED00201E1”,
“dev_addr”: “260CED12”
}
}
],
“data”: {
@type”: “type.googleapis.com/ttn.lorawan.v3.ApplicationUp”,
“end_device_ids”: {
“device_id”: “eui-ac1f09fffe0570fe”,
“application_ids”: {
“application_id”: “lorawan-scanner”
},
“dev_eui”: “AC1F09FFFE0570FE”,
“join_eui”: “70B3D57ED00201E1”,
“dev_addr”: “260CED12”
},
“correlation_ids”: [
“as:up:01GPAE9YQ6VPDBXYRZK3CKQTNJ”,
“gs:conn:01GP9TPNG58KFV31D0EVEWAFQW”,
“gs:up:host:01GP9TPNMTMZ928MBRAN6JSXHD”,
“gs:uplink:01GPAE9YGFDBBNP4EKW86YNQ2M”,
“ns:uplink:01GPAE9YGGZ6WMY8XSG0C5DF6R”,
“rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01GPAE9YGG2REMMQBYHRY6NXWX”,
“rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01GPAE9YQ5CFQ13JSQEJ7E0G8A”
],
“received_at”: “2023-01-09T04:58:32.549895649Z”,
“uplink_message”: {
“session_key_id”: “AYWU47U+wV5t3x7P8SVjQQ==”,
“f_port”: 2,
“frm_payload”: “Cf/NuO5T/5LYmFc=”,
“rx_metadata”: [
{
“gateway_ids”: {
“gateway_id”: “eui-ac1f09fffe0148a2”,
“eui”: “AC1F09FFFE0148A2”
},
“timestamp”: 3388108747,
“rssi”: -70,
“channel_rssi”: -70,
“snr”: 9.8,
“uplink_token”: “CiIKIAoUZXVpLWFjMWYwOWZmZmUwMTQ4YTISCKwfCf/+AUiiEMvfyc8MGgwI+L3unQYQs5OGoAEg+OGS2M3WBA==”,
“received_at”: “2023-01-09T04:58:32.228165025Z”
}
],
“settings”: {
“data_rate”: {
“lora”: {
“bandwidth”: 125000,
“spreading_factor”: 7,
“coding_rate”: “4/5”
}
},
“frequency”: “915200000”,
“timestamp”: 3388108747
},
“received_at”: “2023-01-09T04:58:32.336378782Z”,
“consumed_airtime”: “0.061696s”,
“network_ids”: {
“net_id”: “000013”,
“tenant_id”: “ttn”,
“cluster_id”: “nam1”,
“cluster_address”: “nam1.cloud.thethings.network”
}
}
},
“correlation_ids”: [
“as:up:01GPAE9YQ6VPDBXYRZK3CKQTNJ”,
“gs:conn:01GP9TPNG58KFV31D0EVEWAFQW”,
“gs:up:host:01GP9TPNMTMZ928MBRAN6JSXHD”,
“gs:uplink:01GPAE9YGFDBBNP4EKW86YNQ2M”,
“ns:uplink:01GPAE9YGGZ6WMY8XSG0C5DF6R”,
“rpc:/ttn.lorawan.v3.GsNs/HandleUplink:01GPAE9YGG2REMMQBYHRY6NXWX”,
“rpc:/ttn.lorawan.v3.NsAs/HandleUplink:01GPAE9YQ5CFQ13JSQEJ7E0G8A”
],
“origin”: “ip-10-101-12-119.us-west-1.compute.internal”,
“context”: {
“tenant-id”: “CgN0dG4=”
},
“visibility”: {
“rights”: [
“RIGHT_APPLICATION_TRAFFIC_READ”
]
},
“unique_id”: “01GPAE9YQEJ06QBMDQBHFZZMS1”
}

You are getting location data, it is as Base64 decoded values in “frm_payload”:

The Base64 payload decodes to an byte array: 09 ff cd b8 ee 53 ff 92 d8 98 57

You need a payload decoder in TTN that translates that data into locations.
In TTN, goto your device, select Payload formatters, selecte Custom Javascript formatter and copy the paylod decoder code into the Formatter code field:

This is the decoder you have to use in TTN:

function Decoder(bytes, fport) 
{
  var longitude_int, latitude_int;
  var decoded = {"latitude":"","longitude":""};
  
  if (fport === 2)
  {
    if(bytes[0]==9) // check if the header byte is 9.
    {
      latitude_int = (bytes[1] << 24) | (bytes[2] << 16) | (bytes[3] << 8) | (bytes[4]);
      decoded.latitude = latitude_int / 100000;
      longitude_int = (bytes[6] << 24) | (bytes[7] << 16) | (bytes[8] << 8) | (bytes[9]);
      decoded.longitude = longitude_int / 100000;
      return decoded;
    }
  }
}

You can find this information in our Github repo example

1 Like

Thank you very much Bernd. It works ok.

A final advice. Is possible to get more precise location? Using 6 decimals intead of 5?
Regards,

Hi Alejandro,

I don’t have the 6 decimals solution for our example code, but I have a different code that can use 6 decimals.

It is an more complicated code that we use in our RAK10700 Location Tracker and it has as well an AT command interface, so the LoRaWAN credentials are not hardcoded, but can be setup for each device through the USB. LPWAN-Tracker-Solution

This code is as well optimized for lower power consumption.

1 Like

Thank you Bernd.
I tried to use this new example but I updated the 4630 firmware with the WistoolBox and updated it to RUI.
After this I can not load any other firmware anymore!

I get this error every time I try to load any new sketch even the one who was working before.

Failed to upgrade target. Error is: No data received on serial port. Not able to proceed.
Traceback (most recent call last):
File “main.py”, line 296, in serial
File “dfu\dfu.py”, line 235, in dfu_send_images
File “dfu\dfu.py”, line 199, in _dfu_send_image
File “dfu\dfu_transport_serial.py”, line 179, in send_start_dfu
File “dfu\dfu_transport_serial.py”, line 243, in send_packet
File “dfu\dfu_transport_serial.py”, line 282, in get_ack_nr
nordicsemi.exceptions.NordicSemiException: No data received on serial port. Not able to proceed.

Possible causes:

  • Selected Bootloader version does not match the one on Bluefruit device.
    Please upgrade the Bootloader or select correct version in Tools->Bootloader.
  • Baud rate must be 115200, Flow control must be off.
  • Target is not in DFU mode. Ground DFU pin and RESET and release both to enter DFU mode.

I also try to update the bootloader with instructions I found here Updated bootloader for RAK4631 - #5 by richstimson

but it also gave me errors:
C:\Users\Santiago H\Downloads>adafruit-nrfutil.exe --verbose dfu serial --package RAK4630_bootloader-0.4.1.zip --port COM27 -b 115200 --singlebank --touch 1200
Upgrading target on COM27 with DFU package C:\Users\Santiago H\Downloads\RAK4630_bootloader-0.4.1.zip. Flow control is disabled, Single bank, Touch 1200

Failed to upgrade target. Error is: Serial port could not be opened on COM27. Reason: could not open port ‘COM27’: PermissionError(13, ‘Acceso denegado.’, None, 5)
Traceback (most recent call last):
File “dfu\dfu_transport_serial.py”, line 99, in open
File “serial\serialwin32.py”, line 33, in init
File “serial\serialutil.py”, line 244, in init
File “serial\serialwin32.py”, line 64, in open
serial.serialutil.SerialException: could not open port ‘COM27’: PermissionError(13, ‘Acceso denegado.’, None, 5)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “main.py”, line 296, in serial
File “dfu\dfu.py”, line 226, in dfu_send_images
File “dfu\dfu.py”, line 157, in _dfu_send_image
File “dfu\dfu_transport_serial.py”, line 101, in open
nordicsemi.exceptions.NordicSemiException: Serial port could not be opened on COM27. Reason: could not open port ‘COM27’: PermissionError(13, ‘Acceso denegado.’, None, 5)

Possible causes:

  • Selected Bootloader version does not match the one on Bluefruit device.
    Please upgrade the Bootloader or select correct version in Tools->Bootloader.
  • Baud rate must be 115200, Flow control must be off.
  • Target is not in DFU mode. Ground DFU pin and RESET and release both to enter DFU mode.

I also try with BLE and nothings happens.

I can not see any device callaed RAK4160_OTA when I try to connect it by BLE.

Hello Alejandro,

The bootloader update guide you were using is flashing the Arduino Bootloader, so you are now back to an Arduino version of the RAK4631.

For updating to RUI3 please follow this guide Updating RAK4631 to RUI3

Once you have installed the RUI3 bootloader and a RUI3 based firmware, the BLE is only active for 30 seconds after power-up. You can connect to the device over BLE only during this period.
To change this, you will have to enable BLE from your custom firmware by e.g. enabling the BLE UART (this will enable the OTA-DFU service as well). Here is an example code for the BLE UART

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