RAK4631 doesn't connect on AU915 network from Helium

Issue :
Hi, I’m struggling with connection using OTAA example code on Rak4631 module on a longfi network from Helium on region AU915 (Brazil) but no matter what I do it keeps returning OTAA Join Failed after the set number of tryies.

Setup :
AU915 sub band 2 (already tried sub band 5, 4 and 8 as hotspots nearby where transmitting their beacon on those bands accordingly to the helium explorer webapp) without success.

Docs :
Using code from: longfi-platformio/main.cpp at master · helium/longfi-platformio · GitHub

Details :
Here is what aways happens

14:35:55.844 > <BRD> SyncWord = 2414
14:35:55.844 > <BRD> LoRa Task started
14:35:55.844 > =====================================
14:35:55.844 > Welcome to RAK4630 LoRaWan!!!
14:35:55.844 > Type: OTAA
14:35:55.844 > Region: AU915
14:35:55.844 > =====================================
14:35:55.845 > <LMH> OTAA 
14:35:55.845 > DevEui=60-81-F9-E1-A5-E8-C8-1B
14:35:55.845 > DevAdd=00000000
14:35:55.845 > AppEui=60-81-F9-5E-95-44-90-82
14:35:55.845 > AppKey=XX-XX-XX (here I have defined based on Helium Console keys as MSB)
14:35:55.918 > <LMH> Selected subband 2
14:35:56.918 > <LMH> Selected subband 2
14:35:57.918 > Starting Join
14:35:57.940 > Return from join
14:35:58.311 > <LM> OnRadioTxDone
14:35:58.313 > <LM> OnRadioTxDone => RX Windows #1 4991 #2 6002
14:35:58.313 > <LM> OnRadioTxDone => TX was Join Request
14:36:03.311 > <RADIO> RX window timeout = 3000
14:36:07.274 > <RADIO> RadioIrqProcess => IRQ_RX_TX_TIMEOUT
14:36:07.274 > <LM> OnRadioRxTimeout
14:36:07.436 > <LM> Join network failed 1 time(s)
14:36:07.436 > 
14:36:35.435 > <LM> OnRadioTxDone
14:36:35.436 > <LM> OnRadioTxDone => RX Windows #1 4991 #2 6002
14:36:35.437 > <LM> OnRadioTxDone => TX was Join Request
14:36:40.435 > <RADIO> RX window timeout = 3000
14:36:44.395 > <RADIO> RadioIrqProcess => IRQ_RX_TX_TIMEOUT
14:36:44.395 > <LM> OnRadioRxTimeout
14:36:44.560 > <LM> Join network failed 2 time(s)
14:36:44.560 > 
14:37:12.558 > <LM> OnRadioTxDone
14:37:12.559 > <LM> OnRadioTxDone => RX Windows #1 4991 #2 6002
14:37:12.560 > <LM> OnRadioTxDone => TX was Join Request
14:37:17.558 > <RADIO> RX window timeout = 3000
14:37:21.519 > <RADIO> RadioIrqProcess => IRQ_RX_TX_TIMEOUT
14:37:21.519 > <LM> OnRadioRxTimeout
14:37:21.683 > <LM> Join network failed 3 time(s)
14:37:21.683 > 
14:37:21.683 > <LM> LoRaMacState = idle
14:37:21.683 > OTAA join failed!
14:37:21.683 > Check your EUI's and Keys's!
14:37:21.683 > Check if a Gateway is in range!

Code :

/**
 * file LoRaWAN_OTAA_ABP.ino
 * author rakwireless.com
 * brief LoRaWan node example with OTAA/ABP registration
 * version 0.1
 * date 2020-08-21
 * 
 * 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>
#include <SPI.h>

// 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 g_CurrentClass = CLASS_A;					/* class definition*/
LoRaMacRegion_t g_CurrentRegion = LORAMAC_REGION_AU915;    /* Region:EU868*/
lmh_confirm g_CurrentConfirm = 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 g_lora_param_init = {LORAWAN_ADR_ON, LORAWAN_DATERATE, LORAWAN_PUBLIC_NETWORK, JOINREQ_NBTRIALS, LORAWAN_TX_POWER, LORAWAN_DUTYCYCLE_ON};

// 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 g_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] = {0x60, 0x81, 0xF9, 0xE1, 0xA5, 0xE8, 0xC8, 0x1B};
uint8_t nodeAppEUI[8] = {0x60, 0x81, 0xF9, 0x5E, 0x95, 0x44, 0x90, 0x82};
uint8_t nodeAppKey[16] = {0x12, 0xAC, 0x1F, 0xA5, 0x42, 0xF1, 0x85, 0x3A, 0x99, 0xB7, 0xEB, 0xD5, 0xEE, 0xB4, 0x7A, 0xC8};

// 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 20000                        /**< Defines for user timer, the application data transmission interval. 20s, 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 (g_CurrentRegion)
  {
    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("=====================================");
  
  //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(&g_lora_callbacks, g_lora_param_init, doOTAA, g_CurrentClass, g_CurrentRegion);
  if (err_code != 0)
  {
    Serial.printf("lmh_init failed - %d\n", err_code);
    return;
  }

  delay(1000);
  /* Helium Network LoraWan sub channel 2 is recommended, default channels 0-7*/
  if (!lmh_setSubBandChannels(2))
  {
      Serial.println("lmh_setSubBandChannels() failed");
  }

  delay(1000);

	// Start Join procedure
	Serial.println("Starting Join");
	lmh_join();
	Serial.println("Return from 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(g_CurrentClass);
  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, g_CurrentConfirm);
}

void send_lora_frame(void)
{
  if (lmh_join_status_get() != LMH_SET)
  {
    //Not joined, try again later
    return;
  }

  uint32_t i = 0;
  memset(m_lora_app_data.buffer, 0, LORAWAN_APP_DATA_BUFF_SIZE);
  m_lora_app_data.port = gAppPort;
  m_lora_app_data.buffer[i++] = 'H';
  m_lora_app_data.buffer[i++] = 'e';
  m_lora_app_data.buffer[i++] = 'l';
  m_lora_app_data.buffer[i++] = 'l';
  m_lora_app_data.buffer[i++] = 'o';
  m_lora_app_data.buffer[i++] = '!';
  m_lora_app_data.buffsize = i;

  lmh_error_status error = lmh_send(&m_lora_app_data, g_CurrentConfirm);
  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);
  }
}

/**brief Function for handling user timerout event.
 */
void tx_lora_periodic_handler(void)
{
  TimerSetValue(&appTimer, LORAWAN_APP_INTERVAL);
  TimerStart(&appTimer);
  Serial.println("Sending frame now...");
  send_lora_frame();
}

/**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;
}

Platformio configuration:

; PlatformIO Project Configuration File

;

; Build options: build flags, source filter

; Upload options: custom upload port, speed and extra flags

; Library options: dependencies, extra library storages

; Advanced options: extra scripting

;

[platformio]

default_envs = wiscore_rak4631_v2

[env]

build_flags =

-D DEBUG=1

-D LIB_DEBUG=1

[env:wiscore_rak4631_v2]

platform = nordicnrf52

board = wiscore_rak4631

framework = arduino

lib_deps = beegee-tokyo/[email protected]^2.0.11

Am I forgetting to configure something? I have already tried to enable duty cycle wondering if 3000ms is a RX window too short (as I saw in other topics it may cause a delay on RxTimeout of 65s but independently of LORAWAN_DUTYCYCLE_ON or LORAWAN_DUTYCYCLE_OFF the timeout is the same on region AU915. Thanks in advance for any help.

Welcome to the forum @nilmonto

Unfortunately the example code in the Helium documents is very old and does not work anymore.

Please try our own example code for the RAK4631 => LoRaWAN_OTAA_ABP

All your settings are correct (including subband 2), so you can transfer them to our example code.