1
0
mirror of https://github.com/sandeepmistry/arduino-LoRa.git synced 2025-04-19 13:02:14 +03:00

Add Channel Activity Detection function and examples.

This commit is contained in:
Minoru Tomobe 2020-02-02 23:14:40 +09:00
parent 26640bc6b7
commit e75fd5b84a
5 changed files with 119 additions and 3 deletions

23
API.md
View File

@ -40,7 +40,7 @@ To save further pins one could connect the reset pin of the MCU with reset pin o
#### Pin dio0 interrupt callbacks
The dio0 pin can be used for transmission finish callback and/or receiving callback, check `onTxDone` and `onReceive`.
The dio0 pin can be used for channel activity detection callback, transmission finish callback and/or receiving callback, check `onCadDone` , `onTxDone`, and `onReceive`.
### Set SPI interface
@ -242,6 +242,27 @@ Returns the next byte in the packet or `-1` if no bytes are available.
**Note:** Other Arduino [`Stream` API's](https://www.arduino.cc/en/Reference/Stream) can also be used to read data from the packet
## Channel Activity Detection
**WARNING**: Channel activity detection callback uses the interrupt pin on the `dio0`, check `setPins` function!
### Register callback
Register a callback function for when channel activity detection has done.
```arduino
LoRa.onCadDone(onCadDone);
void onCadDone(boolean signalDetected) {
// ...
}
```
* `onCadDone` - function to call when channel activity detection has done.
* `signalDetected` - if `true`, the radio detects the presence of other LoRa signals.
### Channel Activity detection mode
Puts the radio in channel activity detection mode.
```arduino
LoRa.CAD();
```
## Other radio modes
### Idle mode

View File

@ -0,0 +1,58 @@
#include <SPI.h>
#include "LoRa.h"
#ifdef ARDUINO_SAMD_MKRWAN1300
#error "This example is not compatible with the Arduino MKR WAN 1300 board!"
#endif
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println("LoRa Receiver Callback");
if (!LoRa.begin(915E6)) {
Serial.println("Starting LoRa failed!");
while (1);
}
// register the channel activity dectection callback
LoRa.onCadDone(onCadDone);
// register the receive callback
LoRa.onReceive(onReceive);
// put the radio into CAD mode
LoRa.CAD();
}
void loop() {
// do nothing
}
void onCadDone(boolean signalDetected) {
// detect preamble
if (signalDetected) {
Serial.println("Signal detected");
// put the radio into continuous receive mode
LoRa.receive();
} else {
// try next activity dectection
LoRa.CAD();
}
}
void onReceive(int packetSize) {
// received a packet
Serial.print("Received packet '");
// read packet
for (int i = 0; i < packetSize; i++) {
Serial.print((char)LoRa.read());
}
// print RSSI of packet
Serial.print("' with RSSI ");
Serial.println(LoRa.packetRssi());
// put the radio into CAD mode
LoRa.CAD();
}

View File

@ -32,6 +32,8 @@ flush KEYWORD2
onReceive KEYWORD2
onTxDone KEYWORD2
onCadDone KEYWORD2
CAD KEYWORD2
receive KEYWORD2
idle KEYWORD2
sleep KEYWORD2

View File

@ -46,6 +46,7 @@
#define MODE_TX 0x03
#define MODE_RX_CONTINUOUS 0x05
#define MODE_RX_SINGLE 0x06
#define MODE_CAD 0x07
// PA config
#define PA_BOOST 0x80
@ -54,6 +55,8 @@
#define IRQ_TX_DONE_MASK 0x08
#define IRQ_PAYLOAD_CRC_ERROR_MASK 0x20
#define IRQ_RX_DONE_MASK 0x40
#define IRQ_CAD_DONE_MASK 0x04
#define IRQ_CAD_DETECTED_MASK 0x01
#define MAX_PKT_LENGTH 255
@ -71,6 +74,7 @@ LoRaClass::LoRaClass() :
_packetIndex(0),
_implicitHeaderMode(0),
_onReceive(NULL),
_onCadDone(NULL),
_onTxDone(NULL)
{
// overide Stream timeout value
@ -199,7 +203,7 @@ int LoRaClass::endPacket(bool async)
bool LoRaClass::isTransmitting()
{
if ((readRegister(REG_OP_MODE) & MODE_TX) == MODE_TX) {
if ((readRegister(REG_OP_MODE) & B111) == MODE_TX) {
return true;
}
@ -367,6 +371,24 @@ void LoRaClass::onReceive(void(*callback)(int))
}
}
void LoRaClass::onCadDone(void(*callback)(boolean))
{
_onCadDone = callback;
if (callback) {
pinMode(_dio0, INPUT);
#ifdef SPI_HAS_NOTUSINGINTERRUPT
SPI.usingInterrupt(digitalPinToInterrupt(_dio0));
#endif
attachInterrupt(digitalPinToInterrupt(_dio0), LoRaClass::onDio0Rise, RISING);
} else {
detachInterrupt(digitalPinToInterrupt(_dio0));
#ifdef SPI_HAS_NOTUSINGINTERRUPT
SPI.notUsingInterrupt(digitalPinToInterrupt(_dio0));
#endif
}
}
void LoRaClass::onTxDone(void(*callback)())
{
_onTxDone = callback;
@ -400,6 +422,12 @@ void LoRaClass::receive(int size)
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_CONTINUOUS);
}
void LoRaClass::CAD(void)
{
writeRegister(REG_DIO_MAPPING_1, 0x80);// DIO0 => CADDONE
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_CAD);
}
#endif
void LoRaClass::idle()
@ -679,7 +707,11 @@ void LoRaClass::handleDio0Rise()
// reset FIFO address
writeRegister(REG_FIFO_ADDR_PTR, 0);
}
else if ((irqFlags & IRQ_TX_DONE_MASK) != 0) {
else if ((irqFlags & IRQ_CAD_DONE_MASK) != 0) {
if (_onCadDone) {
_onCadDone((irqFlags & IRQ_CAD_DETECTED_MASK) != 0);
}
} else if ((irqFlags & IRQ_TX_DONE_MASK) != 0) {
if (_onTxDone) {
_onTxDone();
}

View File

@ -57,9 +57,11 @@ public:
#ifndef ARDUINO_SAMD_MKRWAN1300
void onReceive(void(*callback)(int));
void onCadDone(void(*callback)(boolean));
void onTxDone(void(*callback)());
void receive(int size = 0);
void CAD(void);
#endif
void idle();
void sleep();
@ -118,6 +120,7 @@ private:
int _packetIndex;
int _implicitHeaderMode;
void (*_onReceive)(int);
void (*_onCadDone)(boolean);
void (*_onTxDone)();
};