Skip to content

Commit 6f254b0

Browse files
committed
Add interrupt handling and CAD detection example
1 parent 8319d45 commit 6f254b0

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#include <util/atomic.h>
2+
3+
#include <SPI.h>
4+
#include <LoRa.h>
5+
6+
/*
7+
* This example shows how to use interrupts to catch various LoRa events:
8+
* - RxDone
9+
* - TxDone
10+
* - CADDone
11+
* - RxTimeout
12+
* - FHSSChangeChannel
13+
* - CADDetected
14+
* - ValidHeader
15+
* - CRCError
16+
* - PLLLock
17+
* - ModeReady
18+
* - ClockOutput
19+
*
20+
* This specific example goes through the process of turning on CAD detection and
21+
* when a successful CAD was observed, put the LoRa chip to receive mode.
22+
*/
23+
24+
/*
25+
* It's possible to handle LoRa CAD (channel activity detection, page 43) the following way via interrupts:
26+
*
27+
* 1. Write your interrupt service routine (ISR) which is executed when an IRQ arrives to the pin which is connected to DIO[0-5].
28+
* 2. Configure ISR in Arduino for LoRa DIO[0-5] pin: LoRa.setInterruptMode(0, LORA_IRQ_MODE_CADDONE)
29+
* 3. Start CAD: LoRa.cad()
30+
* 4. Check if valid CAD detected after an IRQ arrived : LoRa.readInterrupts() & LORA_IRQ_FLAG_CAD_DETECTED
31+
* 5. Clear IRQs to be able to restart CAD process later: LoRa.clearInterrupts(LORA_IRQ_FLAG_CAD_DETECTED | LORA_IRQ_FLAG_CAD_DONE);
32+
*
33+
* You may use all five DIOs concurrently connected to different Arduino pins (though those pins should intercept IRQs).
34+
*
35+
* Wiring of the current example: LoRa DIO0 - Arduino D3
36+
*/
37+
38+
/* Copyright © 2018 Szőts Ákos <[email protected]> */
39+
40+
// Interrupt Service Routine (ISR)
41+
// Must be as short as physically possible - assigning a variable should make it
42+
static volatile bool interruptHappened = false;
43+
static void isr_pinD3() {
44+
interruptHappened = true;
45+
}
46+
47+
void setup() {
48+
Serial.begin(9600);
49+
while (!Serial)
50+
;
51+
52+
if (!LoRa.begin(915E6)) {
53+
Serial.println("Starting LoRa failed");
54+
while (1)
55+
;
56+
}
57+
58+
// For other constants, like FHSS change channel, CRC error, or RX timeout, see the LoRa.h header file.
59+
// Choose from LORA_IRQ_DIOx_ variants and use this "x" number in place of the first parameter.
60+
// Not all DIOx and interrupt type mixes are possible.
61+
LoRa.setInterruptMode(0 /* DIO0 */, LORA_IRQ_DIO0_CADDONE);
62+
63+
// Launch our ISR function when LoRa interrupt happens
64+
attachInterrupt(digitalPinToInterrupt(3), isr_pinD3, RISING);
65+
66+
// Start LoRa CAD process
67+
LoRa.cad();
68+
69+
Serial.println("Starting LoRa succeeded");
70+
}
71+
72+
void loop() {
73+
if (interruptHappened) {
74+
interruptHappened = false;
75+
76+
const uint8_t loraInterrupts = LoRa.readInterrupts();
77+
if (loraInterrupts & LORA_IRQ_FLAG_CAD_DETECTED) { // Here use LORA_IRQ_FLAG_* variants from LoRa.h
78+
LoRa.parsePacket(); // Put into RXSINGLE mode
79+
// ... Process packet if there's one
80+
}
81+
82+
// Do not let the ISR function and the loop() write and read the interruptHappened variable at the same time
83+
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
84+
{
85+
// It's possible that the ISR function had set interruptHappened to "true" while we were receiving packets.
86+
// Check again to be sure that we clear interrupt flags only when we received no further IRQs.
87+
if (!interruptHappened) {
88+
LoRa.clearInterrupts(LORA_IRQ_FLAG_CAD_DETECTED | LORA_IRQ_FLAG_CAD_DONE);
89+
}
90+
}
91+
92+
// Restart CAD process
93+
LoRa.cad();
94+
}
95+
}

0 commit comments

Comments
 (0)