Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LoRaWAN] Rework bands, official Rx windows, support ADR, confirm frames, improve EEPROM handling, support clock drift #867

Merged
merged 22 commits into from
Nov 12, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
dd79213
[LoRaWAN] rework bands, add ADR, partial MAC support
StevenCellist Oct 5, 2023
c8bc157
[LoRaWAN] Change Rx windows from CAD to RxSingle
StevenCellist Oct 23, 2023
7c3670c
[LoRaWAN] improve persistence, better Rx windows, wear leveling, conf…
StevenCellist Oct 26, 2023
e7b2b27
[LoRaWAN] Module-independent (OTAA) Rx windows, fix confirming downlinks
StevenCellist Oct 30, 2023
f92e0e5
[LoRaWAN] Implement SX127x support, fix MAC uplinking, support clock …
StevenCellist Nov 1, 2023
6c093b2
[ArduinoHal] fix clock drift calculation
StevenCellist Nov 2, 2023
4138dac
[LoRaWAN] Improve band & ADR logic, allow setting ADR, DR, subband, u…
StevenCellist Nov 3, 2023
d540855
[LoRaWAN] Fix EU868 coding rate, improve example
StevenCellist Nov 3, 2023
466aa71
[LoRaWAN] fix unused channel index
StevenCellist Nov 3, 2023
afc01a6
Merge branch 'master' into bands_adr_mac
StevenCellist Nov 3, 2023
3b466ca
[LoRaWAN] fix merge issue (deleted line)
StevenCellist Nov 3, 2023
60f50e0
[LoRaWAN] fix CSMA calling now incorrect function
StevenCellist Nov 3, 2023
ccb28f3
[LoRaWAN] fix include logic
StevenCellist Nov 4, 2023
5796bbe
[LoRaWAN] fix warnings, remove duplicate function
StevenCellist Nov 4, 2023
3df866e
[LoRaWAN] improve examples, add unified sendReceive, bugfixes, add FSK
StevenCellist Nov 8, 2023
84bb8da
[LoRaWAN] improve examples
StevenCellist Nov 10, 2023
966ab6c
[LoRaWAN] add new keywords, add debug guard
StevenCellist Nov 11, 2023
140d35a
[SX127x] Updated startReceive interface to be more in line with SX126x
jgromes Nov 12, 2023
c170bc0
[SX127x] Added public method to convert from bytes to symbols
jgromes Nov 12, 2023
9e7978c
[LoRaWAN] Update start receive for SX127x
jgromes Nov 12, 2023
7002e47
Added note about LoRaWAN beta
jgromes Nov 12, 2023
c9eb2f1
[SX127x] Fixed potential float overflow
jgromes Nov 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 21 additions & 51 deletions examples/LoRaWAN/LoRaWAN_End_Device/LoRaWAN_End_Device.ino
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@
After your device is registered, you can run this example.
The device will join the network and start uploading data.

NOTE: LoRaWAN requires storing some parameters persistently!
RadioLib does this by using EEPROM, by default
starting at address 0 and using 32 bytes.
If you already use EEPROM in your application,
you will have to either avoid this range, or change it
by setting a different start address by changing the value of
RADIOLIB_HAL_PERSISTENT_STORAGE_BASE macro, either
during build or in src/BuildOpt.h.
LoRaWAN v1.1 requires the use of EEPROM (persistent storage).
Please refer to the 'persistent' example once you are familiar
with LoRaWAN.
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
Expand Down Expand Up @@ -53,13 +51,6 @@ void setup() {
while(true);
}

// first we need to initialize the device storage
// this will reset all persistently stored parameters
// NOTE: This should only be done once prior to first joining a network!
// After wiping persistent storage, you will also have to reset
// the end device in TTN and perform the join procedure again!
//node.wipe();

// application identifier - pre-LoRaWAN 1.1.0, this was called appEUI
// when adding new end device in TTN, you will have to enter this number
// you can pick any number you want, but it has to be unique
Expand Down Expand Up @@ -87,17 +78,23 @@ void setup() {
// and can be set to NULL

// some frequency bands only use a subset of the available channels
// you can set the starting channel and their number
// for example, the following corresponds to US915 FSB2 in TTN
// you can select the specific band or set the first channel and last channel
// for example, either of the following corresponds to US915 FSB2 in TTN
/*
node.startChannel = 8;
node.numChannels = 8;
node.selectSubband(2);
node.selectSubband(8, 15);
*/

// now we can start the activation
// this can take up to 20 seconds, and requires a LoRaWAN gateway in range
// this can take up to 10 seconds, and requires a LoRaWAN gateway in range
// a specific starting-datarate can be selected in dynamic bands (e.g. EU868):
/*
uint8_t joinDr = 4;
state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey, joinDr);
*/
Serial.print(F("[LoRaWAN] Attempting over-the-air activation ... "));
state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);

if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Expand All @@ -106,20 +103,6 @@ void setup() {
while(true);
}

// after the device has been activated,
// network can be rejoined after device power cycle
// by calling "begin"
/*
Serial.print(F("[LoRaWAN] Resuming previous session ... "));
state = node.begin();
if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
while(true);
}
*/
}

// counter to keep track of transmitted packets
Expand All @@ -129,23 +112,10 @@ void loop() {
// send uplink to port 10
Serial.print(F("[LoRaWAN] Sending uplink packet ... "));
String strUp = "Hello World! #" + String(count++);
int state = node.uplink(strUp, 10);
if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
}

// after uplink, you can call downlink(),
// to receive any possible reply from the server
// this function must be called within a few seconds
// after uplink to receive the downlink!
Serial.print(F("[LoRaWAN] Waiting for downlink ... "));
String strDown;
state = node.downlink(strDown);
int state = node.sendReceive(strUp, 10, strDown);
if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
Serial.println(F("received a downlink!"));

// print data of the packet (if there are any)
Serial.print(F("[LoRaWAN] Data:\t\t"));
Expand All @@ -171,13 +141,13 @@ void loop() {
Serial.println(F(" Hz"));

} else if(state == RADIOLIB_ERR_RX_TIMEOUT) {
Serial.println(F("timeout!"));
Serial.println(F("no downlink!"));

} else {
Serial.print(F("failed, code "));
Serial.println(state);
}

// wait before sending another packet
delay(10000);
delay(30000);
}
79 changes: 27 additions & 52 deletions examples/LoRaWAN/LoRaWAN_End_Device_ABP/LoRaWAN_End_Device_ABP.ino
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,13 @@
The device will start uploading data directly,
without having to join the network.

NOTE: LoRaWAN requires storing some parameters persistently!
RadioLib does this by using EEPROM, by default
starting at address 0 and using 32 bytes.
If you already use EEPROM in your application,
you will have to either avoid this range, or change it
by setting a different start address by changing the value of
RADIOLIB_HAL_PERSISTENT_STORAGE_BASE macro, either
during build or in src/BuildOpt.h.

LoRaWAN v1.1 requires the use of EEPROM (persistent storage).
Please refer to the 'persistent' example once you are familiar
with LoRaWAN.
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

Expand Down Expand Up @@ -54,13 +52,6 @@ void setup() {
while(true);
}

// first we need to initialize the device storage
// this will reset all persistently stored parameters
// NOTE: This should only be done once prior to first joining a network!
// After wiping persistent storage, you will also have to reset
// the end device in TTN!
//node.wipe();

// device address - this number can be anything
// when adding new end device in TTN, you can generate this number,
// or you can set any value you want, provided it is unique
Expand All @@ -83,16 +74,27 @@ void setup() {
// and can be set to NULL

// some frequency bands only use a subset of the available channels
// you can set the starting channel and their number
// for example, the following corresponds to US915 FSB2 in TTN
// you can select the specific band or set the first channel and last channel
// for example, either of the following corresponds to US915 FSB2 in TTN
/*
node.selectSubband(2);
node.selectSubband(8, 15);
*/

// if using EU868 on ABP in TTN, you need to set the SF for RX2 window manually
/*
node.rx2.drMax = 3;
*/

// to start a LoRaWAN v1.1 session, the user should also provide
// fNwkSIntKey and sNwkSIntKey similar to nwkSKey and appSKey
/*
node.startChannel = 8;
node.numChannels = 8;
state = node.beginABP(devAddr, nwkSKey, appSKey, fNwkSIntKey, sNwkSIntKey);
*/

// start the device by directly providing the encryption keys and device address
Serial.print(F("[LoRaWAN] Attempting over-the-air activation ... "));
state = node.beginAPB(devAddr, (uint8_t*)nwkSKey, (uint8_t*)appSKey);
state = node.beginABP(devAddr, nwkSKey, appSKey);
if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Expand All @@ -101,20 +103,6 @@ void setup() {
while(true);
}

// after the device has been activated,
// network can be rejoined after device power cycle
// by calling "begin"
/*
Serial.print(F("[LoRaWAN] Resuming previous session ... "));
state = node.begin();
if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
while(true);
}
*/
}

// counter to keep track of transmitted packets
Expand All @@ -124,23 +112,10 @@ void loop() {
// send uplink to port 10
Serial.print(F("[LoRaWAN] Sending uplink packet ... "));
String strUp = "Hello World! #" + String(count++);
int state = node.uplink(strUp, 10);
if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
}

// after uplink, you can call downlink(),
// to receive any possible reply from the server
// this function must be called within a few seconds
// after uplink to receive the downlink!
Serial.print(F("[LoRaWAN] Waiting for downlink ... "));
String strDown;
state = node.downlink(strDown);
int state = node.sendReceive(strUp, 10, strDown);
if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
Serial.println(F("received a downlink!"));

// print data of the packet (if there are any)
Serial.print(F("[LoRaWAN] Data:\t\t"));
Expand All @@ -166,13 +141,13 @@ void loop() {
Serial.println(F(" Hz"));

} else if(state == RADIOLIB_ERR_RX_TIMEOUT) {
Serial.println(F("timeout!"));
Serial.println(F("no downlink!"));

} else {
Serial.print(F("failed, code "));
Serial.println(state);
}

// wait before sending another packet
delay(10000);
delay(30000);
}
Loading
Loading