Exact same code is working fine when I use the delay.
As soon as I replace delay with api.system.sleep.all(3000); I do not get data on receiving node. I tried re-initialing the Lora parameters after waking up but that didn’t worked as well.
uint8_t counter = 1;
unsigned int previousTxDuration = 0; // Stores TX duration from previous loop
void send_cb(void) {
// Optional: callback after sending
}
void setup() {
// No Serial
api.lora.nwm.set(); // Set to P2P mode
api.lora.pfreq.set(923200000); // Match receiver frequency
api.lora.psf.set(12); // Spreading Factor
api.lora.pbw.set(125); // Bandwidth
api.lora.pcr.set(0); // Coding Rate
api.lora.ppl.set(8); // Preamble Length
api.lora.ptp.set(10); // TX Power
api.lora.registerPSendCallback(send_cb);
delay(1000);
}
void loop() {
uint8_t payload[3]; // 1 byte for counter + 2 bytes for txDuration
unsigned long startTime = millis(); // Start time before transmission
api.lora.precv(0); // Clear RX buffer
// Transmit payload
payload[0] = counter;
payload[1] = previousTxDuration & 0xFF; // Low byte (from previous iteration)
payload[2] = (previousTxDuration >> 8) & 0xFF; // High byte (from previous iteration)
api.lora.psend(sizeof(payload), payload);
unsigned long endTime = millis(); // End time after transmission
// Calculate transmission duration for the next iteration
previousTxDuration = (endTime - startTime); // Duration taken to transmit
counter++;
if (counter > 50) counter = 1;
delay(3000);
}
Re-Initialized using this function
void reinitLoRa() {
api.lora.nwm.set(); // P2P mode
api.lora.pfreq.set(923200000);
api.lora.psf.set(12);
api.lora.pbw.set(125);
api.lora.pcr.set(0);
api.lora.ppl.set(8);
api.lora.ptp.set(10);
api.lora.registerPSendCallback(send_cb);
}
and calling it after wake up condition.
Please let me know if I am over looking anything. Thanks.
is not a blocking call. It does not wait for the transmission to be finished, just sends it to the underlaying RUI3 system for sending and comes back immediately.
api.system.sleep.all(3000);
Puts the LoRa transceiver and the MCU into sleep mode, most likely before it even started sending.
Improved code (but not the best solution imho):
Use the TX callback to know when the TX is finished, then call api.system.sleep.all(3000);
#include <Arduino.h>
uint8_t counter = 1;
unsigned int previousTxDuration = 0; // Stores TX duration from previous loop
// Flag for TX finished
bool tx_finished = false;
void send_cb(void)
{
// Set TX finished flag
tx_finished = true;
}
void setup()
{
// No Serial
api.lora.nwm.set(); // Set to P2P mode
api.lora.pfreq.set(916000000); // Match receiver frequency
api.lora.psf.set(7); // Spreading Factor
api.lora.pbw.set(250); // Bandwidth
api.lora.pcr.set(0); // Coding Rate
api.lora.ppl.set(8); // Preamble Length
api.lora.ptp.set(10); // TX Power
api.lora.registerPSendCallback(send_cb);
delay(1000);
}
void loop()
{
uint8_t payload[3]; // 1 byte for counter + 2 bytes for txDuration
unsigned long startTime = millis(); // Start time before transmission
api.lora.precv(0); // Clear RX buffer
// Transmit payload
payload[0] = counter;
payload[1] = previousTxDuration & 0xFF; // Low byte (from previous iteration)
payload[2] = (previousTxDuration >> 8) & 0xFF; // High byte (from previous iteration)
api.lora.psend(sizeof(payload), payload);
unsigned long endTime = millis(); // End time after transmission
// Calculate transmission duration for the next iteration
previousTxDuration = (endTime - startTime); // Duration taken to transmit
counter++;
if (counter > 50)
counter = 1;
// delay(3000);
while (!tx_finished)
{
delay(100);
}
tx_finished = false;
api.system.sleep.all(3000);
}
Personally, I would not use the loop() at all if I want to send every three seconds and instead use a timer.
With api.system.lpm(1); you enable automatic power save mode and the module will go into sleep whenever possible.
With api.system.sleep.all(); in the loop, the loop is disabled and doesn’t consume power.
The send routine will wake up by a timer and initiate the sending. Once the transmission is finished, the system goes into sleep mode by itself.
My code
#include <Arduino.h>
uint8_t counter = 1;
unsigned int previousTxDuration = 0; // Stores TX duration from previous loop
bool tx_finished = true;
void send_handler(void *);
void send_cb(void)
{
// Set TX finished flag
tx_finished = true;
}
void setup()
{
// No Serial
api.lora.nwm.set(); // Set to P2P mode
api.lora.pfreq.set(916000000); // Match receiver frequency
api.lora.psf.set(7); // Spreading Factor
api.lora.pbw.set(250); // Bandwidth
api.lora.pcr.set(0); // Coding Rate
api.lora.ppl.set(8); // Preamble Length
api.lora.ptp.set(10); // TX Power
api.lora.registerPSendCallback(send_cb);
delay(1000);
// Enable power saving
api.system.lpm(1);
// Create a timer.
api.system.timer.create(RAK_TIMER_0, send_handler, RAK_TIMER_PERIODIC);
// Start a timer.
api.system.timer.start(RAK_TIMER_0, 3000, NULL);
}
void loop(void)
{
api.system.sleep.all();
}
void send_handler(void *)
{
// Check if last transmission is finished
if (!tx_finished)
{
return;
}
uint8_t payload[3]; // 1 byte for counter + 2 bytes for txDuration
unsigned long startTime = millis(); // Start time before transmission
api.lora.precv(0); // Clear RX buffer
// Transmit payload
payload[0] = counter;
payload[1] = previousTxDuration & 0xFF; // Low byte (from previous iteration)
payload[2] = (previousTxDuration >> 8) & 0xFF; // High byte (from previous iteration)
tx_finished = false;
api.lora.psend(sizeof(payload), payload);
unsigned long endTime = millis(); // End time after transmission
// Calculate transmission duration for the next iteration
previousTxDuration = (endTime - startTime); // Duration taken to transmit
counter++;
if (counter > 50)
counter = 1;
}