From 1415d23dfa45d80b0352d3c47b735a78cb759095 Mon Sep 17 00:00:00 2001 From: sheikhmishar Date: Mon, 19 Dec 2022 18:22:24 +0600 Subject: [PATCH 1/2] from interrupt based blocking callback to loop fn --- .../LoRaDuplexCallback/LoRaDuplexCallback.ino | 14 ++++++++--- .../LoRaReceiverCallback.ino | 16 +++++++++---- .../LoRaSenderNonBlockingCallback.ino | 11 +++++++-- .../LoRaSimpleGateway/LoRaSimpleGateway.ino | 24 ++++++++++++++++--- examples/LoRaSimpleNode/LoRaSimpleNode.ino | 24 ++++++++++++++++--- 5 files changed, 74 insertions(+), 15 deletions(-) diff --git a/examples/LoRaDuplexCallback/LoRaDuplexCallback.ino b/examples/LoRaDuplexCallback/LoRaDuplexCallback.ino index 0511f3e..28831e3 100644 --- a/examples/LoRaDuplexCallback/LoRaDuplexCallback.ino +++ b/examples/LoRaDuplexCallback/LoRaDuplexCallback.ino @@ -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 @@ -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); @@ -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 @@ -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 } diff --git a/examples/LoRaReceiverCallback/LoRaReceiverCallback.ino b/examples/LoRaReceiverCallback/LoRaReceiverCallback.ino index ed554d9..561db09 100644 --- a/examples/LoRaReceiverCallback/LoRaReceiverCallback.ino +++ b/examples/LoRaReceiverCallback/LoRaReceiverCallback.ino @@ -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); @@ -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; } diff --git a/examples/LoRaSenderNonBlockingCallback/LoRaSenderNonBlockingCallback.ino b/examples/LoRaSenderNonBlockingCallback/LoRaSenderNonBlockingCallback.ino index aa79499..5d7536b 100644 --- a/examples/LoRaSenderNonBlockingCallback/LoRaSenderNonBlockingCallback.ino +++ b/examples/LoRaSenderNonBlockingCallback/LoRaSenderNonBlockingCallback.ino @@ -1,7 +1,8 @@ #include #include -int counter = 0; +int counter = 0; +bool txDone = false; // keeps track of txDone for onTxDone void setup() { Serial.begin(9600); @@ -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: "); @@ -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) diff --git a/examples/LoRaSimpleGateway/LoRaSimpleGateway.ino b/examples/LoRaSimpleGateway/LoRaSimpleGateway.ino index 95d84a7..9a203a6 100644 --- a/examples/LoRaSimpleGateway/LoRaSimpleGateway.ino +++ b/examples/LoRaSimpleGateway/LoRaSimpleGateway.ino @@ -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 @@ -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! "; @@ -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()) { @@ -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) diff --git a/examples/LoRaSimpleNode/LoRaSimpleNode.ino b/examples/LoRaSimpleNode/LoRaSimpleNode.ino index db8c6fa..f508c68 100644 --- a/examples/LoRaSimpleNode/LoRaSimpleNode.ino +++ b/examples/LoRaSimpleNode/LoRaSimpleNode.ino @@ -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 @@ -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! "; @@ -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()) { @@ -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) From cbec0b8520d503a54bf5efe631d117bd1cf256ad Mon Sep 17 00:00:00 2001 From: sheikhmishar Date: Mon, 19 Dec 2022 18:26:30 +0600 Subject: [PATCH 2/2] update API.md for interrupt(blocking) -> loop (non blocking) --- API.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/API.md b/API.md index db1cf1c..0aa4072 100644 --- a/API.md +++ b/API.md @@ -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); @@ -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);