Provides a RIOT adaption of Semtech LoRaMAC implementation.
More...
Provides a RIOT adaption of Semtech LoRaMAC implementation.
Introduction
This package provides an API built on top of the Semtech LoRaMAC-node reference implementation of a LoRa network.
Importing this package in an application
This package works with Semtech SX1261, SX1262, SX1268, SX1272 and SX1276 radio devices. Thus, in order to use it properly, the application Makefile
must import the corresponding device driver:
USEMODULE += sx1261
USEMODULE += sx1262
USEMODULE += sx1268
USEMODULE += sx1272
USEMODULE += sx1276
In order to use this package in an application, add the following in the application Makefile
:
USEPKG += semtech-loramac
Since the LoRa radio depends on regional parameters regarding the access to the physical support, the region where the device is used needs to be set at compile time. Example for EU868:
Using the package API
The package provides a simple API for initializing the MAC, setting/getting parameters, joining a network and sending/receiving packets to/from a LoRa Network.
In your main.c
, some header files must be first included:
LoRaMAC header definitions.
Public API and definitions of the Semtech LoRaMAC.
Then define global variables:
0x00, 0x00, 0x00, 0x00 };
0x00, 0x00, 0x00, 0x00 };
0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00 };
#define LORAMAC_APPKEY_LEN
Application key length in bytes.
#define LORAMAC_APPEUI_LEN
Application EUI length in bytes.
#define LORAMAC_DEVEUI_LEN
Device EUI length in bytes.
Semtech LoRaMAC descriptor.
Now in the main
function:
- initialize the LoRaMAC MAC layer
- set the LoRa keys
- join the network
- send some data to the network
int main(void)
{
puts("Join procedure failed");
return 1;
}
puts("Join procedure succeeded");
char *message = "This is RIOT";
printf(
"Cannot send message '%s'\n", message);
return 1;
}
}
#define printf(...)
A wrapper for the printf() function that passes arguments through unmodified, but fails to compile if...
@ LORAMAC_JOIN_OTAA
Other-the-air activation.
uint8_t semtech_loramac_join(semtech_loramac_t *mac, uint8_t type)
Starts a LoRaWAN network join procedure.
void semtech_loramac_set_deveui(semtech_loramac_t *mac, const uint8_t *eui)
Sets the device EUI.
uint8_t semtech_loramac_send(semtech_loramac_t *mac, uint8_t *data, uint8_t len)
Sends data to the LoRaWAN network.
void semtech_loramac_set_appeui(semtech_loramac_t *mac, const uint8_t *eui)
Sets the application EUI.
void semtech_loramac_set_appkey(semtech_loramac_t *mac, const uint8_t *key)
Sets the application key.
int semtech_loramac_init(semtech_loramac_t *mac)
Initializes the semtech loramac mac.
@ SEMTECH_LORAMAC_TX_DONE
Transmission completed.
@ SEMTECH_LORAMAC_JOIN_SUCCEEDED
Join procedure succeeded.
To receive downlink messages, enable the semtech_loramac_rx
and use a dedicated receiving thread.
- In the application Makefile, add
USEMODULE += semtech_loramac_rx
- At the beginning of the application source file, add the necessary includes and declare the message queue and stack arrays:
#include "thread.h"
#define RECV_MSG_QUEUE (4U)
static msg_t _recv_queue[RECV_MSG_QUEUE];
Describes a message object which can be sent between threads.
#define THREAD_STACKSIZE_DEFAULT
A reasonable default stack size that will suffice most smaller tasks.
- Implement the thread: it initializes its message queue and then simply calls the blocking
semtech_loramac_recv
function in a loop: static void *_recv(void *arg)
{
(void)arg;
while (1) {
printf(
"Data received: %s, port: %d\n",
}
return NULL;
}
void msg_init_queue(msg_t *array, int num)
Initialize the current thread's message queue.
uint8_t semtech_loramac_recv(semtech_loramac_t *mac)
Wait for a message sent by the LoRaWAN network.
uint8_t payload[LORAWAN_APP_DATA_MAX_SIZE]
RX payload buffer.
uint8_t payload_len
Length of the RX payload.
semtech_loramac_rx_data_t rx_data
struct handling the RX data
- Finally, this thread can be started after the join procedure succeeds:
kernel_pid_t thread_create(char *stack, int stacksize, uint8_t priority, int flags, thread_task_func_t task_func, void *arg, const char *name)
Creates a new thread.
#define THREAD_PRIORITY_MAIN
Priority of the main thread.
Persistence
If the board CPU provides an internal EEPROM, this package provides a mechanism for storing EUIs, keys and some MAC parameters (frame counter, join status). After a successful join procedure, use semtech_loramac_save
function to persist this information and it will be loaded automatically at the next reboot. If the device is already joined to a network, to avoid another OTAA join procedure use semtech_loramac_is_mac_joined
function to check the join status of the device.
This mechanism is especially useful when using deep sleep power modes that don't preserve RAM.
Low power considerations
The internal implementation of the required LoRaWAN timings (delay before opening RX windows, duty-cycle delays) automatically achieves the lowest possible power consumption while remaining usable when RIOT's low power modes are not blocked. All timings are managed by the ztimer high level timer abstraction layer running on the low-level RTT peripheral which allows for:
- going to a deep-sleep mode with RAM retention (no reboot) between TX and RX1 and between RX1 and RX2 windows, and as a result reduces the power consumption
- using deep-sleep mode with RAM retention and have the duty-cycle restriction still usable between each active cycle (wake-up, measure, send, receive, sleep). As a result, this package can only be used on boards that provide the
periph_rtt
feature.
- Warning
- It is not possible to directly call the original LoRaMAC-node API using this package. This package should only be considered as a wrapper around the original LoRaMAC-node API and only the API provided by this package should be used.
License
The library is using the BSD 3-clause license.
- See also
- https://github.com/Lora-net/LoRaMac-node
|
file | timer.h |
| Semtech LoRaMAC timer compatibility definitions.
|
|
file | semtech_loramac.h |
| Public API and definitions of the Semtech LoRaMAC.
|
|