pot plugin w. example

This commit is contained in:
2018-11-17 02:45:54 +01:00
parent f79f869d55
commit be17cabfdc
85 changed files with 7864 additions and 103 deletions

View File

@@ -0,0 +1,29 @@
language: generic
env:
global:
- IDE_VERSION=1.6.12
matrix:
- BOARD="arduino:avr:uno"
- BOARD="arduino:avr:micro"
- BOARD="arduino:avr:mega:cpu=atmega2560"
- BOARD="arduino:samd:arduino_zero_edbg"
- BOARD="arduino:samd:mkr1000"
before_install:
- /sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16
- sleep 3
- export DISPLAY=:1.0
- wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz
- tar xf arduino-$IDE_VERSION-linux64.tar.xz
- mv arduino-$IDE_VERSION $HOME/arduino-ide
- export PATH=$PATH:$HOME/arduino-ide
- if [[ "$BOARD" =~ "arduino:samd:" ]]; then
arduino --install-boards arduino:samd &> /dev/null;
fi
- buildExampleSketch() { arduino --verbose-build --verify --board $BOARD $PWD/examples/$1/$1.ino; }
install:
- mkdir -p $HOME/Arduino/libraries
- ln -s $PWD $HOME/Arduino/libraries/LoRa
script:
- buildExampleSketch LoRaReceiver
- buildExampleSketch LoRaReceiverCallback
- buildExampleSketch LoRaSender

View File

@@ -0,0 +1,315 @@
# LoRa API
## Include Library
```arduino
#include <LoRa.h>
```
## Setup
### Begin
Initialize the library with the specified frequency.
```arduino
LoRa.begin(frequency);
```
* `frequency` - frequency in Hz (`433E6`, `866E6`, `915E6`)
Returns `1` on success, `0` on failure.
### Set pins
Override the default `NSS`, `NRESET`, and `DIO0` pins used by the library. **Must** be called before `LoRa.begin()`.
```arduino
LoRa.setPins(ss, reset, dio0);
```
* `ss` - new slave select pin to use, defaults to `10`
* `reset` - new reset pin to use, defaults to `9`
* `dio0` - new DIO0 pin to use, defaults to `2`
This call is optional and only needs to be used if you need to change the default pins used.
### Set SPI Frequency
Override the default SPI frequency of 10 MHz used by the library. **Must** be called before `LoRa.begin()`.
```arduino
LoRa.setSPIFrequency(frequency);
```
* `frequency` - new SPI frequency to use, defaults to `10E6`
This call is optional and only needs to be used if you need to change the default SPI frequency used. Some logic level converters cannot support high speeds such as 10 MHz, so a lower SPI frequency can be selected with `LoRa.setSPIFrequency(frequency)`.
### End
Stop the library
```arduino
LoRa.end()
```
## Sending data
### Begin packet
Start the sequence of sending a packet.
```arduino
LoRa.beginPacket();
LoRa.beginPacket(implicitHeader);
```
* `implicitHeader` - (optional) `true` enables implicit header mode, `false` enables explicit header mode (default)
Returns `1` on success, `0` on failure.
### Writing
Write data to the packet. Each packet can contain up to 255 bytes.
```arduino
LoRa.write(byte);
LoRa.write(buffer, length);
```
* `byte` - single byte to write to packet
or
* `buffer` - data to write to packet
* `length` - size of data to write
Returns the number of bytes written.
**Note:** Other Arduino `Print` API's can also be used to write data into the packet
### End packet
End the sequence of sending a packet.
```arduino
LoRa.endPacket()
```
Returns `1` on success, `0` on failure.
## Receiving data
### Parsing packet
Check if a packet has been received.
```arduino
int packetSize = LoRa.parsePacket();
int packetSize = LoRa.parsePacket(size);
```
* `size` - (optional) if `> 0` implicit header mode is enabled with the expected a packet of `size` bytes, default mode is explicit header mode
Returns the packet size in bytes or `0` if no packet was received.
### Continuous receive mode
#### Register callback
Register a callback function for when a packet is received.
```arduino
LoRa.onReceive(onReceive);
void onReceive(int packetSize) {
// ...
}
```
* `onReceive` - function to call when a packet is received.
#### Receive mode
Puts the radio in continuous receive mode.
```arduino
LoRa.receive();
LoRa.receive(int size);
```
* `size` - (optional) if `> 0` implicit header mode is enabled with the expected a packet of `size` bytes, default mode is explicit header mode
The `onReceive` callback will be called when a packet is received.
### Packet RSSI
```arduino
int rssi = LoRa.packetRssi();
```
Returns the RSSI of the received packet.
### Packet SNR
```arduino
float snr = LoRa.packetSnr();
```
Returns the estimated SNR of the received packet in dB.
### Available
```arduino
int availableBytes = LoRa.available()
```
Returns number of bytes available for reading.
### Peeking
Peek at the next byte in the packet.
```arduino
byte b = LoRa.peek();
```
Returns the next byte in the packet or `-1` if no bytes are available.
### Reading
Read the next byte from the packet.
```arduino
byte b = LoRa.read();
```
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
## Other radio modes
### Idle mode
Put the radio in idle (standby) mode.
```arduino
LoRa.idle();
```
### Sleep mode
Put the radio in sleep mode.
```arduino
LoRa.sleep();
```
## Radio parameters
### TX Power
Change the TX power of the radio.
```arduino
LoRa.setTxPower(txPower);
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`.
Most modules have the PA output pin connected to PA BOOST,
### Frequency
Change the frequency of the radio.
```arduino
LoRa.setFrequency(frequency);
```
* `frequency` - frequency in Hz (`433E6`, `866E6`, `915E6`)
### Spreading Factor
Change the spreading factor of the radio.
```arduino
LoRa.setSpreadingFactor(spreadingFactor);
```
* `spreadingFactor` - spreading factor, defaults to `7`
Supported values are between `6` and `12`. If a spreading factor of `6` is set, implicit header mode must be used to transmit and receive packets.
### Signal Bandwidth
Change the signal bandwidth of the radio.
```arduino
LoRa.setSignalBandwidth(signalBandwidth);
```
* `signalBandwidth` - signal bandwidth in Hz, defaults to `125E3`.
Supported values are `7.8E3`, `10.4E3`, `15.6E3`, `20.8E3`, `31.25E3`, `41.7E3`, `62.5E3`, `125E3`, and `250E3`.
### Coding Rate
Change the coding rate of the radio.
```arduino
LoRa.setCodingRate4(codingRateDenominator);
```
* `codingRateDenominator` - denominator of the coding rate, defaults to `5`
Supported values are between `5` and `8`, these correspond to coding rates of `4/5` and `4/8`. The coding rate numerator is fixed at `4`.
### Preamble Length
Change the preamble length of the radio.
```arduino
LoRa.setPreambleLength(preambleLength);
```
* `preambleLength` - preamble length in symbols, defaults to `8`
Supported values are between `6` and `65535`.
### Sync Word
Change the sync word of the radio.
```arduino
LoRa.setSyncWord(syncWord);
```
* `syncWord` - byte value to use as the sync word, defaults to `0x34`
### CRC
Enable or disable CRC usage, by default a CRC is not used.
```arduino
LoRa.crc();
LoRa.noCrc();
```
## Other functions
### Random
Generate a random byte, based on the Wideband RSSI measurement.
```
byte b = LoRa.random();
```
Returns random byte.

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2016 Sandeep Mistry
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,56 @@
# Arduino LoRa
[![Build Status](https://travis-ci.org/sandeepmistry/arduino-LoRa.svg?branch=master)](https://travis-ci.org/sandeepmistry/arduino-LoRa)
An [Arduino](http://arduino.cc/) library for sending and receiving data using [LoRa](https://www.lora-alliance.org/) radios.
## Compatible Hardware
* [Semtech SX1276/77/78/79](http://www.semtech.com/apps/product.php?pn=SX1276) based boards including:
* [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)
### Semtech SX1276/77/78/79 wiring
| Semtech SX1276/77/78/79 | Arduino |
| :---------------------: | :------:|
| VCC | 3.3V |
| GND | GND |
| SCK | SCK |
| MISO | MISO |
| MOSI | MOSI |
| NSS | 10 |
| NRESET | 9 |
| DIO0 | 2 |
`NSS`, `NRESET`, and `DIO0` pins can be changed by using `LoRa.setPins(ss, reset, dio0)`. `DIO0` pin is optional, it is only needed for receive callback mode.
## Installation
### Using the Arduino IDE Library Manager
1. Choose `Sketch` -> `Include Library` -> `Manage Libraries...`
2. Type `LoRa` into the search box.
3. Click the row to select the library.
4. Click the `Install` button to install the library.
### Using Git
```sh
cd ~/Documents/Arduino/libraries/
git clone https://github.com/sandeepmistry/arduino-LoRa LoRa
```
## API
See [API.md](API.md).
## Examples
See [examples](examples) folder.
## License
This libary is [licensed](LICENSE) under the [MIT Licence](http://en.wikipedia.org/wiki/MIT_License).

View File

@@ -0,0 +1,84 @@
#include <SPI.h>
#include <LoRa.h>
#include "SSD1306.h"
SSD1306 display(0x3c, 4, 15);
//OLED pins to ESP32 GPIOs via this connection:
//OLED_SDA -- GPIO4
//OLED_SCL -- GPIO15
//OLED_RST -- GPIO16
// WIFI_LoRa_32 ports
// GPIO5 -- SX1278's SCK
// GPIO19 -- SX1278's MISO
// GPIO27 -- SX1278's MOSI
// GPIO18 -- SX1278's CS
// GPIO14 -- SX1278's RESET
// GPIO26 -- SX1278's IRQ(Interrupt Request)
#define SS 18
#define RST 14
#define DI0 26
#define BAND 433E6
void setup() {
pinMode(16,OUTPUT);
digitalWrite(16, LOW); // set GPIO16 low to reset OLED
delay(50);
digitalWrite(16, HIGH);
display.init();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
Serial.begin(115200);
while (!Serial); //if just the the basic function, must connect to a computer
delay(1000);
Serial.println("LoRa Receiver");
display.drawString(5,5,"LoRa Receiver");
display.display();
SPI.begin(5,19,27,18);
LoRa.setPins(SS,RST,DI0);
if (!LoRa.begin(BAND)) {
display.drawString(5,25,"Starting LoRa failed!");
while (1);
}
Serial.println("LoRa Initial OK!");
display.drawString(5,25,"LoRa Initializing OK!");
display.display();
}
void loop() {
// try to parse packet
int packetSize = LoRa.parsePacket();
if (packetSize) {
// received a packets
Serial.print("Received packet. ");
display.clear();
display.setFont(ArialMT_Plain_16);
display.drawString(3, 0, "Received packet ");
display.display();
// read packet
while (LoRa.available()) {
String data = LoRa.readString();
Serial.print(data);
display.drawString(20,22, data);
display.display();
}
// print RSSI of packet
Serial.print(" with RSSI ");
Serial.println(LoRa.packetRssi());
display.drawString(20, 45, "RSSI: ");
display.drawString(70, 45, (String)LoRa.packetRssi());
display.display();
}
}

View File

@@ -0,0 +1,54 @@
// This example just provide basic LoRa function test;
// Not the LoRa's farthest distance or strongest interference immunity.
// For more informations, please vist www.heltec.cn or mail to support@heltec.cn
#include <SPI.h>
#include <LoRa.h>
// WIFI_LoRa_32 ports
// GPIO5 -- SX1278's SCK
// GPIO19 -- SX1278's MISO
// GPIO27 -- SX1278's MOSI
// GPIO18 -- SX1278's CS
// GPIO14 -- SX1278's RESET
// GPIO26 -- SX1278's IRQ(Interrupt Request)
#define SS 18
#define RST 14
#define DI0 26
#define BAND 433E6
void setup() {
Serial.begin(115200);
while (!Serial); //if just the the basic function, must connect to a computer
delay(1000);
Serial.println("LoRa Receiver");
SPI.begin(5,19,27,18);
LoRa.setPins(SS,RST,DI0);
if (!LoRa.begin(BAND)) {
Serial.println("Starting LoRa failed!");
while (1);
}
}
void loop() {
// try to parse packet
int packetSize = LoRa.parsePacket();
if (packetSize) {
// received a packet
Serial.print("Received packet '");
// read packet
while (LoRa.available()) {
Serial.print((char)LoRa.read());
}
// print RSSI of packet
Serial.print("' with RSSI ");
Serial.println(LoRa.packetRssi());
}
}

View File

@@ -0,0 +1,60 @@
// This example just provide basic LoRa function test;
// Not the LoRa's farthest distance or strongest interference immunity.
// For more informations, please vist www.heltec.cn or mail to support@heltec.cn
#include <SPI.h>
#include <LoRa.h>
// WIFI_LoRa_32 ports
// GPIO5 -- SX1278's SCK
// GPIO19 -- SX1278's MISO
// GPIO27 -- SX1278's MOSI
// GPIO18 -- SX1278's CS
// GPIO14 -- SX1278's RESET
// GPIO26 -- SX1278's IRQ(Interrupt Request)
#define SS 18
#define RST 14
#define DI0 26
#define BAND 433E6
void setup() {
Serial.begin(115200);
while (!Serial); //if just the the basic function, must connect to a computer
SPI.begin(5,19,27,18);
LoRa.setPins(SS,RST,DI0);
Serial.println("LoRa Receiver Callback");
if (!LoRa.begin(BAND)) {
Serial.println("Starting LoRa failed!");
while (1);
}
// register the receive callback
LoRa.onReceive(onReceive);
// put the radio into receive mode
LoRa.receive();
}
void loop() {
// do nothing
}
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());
}

View File

@@ -0,0 +1,85 @@
#include <SPI.h>
#include <LoRa.h>
#include "SSD1306.h"
#include<Arduino.h>
//OLED pins to ESP32 GPIOs via this connecthin:
//OLED_SDA -- GPIO4
//OLED_SCL -- GPIO15
//OLED_RST -- GPIO16
SSD1306 display(0x3c, 4, 15);
// WIFI_LoRa_32 ports
// GPIO5 -- SX1278's SCK
// GPIO19 -- SX1278's MISO
// GPIO27 -- SX1278's MOSI
// GPIO18 -- SX1278's CS
// GPIO14 -- SX1278's RESET
// GPIO26 -- SX1278's IRQ(Interrupt Request)
#define SS 18
#define RST 14
#define DI0 26
#define BAND 433E6 //915E6
int counter = 0;
void setup() {
pinMode(25,OUTPUT); //Send success, LED will bright 1 second
pinMode(16,OUTPUT);
digitalWrite(16, LOW); // set GPIO16 low to reset OLED
delay(50);
digitalWrite(16, HIGH);
Serial.begin(115200);
while (!Serial); //If just the the basic function, must connect to a computer
// Initialising the UI will init the display too.
display.init();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(5,5,"LoRa Sender");
display.display();
SPI.begin(5,19,27,18);
LoRa.setPins(SS,RST,DI0);
Serial.println("LoRa Sender");
if (!LoRa.begin(BAND)) {
Serial.println("Starting LoRa failed!");
while (1);
}
Serial.println("LoRa Initial OK!");
display.drawString(5,20,"LoRa Initializing OK!");
display.display();
delay(2000);
}
void loop() {
Serial.print("Sending packet: ");
Serial.println(counter);
display.clear();
display.setFont(ArialMT_Plain_16);
display.drawString(3, 5, "Sending packet ");
display.drawString(50, 30, String(counter));
display.display();
// send packet
LoRa.beginPacket();
LoRa.print("Hello..");
LoRa.print(counter);
LoRa.endPacket();
counter++;
digitalWrite(25, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(25, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
delay(3000);
}

View File

@@ -0,0 +1,59 @@
// This example just provide basic LoRa function test;
// Not the LoRa's farthest distance or strongest interference immunity.
// For more informations, please vist www.heltec.cn or mail to support@heltec.cn
#include <SPI.h>
#include <LoRa.h>
#include<Arduino.h>
// WIFI_LoRa_32 ports
// GPIO5 -- SX1278's SCK
// GPIO19 -- SX1278's MISO
// GPIO27 -- SX1278's MOSI
// GPIO18 -- SX1278's CS
// GPIO14 -- SX1278's RESET
// GPIO26 -- SX1278's IRQ(Interrupt Request)
#define SS 18
#define RST 14
#define DI0 26
#define BAND 433E6 //915E6 -- 这里的模式选择中检查一下是否可在中国实用915这个频段
int counter = 0;
void setup() {
pinMode(25,OUTPUT); //Send success, LED will bright 1 second
Serial.begin(115200);
while (!Serial); //If just the the basic function, must connect to a computer
SPI.begin(5,19,27,18);
LoRa.setPins(SS,RST,DI0);
// Serial.println("LoRa Sender");
if (!LoRa.begin(BAND)) {
Serial.println("Starting LoRa failed!");
while (1);
}
Serial.println("LoRa Initial OK!");
}
void loop() {
Serial.print("Sending packet: ");
Serial.println(counter);
// send packet
LoRa.beginPacket();
LoRa.print("hello ");
LoRa.print(counter);
LoRa.endPacket();
counter++;
digitalWrite(25, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(25, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
delay(3000);
}

View File

@@ -0,0 +1,57 @@
#######################################
# Syntax Coloring Map For LoRa
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
LoRa KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
begin KEYWORD2
end KEYWORD2
beginPacket KEYWORD2
endPacket KEYWORD2
parsePacket KEYWORD2
packetRssi KEYWORD2
packetSnr KEYWORD2
write KEYWORD2
available KEYWORD2
read KEYWORD2
peek KEYWORD2
flush KEYWORD2
onReceive KEYWORD2
receive KEYWORD2
idle KEYWORD2
sleep KEYWORD2
setTxPower KEYWORD2
setFrequency KEYWORD2
setSpreadingFactor KEYWORD2
setSignalBandwidth KEYWORD2
setCodingRate4 KEYWORD2
setPreambleLength KEYWORD2
setSyncWord KEYWORD2
crc KEYWORD2
noCrc KEYWORD2
random KEYWORD2
setPins KEYWORD2
setSPIFrequency KEYWORD2
dumpRegisters KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################
PA_OUTPUT_RFO_PIN LITERAL1
PA_OUTPUT_PA_BOOST_PIN LITERAL1

View File

@@ -0,0 +1,10 @@
name=LoRa function basic test
version=0.0.2
author=Aaron.Lee <support@heltec.cn>
maintainer=Aaron.Lee <support@heltec.cn>
sentence=An Arduino library for sending and receiving data using LoRa radios.
paragraph=Supports Semtech SX1276/77/78/79 based boards/shields.
category=Communication
url=https://heltec.cn
architectures=*
includes=LoRa.h

View File

@@ -0,0 +1,518 @@
#include <LoRa.h>
// registers
#define REG_FIFO 0x00
#define REG_OP_MODE 0x01
#define REG_FRF_MSB 0x06
#define REG_FRF_MID 0x07
#define REG_FRF_LSB 0x08
#define REG_PA_CONFIG 0x09
#define REG_LNA 0x0c
#define REG_FIFO_ADDR_PTR 0x0d
#define REG_FIFO_TX_BASE_ADDR 0x0e
#define REG_FIFO_RX_BASE_ADDR 0x0f
#define REG_FIFO_RX_CURRENT_ADDR 0x10
#define REG_IRQ_FLAGS 0x12
#define REG_RX_NB_BYTES 0x13
#define REG_PKT_RSSI_VALUE 0x1a
#define REG_PKT_SNR_VALUE 0x1b
#define REG_MODEM_CONFIG_1 0x1d
#define REG_MODEM_CONFIG_2 0x1e
#define REG_PREAMBLE_MSB 0x20
#define REG_PREAMBLE_LSB 0x21
#define REG_PAYLOAD_LENGTH 0x22
#define REG_MODEM_CONFIG_3 0x26
#define REG_RSSI_WIDEBAND 0x2c
#define REG_DETECTION_OPTIMIZE 0x31
#define REG_DETECTION_THRESHOLD 0x37
#define REG_SYNC_WORD 0x39
#define REG_DIO_MAPPING_1 0x40
#define REG_VERSION 0x42
// modes
#define MODE_LONG_RANGE_MODE 0x80
#define MODE_SLEEP 0x00
#define MODE_STDBY 0x01
#define MODE_TX 0x03
#define MODE_RX_CONTINUOUS 0x05
#define MODE_RX_SINGLE 0x06
// PA config
#define PA_BOOST 0x80
// IRQ masks
#define IRQ_TX_DONE_MASK 0x08
#define IRQ_PAYLOAD_CRC_ERROR_MASK 0x20
#define IRQ_RX_DONE_MASK 0x40
#define MAX_PKT_LENGTH 255
LoRaClass::LoRaClass() :
_spiSettings(10E6, MSBFIRST, SPI_MODE0),
_ss(LORA_DEFAULT_SS_PIN), _reset(LORA_DEFAULT_RESET_PIN), _dio0(LORA_DEFAULT_DIO0_PIN),
_frequency(0),
_packetIndex(0),
_implicitHeaderMode(0),
_onReceive(NULL)
{
}
int LoRaClass::begin(long frequency)
{
// setup pins
pinMode(_ss, OUTPUT);
pinMode(_reset, OUTPUT);
// perform reset
digitalWrite(_reset, LOW);
delay(20);
digitalWrite(_reset, HIGH);
delay(50);
// set SS high
digitalWrite(_ss, HIGH);
// start SPI
SPI.begin();
// check version
uint8_t version = readRegister(REG_VERSION);
if (version != 0x12) {
//return 0;
}
// put in sleep mode
sleep();
// set frequency
setFrequency(frequency);
// set base addresses
writeRegister(REG_FIFO_TX_BASE_ADDR, 0);
writeRegister(REG_FIFO_RX_BASE_ADDR, 0);
// set LNA boost
writeRegister(REG_LNA, readRegister(REG_LNA) | 0x03);
// set auto AGC
writeRegister(REG_MODEM_CONFIG_3, 0x04);
// set output power to 17 dBm
setTxPower(17);
// put in standby mode
idle();
return 1;
}
void LoRaClass::end()
{
// put in sleep mode
sleep();
// stop SPI
SPI.end();
}
int LoRaClass::beginPacket(int implicitHeader)
{
// put in standby mode
idle();
if (implicitHeader) {
implicitHeaderMode();
} else {
explicitHeaderMode();
}
// reset FIFO address and paload length
writeRegister(REG_FIFO_ADDR_PTR, 0);
writeRegister(REG_PAYLOAD_LENGTH, 0);
return 1;
}
int LoRaClass::endPacket()
{
// 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);
// clear IRQ's
writeRegister(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK);
return 1;
}
int LoRaClass::parsePacket(int size)
{
int packetLength = 0;
int irqFlags = readRegister(REG_IRQ_FLAGS);
if (size > 0) {
implicitHeaderMode();
writeRegister(REG_PAYLOAD_LENGTH, size & 0xff);
} else {
explicitHeaderMode();
}
// clear IRQ's
writeRegister(REG_IRQ_FLAGS, irqFlags);
if ((irqFlags & IRQ_RX_DONE_MASK) && (irqFlags & IRQ_PAYLOAD_CRC_ERROR_MASK) == 0) {
// received a packet
_packetIndex = 0;
// read packet length
if (_implicitHeaderMode) {
packetLength = readRegister(REG_PAYLOAD_LENGTH);
} else {
packetLength = readRegister(REG_RX_NB_BYTES);
}
// set FIFO address to current RX address
writeRegister(REG_FIFO_ADDR_PTR, readRegister(REG_FIFO_RX_CURRENT_ADDR));
// put in standby mode
idle();
} else if (readRegister(REG_OP_MODE) != (MODE_LONG_RANGE_MODE | MODE_RX_SINGLE)) {
// not currently in RX mode
// reset FIFO address
writeRegister(REG_FIFO_ADDR_PTR, 0);
// put in single RX mode
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_SINGLE);
}
return packetLength;
}
int LoRaClass::packetRssi()
{
return (readRegister(REG_PKT_RSSI_VALUE) - (_frequency < 868E6 ? 164 : 157));
}
float LoRaClass::packetSnr()
{
return ((int8_t)readRegister(REG_PKT_SNR_VALUE)) * 0.25;
}
size_t LoRaClass::write(uint8_t byte)
{
return write(&byte, sizeof(byte));
}
size_t LoRaClass::write(const uint8_t *buffer, size_t size)
{
int currentLength = readRegister(REG_PAYLOAD_LENGTH);
// check size
if ((currentLength + size) > MAX_PKT_LENGTH) {
size = MAX_PKT_LENGTH - currentLength;
}
// write data
for (size_t i = 0; i < size; i++) {
writeRegister(REG_FIFO, buffer[i]);
}
// update length
writeRegister(REG_PAYLOAD_LENGTH, currentLength + size);
return size;
}
int LoRaClass::available()
{
return (readRegister(REG_RX_NB_BYTES) - _packetIndex);
}
int LoRaClass::read()
{
if (!available()) {
return -1;
}
_packetIndex++;
return readRegister(REG_FIFO);
}
int LoRaClass::peek()
{
if (!available()) {
return -1;
}
// store current FIFO address
int currentAddress = readRegister(REG_FIFO_ADDR_PTR);
// read
uint8_t b = readRegister(REG_FIFO);
// restore FIFO address
writeRegister(REG_FIFO_ADDR_PTR, currentAddress);
return b;
}
void LoRaClass::flush()
{
}
void LoRaClass::onReceive(void(*callback)(int))
{
_onReceive = callback;
if (callback) {
writeRegister(REG_DIO_MAPPING_1, 0x00);
attachInterrupt(digitalPinToInterrupt(_dio0), LoRaClass::onDio0Rise, RISING);
} else {
detachInterrupt(digitalPinToInterrupt(_dio0));
}
}
void LoRaClass::receive(int size)
{
if (size > 0) {
implicitHeaderMode();
writeRegister(REG_PAYLOAD_LENGTH, size & 0xff);
} else {
explicitHeaderMode();
}
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_CONTINUOUS);
}
void LoRaClass::idle()
{
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_STDBY);
}
void LoRaClass::sleep()
{
writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_SLEEP);
}
void LoRaClass::setTxPower(int level, int outputPin)
{
if (PA_OUTPUT_RFO_PIN == outputPin) {
// RFO
if (level < 0) {
level = 0;
} else if (level > 14) {
level = 14;
}
writeRegister(REG_PA_CONFIG, 0x70 | level);
} else {
// PA BOOST
if (level < 2) {
level = 2;
} else if (level > 17) {
level = 17;
}
writeRegister(REG_PA_CONFIG, PA_BOOST | (level - 2));
}
}
void LoRaClass::setFrequency(long frequency)
{
_frequency = frequency;
uint64_t frf = ((uint64_t)frequency << 19) / 32000000;
writeRegister(REG_FRF_MSB, (uint8_t)(frf >> 16));
writeRegister(REG_FRF_MID, (uint8_t)(frf >> 8));
writeRegister(REG_FRF_LSB, (uint8_t)(frf >> 0));
}
void LoRaClass::setSpreadingFactor(int sf)
{
if (sf < 6) {
sf = 6;
} else if (sf > 12) {
sf = 12;
}
if (sf == 6) {
writeRegister(REG_DETECTION_OPTIMIZE, 0xc5);
writeRegister(REG_DETECTION_THRESHOLD, 0x0c);
} else {
writeRegister(REG_DETECTION_OPTIMIZE, 0xc3);
writeRegister(REG_DETECTION_THRESHOLD, 0x0a);
}
writeRegister(REG_MODEM_CONFIG_2, (readRegister(REG_MODEM_CONFIG_2) & 0x0f) | ((sf << 4) & 0xf0));
}
void LoRaClass::setSignalBandwidth(long sbw)
{
int bw;
if (sbw <= 7.8E3) {
bw = 0;
} else if (sbw <= 10.4E3) {
bw = 1;
} else if (sbw <= 15.6E3) {
bw = 2;
} else if (sbw <= 20.8E3) {
bw = 3;
} else if (sbw <= 31.25E3) {
bw = 4;
} else if (sbw <= 41.7E3) {
bw = 5;
} else if (sbw <= 62.5E3) {
bw = 6;
} else if (sbw <= 125E3) {
bw = 7;
} else if (sbw <= 250E3) {
bw = 8;
} else /*if (sbw <= 250E3)*/ {
bw = 9;
}
writeRegister(REG_MODEM_CONFIG_1, (readRegister(REG_MODEM_CONFIG_1) & 0x0f) | (bw << 4));
}
void LoRaClass::setCodingRate4(int denominator)
{
if (denominator < 5) {
denominator = 5;
} else if (denominator > 8) {
denominator = 8;
}
int cr = denominator - 4;
writeRegister(REG_MODEM_CONFIG_1, (readRegister(REG_MODEM_CONFIG_1) & 0xf1) | (cr << 1));
}
void LoRaClass::setPreambleLength(long length)
{
writeRegister(REG_PREAMBLE_MSB, (uint8_t)(length >> 8));
writeRegister(REG_PREAMBLE_LSB, (uint8_t)(length >> 0));
}
void LoRaClass::setSyncWord(int sw)
{
writeRegister(REG_SYNC_WORD, sw);
}
void LoRaClass::crc()
{
writeRegister(REG_MODEM_CONFIG_2, readRegister(REG_MODEM_CONFIG_2) | 0x04);
}
void LoRaClass::noCrc()
{
writeRegister(REG_MODEM_CONFIG_2, readRegister(REG_MODEM_CONFIG_2) & 0xfb);
}
byte LoRaClass::random()
{
return readRegister(REG_RSSI_WIDEBAND);
}
void LoRaClass::setPins(int ss, int reset, int dio0)
{
_ss = ss;
_reset = reset;
_dio0 = dio0;
}
void LoRaClass::setSPIFrequency(uint32_t frequency)
{
_spiSettings = SPISettings(frequency, MSBFIRST, SPI_MODE0);
}
void LoRaClass::dumpRegisters(Stream& out)
{
for (int i = 0; i < 128; i++) {
out.print("0x");
out.print(i, HEX);
out.print(": 0x");
out.println(readRegister(i), HEX);
}
}
void LoRaClass::explicitHeaderMode()
{
_implicitHeaderMode = 0;
writeRegister(REG_MODEM_CONFIG_1, readRegister(REG_MODEM_CONFIG_1) & 0xfe);
}
void LoRaClass::implicitHeaderMode()
{
_implicitHeaderMode = 1;
writeRegister(REG_MODEM_CONFIG_1, readRegister(REG_MODEM_CONFIG_1) | 0x01);
}
void LoRaClass::handleDio0Rise()
{
int irqFlags = readRegister(REG_IRQ_FLAGS);
// clear IRQ's
writeRegister(REG_IRQ_FLAGS, irqFlags);
if ((irqFlags & IRQ_PAYLOAD_CRC_ERROR_MASK) == 0) {
// received a packet
_packetIndex = 0;
// read packet length
int packetLength = _implicitHeaderMode ? readRegister(REG_PAYLOAD_LENGTH) : readRegister(REG_RX_NB_BYTES);
// set FIFO address to current RX address
writeRegister(REG_FIFO_ADDR_PTR, readRegister(REG_FIFO_RX_CURRENT_ADDR));
if (_onReceive) {
_onReceive(packetLength);
}
// reset FIFO address
writeRegister(REG_FIFO_ADDR_PTR, 0);
}
}
uint8_t LoRaClass::readRegister(uint8_t address)
{
return singleTransfer(address & 0x7f, 0x00);
}
void LoRaClass::writeRegister(uint8_t address, uint8_t value)
{
singleTransfer(address | 0x80, value);
}
uint8_t LoRaClass::singleTransfer(uint8_t address, uint8_t value)
{
uint8_t response;
digitalWrite(_ss, LOW);
SPI.beginTransaction(_spiSettings);
SPI.transfer(address);
response = SPI.transfer(value);
SPI.endTransaction();
digitalWrite(_ss, HIGH);
return response;
}
void LoRaClass::onDio0Rise()
{
LoRa.handleDio0Rise();
}
LoRaClass LoRa;

View File

@@ -0,0 +1,86 @@
#ifndef LORA_H
#define LORA_H
#include <Arduino.h>
#include <SPI.h>
#define LORA_DEFAULT_SS_PIN 18
#define LORA_DEFAULT_RESET_PIN 14
#define LORA_DEFAULT_DIO0_PIN 26
#define PA_OUTPUT_RFO_PIN 0
#define PA_OUTPUT_PA_BOOST_PIN 1
class LoRaClass : public Stream {
public:
LoRaClass();
int begin(long frequency);
void end();
int beginPacket(int implicitHeader = false);
int endPacket();
int parsePacket(int size = 0);
int packetRssi();
float packetSnr();
// from Print
virtual size_t write(uint8_t byte);
virtual size_t write(const uint8_t *buffer, size_t size);
// from Stream
virtual int available();
virtual int read();
virtual int peek();
virtual void flush();
void onReceive(void(*callback)(int));
void receive(int size = 0);
void idle();
void sleep();
void setTxPower(int level, int outputPin = PA_OUTPUT_PA_BOOST_PIN);
void setFrequency(long frequency);
void setSpreadingFactor(int sf);
void setSignalBandwidth(long sbw);
void setCodingRate4(int denominator);
void setPreambleLength(long length);
void setSyncWord(int sw);
void crc();
void noCrc();
byte random();
void setPins(int ss = LORA_DEFAULT_SS_PIN, int reset = LORA_DEFAULT_RESET_PIN, int dio0 = LORA_DEFAULT_DIO0_PIN);
void setSPIFrequency(uint32_t frequency);
void dumpRegisters(Stream& out);
//private:
void explicitHeaderMode();
void implicitHeaderMode();
void handleDio0Rise();
uint8_t readRegister(uint8_t address);
void writeRegister(uint8_t address, uint8_t value);
uint8_t singleTransfer(uint8_t address, uint8_t value);
static void onDio0Rise();
private:
SPISettings _spiSettings;
int _ss;
int _reset;
int _dio0;
int _frequency;
int _packetIndex;
int _implicitHeaderMode;
void (*_onReceive)(int);
};
extern LoRaClass LoRa;
#endif