I'm trying to implement a minimal LoRaWAN setup for my WLR089 Xplained PRO. I've set up a simple project using the ASF wizard in Microchip studio 7. I have all the necessary libraries included for my current main program. I've used the lorawan.h library found in the ASF Wizard listings for the WLR089.
My program compiles, but I'm confused about the parameters for LORAWAN_Init(); function. In the other examples provided by the default WLR089 ASF projects, this function isn't given any arguments, but the documentation gives two parameters for function pointers: a downlink callback and a join response callback.
Here is my main.c:
#include <asf.h>
#include "lorawan.h"
#define EU_BAND 1
static uint8_t DeviceEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static uint8_t ApplicationEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static uint8_t ApplicationKey[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static void init_system(void)
{
system_init();
delay_init();
}
static void init_lorawan(void)
{
LORAWAN_Init(NULL,NULL);//THIS HERE//
LORAWAN_SetAttr(DEV_EUI, DeviceEUI);
LORAWAN_SetAttr(JOIN_EUI,ApplicationEUI);
LORAWAN_SetAttr(APP_KEY, ApplicationKey);
LORAWAN_SetAttr(EDCLASS,0);
LORAWAN_SetAttr(ADR,1);
}
static void join_network(void)
{
bool joined = false;
while (!joined) {
joined = LORAWAN_Join(LORAWAN_OTAA) == LORAWAN_SUCCESS;
if (!joined) {
delay_ms(5000);
}
}
}
static void send_message(void)
{
uint8_t payload[] = "TESTING";
struct _LorawanSendReq req = {LORAWAN_CNF, 1, (char*)payload, sizeof(payload)-1};
if(LORAWAN_Send(&req) == LORAWAN_SUCCESS){
delay_ms(100);
}
}
int main(void)
{
init_system();
init_lorawan();
join_network();
while (1) {
send_message();
delay_ms(300000);
}
}
Is it necessary to give function callbacks for the initialization? Will my program work without them?
1 Answer 1
These two callbacks are important, especially the second one: without a join notification, how would you know you can actually send uplinks?
Also, do not use delay() in the main loop. Instead use a semaphore (hasJoined) and a deadline, like this:
#include <asf.h>
#include "lorawan.h"
#define EU_BAND 1
static uint8_t DeviceEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static uint8_t ApplicationEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static uint8_t ApplicationKey[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
bool hasJoined = false;
uint32_t intervalBetweenUplinks = 300000;
uint32_t intervalBetweenJoins = 10000;
void joinNotif(StackRetStatus_t r) {
if (r == LORAWAN_SUCCESS) {
hasJoined = true;
/*
Do other stuff
*/
}
}
static void init_system(void) {
system_init();
delay_init();
}
static void init_lorawan(void) {
LORAWAN_Init(NULL, joinNotif); // Leaving the downlink callback NULL for now
LORAWAN_SetAttr(DEV_EUI, DeviceEUI);
LORAWAN_SetAttr(JOIN_EUI, ApplicationEUI);
LORAWAN_SetAttr(APP_KEY, ApplicationKey);
LORAWAN_SetAttr(EDCLASS, 0);
LORAWAN_SetAttr(ADR, 1);
}
static void join_network(void) {
bool joined = LORAWAN_Join(LORAWAN_OTAA) == LORAWAN_SUCCESS;
}
static void send_message(void) {
uint8_t payload[] = "TESTING";
struct _LorawanSendReq req = { LORAWAN_CNF, 1, (char*)payload, sizeof(payload) - 1 };
if (LORAWAN_Send(&req) == LORAWAN_SUCCESS) {
delay_ms(100);
}
}
int main(void) {
init_system();
init_lorawan();
uint32_t nextUplink = CURRENT_MILLIS_FN();
uint32_t nextJoin = CURRENT_MILLIS_FN();
while (1) {
if (hasJoined && CURRENT_MILLIS_FN() >= nextUplink) {
send_message();
nextUplink = CURRENT_MILLIS_FN() + intervalBetweenUplinks;
} else if (!hasJoined && CURRENT_MILLIS_FN() >= nextJoin) {
nextJoin = CURRENT_MILLIS_FN() + intervalBetweenJoins;
join_network();
}
}
}
Replace CURRENT_MILLIS_FN() with whatever function is needed. Do not block execution of code. Let the system notify you of events, and act on that.
2 Comments
CURRENT_MILLIS_FN()? If so, Is the implementation done with a hardware timer? And what ASF module would I need for that?system_init(void) at exaclt the first call: system_clock_init() in system.c. The modules I'm using: GenericBoardSupport, DelayRoutines, PORT-GPIO_PinControl, SERCOM-UASRT_SerialCommunications, SYSTEM_CoreSystemDriver, TC_TimerCounter, StandardSerialI/O, LoRaWAN_Stack