LoRa operations status messages/logs

Good morning @beegee

I am creating my code to work the WisBlock configurations:

  1. LPWAN module: to send the sensors information to LNS → TagoIO
  2. Environment module: temperature and humidity
  3. 4-20ma interface: analog sensors
  4. 0-5V interface: analog sensors

I am developing the code step-by-step, in the complexity. I mean, I already created three libraries:
A serial initialization: to clean the main.cpp
A LEDs initialization: to clean the main.cpp
A LoRa initialization: to clean the main.

If it is possible, I would like your help. My problem is that as you can see in the section “Messages on the monitor” and “The Things Stack device page”, the main.cpp finish with LoRaWAN join sucessfull by The Things Stack log, without error messages, but no LoRaWAN join successful message in the WisBlock.

Maybe I am wrong, but I was expecting to join message in the WisBlock console. Anyway, I would like to have status message. What you recomend?

Blockquote
Main.cpp

/*

  • @file RAK1906-1903-LoRa-01
  • @author Claudio Rosa
  • @brief LoRaWan node example with OTAA registration
  • @brief Setup and read values from a BME680 environment sensor using the BOSCH BSEC library
  • @version 0.1
  • @date 2021-02-18
  • @copyright Copyright © 2021
  • @note RAK5005-O GPIO mapping to RAK4631 GPIO ports
  • IO1 <-> P0.17 (Arduino GPIO number 17)
  • IO2 <-> P1.02 (Arduino GPIO number 34)
  • IO3 <-> P0.21 (Arduino GPIO number 21)
  • IO4 <-> P0.04 (Arduino GPIO number 4)
  • IO5 <-> P0.09 (Arduino GPIO number 9)
  • IO6 <-> P0.10 (Arduino GPIO number 10)
  • SW1 <-> P0.01 (Arduino GPIO number 1)
  • LED1 <-> P1.03 (Arduino GPIO number 35)
  • LED2 <-> P1.04 (Arduino GPIO number 36)
    /
    /
    ************** Libraries *************************** */
    #include <Arduino.h>
    #include <LoRaWan-RAK4630.h> //http://librarymanager/All#SX126x
    #include <SPI.h>
    #include <bsec.h> //http://librarymanager/All#BSEC_BME680 */
    #include <Wire.h>
    #include <SerialInit.h> //private libray to initialize and test Serial/Monitor Communications */
    #include <LEDsInit.h> //private library to initialize and test the LEDs Green and Blue
    #include <LoRaInit.h> //private library to initialize and test the LoRa Radio

// RAK4630 supply three LEDs
int RecPinG = 35, RecPinB = 36;
/* *********************** LoRa definitions *************************** /
String RecRegion = “AU915”;
int RecSubBand = 2;
/
************************************************************ /
/
****************** Configuration Function ****************** */

void setup()
{
// Initialize USB Serial for debug output
SerialInterface USB1(UPLOAD_SPEED,MONITOR_SPEED);
USB1.SerialInit();
// LEDs inialization
LEDsInterface LED(RecPinG, RecPinB);
LED.LEDsInit();

/* ************ LoRa Startup Procedures ******************* */
LoRaRadio Radio1(RecRegion, RecSubBand);
Radio1.LoRaInit();

};

void loop()
{
/* ****** Radio Events ********** /
// Handle Radio events
Radio.IrqProcess();
/
******************************************* */
}

Blockquote

Blockquote
Messages on the monitor

Executing task in folder RAK1906-1903-LoRa-01: C:\Users\Claudio Rosa.platformio\penv\Scripts\pio.exe device monitor <

  • Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time
  • More details at http://bit.ly/pio-monitor-filters
  • Miniterm on COM15 115200,8,N,1 —
  • Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H —
    ==============================================
    = Error 10 to initialize USB port
    ============================================
    = USB port initialized width 115200 baud.
    = Monitor port intialized width 115200 baud.
    ============================================
    ======= work fine in setup section =========
    LED GREEN PIN=35=> OFF
    LED BLUE PIN=36=> OFF
    LED GREEN PIN=35=> ON
    LED BLUE PIN=36=> ON
    LED GREEN PIN=35=> OFF
    LED BLUE PIN=36=> OFF
    LED GREEN PIN=35=> ON
    LED BLUE PIN=36=> ON
    LED GREEN PIN=35=> OFF
    LED BLUE PIN=36=> OFF
    LED GREEN PIN=35=> ON
    LED BLUE PIN=36=> ON
    LED GREEN PIN=35=> OFF
    LED BLUE PIN=36=> OFF
    =========================================
    = LEDS GREEN and BLUE initialized and OFF
    =========================================
    =====================================
    Welcome to RAK4630 LoRaWan!!!
    Type: OTAA
    LoRa Region: AU915
    =====================================

Blockquote

Blockquote
LoRaInit.h

/*

#ifndef LoRa_ini
#define LoRa_ini
#include <Arduino.h>
class LoRaRadio
{
private:
String Region;
int SubBand;
public:
LoRaRadio( String RecRegion,int RecSubBand);
int getInitParams();
void setInitParams( String RecRegion,int RecSubBand);
void LoRaInit();
};
#endif

Blockquote

Blockquote
LoRaInit.cpp

/*

*/

#include <LoRaWan-RAK4630.h>

#include <LoRaInit.h>

#include <Arduino.h>

bool doOTAA = true;

#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*/

lmh_confirm gCurrentConfirm = LMH_CONFIRMED_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_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};

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

uint8_t nodeDeviceEUI[8] = { 0xAC, 0x1F, 0x09, 0xFF, 0xFE, 0x03, 0xB9, 0xBE };

uint8_t nodeAppEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };

uint8_t nodeAppKey[16] = { 0xC2, 0x02, 0x2D, 0xC3, 0xE8, 0xB2, 0x2A, 0x02, 0xDE, 0xDC, 0x8C, 0x7A, 0xC0, 0xF6, 0xFD, 0x30 };

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

LoRaRadio::LoRaRadio( String RecRegion, int RecSubBand )

{

setInitParams(RecRegion, RecSubBand);

}

void LoRaRadio::setInitParams( String RecRegion, int RecSubBand )

{

Region  = RecRegion;

SubBand = RecSubBand;

}

int LoRaRadio::getInitParams()

{

return Region, SubBand;

}

void LoRaRadio::LoRaInit()

{

// Initialize LoRa chip.

lora_rak4630_init();



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

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

Serial.println("Type: OTAA");

#if defined(REGION_AS923)

        Serial.println("LoRa Region: AS923");

        #elif defined(REGION_AU915)

            Serial.println("LoRa Region: AU915");

            #elif defined(REGION_CN470)

                Serial.println("LoRa Region: CN470");

                #elif defined(REGION_CN779)

                    Serial.println("LoRa Region: CN779");

                    #elif defined(REGION_EU433)

                            Serial.println("LoRa Region: EU433");

                            #elif defined(REGION_IN865)

                                    Serial.println("LoRa Region: IN865");

                                    #elif defined(REGION_EU868)

                                            Serial.println("LoRa Region: EU868");

                                            #elif defined(REGION_KR920)

                                                    Serial.println("LoRa Region: KR920");

                                                    #elif defined(REGION_US915)

                                                        Serial.println("LoRa Region: US915");

                                                        #elif defined(REGION_US915_HYBRID)

                                                                Serial.println("LoRa Region: US915_HYBRID");

                                                                #else

                                                                    Serial.println("Please define a region in the compiler options.");

    #endif



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

//create 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);

    }

    else {

        // Setup the EUIs and Keys

        lmh_setDevEui(nodeDeviceEUI);

        lmh_setAppEui(nodeAppEUI);

        lmh_setAppKey(nodeAppKey);

        // Initialize LoRaWan

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

        if (err_code != 0)

            {

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

            }

        // Start Join procedure

        lmh_join();

    }

}

void lorawan_has_joined_handler(void)

{

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

lmh_error_status ret = lmh_class_request(gCurrentClass);

if (ret == LMH_SUCCESS)

{

    delay(1000);

    TimerSetValue(&appTimer, LORAWAN_APP_INTERVAL);

    TimerStart(&appTimer);

}

}

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

}

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, 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);

}

}

/@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;

}

Blockquote

We had a problem with OTAA in the LoRaWAN library that is fixed with the latest version of SX126x-Arduino. Do you use V1.3.1 of the library?

1 Like

Yes, version 1.3.1, i means the newest version available at PlatformIO library. It is working Fine.

I am looking for How to follow the LoRa operations status, for example the Join status, the uplink/downlink status, RSSI, SNR, SF, etc…

For join status we have success and fail callbacks.
Downlink RSSI and SNR are available in the data received callback
Uplink RSSI and SNR are not available, only the gateway knows them
Downlink status is not possible, all you get is the received callback if successful
Uplink status might be useful
SF and DR are set on initialization, it might be possible to write get functions to see if they are changed due to ADR on, but that is controlled by the LoRaWAN server, it would be just informal.

There are other callbacks inside the library for preamble detect, header valid, syncword valid, but these are unused (no callback to user app). These are low level protocol events. I don’t think they are useful for most users.

The LoRaWAN core of the library is based on Semtechs LoRa MAC layer implementation and I do not want to mess around inside there to be honest.