mirror of
https://github.com/sandeepmistry/arduino-LoRa.git
synced 2025-04-19 13:02:14 +03:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
dee0fdb887
10
.travis.yml
10
.travis.yml
@ -9,6 +9,7 @@ env:
|
||||
- BOARD="arduino:samd:arduino_zero_edbg"
|
||||
- BOARD="arduino:samd:mkr1000"
|
||||
- BOARD="arduino:samd:mkrzero"
|
||||
- BOARD="arduino:samd:mkrwan1300"
|
||||
before_install:
|
||||
- wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz
|
||||
- tar xf arduino-$IDE_VERSION-linux64.tar.xz
|
||||
@ -24,9 +25,14 @@ install:
|
||||
script:
|
||||
- buildExampleSketch LoRaDumpRegisters
|
||||
- buildExampleSketch LoRaDuplex
|
||||
- buildExampleSketch LoRaDuplexCallback
|
||||
- if [[ "$BOARD" != "arduino:samd:mkrwan1300" ]]; then
|
||||
buildExampleSketch LoRaDuplexCallback;
|
||||
fi
|
||||
- buildExampleSketch LoRaReceiver
|
||||
- buildExampleSketch LoRaReceiverCallback
|
||||
- if [[ "$BOARD" != "arduino:samd:mkrwan1300" ]]; then
|
||||
buildExampleSketch LoRaReceiverCallback;
|
||||
fi
|
||||
- buildExampleSketch LoRaSender
|
||||
- buildExampleSketch LoRaSenderNonBlocking
|
||||
- buildExampleSketch LoRaSetSpread
|
||||
- buildExampleSketch LoRaSetSyncWord
|
||||
|
34
API.md
34
API.md
@ -38,6 +38,17 @@ To save further pins one could connect the reset pin of the MCU with reset pin o
|
||||
|
||||
* `reset` - set to `-1` to omit this pin
|
||||
|
||||
### Set SPI interface
|
||||
|
||||
Override the default SPI interface used by the library. **Must** be called before `LoRa.begin()`.
|
||||
|
||||
```arduino
|
||||
LoRa.setSPI(spi);
|
||||
```
|
||||
* `spi` - new SPI interface to use, defaults to `SPI`
|
||||
|
||||
This call is optional and only needs to be used if you need to change the default SPI interface used, in the case your Arduino (or compatible) board has more than one SPI interface present.
|
||||
|
||||
### Set SPI Frequency
|
||||
|
||||
Override the default SPI frequency of 10 MHz used by the library. **Must** be called before `LoRa.begin()`.
|
||||
@ -71,7 +82,7 @@ LoRa.beginPacket(implicitHeader);
|
||||
|
||||
* `implicitHeader` - (optional) `true` enables implicit header mode, `false` enables explicit header mode (default)
|
||||
|
||||
Returns `1` on success, `0` on failure.
|
||||
Returns `1` if radio is ready to transmit, `0` if busy or on failure.
|
||||
|
||||
### Writing
|
||||
|
||||
@ -98,8 +109,11 @@ Returns the number of bytes written.
|
||||
End the sequence of sending a packet.
|
||||
|
||||
```arduino
|
||||
LoRa.endPacket()
|
||||
LoRa.endPacket();
|
||||
|
||||
LoRa.endPacket(async);
|
||||
```
|
||||
* `async` - (optional) `true` enables non-blocking mode, `false` waits for transmission to be completed (default)
|
||||
|
||||
Returns `1` on success, `0` on failure.
|
||||
|
||||
@ -122,6 +136,8 @@ Returns the packet size in bytes or `0` if no packet was received.
|
||||
|
||||
### Continuous receive mode
|
||||
|
||||
**WARNING**: Not supported on the Arduino MKR WAN 1300 board!
|
||||
|
||||
#### Register callback
|
||||
|
||||
Register a callback function for when a packet is received.
|
||||
@ -236,7 +252,7 @@ LoRa.setTxPower(txPower, outputPin);
|
||||
* `txPower` - TX power in dB, defaults to `17`
|
||||
* `outputPin` - (optional) PA output pin, supported values are `PA_OUTPUT_RFO_PIN` and `PA_OUTPUT_PA_BOOST_PIN`, defaults to `PA_OUTPUT_PA_BOOST_PIN`.
|
||||
|
||||
Supported values are between `2` and `17` for `PA_OUTPUT_PA_BOOST_PIN`, `0` and `14` for `PA_OUTPUT_RFO_PIN`.
|
||||
Supported values are `2` to `20` for `PA_OUTPUT_PA_BOOST_PIN`, and `0` to `14` for `PA_OUTPUT_RFO_PIN`.
|
||||
|
||||
Most modules have the PA output pin connected to PA BOOST,
|
||||
|
||||
@ -304,7 +320,7 @@ Change the sync word of the radio.
|
||||
LoRa.setSyncWord(syncWord);
|
||||
```
|
||||
|
||||
* `syncWord` - byte value to use as the sync word, defaults to `0x34`
|
||||
* `syncWord` - byte value to use as the sync word, defaults to `0x12`
|
||||
|
||||
### CRC
|
||||
|
||||
@ -316,6 +332,16 @@ LoRa.enableCrc();
|
||||
LoRa.disableCrc();
|
||||
```
|
||||
|
||||
### Invert IQ Signals
|
||||
|
||||
Enable or disable Invert the LoRa I and Q signals, by default a invertIQ is not used.
|
||||
|
||||
```arduino
|
||||
LoRa.enableInvertIQ();
|
||||
|
||||
LoRa.disableInvertIQ();
|
||||
```
|
||||
|
||||
## Other functions
|
||||
|
||||
### Random
|
||||
|
@ -10,6 +10,9 @@ An [Arduino](https://arduino.cc/) library for sending and receiving data using [
|
||||
* [Dragino Lora Shield](http://www.dragino.com/products/module/item/102-lora-shield.html)
|
||||
* [HopeRF](http://www.hoperf.com/rf_transceiver/lora/) [RFM95W](http://www.hoperf.com/rf_transceiver/lora/RFM95W.html), [RFM96W](http://www.hoperf.com/rf_transceiver/lora/RFM96W.html), and [RFM98W](http://www.hoperf.com/rf_transceiver/lora/RFM98W.html)
|
||||
* [Modtronix](http://modtronix.com/) [inAir4](http://modtronix.com/inair4.html), [inAir9](http://modtronix.com/inair9.html), and [inAir9B](http://modtronix.com/inair9b.html)
|
||||
* [Arduino MKR WAN 1300](https://store.arduino.cc/usa/mkr-wan-1300)
|
||||
* **NOTE:** Requires firmware v1.1.6 or later on the on-board Murata module. Please use the [MKRWANFWUpdate_standalone example](https://github.com/arduino-libraries/MKRWAN/blob/master/examples/MKRWANFWUpdate_standalone/MKRWANFWUpdate_standalone.ino) from latest [MKRWAN library](https://github.com/arduino-libraries/MKRWAN) release to update the firmware.
|
||||
* **WARNING**: [LoRa.onReceive(...)](https://github.com/sandeepmistry/arduino-LoRa/blob/master/API.md#register-callback) and [LoRa.recieve()](https://github.com/sandeepmistry/arduino-LoRa/blob/master/API.md#receive-mode) is not compatible with this board!
|
||||
|
||||
### Semtech SX1276/77/78/79 wiring
|
||||
|
||||
|
@ -15,6 +15,10 @@
|
||||
#include <SPI.h> // include libraries
|
||||
#include <LoRa.h>
|
||||
|
||||
#ifdef ARDUINO_SAMD_MKRWAN1300
|
||||
#error "This example is not compatible with the Arduino MKR WAN 1300 board!"
|
||||
#endif
|
||||
|
||||
const int csPin = 7; // LoRa radio chip select
|
||||
const int resetPin = 6; // LoRa radio reset
|
||||
const int irqPin = 1; // change for your board; must be a hardware interrupt pin
|
||||
|
@ -1,6 +1,10 @@
|
||||
#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);
|
||||
|
35
examples/LoRaSenderNonBlocking/LoRaSenderNonBlocking.ino
Normal file
35
examples/LoRaSenderNonBlocking/LoRaSenderNonBlocking.ino
Normal file
@ -0,0 +1,35 @@
|
||||
#include <SPI.h>
|
||||
#include <LoRa.h>
|
||||
|
||||
int counter = 0;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
while (!Serial);
|
||||
|
||||
Serial.println("LoRa Sender non-blocking");
|
||||
|
||||
if (!LoRa.begin(915E6)) {
|
||||
Serial.println("Starting LoRa failed!");
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// wait until the radio is ready to send a packet
|
||||
while (LoRa.beginPacket() == 0) {
|
||||
Serial.print("waiting for radio ... ");
|
||||
delay(100);
|
||||
}
|
||||
|
||||
Serial.print("Sending packet non-blocking: ");
|
||||
Serial.println(counter);
|
||||
|
||||
// send in async / non-blocking mode
|
||||
LoRa.beginPacket();
|
||||
LoRa.print("hello ");
|
||||
LoRa.print(counter);
|
||||
LoRa.endPacket(true); // true = async / non-blocking mode
|
||||
|
||||
counter++;
|
||||
}
|
113
examples/LoRaSimpleGateway/LoRaSimpleGateway.ino
Normal file
113
examples/LoRaSimpleGateway/LoRaSimpleGateway.ino
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
LoRa Simple Gateway/Node Exemple
|
||||
|
||||
This code uses InvertIQ function to create a simple Gateway/Node logic.
|
||||
|
||||
Gateway - Sends messages with enableInvertIQ()
|
||||
- Receives messages with disableInvertIQ()
|
||||
|
||||
Node - Sends messages with disableInvertIQ()
|
||||
- Receives messages with enableInvertIQ()
|
||||
|
||||
With this arrangement a Gateway never receive messages from another Gateway
|
||||
and a Node never receive message from another Node.
|
||||
Only Gateway to Node and vice versa.
|
||||
|
||||
This code receives messages and sends a message every second.
|
||||
|
||||
InvertIQ function basically invert the LoRa I and Q signals.
|
||||
|
||||
See the Semtech datasheet, http://www.semtech.com/images/datasheet/sx1276.pdf
|
||||
for more on InvertIQ register 0x33.
|
||||
|
||||
created 05 August 2018
|
||||
by Luiz H. Cassettari
|
||||
*/
|
||||
|
||||
#include <SPI.h> // include libraries
|
||||
#include <LoRa.h>
|
||||
|
||||
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
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600); // initialize serial
|
||||
while (!Serial);
|
||||
|
||||
LoRa.setPins(csPin, resetPin, irqPin);
|
||||
|
||||
if (!LoRa.begin(frequency)) {
|
||||
Serial.println("LoRa init failed. Check your connections.");
|
||||
while (true); // if failed, do nothing
|
||||
}
|
||||
|
||||
Serial.println("LoRa init succeeded.");
|
||||
Serial.println();
|
||||
Serial.println("LoRa Simple Gateway");
|
||||
Serial.println("Only receive messages from nodes");
|
||||
Serial.println("Tx: invertIQ enable");
|
||||
Serial.println("Rx: invertIQ disable");
|
||||
Serial.println();
|
||||
|
||||
LoRa.onReceive(onReceive);
|
||||
LoRa_rxMode();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (runEvery(5000)) { // repeat every 5000 millis
|
||||
|
||||
String message = "HeLoRa World! ";
|
||||
message += "I'm a Gateway! ";
|
||||
message += millis();
|
||||
|
||||
LoRa_sendMessage(message); // send a message
|
||||
|
||||
Serial.println("Send Message!");
|
||||
}
|
||||
}
|
||||
|
||||
void LoRa_rxMode(){
|
||||
LoRa.disableInvertIQ(); // normal mode
|
||||
LoRa.receive(); // set receive mode
|
||||
}
|
||||
|
||||
void LoRa_txMode(){
|
||||
LoRa.idle(); // set standby mode
|
||||
LoRa.enableInvertIQ(); // active invert I and Q signals
|
||||
}
|
||||
|
||||
void LoRa_sendMessage(String message) {
|
||||
LoRa_txMode(); // set tx mode
|
||||
LoRa.beginPacket(); // start packet
|
||||
LoRa.print(message); // add payload
|
||||
LoRa.endPacket(); // finish packet and send it
|
||||
LoRa_rxMode(); // set rx mode
|
||||
}
|
||||
|
||||
void onReceive(int packetSize) {
|
||||
String message = "";
|
||||
|
||||
while (LoRa.available()) {
|
||||
message += (char)LoRa.read();
|
||||
}
|
||||
|
||||
Serial.print("Gateway Receive: ");
|
||||
Serial.println(message);
|
||||
|
||||
}
|
||||
|
||||
boolean runEvery(unsigned long interval)
|
||||
{
|
||||
static unsigned long previousMillis = 0;
|
||||
unsigned long currentMillis = millis();
|
||||
if (currentMillis - previousMillis >= interval)
|
||||
{
|
||||
previousMillis = currentMillis;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
113
examples/LoRaSimpleNode/LoRaSimpleNode.ino
Normal file
113
examples/LoRaSimpleNode/LoRaSimpleNode.ino
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
LoRa Simple Gateway/Node Exemple
|
||||
|
||||
This code uses InvertIQ function to create a simple Gateway/Node logic.
|
||||
|
||||
Gateway - Sends messages with enableInvertIQ()
|
||||
- Receives messages with disableInvertIQ()
|
||||
|
||||
Node - Sends messages with disableInvertIQ()
|
||||
- Receives messages with enableInvertIQ()
|
||||
|
||||
With this arrangement a Gateway never receive messages from another Gateway
|
||||
and a Node never receive message from another Node.
|
||||
Only Gateway to Node and vice versa.
|
||||
|
||||
This code receives messages and sends a message every second.
|
||||
|
||||
InvertIQ function basically invert the LoRa I and Q signals.
|
||||
|
||||
See the Semtech datasheet, http://www.semtech.com/images/datasheet/sx1276.pdf
|
||||
for more on InvertIQ register 0x33.
|
||||
|
||||
created 05 August 2018
|
||||
by Luiz H. Cassettari
|
||||
*/
|
||||
|
||||
#include <SPI.h> // include libraries
|
||||
#include <LoRa.h>
|
||||
|
||||
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
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600); // initialize serial
|
||||
while (!Serial);
|
||||
|
||||
LoRa.setPins(csPin, resetPin, irqPin);
|
||||
|
||||
if (!LoRa.begin(frequency)) {
|
||||
Serial.println("LoRa init failed. Check your connections.");
|
||||
while (true); // if failed, do nothing
|
||||
}
|
||||
|
||||
Serial.println("LoRa init succeeded.");
|
||||
Serial.println();
|
||||
Serial.println("LoRa Simple Node");
|
||||
Serial.println("Only receive messages from gateways");
|
||||
Serial.println("Tx: invertIQ disable");
|
||||
Serial.println("Rx: invertIQ enable");
|
||||
Serial.println();
|
||||
|
||||
LoRa.onReceive(onReceive);
|
||||
LoRa_rxMode();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (runEvery(1000)) { // repeat every 1000 millis
|
||||
|
||||
String message = "HeLoRa World! ";
|
||||
message += "I'm a Node! ";
|
||||
message += millis();
|
||||
|
||||
LoRa_sendMessage(message); // send a message
|
||||
|
||||
Serial.println("Send Message!");
|
||||
}
|
||||
}
|
||||
|
||||
void LoRa_rxMode(){
|
||||
LoRa.enableInvertIQ(); // active invert I and Q signals
|
||||
LoRa.receive(); // set receive mode
|
||||
}
|
||||
|
||||
void LoRa_txMode(){
|
||||
LoRa.idle(); // set standby mode
|
||||
LoRa.disableInvertIQ(); // normal mode
|
||||
}
|
||||
|
||||
void LoRa_sendMessage(String message) {
|
||||
LoRa_txMode(); // set tx mode
|
||||
LoRa.beginPacket(); // start packet
|
||||
LoRa.print(message); // add payload
|
||||
LoRa.endPacket(); // finish packet and send it
|
||||
LoRa_rxMode(); // set rx mode
|
||||
}
|
||||
|
||||
void onReceive(int packetSize) {
|
||||
String message = "";
|
||||
|
||||
while (LoRa.available()) {
|
||||
message += (char)LoRa.read();
|
||||
}
|
||||
|
||||
Serial.print("Node Receive: ");
|
||||
Serial.println(message);
|
||||
|
||||
}
|
||||
|
||||
boolean runEvery(unsigned long interval)
|
||||
{
|
||||
static unsigned long previousMillis = 0;
|
||||
unsigned long currentMillis = millis();
|
||||
if (currentMillis - previousMillis >= interval)
|
||||
{
|
||||
previousMillis = currentMillis;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -44,6 +44,8 @@ setPreambleLength KEYWORD2
|
||||
setSyncWord KEYWORD2
|
||||
enableCrc KEYWORD2
|
||||
disableCrc KEYWORD2
|
||||
enableInvertIQ KEYWORD2
|
||||
disableInvertIQ KEYWORD2
|
||||
|
||||
random KEYWORD2
|
||||
setPins KEYWORD2
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=LoRa
|
||||
version=0.3.0
|
||||
version=0.5.0
|
||||
author=Sandeep Mistry <sandeep.mistry@gmail.com>
|
||||
maintainer=Sandeep Mistry <sandeep.mistry@gmail.com>
|
||||
sentence=An Arduino library for sending and receiving data using LoRa radios.
|
||||
|
167
src/LoRa.cpp
167
src/LoRa.cpp
@ -10,6 +10,7 @@
|
||||
#define REG_FRF_MID 0x07
|
||||
#define REG_FRF_LSB 0x08
|
||||
#define REG_PA_CONFIG 0x09
|
||||
#define REG_OCP 0x0b
|
||||
#define REG_LNA 0x0c
|
||||
#define REG_FIFO_ADDR_PTR 0x0d
|
||||
#define REG_FIFO_TX_BASE_ADDR 0x0e
|
||||
@ -30,10 +31,13 @@
|
||||
#define REG_FREQ_ERROR_LSB 0x2a
|
||||
#define REG_RSSI_WIDEBAND 0x2c
|
||||
#define REG_DETECTION_OPTIMIZE 0x31
|
||||
#define REG_INVERTIQ 0x33
|
||||
#define REG_DETECTION_THRESHOLD 0x37
|
||||
#define REG_SYNC_WORD 0x39
|
||||
#define REG_INVERTIQ2 0x3b
|
||||
#define REG_DIO_MAPPING_1 0x40
|
||||
#define REG_VERSION 0x42
|
||||
#define REG_PA_DAC 0x4d
|
||||
|
||||
// modes
|
||||
#define MODE_LONG_RANGE_MODE 0x80
|
||||
@ -54,7 +58,8 @@
|
||||
#define MAX_PKT_LENGTH 255
|
||||
|
||||
LoRaClass::LoRaClass() :
|
||||
_spiSettings(8E6, MSBFIRST, SPI_MODE0),
|
||||
_spiSettings(LORA_DEFAULT_SPI_FREQUENCY, MSBFIRST, SPI_MODE0),
|
||||
_spi(&LORA_DEFAULT_SPI),
|
||||
_ss(LORA_DEFAULT_SS_PIN), _reset(LORA_DEFAULT_RESET_PIN), _dio0(LORA_DEFAULT_DIO0_PIN),
|
||||
_frequency(0),
|
||||
_packetIndex(0),
|
||||
@ -67,6 +72,23 @@ LoRaClass::LoRaClass() :
|
||||
|
||||
int LoRaClass::begin(long frequency)
|
||||
{
|
||||
#ifdef ARDUINO_SAMD_MKRWAN1300
|
||||
pinMode(LORA_IRQ_DUMB, OUTPUT);
|
||||
digitalWrite(LORA_IRQ_DUMB, LOW);
|
||||
|
||||
// Hardware reset
|
||||
pinMode(LORA_BOOT0, OUTPUT);
|
||||
digitalWrite(LORA_BOOT0, LOW);
|
||||
|
||||
pinMode(LORA_RESET, OUTPUT);
|
||||
digitalWrite(LORA_RESET, HIGH);
|
||||
delay(200);
|
||||
digitalWrite(LORA_RESET, LOW);
|
||||
delay(200);
|
||||
digitalWrite(LORA_RESET, HIGH);
|
||||
delay(50);
|
||||
#endif
|
||||
|
||||
// setup pins
|
||||
pinMode(_ss, OUTPUT);
|
||||
// set SS high
|
||||
@ -83,7 +105,7 @@ int LoRaClass::begin(long frequency)
|
||||
}
|
||||
|
||||
// start SPI
|
||||
SPI.begin();
|
||||
_spi->begin();
|
||||
|
||||
// check version
|
||||
uint8_t version = readRegister(REG_VERSION);
|
||||
@ -122,11 +144,15 @@ void LoRaClass::end()
|
||||
sleep();
|
||||
|
||||
// stop SPI
|
||||
SPI.end();
|
||||
_spi->end();
|
||||
}
|
||||
|
||||
int LoRaClass::beginPacket(int implicitHeader)
|
||||
{
|
||||
if (isTransmitting()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// put in standby mode
|
||||
idle();
|
||||
|
||||
@ -143,22 +169,40 @@ int LoRaClass::beginPacket(int implicitHeader)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LoRaClass::endPacket()
|
||||
int LoRaClass::endPacket(bool async)
|
||||
{
|
||||
// put in TX mode
|
||||
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_TX);
|
||||
|
||||
// wait for TX done
|
||||
while ((readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK) == 0) {
|
||||
yield();
|
||||
if (async) {
|
||||
// grace time is required for the radio
|
||||
delayMicroseconds(150);
|
||||
} else {
|
||||
// wait for TX done
|
||||
while ((readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK) == 0) {
|
||||
yield();
|
||||
}
|
||||
// clear IRQ's
|
||||
writeRegister(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK);
|
||||
}
|
||||
|
||||
// clear IRQ's
|
||||
writeRegister(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool LoRaClass::isTransmitting()
|
||||
{
|
||||
if ((readRegister(REG_OP_MODE) & MODE_TX) == MODE_TX) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK) {
|
||||
// clear IRQ's
|
||||
writeRegister(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int LoRaClass::parsePacket(int size)
|
||||
{
|
||||
int packetLength = 0;
|
||||
@ -296,6 +340,7 @@ void LoRaClass::flush()
|
||||
{
|
||||
}
|
||||
|
||||
#ifndef ARDUINO_SAMD_MKRWAN1300
|
||||
void LoRaClass::onReceive(void(*callback)(int))
|
||||
{
|
||||
_onReceive = callback;
|
||||
@ -328,6 +373,7 @@ void LoRaClass::receive(int size)
|
||||
|
||||
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_CONTINUOUS);
|
||||
}
|
||||
#endif
|
||||
|
||||
void LoRaClass::idle()
|
||||
{
|
||||
@ -352,10 +398,24 @@ void LoRaClass::setTxPower(int level, int outputPin)
|
||||
writeRegister(REG_PA_CONFIG, 0x70 | level);
|
||||
} else {
|
||||
// PA BOOST
|
||||
if (level < 2) {
|
||||
level = 2;
|
||||
} else if (level > 17) {
|
||||
level = 17;
|
||||
if (level > 17) {
|
||||
if (level > 20) {
|
||||
level = 20;
|
||||
}
|
||||
|
||||
// subtract 3 from level, so 18 - 20 maps to 15 - 17
|
||||
level -= 3;
|
||||
|
||||
// High Power +20 dBm Operation (Semtech SX1276/77/78/79 5.4.3.)
|
||||
writeRegister(REG_PA_DAC, 0x87);
|
||||
setOCP(140);
|
||||
} else {
|
||||
if (level < 2) {
|
||||
level = 2;
|
||||
}
|
||||
//Default value PA_HF/LF or +17dBm
|
||||
writeRegister(REG_PA_DAC, 0x84);
|
||||
setOCP(100);
|
||||
}
|
||||
|
||||
writeRegister(REG_PA_CONFIG, PA_BOOST | (level - 2));
|
||||
@ -373,6 +433,11 @@ void LoRaClass::setFrequency(long frequency)
|
||||
writeRegister(REG_FRF_LSB, (uint8_t)(frf >> 0));
|
||||
}
|
||||
|
||||
int LoRaClass::getSpreadingFactor()
|
||||
{
|
||||
return readRegister(REG_MODEM_CONFIG_2) >> 4;
|
||||
}
|
||||
|
||||
void LoRaClass::setSpreadingFactor(int sf)
|
||||
{
|
||||
if (sf < 6) {
|
||||
@ -390,23 +455,27 @@ void LoRaClass::setSpreadingFactor(int sf)
|
||||
}
|
||||
|
||||
writeRegister(REG_MODEM_CONFIG_2, (readRegister(REG_MODEM_CONFIG_2) & 0x0f) | ((sf << 4) & 0xf0));
|
||||
setLdoFlag();
|
||||
}
|
||||
|
||||
long LoRaClass::getSignalBandwidth()
|
||||
{
|
||||
byte bw = (readRegister(REG_MODEM_CONFIG_1) >> 4);
|
||||
|
||||
switch (bw) {
|
||||
case 0: return 7.8E3;
|
||||
case 1: return 10.4E3;
|
||||
case 2: return 15.6E3;
|
||||
case 3: return 20.8E3;
|
||||
case 4: return 31.25E3;
|
||||
case 5: return 41.7E3;
|
||||
case 6: return 62.5E3;
|
||||
case 7: return 125E3;
|
||||
case 8: return 250E3;
|
||||
case 9: return 500E3;
|
||||
case 1: return 10.4E3;
|
||||
case 2: return 15.6E3;
|
||||
case 3: return 20.8E3;
|
||||
case 4: return 31.25E3;
|
||||
case 5: return 41.7E3;
|
||||
case 6: return 62.5E3;
|
||||
case 7: return 125E3;
|
||||
case 8: return 250E3;
|
||||
case 9: return 500E3;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void LoRaClass::setSignalBandwidth(long sbw)
|
||||
@ -436,6 +505,20 @@ void LoRaClass::setSignalBandwidth(long sbw)
|
||||
}
|
||||
|
||||
writeRegister(REG_MODEM_CONFIG_1, (readRegister(REG_MODEM_CONFIG_1) & 0x0f) | (bw << 4));
|
||||
setLdoFlag();
|
||||
}
|
||||
|
||||
void LoRaClass::setLdoFlag()
|
||||
{
|
||||
// Section 4.1.1.5
|
||||
long symbolDuration = 1000 / ( getSignalBandwidth() / (1L << getSpreadingFactor()) ) ;
|
||||
|
||||
// Section 4.1.1.6
|
||||
boolean ldoOn = symbolDuration > 16;
|
||||
|
||||
uint8_t config3 = readRegister(REG_MODEM_CONFIG_3);
|
||||
bitWrite(config3, 3, ldoOn);
|
||||
writeRegister(REG_MODEM_CONFIG_3, config3);
|
||||
}
|
||||
|
||||
void LoRaClass::setCodingRate4(int denominator)
|
||||
@ -472,6 +555,31 @@ void LoRaClass::disableCrc()
|
||||
writeRegister(REG_MODEM_CONFIG_2, readRegister(REG_MODEM_CONFIG_2) & 0xfb);
|
||||
}
|
||||
|
||||
void LoRaClass::enableInvertIQ()
|
||||
{
|
||||
writeRegister(REG_INVERTIQ, 0x66);
|
||||
writeRegister(REG_INVERTIQ2, 0x19);
|
||||
}
|
||||
|
||||
void LoRaClass::disableInvertIQ()
|
||||
{
|
||||
writeRegister(REG_INVERTIQ, 0x27);
|
||||
writeRegister(REG_INVERTIQ2, 0x1d);
|
||||
}
|
||||
|
||||
void LoRaClass::setOCP(uint8_t mA)
|
||||
{
|
||||
uint8_t ocpTrim = 27;
|
||||
|
||||
if (mA <= 120) {
|
||||
ocpTrim = (mA - 45) / 5;
|
||||
} else if (mA <=240) {
|
||||
ocpTrim = (mA + 30) / 10;
|
||||
}
|
||||
|
||||
writeRegister(REG_OCP, 0x20 | (0x1F & ocpTrim));
|
||||
}
|
||||
|
||||
byte LoRaClass::random()
|
||||
{
|
||||
return readRegister(REG_RSSI_WIDEBAND);
|
||||
@ -484,6 +592,11 @@ void LoRaClass::setPins(int ss, int reset, int dio0)
|
||||
_dio0 = dio0;
|
||||
}
|
||||
|
||||
void LoRaClass::setSPI(SPIClass& spi)
|
||||
{
|
||||
_spi = &spi;
|
||||
}
|
||||
|
||||
void LoRaClass::setSPIFrequency(uint32_t frequency)
|
||||
{
|
||||
_spiSettings = SPISettings(frequency, MSBFIRST, SPI_MODE0);
|
||||
@ -555,10 +668,10 @@ uint8_t LoRaClass::singleTransfer(uint8_t address, uint8_t value)
|
||||
|
||||
digitalWrite(_ss, LOW);
|
||||
|
||||
SPI.beginTransaction(_spiSettings);
|
||||
SPI.transfer(address);
|
||||
response = SPI.transfer(value);
|
||||
SPI.endTransaction();
|
||||
_spi->beginTransaction(_spiSettings);
|
||||
_spi->transfer(address);
|
||||
response = _spi->transfer(value);
|
||||
_spi->endTransaction();
|
||||
|
||||
digitalWrite(_ss, HIGH);
|
||||
|
||||
|
34
src/LoRa.h
34
src/LoRa.h
@ -7,12 +7,22 @@
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#define LORA_DEFAULT_SS_PIN 10
|
||||
#define LORA_DEFAULT_RESET_PIN 9
|
||||
#define LORA_DEFAULT_DIO0_PIN 2
|
||||
#ifdef ARDUINO_SAMD_MKRWAN1300
|
||||
#define LORA_DEFAULT_SPI SPI1
|
||||
#define LORA_DEFAULT_SPI_FREQUENCY 250000
|
||||
#define LORA_DEFAULT_SS_PIN LORA_IRQ_DUMB
|
||||
#define LORA_DEFAULT_RESET_PIN -1
|
||||
#define LORA_DEFAULT_DIO0_PIN -1
|
||||
#else
|
||||
#define LORA_DEFAULT_SPI SPI
|
||||
#define LORA_DEFAULT_SPI_FREQUENCY 8E6
|
||||
#define LORA_DEFAULT_SS_PIN 10
|
||||
#define LORA_DEFAULT_RESET_PIN 9
|
||||
#define LORA_DEFAULT_DIO0_PIN 2
|
||||
#endif
|
||||
|
||||
#define PA_OUTPUT_RFO_PIN 0
|
||||
#define PA_OUTPUT_PA_BOOST_PIN 1
|
||||
#define PA_OUTPUT_RFO_PIN 0
|
||||
#define PA_OUTPUT_PA_BOOST_PIN 1
|
||||
|
||||
class LoRaClass : public Stream {
|
||||
public:
|
||||
@ -22,7 +32,7 @@ public:
|
||||
void end();
|
||||
|
||||
int beginPacket(int implicitHeader = false);
|
||||
int endPacket();
|
||||
int endPacket(bool async = false);
|
||||
|
||||
int parsePacket(int size = 0);
|
||||
int packetRssi();
|
||||
@ -39,9 +49,11 @@ public:
|
||||
virtual int peek();
|
||||
virtual void flush();
|
||||
|
||||
#ifndef ARDUINO_SAMD_MKRWAN1300
|
||||
void onReceive(void(*callback)(int));
|
||||
|
||||
void receive(int size = 0);
|
||||
#endif
|
||||
void idle();
|
||||
void sleep();
|
||||
|
||||
@ -54,6 +66,10 @@ public:
|
||||
void setSyncWord(int sw);
|
||||
void enableCrc();
|
||||
void disableCrc();
|
||||
void enableInvertIQ();
|
||||
void disableInvertIQ();
|
||||
|
||||
void setOCP(uint8_t mA); // Over Current Protection control
|
||||
|
||||
// deprecated
|
||||
void crc() { enableCrc(); }
|
||||
@ -62,6 +78,7 @@ public:
|
||||
byte random();
|
||||
|
||||
void setPins(int ss = LORA_DEFAULT_SS_PIN, int reset = LORA_DEFAULT_RESET_PIN, int dio0 = LORA_DEFAULT_DIO0_PIN);
|
||||
void setSPI(SPIClass& spi);
|
||||
void setSPIFrequency(uint32_t frequency);
|
||||
|
||||
void dumpRegisters(Stream& out);
|
||||
@ -71,9 +88,13 @@ private:
|
||||
void implicitHeaderMode();
|
||||
|
||||
void handleDio0Rise();
|
||||
bool isTransmitting();
|
||||
|
||||
int getSpreadingFactor();
|
||||
long getSignalBandwidth();
|
||||
|
||||
void setLdoFlag();
|
||||
|
||||
uint8_t readRegister(uint8_t address);
|
||||
void writeRegister(uint8_t address, uint8_t value);
|
||||
uint8_t singleTransfer(uint8_t address, uint8_t value);
|
||||
@ -82,6 +103,7 @@ private:
|
||||
|
||||
private:
|
||||
SPISettings _spiSettings;
|
||||
SPIClass* _spi;
|
||||
int _ss;
|
||||
int _reset;
|
||||
int _dio0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user