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

Updated interrupt based blocking callback to loop based non-blocking one #621

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 6 additions & 2 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ Returns `1` on success, `0` on failure.

### Register callback

Register a callback function for when a packet transmission finish.
Register a callback function for when a packet transmission finish. `NOTE:` Only write simple
function to manipulate a state variable. Then use the variable to do action in loop(). Also,
delay() will not work as it is an interrupt callback.

```arduino
LoRa.onTxDone(onTxDone);
Expand Down Expand Up @@ -162,7 +164,9 @@ Returns the packet size in bytes or `0` if no packet was received.

#### Register callback

Register a callback function for when a packet is received.
Register a callback function for when a packet is received. `NOTE:` Only write simple
function to manipulate a state variable. Then use the variable to do action in loop(). Also,
delay() will not work as it is an interrupt callback.

```arduino
LoRa.onReceive(onReceive);
Expand Down
14 changes: 11 additions & 3 deletions examples/LoRaDuplexCallback/LoRaDuplexCallback.ino
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ byte localAddress = 0xBB; // address of this device
byte destination = 0xFF; // destination to send to
long lastSendTime = 0; // last send time
int interval = 2000; // interval between sends
int packetReceived = 0; // keeps track of packetReceived for onReceiveCallback

void setup() {
Serial.begin(9600); // initialize serial
Expand All @@ -44,12 +45,16 @@ void setup() {
while (true); // if failed, do nothing
}

LoRa.onReceive(onReceive);
// onReceive calls interrupt internally. should run only tiny amount of code
// any heavylifting should handled in the loop
// also, should not contain any timer based delay calls
LoRa.onReceive([](int packetLength) { packetReceived = packetLength; });
LoRa.receive();
Serial.println("LoRa init succeeded.");
}

void loop() {
if (packetReceived) onReceive();
if (millis() - lastSendTime > interval) {
String message = "HeLoRa World!"; // send a message
sendMessage(message);
Expand All @@ -71,8 +76,8 @@ void sendMessage(String outgoing) {
msgCount++; // increment message ID
}

void onReceive(int packetSize) {
if (packetSize == 0) return; // if there's no packet, return
void onReceive() {
if (!packetReceived) return; // if there's no packet, return

// read packet header bytes:
int recipient = LoRa.read(); // recipient address
Expand Down Expand Up @@ -106,5 +111,8 @@ void onReceive(int packetSize) {
Serial.println("RSSI: " + String(LoRa.packetRssi()));
Serial.println("Snr: " + String(LoRa.packetSnr()));
Serial.println();

packetReceived = 0; // reset packetReceived so that
// onReceive only runs once per packet
}

16 changes: 12 additions & 4 deletions examples/LoRaReceiverCallback/LoRaReceiverCallback.ino
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#error "This example is not compatible with the Arduino MKR WAN 1300 board!"
#endif

int packetReceived = 0; // keeps track of packetReceived for onReceiveCallback

void setup() {
Serial.begin(9600);
while (!Serial);
Expand All @@ -20,26 +22,32 @@ void setup() {
// LoRa.setGain(6);

// register the receive callback
LoRa.onReceive(onReceive);
// onReceive calls interrupt internally. should run only tiny amount of code
// any heavylifting should handled in the loop
// also, should not contain any timer based delay calls
LoRa.onReceive([](int packetLength) { packetReceived = packetLength; });

// put the radio into receive mode
LoRa.receive();
}

void loop() {
// do nothing
if (packetReceived) onReceive();
}

void onReceive(int packetSize) {
void onReceive() {
// received a packet
Serial.print("Received packet '");

// read packet
for (int i = 0; i < packetSize; i++) {
for (int i = 0; i < packetReceived; i++) {
Serial.print((char)LoRa.read());
}

// print RSSI of packet
Serial.print("' with RSSI ");
Serial.println(LoRa.packetRssi());

// reset packetReceived so that onReceive only runs once per packet
packetReceived = 0;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#include <SPI.h>
#include <LoRa.h>

int counter = 0;
int counter = 0;
bool txDone = false; // keeps track of txDone for onTxDone

void setup() {
Serial.begin(9600);
Expand All @@ -14,10 +15,14 @@ void setup() {
while (1);
}

LoRa.onTxDone(onTxDone);
// onTxDone calls interrupt internally. should run only tiny amount of code
// any heavylifting should handled in the loop
// also, should not contain any timer based delay calls
LoRa.onTxDone([] { txDone = true; });
}

void loop() {
if (txDone) onTxDone();
if (runEvery(5000)) { // repeat every 5000 millis

Serial.print("Sending packet non-blocking: ");
Expand All @@ -35,6 +40,8 @@ void loop() {

void onTxDone() {
Serial.println("TxDone");
txDone = false; // reset packetReceived so that
// onTxDone only runs once per tx
}

boolean runEvery(unsigned long interval)
Expand Down
24 changes: 21 additions & 3 deletions examples/LoRaSimpleGateway/LoRaSimpleGateway.ino
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ const long frequency = 915E6; // LoRa Frequency
const int csPin = 10; // LoRa radio chip select
const int resetPin = 9; // LoRa radio reset
const int irqPin = 2; // change for your board; must be a hardware interrupt pin
int packetReceived = 0; // keeps track of packetReceived for onReceiveCallback
bool txDone = false; // keeps track of txDone for onTxDone

void setup() {
Serial.begin(9600); // initialize serial
Expand All @@ -52,12 +54,22 @@ void setup() {
Serial.println("Rx: invertIQ disable");
Serial.println();

LoRa.onReceive(onReceive);
LoRa.onTxDone(onTxDone);
// register the receive callback
// onReceive calls interrupt internally. should run only tiny amount of code
// any heavylifting should handled in the loop
// also, should not contain any timer based delay calls
LoRa.onReceive([](int packetLength) { packetReceived = packetLength; });

// onTxDone calls interrupt internally. should run only tiny amount of code
// any heavylifting should handled in the loop
// also, should not contain any timer based delay calls
LoRa.onTxDone([] { txDone = true; });
LoRa_rxMode();
}

void loop() {
if (txDone) onTxDone();
if (packetReceived) onReceive();
if (runEvery(5000)) { // repeat every 5000 millis

String message = "HeLoRa World! ";
Expand Down Expand Up @@ -87,7 +99,7 @@ void LoRa_sendMessage(String message) {
LoRa.endPacket(true); // finish packet and send it
}

void onReceive(int packetSize) {
void onReceive() {
String message = "";

while (LoRa.available()) {
Expand All @@ -96,11 +108,17 @@ void onReceive(int packetSize) {

Serial.print("Gateway Receive: ");
Serial.println(message);

packetReceived = 0; // reset packetReceived so that
// onReceive only runs once per packet
}

void onTxDone() {
Serial.println("TxDone");
LoRa_rxMode();

txDone = false; // reset packetReceived so that
// onTxDone only runs once per tx
}

boolean runEvery(unsigned long interval)
Expand Down
24 changes: 21 additions & 3 deletions examples/LoRaSimpleNode/LoRaSimpleNode.ino
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ const long frequency = 915E6; // LoRa Frequency
const int csPin = 10; // LoRa radio chip select
const int resetPin = 9; // LoRa radio reset
const int irqPin = 2; // change for your board; must be a hardware interrupt pin
int packetReceived = 0; // keeps track of packetReceived for onReceiveCallback
bool txDone = false; // keeps track of txDone for onTxDone

void setup() {
Serial.begin(9600); // initialize serial
Expand All @@ -52,12 +54,22 @@ void setup() {
Serial.println("Rx: invertIQ enable");
Serial.println();

LoRa.onReceive(onReceive);
LoRa.onTxDone(onTxDone);
// register the receive callback
// onReceive calls interrupt internally. should run only tiny amount of code
// any heavylifting should handled in the loop
// also, should not contain any timer based delay calls
LoRa.onReceive([](int packetLength) { packetReceived = packetLength; });

// onTxDone calls interrupt internally. should run only tiny amount of code
// any heavylifting should handled in the loop
// also, should not contain any timer based delay calls
LoRa.onTxDone([] { txDone = true; });
LoRa_rxMode();
}

void loop() {
if (txDone) onTxDone();
if (packetReceived) onReceive();
if (runEvery(1000)) { // repeat every 1000 millis

String message = "HeLoRa World! ";
Expand Down Expand Up @@ -87,7 +99,7 @@ void LoRa_sendMessage(String message) {
LoRa.endPacket(true); // finish packet and send it
}

void onReceive(int packetSize) {
void onReceive() {
String message = "";

while (LoRa.available()) {
Expand All @@ -96,11 +108,17 @@ void onReceive(int packetSize) {

Serial.print("Node Receive: ");
Serial.println(message);

packetReceived = 0; // reset packetReceived so that
// onReceive only runs once per packet
}

void onTxDone() {
Serial.println("TxDone");
LoRa_rxMode();

txDone = false; // reset packetReceived so that
// onTxDone only runs once per tx
}

boolean runEvery(unsigned long interval)
Expand Down