[LoRaWAN] Add Class C and Multicast examples

lr2021
StevenCellist 2025-06-01 08:30:07 +02:00
rodzic 6430fa5e38
commit f7c6071169
4 zmienionych plików z 564 dodań i 0 usunięć

Wyświetl plik

@ -0,0 +1,136 @@
/*
RadioLib LoRaWAN Class C Example
This example joins a LoRaWAN network and switches to Class C.
Note that a confirmed uplink with a confirming downlink is
required for the switch to Class C to complete. This example
assumes that coverage is good enough to receive the downlink
at once. It is up to you to handle the situation if coverage
is worse.
Running this examples REQUIRES you to check "Resets DevNonces"
on your LoRaWAN dashboard. Refer to the network's
documentation on how to do this.
For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/
For LoRaWAN details, see the wiki page
https://github.com/jgromes/RadioLib/wiki/LoRaWAN
*/
#include "config.h"
void setup() {
Serial.begin(115200);
while(!Serial);
delay(5000); // Give time to switch to the serial monitor
Serial.println(F("\nSetup ... "));
Serial.println(F("Initialise the radio"));
int16_t state = radio.begin();
debug(state != RADIOLIB_ERR_NONE, F("Initialise radio failed"), state, true);
// Setup the OTAA session information
state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
debug(state != RADIOLIB_ERR_NONE, F("Initialise node failed"), state, true);
Serial.println(F("Join ('login') the LoRaWAN Network"));
state = node.activateOTAA();
debug(state != RADIOLIB_LORAWAN_NEW_SESSION, F("Join failed"), state, true);
// switch class
node.setClass(RADIOLIB_LORAWAN_CLASS_C);
// read the note at the top about this first confirmed uplink
const char* payload = "C";
Serial.println(F("Sending a confirmed uplink"));
state = node.sendReceive(payload, 1, true);
debug(state <= 0, F("No downlink received"), state, true);
Serial.println(F("Ready!\n"));
}
uint32_t lastUplink = 0;
void loop() {
uint8_t downlinkPayload[255];
size_t downlinkLen = 0;
LoRaWANEvent_t downlinkEvent;
// check if a Class C downlink is ready for processing
// tip: internally, this just checks a boolean;
// it does not poll the radio over SPI.
// tip: you are not required to continuously call
// this function; you can do other stuff in between.
// however, a downlink may be overwritten if you
// don't call this function in time for the previous one.
int16_t state = node.getDownlinkClassC(downlinkPayload, &downlinkLen, &downlinkEvent);
if(state > 0) {
Serial.println(F("Received a Class C downlink!"));
// Did we get a downlink with data for us
if(downlinkLen > 0) {
Serial.println(F("Downlink data: "));
arrayDump(downlinkPayload, downlinkLen);
}
// print extra information about the event
Serial.println(F("[LoRaWAN] Event information:"));
Serial.print(F("[LoRaWAN] Datarate:\t"));
Serial.println(downlinkEvent.datarate);
Serial.print(F("[LoRaWAN] Frequency:\t"));
Serial.print(downlinkEvent.freq, 3);
Serial.println(F(" MHz"));
Serial.print(F("[LoRaWAN] Frame count:\t"));
Serial.println(downlinkEvent.fCnt);
Serial.print(F("[LoRaWAN] Port:\t\t"));
Serial.println(downlinkEvent.fPort);
Serial.println(F(" ms"));
Serial.print(F("[LoRaWAN] Rx window: \t"));
Serial.println(state);
Serial.print(F("[LoRaWAN] Cast:\t\t"));
Serial.println(downlinkEvent.multicast ? "Multi" : "Uni");
}
// if less than uplinkIntervalSeconds have elapsed since previous uplink,
// stop and go back to the top of the loop()
if(millis() - lastUplink < uplinkIntervalSeconds * 1000) {
return;
}
Serial.println(F("Sending uplink"));
// This is the place to gather the sensor inputs
// Instead of reading any real sensor, we just generate some random numbers as example
uint8_t value1 = radio.random(100);
uint16_t value2 = radio.random(2000);
// Build payload byte array
uint8_t uplinkPayload[3];
uplinkPayload[0] = value1;
uplinkPayload[1] = highByte(value2); // See notes for high/lowByte functions
uplinkPayload[2] = lowByte(value2);
// Perform an uplink
int16_t state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload));
debug(state < RADIOLIB_ERR_NONE, F("Error in sendReceive"), state, false);
// Check if a downlink was received
// (state 0 = no downlink, state 1/2/3 = downlink in window Rx1/Rx2/RxC)
if(state > 0) {
Serial.println(F("Received a downlink"));
} else {
Serial.println(F("No downlink received"));
}
Serial.print(F("Next uplink in "));
Serial.print(uplinkIntervalSeconds);
Serial.println(F(" seconds\n"));
// set timestamp of last uplink
lastUplink = millis();
}

Wyświetl plik

@ -0,0 +1,141 @@
#ifndef _RADIOLIB_EX_LORAWAN_CONFIG_H
#define _RADIOLIB_EX_LORAWAN_CONFIG_H
#include <RadioLib.h>
// first you have to set your radio model and pin configuration
// this is provided just as a default example
SX1262 radio = new Module(8, 14, 12, 13);
// if you have RadioBoards (https://github.com/radiolib-org/RadioBoards)
// and are using one of the supported boards, you can do the following:
/*
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// how often to send an uplink - consider legal & FUP constraints - see notes
const uint32_t uplinkIntervalSeconds = 1UL * 60UL; // minutes x seconds
// joinEUI - previous versions of LoRaWAN called this AppEUI
// for development purposes you can use all zeros - see wiki for details
#define RADIOLIB_LORAWAN_JOIN_EUI 0x0000000000000000
// the Device EUI & two keys can be generated on the TTN console
#ifndef RADIOLIB_LORAWAN_DEV_EUI // Replace with your Device EUI
#define RADIOLIB_LORAWAN_DEV_EUI 0x---------------
#endif
#ifndef RADIOLIB_LORAWAN_APP_KEY // Replace with your App Key
#define RADIOLIB_LORAWAN_APP_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
#endif
#ifndef RADIOLIB_LORAWAN_NWK_KEY // Put your Nwk Key here
#define RADIOLIB_LORAWAN_NWK_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
#endif
// for the curious, the #ifndef blocks allow for automated testing &/or you can
// put your EUI & keys in to your platformio.ini - see wiki for more tips
// regional choices: EU868, US915, AU915, AS923, AS923_2, AS923_3, AS923_4, IN865, KR920, CN500
const LoRaWANBand_t Region = EU868;
const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
// ============================================================================
// Below is to support the sketch - only make changes if the notes say so ...
// copy over the EUI's & keys in to the something that will not compile if incorrectly formatted
uint64_t joinEUI = RADIOLIB_LORAWAN_JOIN_EUI;
uint64_t devEUI = RADIOLIB_LORAWAN_DEV_EUI;
uint8_t appKey[] = { RADIOLIB_LORAWAN_APP_KEY };
uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY };
// create the LoRaWAN node
LoRaWANNode node(&radio, &Region, subBand);
// result code to text - these are error codes that can be raised when using LoRaWAN
// however, RadioLib has many more - see https://jgromes.github.io/RadioLib/group__status__codes.html for a complete list
String stateDecode(const int16_t result) {
switch (result) {
case RADIOLIB_ERR_NONE:
return "ERR_NONE";
case RADIOLIB_ERR_CHIP_NOT_FOUND:
return "ERR_CHIP_NOT_FOUND";
case RADIOLIB_ERR_PACKET_TOO_LONG:
return "ERR_PACKET_TOO_LONG";
case RADIOLIB_ERR_RX_TIMEOUT:
return "ERR_RX_TIMEOUT";
case RADIOLIB_ERR_MIC_MISMATCH:
return "ERR_MIC_MISMATCH";
case RADIOLIB_ERR_INVALID_BANDWIDTH:
return "ERR_INVALID_BANDWIDTH";
case RADIOLIB_ERR_INVALID_SPREADING_FACTOR:
return "ERR_INVALID_SPREADING_FACTOR";
case RADIOLIB_ERR_INVALID_CODING_RATE:
return "ERR_INVALID_CODING_RATE";
case RADIOLIB_ERR_INVALID_FREQUENCY:
return "ERR_INVALID_FREQUENCY";
case RADIOLIB_ERR_INVALID_OUTPUT_POWER:
return "ERR_INVALID_OUTPUT_POWER";
case RADIOLIB_ERR_NETWORK_NOT_JOINED:
return "RADIOLIB_ERR_NETWORK_NOT_JOINED";
case RADIOLIB_ERR_DOWNLINK_MALFORMED:
return "RADIOLIB_ERR_DOWNLINK_MALFORMED";
case RADIOLIB_ERR_INVALID_REVISION:
return "RADIOLIB_ERR_INVALID_REVISION";
case RADIOLIB_ERR_INVALID_PORT:
return "RADIOLIB_ERR_INVALID_PORT";
case RADIOLIB_ERR_NO_RX_WINDOW:
return "RADIOLIB_ERR_NO_RX_WINDOW";
case RADIOLIB_ERR_INVALID_CID:
return "RADIOLIB_ERR_INVALID_CID";
case RADIOLIB_ERR_UPLINK_UNAVAILABLE:
return "RADIOLIB_ERR_UPLINK_UNAVAILABLE";
case RADIOLIB_ERR_COMMAND_QUEUE_FULL:
return "RADIOLIB_ERR_COMMAND_QUEUE_FULL";
case RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND:
return "RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND";
case RADIOLIB_ERR_JOIN_NONCE_INVALID:
return "RADIOLIB_ERR_JOIN_NONCE_INVALID";
case RADIOLIB_ERR_DWELL_TIME_EXCEEDED:
return "RADIOLIB_ERR_DWELL_TIME_EXCEEDED";
case RADIOLIB_ERR_CHECKSUM_MISMATCH:
return "RADIOLIB_ERR_CHECKSUM_MISMATCH";
case RADIOLIB_ERR_NO_JOIN_ACCEPT:
return "RADIOLIB_ERR_NO_JOIN_ACCEPT";
case RADIOLIB_LORAWAN_SESSION_RESTORED:
return "RADIOLIB_LORAWAN_SESSION_RESTORED";
case RADIOLIB_LORAWAN_NEW_SESSION:
return "RADIOLIB_LORAWAN_NEW_SESSION";
case RADIOLIB_ERR_NONCES_DISCARDED:
return "RADIOLIB_ERR_NONCES_DISCARDED";
case RADIOLIB_ERR_SESSION_DISCARDED:
return "RADIOLIB_ERR_SESSION_DISCARDED";
}
return "See https://jgromes.github.io/RadioLib/group__status__codes.html";
}
// helper function to display any issues
void debug(bool failed, const __FlashStringHelper* message, int state, bool halt) {
if(failed) {
Serial.print(message);
Serial.print(" - ");
Serial.print(stateDecode(state));
Serial.print(" (");
Serial.print(state);
Serial.println(")");
while(halt) { delay(1); }
}
}
// helper function to display a byte array
void arrayDump(uint8_t *buffer, uint16_t len) {
for(uint16_t c = 0; c < len; c++) {
char b = buffer[c];
if(b < 0x10) { Serial.print('0'); }
Serial.print(b, HEX);
}
Serial.println();
}
#endif

Wyświetl plik

@ -0,0 +1,133 @@
/*
RadioLib LoRaWAN Multicast Example
This example joins a LoRaWAN network and starts a
Multicast session (only Multicast over Class C is implemented).
You should refer to the network's documentation on how
to create a Multicast group (or device).
Note that you can switch the device to Class C as well
to receive Unicast downlinks. In this case, you must
use the downlink event details to discern whether a
downlink belongs to the Unicast or Multicast session.
Running this examples REQUIRES you to check "Resets DevNonces"
on your LoRaWAN dashboard. Refer to the network's
documentation on how to do this.
For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/
For LoRaWAN details, see the wiki page
https://github.com/jgromes/RadioLib/wiki/LoRaWAN
*/
#include "config.h"
void setup() {
Serial.begin(115200);
while(!Serial);
delay(5000); // Give time to switch to the serial monitor
Serial.println(F("\nSetup ... "));
Serial.println(F("Initialise the radio"));
int16_t state = radio.begin();
debug(state != RADIOLIB_ERR_NONE, F("Initialise radio failed"), state, true);
// Setup the OTAA session information
state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
debug(state != RADIOLIB_ERR_NONE, F("Initialise node failed"), state, true);
Serial.println(F("Join ('login') the LoRaWAN Network"));
state = node.activateOTAA();
debug(state != RADIOLIB_LORAWAN_NEW_SESSION, F("Join failed"), state, true);
// Start a Multicast session over Class C
// (this will automatically perform a switch to Class C for Multicast)
node.startMulticastSession(RADIOLIB_LORAWAN_CLASS_C, mcDevAddr, mcAppSKey, mcNwkSKey);
Serial.println(F("Ready!\n"));
}
uint32_t lastUplink = 0;
void loop() {
uint8_t downlinkPayload[255];
size_t downlinkLen = 0;
LoRaWANEvent_t downlinkEvent;
// check if a Class C downlink is ready for processing
// tip: internally, this just checks a boolean;
// it does not poll the radio over SPI.
// tip: you are not required to continuously call
// this function; you can do other stuff in between.
// however, a downlink may be overwritten if you
// don't call this function in time for the previous one.
int16_t state = node.getDownlinkClassC(downlinkPayload, &downlinkLen, &downlinkEvent);
if(state > 0) {
Serial.println(F("Received a Class C downlink!"));
// Did we get a downlink with data for us
if(downlinkLen > 0) {
Serial.println(F("Downlink data: "));
arrayDump(downlinkPayload, downlinkLen);
}
// print extra information about the event
Serial.println(F("[LoRaWAN] Event information:"));
Serial.print(F("[LoRaWAN] Datarate:\t"));
Serial.println(downlinkEvent.datarate);
Serial.print(F("[LoRaWAN] Frequency:\t"));
Serial.print(downlinkEvent.freq, 3);
Serial.println(F(" MHz"));
Serial.print(F("[LoRaWAN] Frame count:\t"));
Serial.println(downlinkEvent.fCnt);
Serial.print(F("[LoRaWAN] Port:\t\t"));
Serial.println(downlinkEvent.fPort);
Serial.println(F(" ms"));
Serial.print(F("[LoRaWAN] Rx window: \t"));
Serial.println(state);
Serial.print(F("[LoRaWAN] Cast:\t\t"));
Serial.println(downlinkEvent.multicast ? "Multi" : "Uni");
}
// if less than uplinkIntervalSeconds have elapsed since previous uplink,
// stop and go back to the top of the loop()
if(millis() - lastUplink < uplinkIntervalSeconds * 1000) {
return;
}
Serial.println(F("Sending uplink"));
// This is the place to gather the sensor inputs
// Instead of reading any real sensor, we just generate some random numbers as example
uint8_t value1 = radio.random(100);
uint16_t value2 = radio.random(2000);
// Build payload byte array
uint8_t uplinkPayload[3];
uplinkPayload[0] = value1;
uplinkPayload[1] = highByte(value2); // See notes for high/lowByte functions
uplinkPayload[2] = lowByte(value2);
// Perform an uplink
int16_t state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload));
debug(state < RADIOLIB_ERR_NONE, F("Error in sendReceive"), state, false);
// Check if a downlink was received
// (state 0 = no downlink, state 1/2/3 = downlink in window Rx1/Rx2/RxC)
if(state > 0) {
Serial.println(F("Received a downlink"));
} else {
Serial.println(F("No downlink received"));
}
Serial.print(F("Next uplink in "));
Serial.print(uplinkIntervalSeconds);
Serial.println(F(" seconds\n"));
// set timestamp of last uplink
lastUplink = millis();
}

Wyświetl plik

@ -0,0 +1,154 @@
#ifndef _RADIOLIB_EX_LORAWAN_CONFIG_H
#define _RADIOLIB_EX_LORAWAN_CONFIG_H
#include <RadioLib.h>
// first you have to set your radio model and pin configuration
// this is provided just as a default example
SX1262 radio = new Module(8, 14, 12, 13);
// if you have RadioBoards (https://github.com/radiolib-org/RadioBoards)
// and are using one of the supported boards, you can do the following:
/*
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// how often to send an uplink - consider legal & FUP constraints - see notes
const uint32_t uplinkIntervalSeconds = 1UL * 60UL; // minutes x seconds
// joinEUI - previous versions of LoRaWAN called this AppEUI
// for development purposes you can use all zeros - see wiki for details
#define RADIOLIB_LORAWAN_JOIN_EUI 0x0000000000000000
// the Device EUI & two keys can be generated on the TTN console
#ifndef RADIOLIB_LORAWAN_DEV_EUI // Replace with your Device EUI
#define RADIOLIB_LORAWAN_DEV_EUI 0x---------------
#endif
#ifndef RADIOLIB_LORAWAN_APP_KEY // Replace with your App Key
#define RADIOLIB_LORAWAN_APP_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
#endif
#ifndef RADIOLIB_LORAWAN_NWK_KEY // Put your Nwk Key here
#define RADIOLIB_LORAWAN_NWK_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
#endif
#ifndef RADIOLIB_LORAWAN_MC_DEV_ADDR // Replace with your Multicast Device Address
#define RADIOLIB_LORAWAN_MC_DEV_ADDR 0x---------------
#endif
#ifndef RADIOLIB_LORAWAN_MC_APP_SKEY // Replace with your Multicast App SKey
#define RADIOLIB_LORAWAN_MC_APP_SKEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
#endif
#ifndef RADIOLIB_LORAWAN_MC_NWK_SKEY // Put your Multicast Nwk SKey here
#define RADIOLIB_LORAWAN_MC_NWK_SKEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
#endif
// for the curious, the #ifndef blocks allow for automated testing &/or you can
// put your EUI & keys in to your platformio.ini - see wiki for more tips
// regional choices: EU868, US915, AU915, AS923, AS923_2, AS923_3, AS923_4, IN865, KR920, CN500
const LoRaWANBand_t Region = EU868;
const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
// ============================================================================
// Below is to support the sketch - only make changes if the notes say so ...
// copy over the EUI's & keys in to the something that will not compile if incorrectly formatted
uint64_t joinEUI = RADIOLIB_LORAWAN_JOIN_EUI;
uint64_t devEUI = RADIOLIB_LORAWAN_DEV_EUI;
uint8_t appKey[] = { RADIOLIB_LORAWAN_APP_KEY };
uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY };
uint32_t mcDevAddr = RADIOLIB_LORAWAN_MC_DEV_ADDR;
uint8_t mcAppSKey[] = { RADIOLIB_LORAWAN_MC_APP_SKEY };
uint8_t mcNwkSKey[] = { RADIOLIB_LORAWAN_MC_NWK_SKEY };
// create the LoRaWAN node
LoRaWANNode node(&radio, &Region, subBand);
// result code to text - these are error codes that can be raised when using LoRaWAN
// however, RadioLib has many more - see https://jgromes.github.io/RadioLib/group__status__codes.html for a complete list
String stateDecode(const int16_t result) {
switch (result) {
case RADIOLIB_ERR_NONE:
return "ERR_NONE";
case RADIOLIB_ERR_CHIP_NOT_FOUND:
return "ERR_CHIP_NOT_FOUND";
case RADIOLIB_ERR_PACKET_TOO_LONG:
return "ERR_PACKET_TOO_LONG";
case RADIOLIB_ERR_RX_TIMEOUT:
return "ERR_RX_TIMEOUT";
case RADIOLIB_ERR_MIC_MISMATCH:
return "ERR_MIC_MISMATCH";
case RADIOLIB_ERR_INVALID_BANDWIDTH:
return "ERR_INVALID_BANDWIDTH";
case RADIOLIB_ERR_INVALID_SPREADING_FACTOR:
return "ERR_INVALID_SPREADING_FACTOR";
case RADIOLIB_ERR_INVALID_CODING_RATE:
return "ERR_INVALID_CODING_RATE";
case RADIOLIB_ERR_INVALID_FREQUENCY:
return "ERR_INVALID_FREQUENCY";
case RADIOLIB_ERR_INVALID_OUTPUT_POWER:
return "ERR_INVALID_OUTPUT_POWER";
case RADIOLIB_ERR_NETWORK_NOT_JOINED:
return "RADIOLIB_ERR_NETWORK_NOT_JOINED";
case RADIOLIB_ERR_DOWNLINK_MALFORMED:
return "RADIOLIB_ERR_DOWNLINK_MALFORMED";
case RADIOLIB_ERR_INVALID_REVISION:
return "RADIOLIB_ERR_INVALID_REVISION";
case RADIOLIB_ERR_INVALID_PORT:
return "RADIOLIB_ERR_INVALID_PORT";
case RADIOLIB_ERR_NO_RX_WINDOW:
return "RADIOLIB_ERR_NO_RX_WINDOW";
case RADIOLIB_ERR_INVALID_CID:
return "RADIOLIB_ERR_INVALID_CID";
case RADIOLIB_ERR_UPLINK_UNAVAILABLE:
return "RADIOLIB_ERR_UPLINK_UNAVAILABLE";
case RADIOLIB_ERR_COMMAND_QUEUE_FULL:
return "RADIOLIB_ERR_COMMAND_QUEUE_FULL";
case RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND:
return "RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND";
case RADIOLIB_ERR_JOIN_NONCE_INVALID:
return "RADIOLIB_ERR_JOIN_NONCE_INVALID";
case RADIOLIB_ERR_DWELL_TIME_EXCEEDED:
return "RADIOLIB_ERR_DWELL_TIME_EXCEEDED";
case RADIOLIB_ERR_CHECKSUM_MISMATCH:
return "RADIOLIB_ERR_CHECKSUM_MISMATCH";
case RADIOLIB_ERR_NO_JOIN_ACCEPT:
return "RADIOLIB_ERR_NO_JOIN_ACCEPT";
case RADIOLIB_LORAWAN_SESSION_RESTORED:
return "RADIOLIB_LORAWAN_SESSION_RESTORED";
case RADIOLIB_LORAWAN_NEW_SESSION:
return "RADIOLIB_LORAWAN_NEW_SESSION";
case RADIOLIB_ERR_NONCES_DISCARDED:
return "RADIOLIB_ERR_NONCES_DISCARDED";
case RADIOLIB_ERR_SESSION_DISCARDED:
return "RADIOLIB_ERR_SESSION_DISCARDED";
}
return "See https://jgromes.github.io/RadioLib/group__status__codes.html";
}
// helper function to display any issues
void debug(bool failed, const __FlashStringHelper* message, int state, bool halt) {
if(failed) {
Serial.print(message);
Serial.print(" - ");
Serial.print(stateDecode(state));
Serial.print(" (");
Serial.print(state);
Serial.println(")");
while(halt) { delay(1); }
}
}
// helper function to display a byte array
void arrayDump(uint8_t *buffer, uint16_t len) {
for(uint16_t c = 0; c < len; c++) {
char b = buffer[c];
if(b < 0x10) { Serial.print('0'); }
Serial.print(b, HEX);
}
Serial.println();
}
#endif