Initial commit of Arduino libraries
This commit is contained in:
51
RadioLib/CMakeLists.txt
Normal file
51
RadioLib/CMakeLists.txt
Normal file
@@ -0,0 +1,51 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
if(ESP_PLATFORM)
|
||||
# Build RadioLib as an ESP-IDF component
|
||||
# required because ESP-IDF runs cmake in script mode
|
||||
# and needs idf_component_register()
|
||||
file(GLOB_RECURSE RADIOLIB_ESP_SOURCES
|
||||
"src/*.*"
|
||||
)
|
||||
|
||||
idf_component_register(
|
||||
SRCS ${RADIOLIB_ESP_SOURCES}
|
||||
INCLUDE_DIRS . src
|
||||
)
|
||||
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(CMAKE_SCRIPT_MODE_FILE)
|
||||
message(FATAL_ERROR "Attempted to build RadioLib in script mode")
|
||||
endif()
|
||||
|
||||
project(radiolib)
|
||||
|
||||
file(GLOB_RECURSE RADIOLIB_SOURCES
|
||||
"src/*.cpp"
|
||||
)
|
||||
|
||||
add_library(RadioLib ${RADIOLIB_SOURCES})
|
||||
|
||||
target_include_directories(RadioLib
|
||||
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
||||
|
||||
# use c++20 standard
|
||||
set_property(TARGET RadioLib PROPERTY CXX_STANDARD 20)
|
||||
|
||||
# enable most warnings
|
||||
target_compile_options(RadioLib PRIVATE -Wall -Wextra)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
install(TARGETS RadioLib
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
|
||||
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/RadioLib
|
||||
FILES_MATCHING PATTERN "*.h"
|
||||
)
|
||||
3
RadioLib/CODE_OF_CONDUCT.md
Normal file
3
RadioLib/CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Code of Conduct
|
||||
|
||||
Don't be an a*shole.
|
||||
110
RadioLib/CONTRIBUTING.md
Normal file
110
RadioLib/CONTRIBUTING.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Contributing to RadioLib
|
||||
|
||||
First of all, thank you very much for taking the time to contribute! All feedback and ideas are greatly appreciated.
|
||||
To keep this library organized, please follow these rules.
|
||||
|
||||
## Issues
|
||||
|
||||
The following rules guide submission of new issues. These rules are in place mainly so that the issue author can get help as quickly as possible.
|
||||
|
||||
1. **Questions are welcome, spam is not.**
|
||||
Any issues without description will be considered spam and as such will be **CLOSED** and **LOCKED** immediately!
|
||||
2. **This repository has issue templates.**
|
||||
To report bugs or suggest new features, use the provided issue templates. Use the default issue only if the templates do not fit your issue type.
|
||||
3. **Be as clear as possible when creating issues.**
|
||||
Issues with generic titles (e.g. "not working", "lora", etc.) will be **CLOSED** until the title is fixed, since the title is supposed to categorize the issue. The same applies for issues with very little information and extensive grammatical or formatting errors that make it difficult to find out what is the actual issue.
|
||||
4. **Issues deserve some attention too.**
|
||||
Issues that are left for 2 weeks without response by the original author when asked for further information will be closed due to inactivity. This is to keep track of important issues, the author is encouraged to reopen the issue at a later date.
|
||||
|
||||
## Code style guidelines
|
||||
|
||||
I like pretty code! Or at least, I like *consistent* code style. When creating pull requests, please follow these style guidelines, they're in place to keep high code readability.
|
||||
|
||||
1. **Bracket style**
|
||||
This library uses the following style of bracket indentation (1TBS, or "javascript" style):
|
||||
|
||||
```c++
|
||||
if (foo) {
|
||||
bar();
|
||||
} else {
|
||||
baz();
|
||||
}
|
||||
```
|
||||
|
||||
2. **Tabs**
|
||||
Use 2 space characters for tabs.
|
||||
|
||||
3. **Single-line comments**
|
||||
Comments can be very useful - and they can become the bane of readability. Every single-line comment should start at new line, have one space between comment delimiter `//` and the start of the comment itself. The comment should also start with a lower-case letter.
|
||||
|
||||
```c++
|
||||
// this function does something
|
||||
foo("bar");
|
||||
|
||||
// here it does something else
|
||||
foo(12345);
|
||||
```
|
||||
|
||||
4. **Split code into blocks**
|
||||
It is very easy to write code that machine can read. It is much harder to write one that humans can read. That's why it's a great idea to split code into blocks - even if the block is just a single line!
|
||||
|
||||
```c++
|
||||
// build a temporary buffer (first block)
|
||||
uint8_t* data = new uint8_t[len + 1];
|
||||
if(!data) {
|
||||
return(RADIOLIB_ERR_MEMORY_ALLOCATION_FAILED);
|
||||
}
|
||||
|
||||
// read the received data (second block)
|
||||
state = readData(data, len);
|
||||
|
||||
// add null terminator (third block)
|
||||
data[len] = 0;
|
||||
```
|
||||
|
||||
5. **Doxygen**
|
||||
If you're adding a new method, make sure to add appropriate Doxygen comments, so that the documentation is always complete.
|
||||
|
||||
6. **Keywords**
|
||||
This is an Arduino library, so it needs to comply with the Arduino library specification. To add a new keyword to the Arduino IDE syntax highlighting, add it to the keywords.txt file. **Use true tabs in keywords.txt! No spaces there!**
|
||||
|
||||
7. **Dynamic memory**
|
||||
Sometimes, RadioLib might be used in critical applications where dynamic memory allocation using `new` or `malloc` might cause issues. For such cases, RadioLib provides the option to compile using only static arrays. This means that every dynamically allocated array must have a sufficiently large static counterpart. Naturally, all dynamically allocated memory must be properly de-allocated using `delete` or `free`.
|
||||
|
||||
```c++
|
||||
// build a temporary buffer
|
||||
#if defined(RADIOLIB_STATIC_ONLY)
|
||||
uint8_t data[RADIOLIB_STATIC_ARRAY_SIZE + 1];
|
||||
#else
|
||||
uint8_t* data = new uint8_t[length + 1];
|
||||
if(!data) {
|
||||
return(RADIOLIB_ERR_MEMORY_ALLOCATION_FAILED);
|
||||
}
|
||||
#endif
|
||||
|
||||
// read the received data
|
||||
readData(data, length);
|
||||
|
||||
// deallocate temporary buffer
|
||||
#if !defined(RADIOLIB_STATIC_ONLY)
|
||||
delete[] data;
|
||||
#endif
|
||||
```
|
||||
|
||||
8. **God Mode**
|
||||
During development, it can be useful to have access to the low level drivers, such as the SPI commands. These are incredibly powerful, since they will basically let user do anything he wants with the module, outside of the normal level of sanity checks. As such, they are normally protected using C++ access modifiers `private` or `protected`. God mode disables this protection, and so any newly implemented `class` must contain the appropriate macro check:
|
||||
|
||||
```c++
|
||||
class Module {
|
||||
void publicMethod();
|
||||
|
||||
#if defined(RADIOLIB_GODMODE)
|
||||
private:
|
||||
#endif
|
||||
|
||||
void privateMethod();
|
||||
};
|
||||
```
|
||||
|
||||
9. **No Arduino Strings**
|
||||
Arduino `String` class should never be used internally in the library. The only allowed occurence of Arduino `String` is in public API methods, and only at the top-most layer.
|
||||
2566
RadioLib/Doxyfile
Normal file
2566
RadioLib/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
100
RadioLib/README.md
Normal file
100
RadioLib/README.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# RadioLib  [](https://registry.platformio.org/libraries/jgromes/RadioLib) [](https://components.espressif.com/components/jgromes/radiolib)
|
||||
|
||||
### _One radio library to rule them all!_
|
||||
|
||||
## Universal wireless communication library for embedded devices
|
||||
|
||||
RadioLib allows its users to integrate all sorts of different wireless communication modules, protocols and even digital modes into a single consistent system.
|
||||
Want to add a Bluetooth interface to your LoRa network? Sure thing! Do you just want to go really old-school and play around with radio teletype, slow-scan TV, or even Hellschreiber using nothing but a cheap radio module? Why not!
|
||||
|
||||
RadioLib natively supports Arduino, but can run in non-Arduino environments as well! See [this Wiki page](https://github.com/jgromes/RadioLib/wiki/Porting-to-non-Arduino-Platforms) and [examples/NonArduino](https://github.com/jgromes/RadioLib/tree/master/examples/NonArduino).
|
||||
|
||||
RadioLib was originally created as a driver for [__RadioShield__](https://github.com/jgromes/RadioShield), but it can be used to control as many different wireless modules as you like - or at least as many as your microcontroller can handle!
|
||||
|
||||
### Quick links:
|
||||
* [__Wiki__](https://github.com/jgromes/RadioLib/wiki) - contains useful general information on using this library
|
||||
* [__FAQ__](https://github.com/jgromes/RadioLib/wiki/Frequently-Asked-Questions) - frequently asked questions, and answers
|
||||
* [__API Reference__](https://jgromes.github.io/RadioLib) - full API reference, automatically generated from the source code
|
||||
* [__Status Code Decoder__](https://radiolib-org.github.io/status_decoder/decode.html) - decoder for status codes returned by RadioLib methods
|
||||
* [__Debug Log Decoder__](https://radiolib-org.github.io/debug_decoder/decode.html) - decoder for RadioLib SPI debug logs
|
||||
|
||||
### Supported modules:
|
||||
* __CC1101__ FSK radio module
|
||||
* __LLCC68__ LoRa module
|
||||
* __LR11x0__ series LoRa/GFSK modules (LR1110, LR1120, LR1121)
|
||||
* __nRF24L01__ 2.4 GHz module
|
||||
* __RF69__ FSK/OOK radio module
|
||||
* __RFM2x__ series FSK modules (RFM22, RM23)
|
||||
* __RFM9x__ series LoRa modules (RFM95, RM96, RFM97, RFM98)
|
||||
* __Si443x__ series FSK modules (Si4430, Si4431, Si4432)
|
||||
* __STM32WL__ integrated microcontroller/LoRa module
|
||||
* __SX126x__ series LoRa modules (SX1261, SX1262, SX1268)
|
||||
* __SX127x__ series LoRa modules (SX1272, SX1273, SX1276, SX1277, SX1278, SX1279)
|
||||
* __SX128x__ series LoRa/GFSK/BLE/FLRC modules (SX1280, SX1281, SX1282)
|
||||
* __SX123x__ FSK/OOK radio modules (SX1231, SX1233)
|
||||
|
||||
### Supported protocols and digital modes:
|
||||
* [__AX.25__](https://www.sigidwiki.com/wiki/PACKET) using 2-FSK or AFSK for modules:
|
||||
SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, RFM2x, Si443x, LR11x0 and SX128x
|
||||
* [__RTTY__](https://www.sigidwiki.com/wiki/RTTY) using 2-FSK or AFSK for modules:
|
||||
SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x, LR11x0 and SX128x
|
||||
* [__Morse Code__](https://www.sigidwiki.com/wiki/Morse_Code_(CW)) using 2-FSK or AFSK for modules:
|
||||
SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x, LR11x0 and SX128x
|
||||
* [__SSTV__](https://www.sigidwiki.com/wiki/SSTV) using 2-FSK or AFSK for modules:
|
||||
SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, RFM2x and Si443x
|
||||
* [__Hellschreiber__](https://www.sigidwiki.com/wiki/Hellschreiber) using 2-FSK or AFSK for modules:
|
||||
SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x, LR11x0 and SX128x
|
||||
* [__APRS__](https://www.sigidwiki.com/wiki/APRS) using AFSK for modules:
|
||||
SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x and SX128x
|
||||
* [__POCSAG__](https://www.sigidwiki.com/wiki/POCSAG) using 2-FSK for modules:
|
||||
SX127x, RFM9x, RF69, SX1231, CC1101, nRF24L01, RFM2x and Si443x
|
||||
* [__LoRaWAN__](https://lora-alliance.org/) using LoRa and FSK for modules:
|
||||
SX127x, RFM9x, SX126x, LR11x0 and SX128x
|
||||
|
||||
### Supported Arduino platforms:
|
||||
* __Arduino__
|
||||
* [__AVR__](https://github.com/arduino/ArduinoCore-avr) - Arduino Uno, Mega, Leonardo, Pro Mini, Nano etc.
|
||||
* NOTE: Arduino boards based on ATmega328 (Uno, Pro Mini, Nano etc.) and smaller are NOT recommended. This is because the ATmega328 MCU is very constrained in terms of program and memory size, so the library will end up taking most of the space available.
|
||||
* [__mbed__](https://github.com/arduino/ArduinoCore-mbed) - Arduino Nano 33 BLE and Arduino Portenta H7
|
||||
* [__megaAVR__](https://github.com/arduino/ArduinoCore-megaavr) - Arduino Uno WiFi Rev.2 and Nano Every
|
||||
* [__SAM__](https://github.com/arduino/ArduinoCore-sam) - Arduino Due
|
||||
* [__SAMD__](https://github.com/arduino/ArduinoCore-samd) - Arduino Zero, MKR boards, M0 Pro etc.
|
||||
* [__Renesas__](https://github.com/arduino/ArduinoCore-renesas) - Arduino Uno R4
|
||||
|
||||
* __Adafruit__
|
||||
* [__SAMD__](https://github.com/adafruit/ArduinoCore-samd) - Adafruit Feather M0 and M4 boards (Feather, Metro, Gemma, Trinket etc.)
|
||||
* [__nRF52__](https://github.com/adafruit/Adafruit_nRF52_Arduino) - Adafruit Feather nRF528x, Bluefruit and CLUE
|
||||
|
||||
* __Espressif__
|
||||
* [__ESP32__](https://github.com/espressif/arduino-esp32) - ESP32-based boards
|
||||
* [__ESP8266__](https://github.com/esp8266/Arduino) - ESP8266-based boards
|
||||
|
||||
* __Intel__
|
||||
* [__Curie__](https://github.com/arduino/ArduinoCore-arc32) - Arduino 101
|
||||
|
||||
* __SparkFun__
|
||||
* [__Apollo3__](https://github.com/sparkfun/Arduino_Apollo3) - Sparkfun Artemis Redboard
|
||||
|
||||
* __ST Microelectronics__
|
||||
* [__STM32__ (official core)](https://github.com/stm32duino/Arduino_Core_STM32) - STM32 Nucleo, Discovery, Maple, BluePill, BlackPill etc.
|
||||
* [__STM32__ (unofficial core)](https://github.com/rogerclarkmelbourne/Arduino_STM32) - STM32F1 and STM32F4-based boards
|
||||
|
||||
* __MCUdude__
|
||||
* [__MegaCoreX__](https://github.com/MCUdude/MegaCoreX) - megaAVR-0 series (ATmega4809, ATmega3209 etc.)
|
||||
* [__MegaCore__](https://github.com/MCUdude/MegaCore) - AVR (ATmega1281, ATmega640 etc.)
|
||||
|
||||
* __Raspberry Pi__
|
||||
* [__RP2040__ (official core)](https://github.com/arduino/ArduinoCore-mbed) - Raspberry Pi Pico and Arduino Nano RP2040 Connect
|
||||
* [__RP2040__ (unofficial core)](https://github.com/earlephilhower/arduino-pico) - Raspberry Pi Pico/RP2040-based boards
|
||||
* [__Raspberry Pi__](https://github.com/me-no-dev/RasPiArduino) - Arduino framework for RaspberryPI
|
||||
|
||||
* __Heltec__
|
||||
* [__CubeCell__](https://github.com/HelTecAutomation/CubeCell-Arduino) - ASR650X series (CubeCell-Board, CubeCell-Capsule, CubeCell-Module etc.)
|
||||
|
||||
* __PJRC__
|
||||
* [__Teensy__](https://github.com/PaulStoffregen/cores) - Teensy 2.x, 3.x and 4.x boards
|
||||
|
||||
* __Silicon Labs__
|
||||
* [__EFR32__](https://github.com/SiliconLabs/arduino) - Silicon Labs xG24, xG27 and other boards
|
||||
|
||||
The list above is by no means exhaustive - RadioLib code is independent of the used platform! Compilation of all examples is tested for all platforms officially supported prior to releasing new version. In addition, RadioLib includes an internal hardware abstraction layer, which allows it to be easily ported even to non-Arduino environments.
|
||||
5
RadioLib/SECURITY.md
Normal file
5
RadioLib/SECURITY.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Security Policy
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
RadioLib is provided as-is without any warranty, and is not intended to be used in security-critical applications. However, if you discover a vulnerability within the library code, please report it to gromes.jan@gmail.com.
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
RadioLib AFSK External Radio example
|
||||
|
||||
This example shows how to use your Arduino
|
||||
as modulator for an external analogue FM radio.
|
||||
|
||||
The example sends APRS position reports with
|
||||
audio modulated as AFSK at 1200 baud using
|
||||
Bell 202 tones. However, any other AFSK
|
||||
protocol (RTTY, SSTV, etc.) may be used as well.
|
||||
|
||||
DO NOT transmit in APRS bands unless
|
||||
you have a ham radio license!
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// create a dummy radio module
|
||||
ExternalRadio radio;
|
||||
|
||||
// create AFSK client instance using the external radio
|
||||
// pin 5 is connected to the radio sound input
|
||||
AFSKClient audio(&radio, 5);
|
||||
|
||||
// create AX.25 client instance using the AFSK instance
|
||||
AX25Client ax25(&audio);
|
||||
|
||||
// create APRS client instance using the AX.25 client
|
||||
APRSClient aprs(&ax25);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize AX.25 client
|
||||
Serial.print(F("[AX.25] Initializing ... "));
|
||||
// source station callsign: "N7LEM"
|
||||
// source station SSID: 0
|
||||
// preamble length: 8 bytes
|
||||
int16_t state = ax25.begin("N7LEM");
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize APRS client
|
||||
Serial.print(F("[APRS] Initializing ... "));
|
||||
// symbol: '>' (car)
|
||||
state = aprs.begin('>');
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[APRS] Sending position ... "));
|
||||
|
||||
// send a location without message or timestamp
|
||||
char destination[] = "N0CALL";
|
||||
char latitude[] = "4911.67N";
|
||||
char longitude[] = "01635.96E";
|
||||
int state = aprs.sendPosition(destination, 0, latitude, longitude);
|
||||
delay(500);
|
||||
|
||||
// send a location with message and without timestamp
|
||||
char message[] = "I'm here!";
|
||||
state |= aprs.sendPosition(destination, 0, latitude, longitude, message);
|
||||
delay(500);
|
||||
|
||||
// send a location with message and timestamp
|
||||
char timestamp[] = "093045z";
|
||||
state |= aprs.sendPosition(destination, 0, latitude, longitude, message, timestamp);
|
||||
delay(500);
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
// wait one minute before transmitting again
|
||||
delay(60000);
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
RadioLib AFSK Imperial March Example
|
||||
|
||||
This example shows how to EXECUTE ORDER 66
|
||||
|
||||
Other modules that can be used for AFSK:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- Si443x/RFM2x
|
||||
- SX126x/LLCC68
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// include the melody
|
||||
#include "melody.h"
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// create AFSK client instance using the FSK module
|
||||
// this requires connection to the module direct
|
||||
// input pin, here connected to Arduino pin 5
|
||||
// SX127x/RFM9x: DIO2
|
||||
// RF69: DIO2
|
||||
// SX1231: DIO2
|
||||
// CC1101: GDO2
|
||||
// Si443x/RFM2x: GPIO
|
||||
// SX126x/LLCC68: DIO2
|
||||
AFSKClient audio(&radio, 5);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
|
||||
// when using one of the non-LoRa modules for AFSK
|
||||
// (RF69, CC1101,, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize AFSK client
|
||||
Serial.print(F("[AFSK] Initializing ... "));
|
||||
state = audio.begin();
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[AFSK] Executing Order 66 ... "));
|
||||
|
||||
// calculate whole note duration
|
||||
int wholenote = (60000 * 4) / 120;
|
||||
|
||||
// iterate over the melody
|
||||
for(unsigned int note = 0; note < sizeof(melody) / sizeof(melody[0]); note += 2) {
|
||||
// calculate the duration of each note
|
||||
int noteDuration = 0;
|
||||
int divider = melody[note + 1];
|
||||
if(divider > 0) {
|
||||
// regular note, just proceed
|
||||
noteDuration = wholenote / divider;
|
||||
} else if(divider < 0) {
|
||||
// dotted notes are represented with negative durations!!
|
||||
noteDuration = wholenote / abs(divider);
|
||||
noteDuration *= 1.5; // increases the duration in half for dotted notes
|
||||
}
|
||||
|
||||
// we only play the note for 90% of the duration, leaving 10% as a pause
|
||||
audio.tone(melody[note]);
|
||||
delay(noteDuration*0.9);
|
||||
audio.noTone();
|
||||
delay(noteDuration*0.1);
|
||||
}
|
||||
|
||||
Serial.println(F("done!"));
|
||||
|
||||
// wait for a second
|
||||
delay(1000);
|
||||
}
|
||||
128
RadioLib/examples/AFSK/AFSK_Imperial_March/melody.h
Normal file
128
RadioLib/examples/AFSK/AFSK_Imperial_March/melody.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
Note definitions, melody and melody-related functions
|
||||
adapted from https://github.com/robsoncouto/arduino-songs
|
||||
by Robson Couto, 2019
|
||||
*/
|
||||
|
||||
#define NOTE_B0 31
|
||||
#define NOTE_C1 33
|
||||
#define NOTE_CS1 35
|
||||
#define NOTE_D1 37
|
||||
#define NOTE_DS1 39
|
||||
#define NOTE_E1 41
|
||||
#define NOTE_F1 44
|
||||
#define NOTE_FS1 46
|
||||
#define NOTE_G1 49
|
||||
#define NOTE_GS1 52
|
||||
#define NOTE_A1 55
|
||||
#define NOTE_AS1 58
|
||||
#define NOTE_B1 62
|
||||
#define NOTE_C2 65
|
||||
#define NOTE_CS2 69
|
||||
#define NOTE_D2 73
|
||||
#define NOTE_DS2 78
|
||||
#define NOTE_E2 82
|
||||
#define NOTE_F2 87
|
||||
#define NOTE_FS2 93
|
||||
#define NOTE_G2 98
|
||||
#define NOTE_GS2 104
|
||||
#define NOTE_A2 110
|
||||
#define NOTE_AS2 117
|
||||
#define NOTE_B2 123
|
||||
#define NOTE_C3 131
|
||||
#define NOTE_CS3 139
|
||||
#define NOTE_D3 147
|
||||
#define NOTE_DS3 156
|
||||
#define NOTE_E3 165
|
||||
#define NOTE_F3 175
|
||||
#define NOTE_FS3 185
|
||||
#define NOTE_G3 196
|
||||
#define NOTE_GS3 208
|
||||
#define NOTE_A3 220
|
||||
#define NOTE_AS3 233
|
||||
#define NOTE_B3 247
|
||||
#define NOTE_C4 262
|
||||
#define NOTE_CS4 277
|
||||
#define NOTE_D4 294
|
||||
#define NOTE_DS4 311
|
||||
#define NOTE_E4 330
|
||||
#define NOTE_F4 349
|
||||
#define NOTE_FS4 370
|
||||
#define NOTE_G4 392
|
||||
#define NOTE_GS4 415
|
||||
#define NOTE_A4 440
|
||||
#define NOTE_AS4 466
|
||||
#define NOTE_B4 494
|
||||
#define NOTE_C5 523
|
||||
#define NOTE_CS5 554
|
||||
#define NOTE_D5 587
|
||||
#define NOTE_DS5 622
|
||||
#define NOTE_E5 659
|
||||
#define NOTE_F5 698
|
||||
#define NOTE_FS5 740
|
||||
#define NOTE_G5 784
|
||||
#define NOTE_GS5 831
|
||||
#define NOTE_A5 880
|
||||
#define NOTE_AS5 932
|
||||
#define NOTE_B5 988
|
||||
#define NOTE_C6 1047
|
||||
#define NOTE_CS6 1109
|
||||
#define NOTE_D6 1175
|
||||
#define NOTE_DS6 1245
|
||||
#define NOTE_E6 1319
|
||||
#define NOTE_F6 1397
|
||||
#define NOTE_FS6 1480
|
||||
#define NOTE_G6 1568
|
||||
#define NOTE_GS6 1661
|
||||
#define NOTE_A6 1760
|
||||
#define NOTE_AS6 1865
|
||||
#define NOTE_B6 1976
|
||||
#define NOTE_C7 2093
|
||||
#define NOTE_CS7 2217
|
||||
#define NOTE_D7 2349
|
||||
#define NOTE_DS7 2489
|
||||
#define NOTE_E7 2637
|
||||
#define NOTE_F7 2794
|
||||
#define NOTE_FS7 2960
|
||||
#define NOTE_G7 3136
|
||||
#define NOTE_GS7 3322
|
||||
#define NOTE_A7 3520
|
||||
#define NOTE_AS7 3729
|
||||
#define NOTE_B7 3951
|
||||
#define NOTE_C8 4186
|
||||
#define NOTE_CS8 4435
|
||||
#define NOTE_D8 4699
|
||||
#define NOTE_DS8 4978
|
||||
#define REST 0
|
||||
|
||||
// notes of the melody followed by the duration.
|
||||
// a 4 means a quarter note, 8 an eighteenth , 16 sixteenth, so on
|
||||
// !!negative numbers are used to represent dotted notes,
|
||||
// so -4 means a dotted quarter note, that is, a quarter plus an eighteenth!!
|
||||
int melody[] = {
|
||||
|
||||
// Darth Vader theme (Imperial March) - Star wars
|
||||
// Score available at https://musescore.com/user/202909/scores/1141521
|
||||
// The tenor saxophone part was used
|
||||
|
||||
NOTE_A4,-4, NOTE_A4,-4, NOTE_A4,16, NOTE_A4,16, NOTE_A4,16, NOTE_A4,16, NOTE_F4,8, REST,8,
|
||||
NOTE_A4,-4, NOTE_A4,-4, NOTE_A4,16, NOTE_A4,16, NOTE_A4,16, NOTE_A4,16, NOTE_F4,8, REST,8,
|
||||
NOTE_A4,4, NOTE_A4,4, NOTE_A4,4, NOTE_F4,-8, NOTE_C5,16,
|
||||
|
||||
NOTE_A4,4, NOTE_F4,-8, NOTE_C5,16, NOTE_A4,2,//4
|
||||
NOTE_E5,4, NOTE_E5,4, NOTE_E5,4, NOTE_F5,-8, NOTE_C5,16,
|
||||
NOTE_A4,4, NOTE_F4,-8, NOTE_C5,16, NOTE_A4,2,
|
||||
|
||||
NOTE_A5,4, NOTE_A4,-8, NOTE_A4,16, NOTE_A5,4, NOTE_GS5,-8, NOTE_G5,16, //7
|
||||
NOTE_DS5,16, NOTE_D5,16, NOTE_DS5,8, REST,8, NOTE_A4,8, NOTE_DS5,4, NOTE_D5,-8, NOTE_CS5,16,
|
||||
|
||||
NOTE_C5,16, NOTE_B4,16, NOTE_C5,16, REST,8, NOTE_F4,8, NOTE_GS4,4, NOTE_F4,-8, NOTE_A4,-16,//9
|
||||
NOTE_C5,4, NOTE_A4,-8, NOTE_C5,16, NOTE_E5,2,
|
||||
|
||||
NOTE_A5,4, NOTE_A4,-8, NOTE_A4,16, NOTE_A5,4, NOTE_GS5,-8, NOTE_G5,16, //7
|
||||
NOTE_DS5,16, NOTE_D5,16, NOTE_DS5,8, REST,8, NOTE_A4,8, NOTE_DS5,4, NOTE_D5,-8, NOTE_CS5,16,
|
||||
|
||||
NOTE_C5,16, NOTE_B4,16, NOTE_C5,16, REST,8, NOTE_F4,8, NOTE_GS4,4, NOTE_F4,-8, NOTE_A4,-16,//9
|
||||
NOTE_A4,4, NOTE_F4,-8, NOTE_C5,16, NOTE_A4,2,
|
||||
|
||||
};
|
||||
92
RadioLib/examples/AFSK/AFSK_Tone/AFSK_Tone.ino
Normal file
92
RadioLib/examples/AFSK/AFSK_Tone/AFSK_Tone.ino
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
RadioLib AFSK Example
|
||||
|
||||
This example shows hot to send audio FSK tones
|
||||
using SX1278's FSK modem.
|
||||
|
||||
Other modules that can be used for AFSK:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- Si443x/RFM2x
|
||||
- SX126x/LLCC68
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// create AFSK client instance using the FSK module
|
||||
// this requires connection to the module direct
|
||||
// input pin, here connected to Arduino pin 5
|
||||
// SX127x/RFM9x: DIO2
|
||||
// RF69: DIO2
|
||||
// SX1231: DIO2
|
||||
// CC1101: GDO2
|
||||
// Si443x/RFM2x: GPIO
|
||||
// SX126x/LLCC68: DIO2
|
||||
AFSKClient audio(&radio, 5);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
|
||||
// when using one of the non-LoRa modules for AFSK
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize AFSK client
|
||||
Serial.print(F("[AFSK] Initializing ... "));
|
||||
state = audio.begin();
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// AFSKClient can be used to transmit tones,
|
||||
// same as Arduino tone() function
|
||||
|
||||
// 400 Hz tone
|
||||
Serial.print(F("[AFSK] 400 Hz tone ... "));
|
||||
audio.tone(400);
|
||||
delay(1000);
|
||||
|
||||
// silence
|
||||
Serial.println(F("done!"));
|
||||
audio.noTone();
|
||||
delay(1000);
|
||||
|
||||
// AFSKClient can also be used to transmit HAM-friendly
|
||||
// RTTY, Morse code, Hellschreiber, SSTV and AX.25.
|
||||
// Details on how to use AFSK are in the example
|
||||
// folders for each of the above modes.
|
||||
}
|
||||
101
RadioLib/examples/AFSK/AFSK_Tone_AM/AFSK_Tone_AM.ino
Normal file
101
RadioLib/examples/AFSK/AFSK_Tone_AM/AFSK_Tone_AM.ino
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
RadioLib AM-modulated AFSK Example
|
||||
|
||||
This example shows hot to send AM-modulated
|
||||
audio FSK tones using SX1278's OOK modem.
|
||||
|
||||
Other modules that can be used for AFSK:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
SX1278 radio = new Module(10, 2, 9);
|
||||
|
||||
// create AFSK client instance using the FSK module
|
||||
// this requires connection to the module direct
|
||||
// input pin, here connected to Arduino pin 5
|
||||
// SX127x/RFM9x: DIO2
|
||||
// RF69: DIO2
|
||||
// SX1231: DIO2
|
||||
// CC1101: GDO2
|
||||
AFSKClient audio(&radio, 5);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
|
||||
// when using one of the non-LoRa modules for AFSK
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize AFSK client
|
||||
Serial.print(F("[AFSK] Initializing ... "));
|
||||
state = audio.begin();
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// after that, set mode to OOK
|
||||
Serial.print(F("[SX1278] Switching to OOK ... "));
|
||||
state = radio.setOOK(true);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// AFSKClient can be used to transmit tones,
|
||||
// same as Arduino tone() function
|
||||
|
||||
// 400 Hz tone
|
||||
Serial.print(F("[AFSK] 400 Hz tone ... "));
|
||||
audio.tone(400);
|
||||
delay(1000);
|
||||
|
||||
// silence
|
||||
Serial.println(F("done!"));
|
||||
audio.noTone();
|
||||
delay(1000);
|
||||
|
||||
// AFSKClient can also be used to transmit HAM-friendly
|
||||
// RTTY, Morse code, Hellschreiber, SSTV and AX.25.
|
||||
// Details on how to use AFSK are in the example
|
||||
// folders for each of the above modes.
|
||||
|
||||
// CAUTION: Unlike standard AFSK, the result when using OOK
|
||||
// must be demodulated as AM!
|
||||
}
|
||||
123
RadioLib/examples/APRS/APRS_MicE/APRS_MicE.ino
Normal file
123
RadioLib/examples/APRS/APRS_MicE/APRS_MicE.ino
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
RadioLib APRS Mic-E Example
|
||||
|
||||
This example sends APRS position reports
|
||||
encoded in the Mic-E format using SX1278's
|
||||
FSK modem. The data is modulated as AFSK
|
||||
at 1200 baud using Bell 202 tones.
|
||||
|
||||
DO NOT transmit in APRS bands unless
|
||||
you have a ham radio license!
|
||||
|
||||
Other modules that can be used for APRS:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- nRF24
|
||||
- Si443x/RFM2x
|
||||
- SX126x/LLCC68
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create AFSK client instance using the FSK module
|
||||
// this requires connection to the module direct
|
||||
// input pin, here connected to Arduino pin 5
|
||||
// SX127x/RFM9x: DIO2
|
||||
// RF69: DIO2
|
||||
// SX1231: DIO2
|
||||
// CC1101: GDO2
|
||||
// Si443x/RFM2x: GPIO
|
||||
// SX126x/LLCC68: DIO2
|
||||
AFSKClient audio(&radio, 5);
|
||||
|
||||
// create AX.25 client instance using the AFSK instance
|
||||
AX25Client ax25(&audio);
|
||||
|
||||
// create APRS client instance using the AX.25 client
|
||||
APRSClient aprs(&ax25);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278
|
||||
// NOTE: moved to ISM band on purpose
|
||||
// DO NOT transmit in APRS bands without ham radio license!
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
|
||||
// when using one of the non-LoRa modules for AX.25
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize AX.25 client
|
||||
Serial.print(F("[AX.25] Initializing ... "));
|
||||
// source station callsign: "N7LEM"
|
||||
// source station SSID: 0
|
||||
// preamble length: 8 bytes
|
||||
state = ax25.begin("N7LEM");
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize APRS client
|
||||
Serial.print(F("[APRS] Initializing ... "));
|
||||
// symbol: '>' (car)
|
||||
state = aprs.begin('>');
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[APRS] Sending Mic-E position ... "));
|
||||
int state = aprs.sendMicE(49.1945, 16.6000, 120, 10, RADIOLIB_APRS_MIC_E_TYPE_EN_ROUTE);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
// wait one minute before transmitting again
|
||||
delay(60000);
|
||||
}
|
||||
157
RadioLib/examples/APRS/APRS_Position/APRS_Position.ino
Normal file
157
RadioLib/examples/APRS/APRS_Position/APRS_Position.ino
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
RadioLib APRS Position Example
|
||||
|
||||
This example sends APRS position reports
|
||||
using SX1278's FSK modem. The data is
|
||||
modulated as AFSK at 1200 baud using Bell
|
||||
202 tones.
|
||||
|
||||
DO NOT transmit in APRS bands unless
|
||||
you have a ham radio license!
|
||||
|
||||
Other modules that can be used for APRS:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- nRF24
|
||||
- Si443x/RFM2x
|
||||
- SX126x/LLCC68
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create AFSK client instance using the FSK module
|
||||
// this requires connection to the module direct
|
||||
// input pin, here connected to Arduino pin 5
|
||||
// SX127x/RFM9x: DIO2
|
||||
// RF69: DIO2
|
||||
// SX1231: DIO2
|
||||
// CC1101: GDO2
|
||||
// Si443x/RFM2x: GPIO
|
||||
// SX126x/LLCC68: DIO2
|
||||
AFSKClient audio(&radio, 5);
|
||||
|
||||
// create AX.25 client instance using the AFSK instance
|
||||
AX25Client ax25(&audio);
|
||||
|
||||
// create APRS client instance using the AX.25 client
|
||||
APRSClient aprs(&ax25);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278
|
||||
// NOTE: moved to ISM band on purpose
|
||||
// DO NOT transmit in APRS bands without ham radio license!
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK(434.0);
|
||||
|
||||
// when using one of the non-LoRa modules for AX.25
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize AX.25 client
|
||||
Serial.print(F("[AX.25] Initializing ... "));
|
||||
// source station callsign: "N7LEM"
|
||||
// source station SSID: 0
|
||||
// preamble length: 8 bytes
|
||||
state = ax25.begin("N7LEM");
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize APRS client
|
||||
Serial.print(F("[APRS] Initializing ... "));
|
||||
// symbol: '>' (car)
|
||||
state = aprs.begin('>');
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.println(F("[APRS] Sending location reports"));
|
||||
|
||||
// send a location without message or timestamp
|
||||
char destination[] = "N0CALL";
|
||||
char latitude[] = "4911.67N";
|
||||
char longitude[] = "01635.96E";
|
||||
int state = aprs.sendPosition(destination, 0, latitude, longitude);
|
||||
if(state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("[APRS] Failed to send location, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
delay(500);
|
||||
|
||||
// send a location with message and without timestamp
|
||||
char message[] = "I'm here!";
|
||||
state = aprs.sendPosition(destination, 0, latitude, longitude, message);
|
||||
if(state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("[APRS] Failed to send location and message code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
delay(500);
|
||||
|
||||
// you can also set repeater callsigns and SSIDs
|
||||
// up to 8 repeaters may be used
|
||||
// sendPosition will be sent with "WIDE2-2" path
|
||||
char* repeaterCallsigns[] = { "WIDE2" };
|
||||
uint8_t repeaterSSIDs[] = { 2 };
|
||||
aprs.useRepeaters(repeaterCallsigns, repeaterSSIDs, 1);
|
||||
|
||||
// send a location with message and timestamp
|
||||
char timestamp[] = "093045z";
|
||||
state = aprs.sendPosition(destination, 0, latitude, longitude, message, timestamp);
|
||||
if(state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("[APRS] Failed to send location, message and timestamp code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
delay(500);
|
||||
|
||||
// when repeaters are no longer needed, they can be dropped
|
||||
aprs.dropRepeaters();
|
||||
|
||||
// wait one minute before transmitting again
|
||||
Serial.println(F("[APRS] All done!"));
|
||||
delay(60000);
|
||||
}
|
||||
|
||||
106
RadioLib/examples/APRS/APRS_Position_LoRa/APRS_Position_LoRa.ino
Normal file
106
RadioLib/examples/APRS/APRS_Position_LoRa/APRS_Position_LoRa.ino
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
RadioLib APRS Position over LoRa Example
|
||||
|
||||
This example sends APRS position reports
|
||||
using SX1278's LoRa modem.
|
||||
|
||||
Other modules that can be used for APRS:
|
||||
- SX127x/RFM9x
|
||||
- SX126x/LLCC68
|
||||
- SX128x
|
||||
- LR11x0
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create APRS client instance using the LoRa radio
|
||||
APRSClient aprs(&radio);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with the settings necessary for LoRa iGates
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
// frequency: 433.775 MHz
|
||||
// bandwidth: 125 kHz
|
||||
// spreading factor: 12
|
||||
// coding rate: 4/5
|
||||
int state = radio.begin(433.775, 125, 12, 5);
|
||||
|
||||
// when using one of the non-LoRa modules for AX.25
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize APRS client
|
||||
Serial.print(F("[APRS] Initializing ... "));
|
||||
// symbol: '>' (car)
|
||||
// callsign "N7LEM"
|
||||
// SSID 1
|
||||
char source[] = "N7LEM";
|
||||
state = aprs.begin('>', source, 1);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[APRS] Sending position ... "));
|
||||
|
||||
// send a location with message and timestamp
|
||||
// SSID is set to 1, as APRS over LoRa uses WIDE1-1 path by default
|
||||
char destination[] = "GPS";
|
||||
char latitude[] = "4911.67N";
|
||||
char longitude[] = "01635.96E";
|
||||
char message[] = "I'm here!";
|
||||
char timestamp[] = "093045z";
|
||||
int state = aprs.sendPosition(destination, 1, latitude, longitude, message, timestamp);
|
||||
delay(500);
|
||||
|
||||
// you can also send Mic-E encoded messages
|
||||
state |= state = aprs.sendMicE(49.1945, 16.6000, 120, 10, RADIOLIB_APRS_MIC_E_TYPE_EN_ROUTE);
|
||||
delay(500);
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
// wait one minute before transmitting again
|
||||
delay(60000);
|
||||
}
|
||||
179
RadioLib/examples/AX25/AX25_Frames/AX25_Frames.ino
Normal file
179
RadioLib/examples/AX25/AX25_Frames/AX25_Frames.ino
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
RadioLib AX.25 Frame Example
|
||||
|
||||
This example shows how to send various
|
||||
AX.25 frames using SX1278's FSK modem.
|
||||
|
||||
Other modules that can be used for AX.25:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- SX126x
|
||||
- nRF24
|
||||
- Si443x/RFM2x
|
||||
- LR11x0
|
||||
|
||||
Using raw AX.25 frames requires some
|
||||
knowledge of the protocol, refer to
|
||||
AX25_Transmit for basic operation.
|
||||
Frames shown in this example are not
|
||||
exhaustive; all possible AX.25 frames
|
||||
should be supported.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create AX.25 client instance using the FSK module
|
||||
AX25Client ax25(&radio);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bit rate: 1.2 kbps (1200 baud 2-FSK AX.25)
|
||||
// frequency deviation: 0.5 kHz (1200 baud 2-FSK AX.25)
|
||||
int state = radio.beginFSK(434.0, 1.2, 0.5);
|
||||
|
||||
// when using one of the non-LoRa modules for AX.25
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize AX.25 client
|
||||
Serial.print(F("[AX.25] Initializing ... "));
|
||||
// source station callsign: "N7LEM"
|
||||
// source station SSID: 0
|
||||
// preamble length: 8 bytes
|
||||
state = ax25.begin("N7LEM");
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// create AX.25 Unnumbered Information frame
|
||||
// destination station callsign: "NJ7P"
|
||||
// destination station SSID: 0
|
||||
// source station callsign: "N7LEM"
|
||||
// source station SSID: 0
|
||||
// control field: UI, P/F not used, unnumbered frame
|
||||
// protocol identifier: no layer 3 protocol implemented
|
||||
// information field: "Hello World!"
|
||||
AX25Frame frameUI("NJ7P", 0, "N7LEM", 0, RADIOLIB_AX25_CONTROL_U_UNNUMBERED_INFORMATION |
|
||||
RADIOLIB_AX25_CONTROL_POLL_FINAL_DISABLED | RADIOLIB_AX25_CONTROL_UNNUMBERED_FRAME,
|
||||
RADIOLIB_AX25_PID_NO_LAYER_3, "Hello World (unnumbered)!");
|
||||
|
||||
// send the frame
|
||||
Serial.print(F("[AX.25] Sending UI frame ... "));
|
||||
int state = ax25.sendFrame(&frameUI);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// the packet was successfully transmitted
|
||||
Serial.println(F("success!"));
|
||||
|
||||
} else {
|
||||
// some error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
delay(1000);
|
||||
|
||||
// create AX.25 Receive Ready frame
|
||||
// destination station callsign: "NJ7P"
|
||||
// destination station SSID: 0
|
||||
// source station callsign: "N7LEM"
|
||||
// source station SSID: 0
|
||||
// control field: RR, P/F not used, supervisory frame
|
||||
AX25Frame frameRR("NJ7P", 0, "N7LEM", 0, RADIOLIB_AX25_CONTROL_S_RECEIVE_READY |
|
||||
RADIOLIB_AX25_CONTROL_POLL_FINAL_DISABLED | RADIOLIB_AX25_CONTROL_SUPERVISORY_FRAME);
|
||||
|
||||
// set receive sequence number (0 - 7)
|
||||
frameRR.setRecvSequence(0);
|
||||
|
||||
// send the frame
|
||||
Serial.print(F("[AX.25] Sending RR frame ... "));
|
||||
state = ax25.sendFrame(&frameRR);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// the packet was successfully transmitted
|
||||
Serial.println(F("success!"));
|
||||
|
||||
} else {
|
||||
// some error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
delay(1000);
|
||||
|
||||
// create AX.25 Information frame
|
||||
// destination station callsign: "NJ7P"
|
||||
// destination station SSID: 0
|
||||
// source station callsign: "N7LEM"
|
||||
// source station SSID: 0
|
||||
// control field: P/F not used, information frame
|
||||
// protocol identifier: no layer 3 protocol implemented
|
||||
// information field: "Hello World (numbered)!"
|
||||
AX25Frame frameI("NJ7P", 0, "N7LEM", 0, RADIOLIB_AX25_CONTROL_POLL_FINAL_DISABLED |
|
||||
RADIOLIB_AX25_CONTROL_INFORMATION_FRAME, RADIOLIB_AX25_PID_NO_LAYER_3,
|
||||
"Hello World (numbered)!");
|
||||
|
||||
// set receive sequence number (0 - 7)
|
||||
frameI.setRecvSequence(0);
|
||||
|
||||
// set send sequence number (0 - 7)
|
||||
frameI.setSendSequence(0);
|
||||
|
||||
// send the frame
|
||||
Serial.print(F("[AX.25] Sending I frame ... "));
|
||||
state = ax25.sendFrame(&frameI);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// the packet was successfully transmitted
|
||||
Serial.println(F("success!"));
|
||||
|
||||
} else {
|
||||
// some error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
99
RadioLib/examples/AX25/AX25_Transmit/AX25_Transmit.ino
Normal file
99
RadioLib/examples/AX25/AX25_Transmit/AX25_Transmit.ino
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
RadioLib AX.25 Transmit Example
|
||||
|
||||
This example sends AX.25 messages using
|
||||
SX1278's FSK modem.
|
||||
|
||||
Other modules that can be used for AX.25:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- SX126x
|
||||
- nRF24
|
||||
- Si443x/RFM2x
|
||||
- LR11x0
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create AX.25 client instance using the FSK module
|
||||
AX25Client ax25(&radio);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bit rate: 1.2 kbps (1200 baud 2-FSK AX.25)
|
||||
int state = radio.beginFSK(434.0, 1.2);
|
||||
|
||||
// when using one of the non-LoRa modules for AX.25
|
||||
// (RF69, CC1101,, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize AX.25 client
|
||||
Serial.print(F("[AX.25] Initializing ... "));
|
||||
// source station callsign: "N7LEM"
|
||||
// source station SSID: 0
|
||||
// preamble length: 8 bytes
|
||||
state = ax25.begin("N7LEM");
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// send AX.25 unnumbered information frame
|
||||
Serial.print(F("[AX.25] Sending UI frame ... "));
|
||||
// destination station callsign: "NJ7P"
|
||||
// destination station SSID: 0
|
||||
int state = ax25.transmit("Hello World!", "NJ7P");
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// the packet was successfully transmitted
|
||||
Serial.println(F("success!"));
|
||||
|
||||
} else {
|
||||
// some error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
125
RadioLib/examples/AX25/AX25_Transmit_AFSK/AX25_Transmit_AFSK.ino
Normal file
125
RadioLib/examples/AX25/AX25_Transmit_AFSK/AX25_Transmit_AFSK.ino
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
RadioLib AX.25 Transmit AFSK Example
|
||||
|
||||
This example sends AX.25 messages using
|
||||
SX1278's FSK modem. The data is modulated
|
||||
as AFSK at 1200 baud using Bell 202 tones.
|
||||
|
||||
Other modules that can be used for AX.25
|
||||
with AFSK modulation:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- nRF24
|
||||
- Si443x/RFM2x
|
||||
- SX126x/LLCC68
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create AFSK client instance using the FSK module
|
||||
// this requires connection to the module direct
|
||||
// input pin, here connected to Arduino pin 5
|
||||
// SX127x/RFM9x: DIO2
|
||||
// RF69: DIO2
|
||||
// SX1231: DIO2
|
||||
// CC1101: GDO2
|
||||
// Si443x/RFM2x: GPIO
|
||||
// SX126x/LLCC68: DIO2
|
||||
AFSKClient audio(&radio, 5);
|
||||
|
||||
// create AX.25 client instance using the AFSK instance
|
||||
AX25Client ax25(&audio);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
|
||||
// when using one of the non-LoRa modules for AX.25
|
||||
// (RF69, CC1101,, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize AX.25 client
|
||||
Serial.print(F("[AX.25] Initializing ... "));
|
||||
// source station callsign: "N7LEM"
|
||||
// source station SSID: 0
|
||||
// preamble length: 8 bytes
|
||||
state = ax25.begin("N7LEM");
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// Sometimes, it may be required to adjust audio
|
||||
// frequencies to match the expected 1200/2200 Hz tones.
|
||||
// The following method will offset mark frequency by
|
||||
// 100 Hz up and space frequency by 100 Hz down
|
||||
/*
|
||||
Serial.print(F("[AX.25] Setting correction ... "));
|
||||
state = ax25.setCorrection(100, -100);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// send AX.25 unnumbered information frame
|
||||
Serial.print(F("[AX.25] Sending UI frame ... "));
|
||||
// destination station callsign: "NJ7P"
|
||||
// destination station SSID: 0
|
||||
int state = ax25.transmit("Hello World!", "NJ7P");
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// the packet was successfully transmitted
|
||||
Serial.println(F("success!"));
|
||||
|
||||
} else {
|
||||
// some error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
RadioLib Bell Modem Transmit Example
|
||||
|
||||
This example shows how to transmit binary data
|
||||
using audio Bell 202 tones.
|
||||
|
||||
Other implemented Bell modems
|
||||
- Bell 101
|
||||
- Bell 103
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// create Bell modem instance using the FSK module
|
||||
// this requires connection to the module direct
|
||||
// input pin, here connected to Arduino pin 5
|
||||
// SX127x/RFM9x: DIO2
|
||||
// RF69: DIO2
|
||||
// SX1231: DIO2
|
||||
// CC1101: GDO2
|
||||
// Si443x/RFM2x: GPIO
|
||||
// SX126x/LLCC68: DIO2
|
||||
BellClient bell(&radio, 5);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
|
||||
// when using one of the non-LoRa modules for AFSK
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize Bell 202 modem
|
||||
Serial.print(F("[Bell 202] Initializing ... "));
|
||||
state = bell.begin(Bell202);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[Bell 202] Sending data ... "));
|
||||
|
||||
// send out idle condition for 500 ms
|
||||
bell.idle();
|
||||
delay(500);
|
||||
|
||||
// BellClient supports all methods of the Serial class
|
||||
|
||||
// Arduino String class
|
||||
String aStr = "Arduino String";
|
||||
bell.println(aStr);
|
||||
|
||||
// character array (C-String)
|
||||
bell.println("C-String");
|
||||
|
||||
// string saved in flash
|
||||
bell.println(F("Flash String"));
|
||||
|
||||
// character
|
||||
bell.println('c');
|
||||
|
||||
// byte
|
||||
// formatting DEC/HEX/OCT/BIN is supported for
|
||||
// any integer type (byte/int/long)
|
||||
bell.println(255, HEX);
|
||||
|
||||
// integer number
|
||||
int i = 1000;
|
||||
bell.println(i);
|
||||
|
||||
// floating point number
|
||||
float f = -3.1415;
|
||||
bell.println(f, 3);
|
||||
|
||||
// ITA2-encoded string
|
||||
ITA2String str("HELLO WORLD!");
|
||||
bell.print(str);
|
||||
|
||||
// turn the transmitter off
|
||||
bell.standby();
|
||||
|
||||
Serial.println(F("done!"));
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
RadioLib CC1101 Receive with Address Example
|
||||
|
||||
This example receives packets using CC1101 FSK radio
|
||||
module. Packets can have 1-byte address of the
|
||||
destination node. After setting node address, this node
|
||||
will automatically filter out any packets that do not
|
||||
contain either node address or broadcast addresses.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// CC1101 has the following connections:
|
||||
// CS pin: 10
|
||||
// GDO0 pin: 2
|
||||
// RST pin: unused
|
||||
// GDO2 pin: 3 (optional)
|
||||
CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize CC1101 with default settings
|
||||
Serial.print(F("[CC1101] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set node address
|
||||
// NOTE: Calling this method will automatically enable
|
||||
// address filtering. CC1101 also allows to set
|
||||
// number of broadcast address (0/1/2).
|
||||
// The following sets one broadcast address 0x00.
|
||||
// When setting two broadcast addresses, 0x00 and
|
||||
// 0xFF will be used.
|
||||
Serial.print(F("[CC1101] Setting node address ... "));
|
||||
state = radio.setNodeAddress(0x01, 1);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// address filtering can also be disabled
|
||||
// NOTE: Calling this method will also erase previously
|
||||
// set node address
|
||||
/*
|
||||
Serial.print(F("[CC1101] Disabling address filtering ... "));
|
||||
state == radio.disableAddressFiltering();
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[CC1101] Waiting for incoming transmission ... "));
|
||||
|
||||
// you can receive data as an Arduino String
|
||||
String str;
|
||||
int state = radio.receive(str);
|
||||
|
||||
// you can also receive data as byte array
|
||||
/*
|
||||
byte byteArr[8];
|
||||
int state = radio.receive(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// packet was successfully received
|
||||
Serial.println(F("success!"));
|
||||
|
||||
// print the data of the packet
|
||||
Serial.print(F("[CC1101] Data:\t\t"));
|
||||
Serial.println(str);
|
||||
|
||||
// print RSSI (Received Signal Strength Indicator)
|
||||
// of the last received packet
|
||||
Serial.print(F("[CC1101] RSSI:\t\t"));
|
||||
Serial.print(radio.getRSSI());
|
||||
Serial.println(F(" dBm"));
|
||||
|
||||
// print LQI (Link Quality Indicator)
|
||||
// of the last received packet, lower is better
|
||||
Serial.print(F("[CC1101] LQI:\t\t"));
|
||||
Serial.println(radio.getLQI());
|
||||
|
||||
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
|
||||
// packet was received, but is malformed
|
||||
Serial.println(F("CRC error!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
RadioLib CC1101 Blocking Receive Example
|
||||
|
||||
This example receives packets using CC1101 FSK radio module.
|
||||
To successfully receive data, the following settings have to be the same
|
||||
on both transmitter and receiver:
|
||||
- carrier frequency
|
||||
- bit rate
|
||||
- frequency deviation
|
||||
- sync word
|
||||
|
||||
Using blocking receive is not recommended, as it will lead
|
||||
to significant amount of timeouts, inefficient use of processor
|
||||
time and can some miss packets!
|
||||
Instead, interrupt receive is recommended.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// CC1101 has the following connections:
|
||||
// CS pin: 10
|
||||
// GDO0 pin: 2
|
||||
// RST pin: unused
|
||||
// GDO2 pin: 3 (optional)
|
||||
CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize CC1101 with default settings
|
||||
Serial.print(F("[CC1101] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[CC1101] Waiting for incoming transmission ... "));
|
||||
|
||||
// you can receive data as an Arduino String
|
||||
String str;
|
||||
int state = radio.receive(str);
|
||||
|
||||
// you can also receive data as byte array
|
||||
/*
|
||||
byte byteArr[8];
|
||||
int state = radio.receive(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// packet was successfully received
|
||||
Serial.println(F("success!"));
|
||||
|
||||
// print the data of the packet
|
||||
Serial.print(F("[CC1101] Data:\t\t"));
|
||||
Serial.println(str);
|
||||
|
||||
// print RSSI (Received Signal Strength Indicator)
|
||||
// of the last received packet
|
||||
Serial.print(F("[CC1101] RSSI:\t\t"));
|
||||
Serial.print(radio.getRSSI());
|
||||
Serial.println(F(" dBm"));
|
||||
|
||||
// print LQI (Link Quality Indicator)
|
||||
// of the last received packet, lower is better
|
||||
Serial.print(F("[CC1101] LQI:\t\t"));
|
||||
Serial.println(radio.getLQI());
|
||||
|
||||
} else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
|
||||
// timeout occurred while waiting for a packet
|
||||
Serial.println(F("timeout!"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
|
||||
// packet was received, but is malformed
|
||||
Serial.println(F("CRC error!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
RadioLib CC1101 Receive with Interrupts Example
|
||||
|
||||
This example listens for FSK transmissions and tries to
|
||||
receive them. Once a packet is received, an interrupt is
|
||||
triggered.
|
||||
|
||||
To successfully receive data, the following settings have to be the same
|
||||
on both transmitter and receiver:
|
||||
- carrier frequency
|
||||
- bit rate
|
||||
- frequency deviation
|
||||
- sync word
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// CC1101 has the following connections:
|
||||
// CS pin: 10
|
||||
// GDO0 pin: 2
|
||||
// RST pin: unused
|
||||
// GDO2 pin: 3 (optional)
|
||||
CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// flag to indicate that a packet was received
|
||||
volatile bool receivedFlag = false;
|
||||
|
||||
// this function is called when a complete packet
|
||||
// is received by the module
|
||||
// IMPORTANT: this function MUST be 'void' type
|
||||
// and MUST NOT have any arguments!
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
ICACHE_RAM_ATTR
|
||||
#endif
|
||||
void setFlag(void) {
|
||||
// we got a packet, set the flag
|
||||
receivedFlag = true;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize CC1101 with default settings
|
||||
Serial.print(F("[CC1101] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set the function that will be called
|
||||
// when new packet is received
|
||||
radio.setPacketReceivedAction(setFlag);
|
||||
|
||||
// start listening for packets
|
||||
Serial.print(F("[CC1101] Starting to listen ... "));
|
||||
state = radio.startReceive();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// if needed, 'listen' mode can be disabled by calling
|
||||
// any of the following methods:
|
||||
//
|
||||
// radio.standby()
|
||||
// radio.sleep()
|
||||
// radio.transmit();
|
||||
// radio.receive();
|
||||
// radio.readData();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// check if the flag is set
|
||||
if(receivedFlag) {
|
||||
// reset flag
|
||||
receivedFlag = false;
|
||||
|
||||
// you can read received data as an Arduino String
|
||||
String str;
|
||||
int state = radio.readData(str);
|
||||
|
||||
// you can also read received data as byte array
|
||||
/*
|
||||
byte byteArr[8];
|
||||
int numBytes = radio.getPacketLength();
|
||||
int state = radio.readData(byteArr, numBytes);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// packet was successfully received
|
||||
Serial.println(F("[CC1101] Received packet!"));
|
||||
|
||||
// print data of the packet
|
||||
Serial.print(F("[CC1101] Data:\t\t"));
|
||||
Serial.println(str);
|
||||
|
||||
// print RSSI (Received Signal Strength Indicator)
|
||||
// of the last received packet
|
||||
Serial.print(F("[CC1101] RSSI:\t\t"));
|
||||
Serial.print(radio.getRSSI());
|
||||
Serial.println(F(" dBm"));
|
||||
|
||||
// print LQI (Link Quality Indicator)
|
||||
// of the last received packet, lower is better
|
||||
Serial.print(F("[CC1101] LQI:\t\t"));
|
||||
Serial.println(radio.getLQI());
|
||||
|
||||
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
|
||||
// packet was received, but is malformed
|
||||
Serial.println(F("CRC error!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
// put module back to listen mode
|
||||
radio.startReceive();
|
||||
}
|
||||
|
||||
}
|
||||
125
RadioLib/examples/CC1101/CC1101_Settings/CC1101_Settings.ino
Normal file
125
RadioLib/examples/CC1101/CC1101_Settings/CC1101_Settings.ino
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
RadioLib CC1101 Settings Example
|
||||
|
||||
This example shows how to change all the properties of RF69 radio.
|
||||
RadioLib currently supports the following settings:
|
||||
- pins (SPI slave select, digital IO 0, digital IO 1)
|
||||
- carrier frequency
|
||||
- bit rate
|
||||
- receiver bandwidth
|
||||
- allowed frequency deviation
|
||||
- output power during transmission
|
||||
- sync word
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// CC1101 has the following connections:
|
||||
// CS pin: 10
|
||||
// GDO0 pin: 2
|
||||
// RST pin: unused
|
||||
// GDO2 pin: 3 (optional)
|
||||
CC1101 radio1 = new Module(10, 2, RADIOLIB_NC, 3);
|
||||
|
||||
// second CC1101 has different connections:
|
||||
// CS pin: 9
|
||||
// GDO0 pin: 4
|
||||
// RST pin: unused
|
||||
// GDO2 pin: 5 (optional)
|
||||
CC1101 radio2 = new Module(9, 4, RADIOLIB_NC, 5);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio3 = new RadioModule();
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize CC1101 with default settings
|
||||
Serial.print(F("[CC1101] Initializing ... "));
|
||||
int state = radio1.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize CC1101 with non-default settings
|
||||
Serial.print(F("[CC1101] Initializing ... "));
|
||||
// carrier frequency: 434.0 MHz
|
||||
// bit rate: 32.0 kbps
|
||||
// frequency deviation: 60.0 kHz
|
||||
// Rx bandwidth: 250.0 kHz
|
||||
// output power: 7 dBm
|
||||
// preamble length: 32 bits
|
||||
state = radio2.begin(434.0, 32.0, 60.0, 250.0, 7, 32);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// you can also change the settings at runtime
|
||||
// and check if the configuration was changed successfully
|
||||
|
||||
// set carrier frequency to 433.5 MHz
|
||||
if (radio1.setFrequency(433.5) == RADIOLIB_ERR_INVALID_FREQUENCY) {
|
||||
Serial.println(F("[CC1101] Selected frequency is invalid for this module!"));
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set bit rate to 100.0 kbps
|
||||
state = radio1.setBitRate(100.0);
|
||||
if (state == RADIOLIB_ERR_INVALID_BIT_RATE) {
|
||||
Serial.println(F("[CC1101] Selected bit rate is invalid for this module!"));
|
||||
while (true) { delay(10); }
|
||||
} else if (state == RADIOLIB_ERR_INVALID_BIT_RATE_BW_RATIO) {
|
||||
Serial.println(F("[CC1101] Selected bit rate to bandwidth ratio is invalid!"));
|
||||
Serial.println(F("[CC1101] Increase receiver bandwidth to set this bit rate."));
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set receiver bandwidth to 250.0 kHz
|
||||
if (radio1.setRxBandwidth(250.0) == RADIOLIB_ERR_INVALID_RX_BANDWIDTH) {
|
||||
Serial.println(F("[CC1101] Selected receiver bandwidth is invalid for this module!"));
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set allowed frequency deviation to 10.0 kHz
|
||||
if (radio1.setFrequencyDeviation(10.0) == RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION) {
|
||||
Serial.println(F("[CC1101] Selected frequency deviation is invalid for this module!"));
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set output power to 5 dBm
|
||||
if (radio1.setOutputPower(5) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) {
|
||||
Serial.println(F("[CC1101] Selected output power is invalid for this module!"));
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// 2 bytes can be set as sync word
|
||||
if (radio1.setSyncWord(0x01, 0x23) == RADIOLIB_ERR_INVALID_SYNC_WORD) {
|
||||
Serial.println(F("[CC1101] Selected sync word is invalid for this module!"));
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// nothing here
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
RadioLib CC1101 Transmit to Address Example
|
||||
|
||||
This example transmits packets using CC1101 FSK radio
|
||||
module. Packets can have 1-byte address of the
|
||||
destination node. After setting node address, this node
|
||||
will automatically filter out any packets that do not
|
||||
contain either node address or broadcast addresses.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// CC1101 has the following connections:
|
||||
// CS pin: 10
|
||||
// GDO0 pin: 2
|
||||
// RST pin: unused
|
||||
// GDO2 pin: 3 (optional)
|
||||
CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize CC1101 with default settings
|
||||
Serial.print(F("[CC1101] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set node address
|
||||
// NOTE: Calling this method will automatically enable
|
||||
// address filtering. CC1101 also allows to set
|
||||
// number of broadcast address (0/1/2).
|
||||
// The following sets one broadcast address 0x00.
|
||||
// When setting two broadcast addresses, 0x00 and
|
||||
// 0xFF will be used.
|
||||
Serial.print(F("[CC1101] Setting node address ... "));
|
||||
state = radio.setNodeAddress(0x01, 1);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// address filtering can also be disabled
|
||||
// NOTE: Calling this method will also erase previously
|
||||
// set node address
|
||||
/*
|
||||
Serial.print(F("[CC1101] Disabling address filtering ... "));
|
||||
state == radio.disableAddressFiltering();
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[CC1101] Transmitting packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to 64 characters long
|
||||
int state = radio.transmit("Hello World!");
|
||||
|
||||
// you can also transmit byte array up to 64 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
||||
int state = radio.transmit(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// the packet was successfully transmitted
|
||||
Serial.println(F("success!"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
|
||||
// the supplied packet was longer than 255 bytes
|
||||
Serial.println(F("too long!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
RadioLib CC1101 Blocking Transmit Example
|
||||
|
||||
This example transmits packets using CC1101 FSK radio module.
|
||||
Each packet contains up to 64 bytes of data, in the form of:
|
||||
- Arduino String
|
||||
- null-terminated char array (C-string)
|
||||
- arbitrary binary data (byte array)
|
||||
|
||||
Using blocking transmit is not recommended, as it will lead
|
||||
to inefficient use of processor time!
|
||||
Instead, interrupt transmit is recommended.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// CC1101 has the following connections:
|
||||
// CS pin: 10
|
||||
// GDO0 pin: 2
|
||||
// RST pin: unused
|
||||
// GDO2 pin: 3
|
||||
CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize CC1101 with default settings
|
||||
Serial.print(F("[CC1101] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
// counter to keep track of transmitted packets
|
||||
int count = 0;
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[CC1101] Transmitting packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to 64 characters long
|
||||
String str = "Hello World! #" + String(count++);
|
||||
int state = radio.transmit(str);
|
||||
|
||||
// you can also transmit byte array up to 64 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
||||
int state = radio.transmit(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// the packet was successfully transmitted
|
||||
Serial.println(F("success!"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
|
||||
// the supplied packet was longer than 64 bytes
|
||||
Serial.println(F("too long!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
RadioLib CC1101 Transmit with Interrupts Example
|
||||
|
||||
This example transmits packets using CC1101 FSK radio module.
|
||||
Once a packet is transmitted, an interrupt is triggered.
|
||||
Each packet contains up to 64 bytes of data, in the form of:
|
||||
- Arduino String
|
||||
- null-terminated char array (C-string)
|
||||
- arbitrary binary data (byte array)
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// CC1101 has the following connections:
|
||||
// CS pin: 10
|
||||
// GDO0 pin: 2
|
||||
// RST pin: unused
|
||||
// GDO2 pin: 3
|
||||
CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// save transmission state between loops
|
||||
int transmissionState = RADIOLIB_ERR_NONE;
|
||||
|
||||
// flag to indicate that a packet was sent
|
||||
volatile bool transmittedFlag = false;
|
||||
|
||||
// this function is called when a complete packet
|
||||
// is transmitted by the module
|
||||
// IMPORTANT: this function MUST be 'void' type
|
||||
// and MUST NOT have any arguments!
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
ICACHE_RAM_ATTR
|
||||
#endif
|
||||
void setFlag(void) {
|
||||
// we sent a packet, set the flag
|
||||
transmittedFlag = true;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize CC1101 with default settings
|
||||
Serial.print(F("[CC1101] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set the function that will be called
|
||||
// when packet transmission is finished
|
||||
radio.setPacketSentAction(setFlag);
|
||||
|
||||
// start transmitting the first packet
|
||||
Serial.print(F("[CC1101] Sending first packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 64 characters long
|
||||
transmissionState = radio.startTransmit("Hello World!");
|
||||
|
||||
// you can also transmit byte array up to 64 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x56,
|
||||
0x78, 0xAB, 0xCD, 0xEF};
|
||||
state = radio.startTransmit(byteArr, 8);
|
||||
*/
|
||||
}
|
||||
|
||||
// counter to keep track of transmitted packets
|
||||
int count = 0;
|
||||
|
||||
void loop() {
|
||||
// check if the previous transmission finished
|
||||
if(transmittedFlag) {
|
||||
// reset flag
|
||||
transmittedFlag = false;
|
||||
|
||||
if (transmissionState == RADIOLIB_ERR_NONE) {
|
||||
// packet was successfully sent
|
||||
Serial.println(F("transmission finished!"));
|
||||
|
||||
// NOTE: when using interrupt-driven transmit method,
|
||||
// it is not possible to automatically measure
|
||||
// transmission data rate using getDataRate()
|
||||
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(transmissionState);
|
||||
|
||||
}
|
||||
|
||||
// clean up after transmission is finished
|
||||
// this will ensure transmitter is disabled,
|
||||
// RF switch is powered down etc.
|
||||
radio.finishTransmit();
|
||||
|
||||
// wait a second before transmitting again
|
||||
delay(1000);
|
||||
|
||||
// send another one
|
||||
Serial.print(F("[CC1101] Sending another packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 64 characters long
|
||||
String str = "Hello World! #" + String(count++);
|
||||
transmissionState = radio.startTransmit(str);
|
||||
|
||||
// you can also transmit byte array up to 64 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
|
||||
0x89, 0xAB, 0xCD, 0xEF};
|
||||
int state = radio.startTransmit(byteArr, 8);
|
||||
*/
|
||||
}
|
||||
}
|
||||
146
RadioLib/examples/FSK4/FSK4_Transmit/FSK4_Transmit.ino
Normal file
146
RadioLib/examples/FSK4/FSK4_Transmit/FSK4_Transmit.ino
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
RadioLib FSK4 Transmit Example
|
||||
|
||||
This example sends an example FSK-4 'Horus Binary' message
|
||||
using SX1278's FSK modem.
|
||||
|
||||
This signal can be demodulated using a SSB demodulator (SDR or otherwise),
|
||||
and horusdemodlib: https://github.com/projecthorus/horusdemodlib/wiki
|
||||
|
||||
Other modules that can be used for FSK4:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- SX126x
|
||||
- nRF24
|
||||
- Si443x/RFM2x
|
||||
- SX128x
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create FSK4 client instance using the FSK module
|
||||
FSK4Client fsk4(&radio);
|
||||
|
||||
// An encoded Horus Binary telemetry packet.
|
||||
// Refer here for packet format information:
|
||||
// https://github.com/projecthorus/horusdemodlib/wiki/2---Modem-Details#horus-binary-v1-mode-4-fsk
|
||||
// After demodulation, deinterleaving, and descrambling, this results in a packet:
|
||||
// 00000001172D0000000000000000D20463010AFF2780
|
||||
// This decodes to the Habitat-compatible telemetry string:
|
||||
// $$4FSKTEST,0,01:23:45,0.00000,0.00000,1234,99,1,10,5.00*ABCD
|
||||
int horusPacketLen = 45;
|
||||
byte horusPacket[] = {
|
||||
0x45, 0x24, 0x24, 0x48, 0x2F, 0x12, 0x16, 0x08, 0x15, 0xC1,
|
||||
0x49, 0xB2, 0x06, 0xFC, 0x92, 0xEB, 0x93, 0xD7, 0xEE, 0x5D,
|
||||
0x35, 0xA0, 0x91, 0xDA, 0x8D, 0x5F, 0x85, 0x6B, 0x63, 0x03,
|
||||
0x6B, 0x60, 0xEA, 0xFE, 0x55, 0x9D, 0xF1, 0xAB, 0xE5, 0x5E,
|
||||
0xDB, 0x7C, 0xDB, 0x21, 0x5A, 0x19
|
||||
};
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
|
||||
// when using one of the non-LoRa modules for FSK4
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize FSK4 client
|
||||
// NOTE: FSK4 frequency shift will be rounded
|
||||
// to the nearest multiple of frequency step size.
|
||||
// The exact value depends on the module:
|
||||
// SX127x/RFM9x - 61 Hz
|
||||
// RF69 - 61 Hz
|
||||
// CC1101 - 397 Hz
|
||||
// SX126x - 1 Hz
|
||||
// nRF24 - 1000000 Hz
|
||||
// Si443x/RFM2x - 156 Hz
|
||||
// SX128x - 198 Hz
|
||||
Serial.print(F("[FSK4] Initializing ... "));
|
||||
// low ("space") frequency: 434.0 MHz
|
||||
// frequency shift: 270 Hz
|
||||
// baud rate: 100 baud
|
||||
state = fsk4.begin(434.0, 270, 100);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// sometimes, it may be needed to set some manual corrections
|
||||
// this can be done for tone frequencies,
|
||||
// as well as tone lengths
|
||||
/*
|
||||
// set frequency shift offsets to -120, 60, 0 and 60 Hz and decrease tone length to 95%
|
||||
int offsets[4] = { -120, -60, 0, 60 };
|
||||
Serial.print(F("[FSK4] Setting corrections ... "));
|
||||
state = fsk4.setCorrection(offsets, 0.95);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[FSK4] Sending FSK4 data packet ... "));
|
||||
|
||||
// send out idle condition for 1000 ms
|
||||
fsk4.idle();
|
||||
delay(1000);
|
||||
|
||||
// FSK4Client supports binary write methods
|
||||
|
||||
// send some bytes as a preamble
|
||||
for(int i = 0; i < 8; i++) {
|
||||
fsk4.write(0x1B);
|
||||
}
|
||||
|
||||
// now send the encoded packet
|
||||
fsk4.write(horusPacket, horusPacketLen);
|
||||
|
||||
Serial.println(F("done!"));
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
||||
147
RadioLib/examples/FSK4/FSK4_Transmit_AFSK/FSK4_Transmit_AFSK.ino
Normal file
147
RadioLib/examples/FSK4/FSK4_Transmit_AFSK/FSK4_Transmit_AFSK.ino
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
RadioLib FSK4 Transmit AFSK Example
|
||||
|
||||
This example sends an example FSK-4 'Horus Binary' message
|
||||
using SX1278's FSK modem. The data is modulated as AFSK.
|
||||
|
||||
This signal can be demodulated using an FM demodulator (SDR or otherwise),
|
||||
and horusdemodlib: https://github.com/projecthorus/horusdemodlib/wiki
|
||||
|
||||
Other modules that can be used for FSK4:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- Si443x/RFM2x
|
||||
- SX126x/LLCC68
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create AFSK client instance using the FSK module
|
||||
// this requires connection to the module direct
|
||||
// input pin, here connected to Arduino pin 5
|
||||
// SX127x/RFM9x: DIO2
|
||||
// RF69: DIO2
|
||||
// SX1231: DIO2
|
||||
// CC1101: GDO2
|
||||
// Si443x/RFM2x: GPIO
|
||||
// SX126x/LLCC68: DIO2
|
||||
AFSKClient audio(&radio, 5);
|
||||
|
||||
// create FSK4 client instance using the AFSK instance
|
||||
FSK4Client fsk4(&audio);
|
||||
|
||||
// An encoded Horus Binary telemetry packet.
|
||||
// Refer here for packet format information:
|
||||
// https://github.com/projecthorus/horusdemodlib/wiki/2---Modem-Details#horus-binary-v1-mode-4-fsk
|
||||
// After demodulation, deinterleaving, and descrambling, this results in a packet:
|
||||
// 00000001172D0000000000000000D20463010AFF2780
|
||||
// This decodes to the Habitat-compatible telemetry string:
|
||||
// $$4FSKTEST,0,01:23:45,0.00000,0.00000,1234,99,1,10,5.00*ABCD
|
||||
int horusPacketLen = 45;
|
||||
byte horusPacket[] = {
|
||||
0x45, 0x24, 0x24, 0x48, 0x2F, 0x12, 0x16, 0x08, 0x15, 0xC1,
|
||||
0x49, 0xB2, 0x06, 0xFC, 0x92, 0xEB, 0x93, 0xD7, 0xEE, 0x5D,
|
||||
0x35, 0xA0, 0x91, 0xDA, 0x8D, 0x5F, 0x85, 0x6B, 0x63, 0x03,
|
||||
0x6B, 0x60, 0xEA, 0xFE, 0x55, 0x9D, 0xF1, 0xAB, 0xE5, 0x5E,
|
||||
0xDB, 0x7C, 0xDB, 0x21, 0x5A, 0x19
|
||||
};
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
|
||||
// when using one of the non-LoRa modules for RTTY
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize FSK4 client
|
||||
// NOTE: Unlike FSK FSK4, AFSK requires no rounding of
|
||||
// the frequency shift.
|
||||
Serial.print(F("[FSK4] Initializing ... "));
|
||||
// lowest ("space") frequency: 400 Hz
|
||||
// frequency shift: 270 Hz
|
||||
// baud rate: 100 baud
|
||||
state = fsk4.begin(400, 270, 100);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// sometimes, it may be needed to set some manual corrections
|
||||
// this can be done for tone frequencies,
|
||||
// as well as tone lengths
|
||||
/*
|
||||
// set audio tone offsets to -10, 20, 0 and 5 Hz and decrease tone length to 95%
|
||||
int offsets[4] = { -10, 20, 0, 5 };
|
||||
Serial.print(F("[FSK4] Setting corrections ... "));
|
||||
state = fsk4.setCorrection(offsets, 0.95);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[FSK4] Sending FSK4 data packet ... "));
|
||||
|
||||
// send out idle condition for 500 ms
|
||||
fsk4.idle();
|
||||
delay(1000);
|
||||
|
||||
// FSK4Client supports binary write methods
|
||||
|
||||
// send some bytes as a preamble
|
||||
for(int i = 0; i < 8; i++) {
|
||||
fsk4.write(0x1B);
|
||||
}
|
||||
|
||||
// now send the encoded packet
|
||||
fsk4.write(horusPacket, horusPacketLen);
|
||||
|
||||
Serial.println(F("done!"));
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
RadioLib Hellschreiber Transmit Example
|
||||
|
||||
This example sends Hellschreiber message using
|
||||
SX1278's FSK modem.
|
||||
|
||||
Other modules that can be used for Hellschreiber:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- SX126x
|
||||
- nRF24
|
||||
- Si443x/RFM2x
|
||||
- SX128x
|
||||
- LR11x0
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create Hellschreiber client instance using the FSK module
|
||||
HellClient hell(&radio);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
|
||||
// when using one of the non-LoRa modules for Morse code
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize Hellschreiber client
|
||||
Serial.print(F("[Hell] Initializing ... "));
|
||||
// base frequency: 434.0 MHz
|
||||
// speed: 122.5 Baud ("Feld Hell")
|
||||
state = hell.begin(434.0);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[Hell] Sending Hellschreiber data ... "));
|
||||
|
||||
// HellClient supports all methods of the Serial class
|
||||
// NOTE: Lower case letter will be capitalized.
|
||||
|
||||
// Arduino String class
|
||||
String aStr = "Arduino String";
|
||||
hell.print(aStr);
|
||||
|
||||
// character array (C-String)
|
||||
hell.print("C-String");
|
||||
|
||||
// string saved in flash
|
||||
hell.print(F("Flash String"));
|
||||
|
||||
// character
|
||||
hell.print('c');
|
||||
|
||||
// byte
|
||||
// formatting DEC/HEX/OCT/BIN is supported for
|
||||
// any integer type (byte/int/long)
|
||||
hell.print(255, HEX);
|
||||
|
||||
// integer number
|
||||
int i = 1000;
|
||||
hell.print(i);
|
||||
|
||||
// floating point number
|
||||
// NOTE: println() has no effect on the transmission,
|
||||
// and is only kept for compatibility reasons.
|
||||
float f = -3.1415;
|
||||
hell.println(f, 3);
|
||||
|
||||
// custom glyph - must be a 7 byte array of rows 7 pixels long
|
||||
uint8_t customGlyph[] = { 0b0000000, 0b0010100, 0b0010100, 0b0000000, 0b0100010, 0b0011100, 0b0000000 };
|
||||
hell.printGlyph(customGlyph);
|
||||
|
||||
Serial.println(F("done!"));
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
RadioLib Hellschreiber Transmit AFSK Example
|
||||
|
||||
This example sends Hellschreiber message using
|
||||
SX1278's FSK modem. The data is modulated
|
||||
as AFSK.
|
||||
|
||||
Other modules that can be used for Hellschreiber
|
||||
with AFSK modulation:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- Si443x/RFM2x
|
||||
- SX126x/LLCC68
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create AFSK client instance using the FSK module
|
||||
// this requires connection to the module direct
|
||||
// input pin, here connected to Arduino pin 5
|
||||
// SX127x/RFM9x: DIO2
|
||||
// RF69: DIO2
|
||||
// SX1231: DIO2
|
||||
// CC1101: GDO2
|
||||
// Si443x/RFM2x: GPIO
|
||||
// SX126x/LLCC68: DIO2
|
||||
AFSKClient audio(&radio, 5);
|
||||
|
||||
// create Hellschreiber client instance using the AFSK instance
|
||||
HellClient hell(&audio);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
|
||||
// when using one of the non-LoRa modules for Morse code
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize Hellschreiber client
|
||||
Serial.print(F("[Hell] Initializing ... "));
|
||||
// AFSK tone frequency: 400 Hz
|
||||
// speed: 122.5 Baud ("Feld Hell")
|
||||
state = hell.begin(400);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[Hell] Sending Hellschreiber data ... "));
|
||||
|
||||
// HellClient supports all methods of the Serial class
|
||||
// NOTE: Lower case letter will be capitalized.
|
||||
|
||||
// Arduino String class
|
||||
String aStr = "Arduino String";
|
||||
hell.print(aStr);
|
||||
|
||||
// character array (C-String)
|
||||
hell.print("C-String");
|
||||
|
||||
// string saved in flash
|
||||
hell.print(F("Flash String"));
|
||||
|
||||
// in AFSK mode, it is possible to invert the text colors
|
||||
// use white text on black background
|
||||
hell.setInversion(true);
|
||||
hell.print("Inverted String");
|
||||
hell.setInversion(false);
|
||||
|
||||
// character
|
||||
hell.print('c');
|
||||
|
||||
// byte
|
||||
// formatting DEC/HEX/OCT/BIN is supported for
|
||||
// any integer type (byte/int/long)
|
||||
hell.print(255, HEX);
|
||||
|
||||
// integer number
|
||||
int i = 1000;
|
||||
hell.print(i);
|
||||
|
||||
// floating point number
|
||||
// NOTE: println() has no effect on the transmission,
|
||||
// and is only kept for compatibility reasons.
|
||||
float f = -3.1415;
|
||||
hell.println(f, 3);
|
||||
|
||||
// custom glyph - must be a 7 byte array of rows 7 pixels long
|
||||
uint8_t customGlyph[] = { 0b0000000, 0b0010100, 0b0010100, 0b0000000, 0b0100010, 0b0011100, 0b0000000 };
|
||||
hell.printGlyph(customGlyph);
|
||||
|
||||
Serial.println(F("done!"));
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
RadioLib LR11x0 Blocking Channel Activity Detection Example
|
||||
|
||||
This example uses LR1110 to scan the current LoRa
|
||||
channel and detect ongoing LoRa transmissions.
|
||||
Unlike SX127x CAD, LR11x0 can detect any part
|
||||
of LoRa transmission, not just the preamble.
|
||||
|
||||
Other modules from LR11x0 family can also be used.
|
||||
|
||||
This example assumes Seeed Studio Wio WM1110 is used.
|
||||
For other LR11x0 modules, some configuration such as
|
||||
RF switch control may have to be adjusted.
|
||||
|
||||
Using blocking CAD is not recommended, as it will lead
|
||||
to significant amount of timeouts, inefficient use of processor
|
||||
time and can some miss packets!
|
||||
Instead, interrupt CAD is recommended.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---lora-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// IRQ pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// set RF switch configuration for Wio WM1110
|
||||
// Wio WM1110 uses DIO5 and DIO6 for RF switching
|
||||
// NOTE: other boards may be different!
|
||||
static const uint32_t rfswitch_dio_pins[] = {
|
||||
RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6,
|
||||
RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC
|
||||
};
|
||||
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
// mode DIO5 DIO6
|
||||
{ LR11x0::MODE_STBY, { LOW, LOW } },
|
||||
{ LR11x0::MODE_RX, { HIGH, LOW } },
|
||||
{ LR11x0::MODE_TX, { HIGH, HIGH } },
|
||||
{ LR11x0::MODE_TX_HP, { LOW, HIGH } },
|
||||
{ LR11x0::MODE_TX_HF, { LOW, LOW } },
|
||||
{ LR11x0::MODE_GNSS, { LOW, LOW } },
|
||||
{ LR11x0::MODE_WIFI, { LOW, LOW } },
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set RF switch control configuration
|
||||
radio.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[LR1110] Scanning channel for LoRa transmission ... "));
|
||||
|
||||
// start scanning current channel
|
||||
int state = radio.scanChannel();
|
||||
|
||||
if (state == RADIOLIB_LORA_DETECTED) {
|
||||
// LoRa preamble was detected
|
||||
Serial.println(F("detected!"));
|
||||
|
||||
} else if (state == RADIOLIB_CHANNEL_FREE) {
|
||||
// no preamble was detected, channel is free
|
||||
Serial.println(F("channel is free!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
// wait 100 ms before new scan
|
||||
delay(100);
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
RadioLib LR11x0 Channel Activity Detection Example
|
||||
|
||||
This example uses LR1110 to scan the current LoRa
|
||||
channel and detect ongoing LoRa transmissions.
|
||||
Unlike SX127x CAD, LR11x0 can detect any part
|
||||
of LoRa transmission, not just the preamble.
|
||||
|
||||
Other modules from LR11x0 family can also be used.
|
||||
|
||||
This example assumes Seeed Studio Wio WM1110 is used.
|
||||
For other LR11x0 modules, some configuration such as
|
||||
RF switch control may have to be adjusted.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---lora-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// IRQ pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// set RF switch configuration for Wio WM1110
|
||||
// Wio WM1110 uses DIO5 and DIO6 for RF switching
|
||||
// NOTE: other boards may be different!
|
||||
static const uint32_t rfswitch_dio_pins[] = {
|
||||
RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6,
|
||||
RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC
|
||||
};
|
||||
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
// mode DIO5 DIO6
|
||||
{ LR11x0::MODE_STBY, { LOW, LOW } },
|
||||
{ LR11x0::MODE_RX, { HIGH, LOW } },
|
||||
{ LR11x0::MODE_TX, { HIGH, HIGH } },
|
||||
{ LR11x0::MODE_TX_HP, { LOW, HIGH } },
|
||||
{ LR11x0::MODE_TX_HF, { LOW, LOW } },
|
||||
{ LR11x0::MODE_GNSS, { LOW, LOW } },
|
||||
{ LR11x0::MODE_WIFI, { LOW, LOW } },
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
|
||||
// flag to indicate that a packet was detected or CAD timed out
|
||||
volatile bool scanFlag = false;
|
||||
|
||||
// this function is called when a complete packet
|
||||
// is received by the module
|
||||
// IMPORTANT: this function MUST be 'void' type
|
||||
// and MUST NOT have any arguments!
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
ICACHE_RAM_ATTR
|
||||
#endif
|
||||
void setFlag(void) {
|
||||
// something happened, set the flag
|
||||
scanFlag = true;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set RF switch control configuration
|
||||
radio.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table);
|
||||
|
||||
// set the function that will be called
|
||||
// when LoRa packet or timeout is detected
|
||||
radio.setIrqAction(setFlag);
|
||||
|
||||
// start scanning the channel
|
||||
Serial.print(F("[LR1110] Starting scan for LoRa preamble ... "));
|
||||
state = radio.startChannelScan();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// check if the flag is set
|
||||
if(scanFlag) {
|
||||
// reset flag
|
||||
scanFlag = false;
|
||||
|
||||
// check CAD result
|
||||
int state = radio.getChannelScanResult();
|
||||
|
||||
if (state == RADIOLIB_LORA_DETECTED) {
|
||||
// LoRa packet was detected
|
||||
Serial.println(F("[LR1110] Packet detected!"));
|
||||
|
||||
} else if (state == RADIOLIB_CHANNEL_FREE) {
|
||||
// channel is free
|
||||
Serial.println(F("[LR1110] Channel is free!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("[LR1110] Failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
// start scanning the channel again
|
||||
Serial.print(F("[LR1110] Starting scan for LoRa preamble ... "));
|
||||
state = radio.startChannelScan();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
RadioLib LR11x0 Firmware Update Example
|
||||
|
||||
This example updates the internal LR1110 firmware.
|
||||
Newer versions of the firmware introduce fixes
|
||||
and possibly even new features, so it is recommended
|
||||
to use the latest available firmware version
|
||||
when possible.
|
||||
|
||||
Other modules from LR11x0 family can also be used.
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// select the firmware image you want to upload
|
||||
// WARNING: Make sure you select the correct firmware
|
||||
// for your device! Uploading incorrect firmware
|
||||
// (e.g. LR1110 firmware to LR1120 device)
|
||||
// may damage your hardware!
|
||||
//#define RADIOLIB_LR1110_FIRMWARE_0303
|
||||
//#define RADIOLIB_LR1110_FIRMWARE_0304
|
||||
//#define RADIOLIB_LR1110_FIRMWARE_0305
|
||||
//#define RADIOLIB_LR1110_FIRMWARE_0306
|
||||
//#define RADIOLIB_LR1110_FIRMWARE_0307
|
||||
#define RADIOLIB_LR1110_FIRMWARE_0401
|
||||
//#define RADIOLIB_LR1120_FIRMWARE_0101
|
||||
//#define RADIOLIB_LR1120_FIRMWARE_0102
|
||||
//#define RADIOLIB_LR1120_FIRMWARE_0201
|
||||
//#define RADIOLIB_LR1121_FIRMWARE_0102
|
||||
//#define RADIOLIB_LR1121_FIRMWARE_0103
|
||||
|
||||
// enable this macro if you want to store the image in host
|
||||
// MCU RAM instead of Flash.
|
||||
// NOTE: the firmware images are very large, up to 240 kB!
|
||||
//#define RADIOLIB_LR1110_FIRMWARE_IN_RAM
|
||||
|
||||
// include the firmware image
|
||||
#include <modules/LR11x0/LR11x0_firmware.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO1 pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// print the firmware versions before the update
|
||||
printVersions();
|
||||
|
||||
// prompt the user
|
||||
Serial.println(F("[LR1110] Send any character to start the update"));
|
||||
while(!Serial.available()) { delay(1); }
|
||||
|
||||
// upload update into LR11x0 non-volatile memory
|
||||
Serial.print(F("[LR1110] Updating firmware, this may take several seconds ... "));
|
||||
state = radio.updateFirmware(lr11xx_firmware_image, RADIOLIB_LR11X0_FIRMWARE_IMAGE_SIZE);
|
||||
/*
|
||||
use the following if you enabled RADIOLIB_LR1110_FIRMWARE_IN_RAM
|
||||
state = radio.updateFirmware(lr11xx_firmware_image, RADIOLIB_LR11X0_FIRMWARE_IMAGE_SIZE, false);
|
||||
*/
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// print the firmware versions after the update
|
||||
printVersions();
|
||||
|
||||
}
|
||||
|
||||
void printVersions() {
|
||||
LR11x0VersionInfo_t version;
|
||||
Serial.print(F("[LR1110] Reading firmware versions ... "));
|
||||
int16_t state = radio.getVersionInfo(&version);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
||||
Serial.print(F("[LR1110] Device: "));
|
||||
Serial.println(version.device);
|
||||
|
||||
Serial.print(F("[LR1110] Base firmware: "));
|
||||
Serial.print(version.fwMajor);
|
||||
Serial.print('.');
|
||||
Serial.println(version.fwMinor);
|
||||
|
||||
Serial.print(F("[LR1110] WiFi firmware: "));
|
||||
Serial.print(version.fwMajorWiFi);
|
||||
Serial.print('.');
|
||||
Serial.println(version.fwMinorWiFi);
|
||||
|
||||
Serial.print(F("[LR1110] GNSS firmware: "));
|
||||
Serial.print(version.fwGNSS);
|
||||
Serial.print('.');
|
||||
Serial.println(version.almanacGNSS);
|
||||
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
}
|
||||
157
RadioLib/examples/LR11x0/LR11x0_GFSK_Modem/LR11x0_GFSK_Modem.ino
Normal file
157
RadioLib/examples/LR11x0/LR11x0_GFSK_Modem/LR11x0_GFSK_Modem.ino
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
RadioLib LR11x0 GFSK Modem Example
|
||||
|
||||
This example shows how to use GFSK modem in LR11x0 chips.
|
||||
|
||||
NOTE: The sketch below is just a guide on how to use
|
||||
GFSK modem, so this code should not be run directly!
|
||||
Instead, modify the other examples to use GFSK
|
||||
modem and use the appropriate configuration
|
||||
methods.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---gfsk-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// IRQ pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.beginGFSK();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// if needed, you can switch between any of the modems
|
||||
//
|
||||
// radio.begin() start LoRa modem (and disable GFSK)
|
||||
// radio.beginGFSK() start GFSK modem (and disable LoRa)
|
||||
|
||||
// the following settings can also
|
||||
// be modified at run-time
|
||||
state = radio.setFrequency(433.5);
|
||||
state = radio.setBitRate(100.0);
|
||||
state = radio.setFrequencyDeviation(10.0);
|
||||
state = radio.setRxBandwidth(250.0);
|
||||
state = radio.setOutputPower(10.0);
|
||||
state = radio.setDataShaping(RADIOLIB_SHAPING_1_0);
|
||||
uint8_t syncWord[] = {0x01, 0x23, 0x45, 0x67,
|
||||
0x89, 0xAB, 0xCD, 0xEF};
|
||||
state = radio.setSyncWord(syncWord, 8);
|
||||
if (state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("Unable to set configuration, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// GFSK modem on LR11x0 can handle the sync word setting in bits, not just
|
||||
// whole bytes. The value used is left-justified.
|
||||
// This makes same result as radio.setSyncWord(syncWord, 8):
|
||||
state = radio.setSyncBits(syncWord, 64);
|
||||
// This will use 0x012 as sync word (12 bits only):
|
||||
state = radio.setSyncBits(syncWord, 12);
|
||||
|
||||
// GFSK modem allows advanced CRC configuration
|
||||
// Default is CCIT CRC16 (2 bytes, initial 0x1D0F, polynomial 0x1021, inverted)
|
||||
// Set CRC to IBM CRC (2 bytes, initial 0xFFFF, polynomial 0x8005, non-inverted)
|
||||
state = radio.setCRC(2, 0xFFFF, 0x8005, false);
|
||||
// set CRC length to 0 to disable CRC
|
||||
|
||||
#warning "This sketch is just an API guide! Read the note at line 6."
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// GFSK modem can use the same transmit/receive methods
|
||||
// as the LoRa modem, even their interrupt-driven versions
|
||||
|
||||
// transmit GFSK packet
|
||||
int state = radio.transmit("Hello World!");
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
|
||||
0x89, 0xAB, 0xCD, 0xEF};
|
||||
int state = radio.transmit(byteArr, 8);
|
||||
*/
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("[LR1110] Packet transmitted successfully!"));
|
||||
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
|
||||
Serial.println(F("[LR1110] Packet too long!"));
|
||||
} else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
|
||||
Serial.println(F("[LR1110] Timed out while transmitting!"));
|
||||
} else {
|
||||
Serial.println(F("[LR1110] Failed to transmit packet, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
// receive GFSK packet
|
||||
String str;
|
||||
state = radio.receive(str);
|
||||
/*
|
||||
byte byteArr[8];
|
||||
int state = radio.receive(byteArr, 8);
|
||||
*/
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("[LR1110] Received packet!"));
|
||||
Serial.print(F("[LR1110] Data:\t"));
|
||||
Serial.println(str);
|
||||
} else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
|
||||
Serial.println(F("[LR1110] Timed out while waiting for packet!"));
|
||||
} else {
|
||||
Serial.print(F("[LR1110] Failed to receive packet, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
// GFSK modem has built-in address filtering system
|
||||
// it can be enabled by setting node address, broadcast
|
||||
// address, or both
|
||||
//
|
||||
// to transmit packet to a particular address,
|
||||
// use the following methods:
|
||||
//
|
||||
// radio.transmit("Hello World!", address);
|
||||
// radio.startTransmit("Hello World!", address);
|
||||
|
||||
// set node address to 0x02
|
||||
state = radio.setNodeAddress(0x02);
|
||||
// set broadcast address to 0xFF
|
||||
state = radio.setBroadcastAddress(0xFF);
|
||||
if (state != RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("[LR1110] Unable to set address filter, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
// address filtering can also be disabled
|
||||
// NOTE: calling this method will also erase previously set
|
||||
// node and broadcast address
|
||||
/*
|
||||
state = radio.disableAddressFiltering();
|
||||
if (state != RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("Unable to remove address filter, code "));
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
RadioLib LR11x0 GNSS Almanac Update Example
|
||||
|
||||
This example updates the LR11x0 GNSS almanac.
|
||||
Almanac is a database of orbital predictions of
|
||||
GNSS satellites, which allows the module to predict
|
||||
when different satellites will appear in the sky,
|
||||
and frequency of their signal.
|
||||
|
||||
Up-to-date almanac is necessary for operation!
|
||||
After an update, data will remain valid for 30 days.
|
||||
All GNSS examples require at least limited
|
||||
visibility of the sky!
|
||||
|
||||
NOTE: This example will only work for LR11x0 devices
|
||||
with sufficiently recent firmware!
|
||||
LR1110: 4.1
|
||||
LR1120: 2.1
|
||||
If your device firmware reports older firmware,
|
||||
update it using the LR11x0_Firmware_Update example.
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO1 pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// set RF switch configuration for Wio WM1110
|
||||
// Wio WM1110 uses DIO5 and DIO6 for RF switching
|
||||
// NOTE: other boards may be different!
|
||||
static const uint32_t rfswitch_dio_pins[] = {
|
||||
RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6,
|
||||
RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC
|
||||
};
|
||||
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
// mode DIO5 DIO6
|
||||
{ LR11x0::MODE_STBY, { LOW, LOW } },
|
||||
{ LR11x0::MODE_RX, { HIGH, LOW } },
|
||||
{ LR11x0::MODE_TX, { HIGH, HIGH } },
|
||||
{ LR11x0::MODE_TX_HP, { LOW, HIGH } },
|
||||
{ LR11x0::MODE_TX_HF, { LOW, LOW } },
|
||||
{ LR11x0::MODE_GNSS, { LOW, LOW } },
|
||||
{ LR11x0::MODE_WIFI, { LOW, LOW } },
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
|
||||
// structure to save information about the GNSS almanac
|
||||
LR11x0GnssAlmanacStatus_t almStatus;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.beginGNSS(RADIOLIB_LR11X0_GNSS_CONSTELLATION_GPS);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set RF switch control configuration
|
||||
radio.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table);
|
||||
|
||||
// check the firmware version
|
||||
Serial.print(F("[LR1110] Checking firmware version ... "));
|
||||
state = radio.isGnssScanCapable();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("check passed!"));
|
||||
} else {
|
||||
Serial.println(F("check failed, firmware update needed."));
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// run GNSS scans until we get at least the time
|
||||
// NOTE: Depending on visibility of satellites,
|
||||
// this may take multiple attempts!
|
||||
while(true) {
|
||||
// run GNSS scan
|
||||
Serial.print(F("[LR1110] Running GNSS scan ... "));
|
||||
state = radio.gnssScan(NULL);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// check almanac status
|
||||
Serial.print(F("[LR1110] Checking GNSS almanac ... "));
|
||||
state = radio.getGnssAlmanacStatus(&almStatus);
|
||||
if (state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// we have the status, check if we have demodulated time
|
||||
if(almStatus.gps.status < RADIOLIB_LR11X0_GNSS_ALMANAC_STATUS_UP_TO_DATE) {
|
||||
Serial.println(F("time unknown, another scan needed."));
|
||||
|
||||
} else if(almStatus.gps.numUpdateNeeded > 0) {
|
||||
Serial.print(almStatus.gps.numUpdateNeeded);
|
||||
Serial.println(F(" satellites out-of-date."));
|
||||
break;
|
||||
|
||||
} else {
|
||||
Serial.println(F("no update needed!"));
|
||||
while (true) { delay(10); }
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// wait until almanac data is available in the signal
|
||||
// multiple attempts are needed for this
|
||||
Serial.print(F("[LR1110] Waiting for subframe ... "));
|
||||
int state = radio.gnssDelayUntilSubframe(&almStatus, RADIOLIB_LR11X0_GNSS_CONSTELLATION_GPS);
|
||||
if(state == RADIOLIB_ERR_GNSS_SUBFRAME_NOT_AVAILABLE) {
|
||||
Serial.println(F("not enough time left."));
|
||||
|
||||
// wait until the next update window
|
||||
delay(2000);
|
||||
|
||||
} else {
|
||||
Serial.println(F("done!"));
|
||||
|
||||
// we have enough time to start the update
|
||||
Serial.print(F("[LR1110] Starting update ... "));
|
||||
state = radio.updateGnssAlmanac(RADIOLIB_LR11X0_GNSS_CONSTELLATION_GPS);
|
||||
if(state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
} else {
|
||||
Serial.println(F("done!"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check whether another update is needed
|
||||
Serial.print(F("[LR1110] Checking GNSS almanac ... "));
|
||||
state = radio.getGnssAlmanacStatus(&almStatus);
|
||||
if(state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// check if we have completed the update
|
||||
if(almStatus.gps.numUpdateNeeded == 0) {
|
||||
Serial.println(F("all satellites up-to-date!"));
|
||||
while (true) { delay(10); }
|
||||
} else {
|
||||
Serial.print(almStatus.gps.numUpdateNeeded);
|
||||
Serial.println(F(" satellites out-of-date."));
|
||||
}
|
||||
|
||||
// wait a bit before the next update attempt
|
||||
delay(1000);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
RadioLib LR11x0 GNSS Autonomous Position Example
|
||||
|
||||
This example performs GNSS scans and calculates
|
||||
position of the device using autonomous mode.
|
||||
In this mode, scan data does not need to be uploaded
|
||||
to LoRaCloud, however, it requires up-to-date almanac
|
||||
data. Run the LR11x0_Almanac_Update example to update
|
||||
the device almanac.
|
||||
|
||||
NOTE: This example will only work for LR11x0 devices
|
||||
with sufficiently recent firmware!
|
||||
LR1110: 4.1
|
||||
LR1120: 2.1
|
||||
If your device firmware reports older firmware,
|
||||
update it using the LR11x0_Firmware_Update example.
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO1 pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// set RF switch configuration for Wio WM1110
|
||||
// Wio WM1110 uses DIO5 and DIO6 for RF switching
|
||||
// NOTE: other boards may be different!
|
||||
static const uint32_t rfswitch_dio_pins[] = {
|
||||
RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6,
|
||||
RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC
|
||||
};
|
||||
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
// mode DIO5 DIO6
|
||||
{ LR11x0::MODE_STBY, { LOW, LOW } },
|
||||
{ LR11x0::MODE_RX, { HIGH, LOW } },
|
||||
{ LR11x0::MODE_TX, { HIGH, HIGH } },
|
||||
{ LR11x0::MODE_TX_HP, { LOW, HIGH } },
|
||||
{ LR11x0::MODE_TX_HF, { LOW, LOW } },
|
||||
{ LR11x0::MODE_GNSS, { LOW, LOW } },
|
||||
{ LR11x0::MODE_WIFI, { LOW, LOW } },
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
|
||||
// structure to save information about the GNSS scan result
|
||||
LR11x0GnssResult_t gnssResult;
|
||||
|
||||
// structure to save information about the calculated GNSS position
|
||||
LR11x0GnssPosition_t gnssPosition;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.beginGNSS(RADIOLIB_LR11X0_GNSS_CONSTELLATION_GPS);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set RF switch control configuration
|
||||
radio.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table);
|
||||
|
||||
// check the firmware version
|
||||
Serial.print(F("[LR1110] Checking firmware version ... "));
|
||||
state = radio.isGnssScanCapable();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("check passed!"));
|
||||
} else {
|
||||
Serial.println(F("check failed, firmware update needed."));
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
Serial.println(F("Scan result\t| Latitude\t| Longitude\t| Accuracy\t| Number of satellites"));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// run GNSS scan
|
||||
int state = radio.gnssScan(&gnssResult);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
// success!
|
||||
Serial.print(gnssResult.demodStat); Serial.print("\t\t| ");
|
||||
|
||||
// get the actual data
|
||||
state = radio.getGnssPosition(&gnssPosition);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
// print the position
|
||||
Serial.print(gnssPosition.latitude, 6);
|
||||
Serial.print("\t| ");
|
||||
Serial.print(gnssPosition.longitude, 6);
|
||||
Serial.print("\t| ");
|
||||
Serial.print(gnssPosition.accuracy);
|
||||
Serial.print("\t\t| ");
|
||||
Serial.println(gnssPosition.numSatsUsed);
|
||||
|
||||
} else {
|
||||
Serial.print(F("Failed to read result, code "));
|
||||
Serial.print(state);
|
||||
Serial.print(F(" (solver error "));
|
||||
Serial.print(RADIOLIB_GET_GNSS_SOLVER_ERROR(state));
|
||||
Serial.println(F(")"));
|
||||
}
|
||||
|
||||
} else {
|
||||
Serial.print(F("Scan failed, code "));
|
||||
Serial.print(state);
|
||||
Serial.print(F(" (demodulator error "));
|
||||
Serial.print(RADIOLIB_GET_GNSS_DEMOD_ERROR(state));
|
||||
Serial.println(F(")"));
|
||||
|
||||
}
|
||||
|
||||
// wait a bit before the next scan
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
RadioLib LR11x0 GNSS Satellites Example
|
||||
|
||||
This example performs GNSS scans and shows the satellites
|
||||
currently in view. It is mostly useful to verify
|
||||
visibility and antenna setup.
|
||||
|
||||
NOTE: This example will only work for LR11x0 devices
|
||||
with sufficiently recent firmware!
|
||||
LR1110: 4.1
|
||||
LR1120: 2.1
|
||||
If your device firmware reports older firmware,
|
||||
update it using the LR11x0_Firmware_Update example.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---wifi-scan
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO1 pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// set RF switch configuration for Wio WM1110
|
||||
// Wio WM1110 uses DIO5 and DIO6 for RF switching
|
||||
// NOTE: other boards may be different!
|
||||
static const uint32_t rfswitch_dio_pins[] = {
|
||||
RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6,
|
||||
RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC
|
||||
};
|
||||
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
// mode DIO5 DIO6
|
||||
{ LR11x0::MODE_STBY, { LOW, LOW } },
|
||||
{ LR11x0::MODE_RX, { HIGH, LOW } },
|
||||
{ LR11x0::MODE_TX, { HIGH, HIGH } },
|
||||
{ LR11x0::MODE_TX_HP, { LOW, HIGH } },
|
||||
{ LR11x0::MODE_TX_HF, { LOW, LOW } },
|
||||
{ LR11x0::MODE_GNSS, { LOW, LOW } },
|
||||
{ LR11x0::MODE_WIFI, { LOW, LOW } },
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
|
||||
// structure to save information about the GNSS scan result
|
||||
LR11x0GnssResult_t gnssResult;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.beginGNSS(RADIOLIB_LR11X0_GNSS_CONSTELLATION_GPS);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set RF switch control configuration
|
||||
radio.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table);
|
||||
|
||||
// check the firmware version
|
||||
Serial.print(F("[LR1110] Checking firmware version ... "));
|
||||
state = radio.isGnssScanCapable();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("check passed!"));
|
||||
} else {
|
||||
Serial.println(F("check failed, firmware update needed."));
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[LR1110] Running GNSS scan ... "));
|
||||
int state = radio.gnssScan(&gnssResult);
|
||||
if(state != RADIOLIB_ERR_NONE) {
|
||||
// some error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.print(state);
|
||||
Serial.print(F(" (demodulator error "));
|
||||
Serial.print(RADIOLIB_GET_GNSS_DEMOD_ERROR(state));
|
||||
Serial.println(F(")"));
|
||||
|
||||
} else {
|
||||
Serial.println(F("success!"));
|
||||
|
||||
// print the table header
|
||||
Serial.print(F("[LR1110] Detected "));
|
||||
Serial.print(gnssResult.numSatsDet);
|
||||
Serial.println(F(" satellite(s):"));
|
||||
Serial.println(F(" # | ID | C/N0 [dB]\t| Doppler [Hz]"));
|
||||
|
||||
// read all results at once
|
||||
LR11x0GnssSatellite_t satellites[32];
|
||||
state = radio.getGnssSatellites(satellites, gnssResult.numSatsDet);
|
||||
if(state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("Failed to read results, code "));
|
||||
Serial.println(state);
|
||||
} else {
|
||||
// print all the results
|
||||
for(int i = 0; i < gnssResult.numSatsDet; i++) {
|
||||
if(i < 10) { Serial.print(" "); } Serial.print(i); Serial.print(" | ");
|
||||
Serial.print(satellites[i].svId); Serial.print(" | ");
|
||||
Serial.print(satellites[i].c_n0); Serial.print("\t\t| ");
|
||||
Serial.println(satellites[i].doppler);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// wait for a second before scanning again
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
RadioLib LR11x0 LR-FHSS Modem Example
|
||||
|
||||
This example shows how to use LR-FHSS modem in LR11x0 chips.
|
||||
This modem can only transmit data, and is not able to receive.
|
||||
|
||||
NOTE: The sketch below is just a guide on how to use
|
||||
LR-FHSS modem, so this code should not be run directly!
|
||||
Instead, modify the other examples to use LR-FHSS
|
||||
modem and use the appropriate configuration
|
||||
methods.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---lr-fhss-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// IRQ pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.beginLRFHSS();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// if needed, you can switch between any of the modems
|
||||
//
|
||||
// radio.begin() start LoRa modem (and disable LR-FHSS)
|
||||
// radio.beginLRFHSS() start LR-FHSS modem (and disable LoRa)
|
||||
|
||||
// the following settings can also
|
||||
// be modified at run-time
|
||||
state = radio.setFrequency(433.5);
|
||||
state = radio.setLrFhssConfig(RADIOLIB_LR11X0_LR_FHSS_BW_1523_4, // bandwidth
|
||||
RADIOLIB_LR11X0_LR_FHSS_CR_1_2, // coding rate
|
||||
3, // header count
|
||||
0x13A); // hopping sequence seed
|
||||
state = radio.setOutputPower(10.0);
|
||||
uint8_t syncWord[] = {0x01, 0x23, 0x45, 0x67};
|
||||
state = radio.setSyncWord(syncWord, 4);
|
||||
if (state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("Unable to set configuration, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
#warning "This sketch is just an API guide! Read the note at line 6."
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// LR-FHSS modem can only transmit!
|
||||
// transmit LR-FHSS packet
|
||||
int state = radio.transmit("Hello World!");
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
|
||||
0x89, 0xAB, 0xCD, 0xEF};
|
||||
int state = radio.transmit(byteArr, 8);
|
||||
*/
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("[LR1110] Packet transmitted successfully!"));
|
||||
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
|
||||
Serial.println(F("[LR1110] Packet too long!"));
|
||||
} else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
|
||||
Serial.println(F("[LR1110] Timed out while transmitting!"));
|
||||
} else {
|
||||
Serial.println(F("[LR1110] Failed to transmit packet, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
}
|
||||
173
RadioLib/examples/LR11x0/LR11x0_PingPong/LR11x0_PingPong.ino
Normal file
173
RadioLib/examples/LR11x0/LR11x0_PingPong/LR11x0_PingPong.ino
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
RadioLib LR11x0 Ping-Pong Example
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---lora-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// uncomment the following only on one
|
||||
// of the nodes to initiate the pings
|
||||
//#define INITIATING_NODE
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// IRQ pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// set RF switch configuration for Wio WM1110
|
||||
// Wio WM1110 uses DIO5 and DIO6 for RF switching
|
||||
// NOTE: other boards may be different!
|
||||
static const uint32_t rfswitch_dio_pins[] = {
|
||||
RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6,
|
||||
RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC
|
||||
};
|
||||
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
// mode DIO5 DIO6
|
||||
{ LR11x0::MODE_STBY, { LOW, LOW } },
|
||||
{ LR11x0::MODE_RX, { HIGH, LOW } },
|
||||
{ LR11x0::MODE_TX, { HIGH, HIGH } },
|
||||
{ LR11x0::MODE_TX_HP, { LOW, HIGH } },
|
||||
{ LR11x0::MODE_TX_HF, { LOW, LOW } },
|
||||
{ LR11x0::MODE_GNSS, { LOW, LOW } },
|
||||
{ LR11x0::MODE_WIFI, { LOW, LOW } },
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
|
||||
// save transmission states between loops
|
||||
int transmissionState = RADIOLIB_ERR_NONE;
|
||||
|
||||
// flag to indicate transmission or reception state
|
||||
bool transmitFlag = false;
|
||||
|
||||
// flag to indicate that a packet was sent or received
|
||||
volatile bool operationDone = false;
|
||||
|
||||
// this function is called when a complete packet
|
||||
// is transmitted or received by the module
|
||||
// IMPORTANT: this function MUST be 'void' type
|
||||
// and MUST NOT have any arguments!
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
ICACHE_RAM_ATTR
|
||||
#endif
|
||||
void setFlag(void) {
|
||||
// we sent or received a packet, set the flag
|
||||
operationDone = true;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set RF switch control configuration
|
||||
radio.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table);
|
||||
|
||||
// set the function that will be called
|
||||
// when new packet is received
|
||||
radio.setIrqAction(setFlag);
|
||||
|
||||
#if defined(INITIATING_NODE)
|
||||
// send the first packet on this node
|
||||
Serial.print(F("[LR1110] Sending first packet ... "));
|
||||
transmissionState = radio.startTransmit("Hello World!");
|
||||
transmitFlag = true;
|
||||
#else
|
||||
// start listening for LoRa packets on this node
|
||||
Serial.print(F("[LR1110] Starting to listen ... "));
|
||||
state = radio.startReceive();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// check if the previous operation finished
|
||||
if(operationDone) {
|
||||
// reset flag
|
||||
operationDone = false;
|
||||
|
||||
if(transmitFlag) {
|
||||
// the previous operation was transmission, listen for response
|
||||
// print the result
|
||||
if (transmissionState == RADIOLIB_ERR_NONE) {
|
||||
// packet was successfully sent
|
||||
Serial.println(F("transmission finished!"));
|
||||
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(transmissionState);
|
||||
|
||||
}
|
||||
|
||||
// listen for response
|
||||
radio.startReceive();
|
||||
transmitFlag = false;
|
||||
|
||||
} else {
|
||||
// the previous operation was reception
|
||||
// print data and send another packet
|
||||
String str;
|
||||
int state = radio.readData(str);
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// packet was successfully received
|
||||
Serial.println(F("[LR1110] Received packet!"));
|
||||
|
||||
// print data of the packet
|
||||
Serial.print(F("[LR1110] Data:\t\t"));
|
||||
Serial.println(str);
|
||||
|
||||
// print RSSI (Received Signal Strength Indicator)
|
||||
Serial.print(F("[LR1110] RSSI:\t\t"));
|
||||
Serial.print(radio.getRSSI());
|
||||
Serial.println(F(" dBm"));
|
||||
|
||||
// print SNR (Signal-to-Noise Ratio)
|
||||
Serial.print(F("[LR1110] SNR:\t\t"));
|
||||
Serial.print(radio.getSNR());
|
||||
Serial.println(F(" dB"));
|
||||
|
||||
}
|
||||
|
||||
// wait a second before transmitting again
|
||||
delay(1000);
|
||||
|
||||
// send another one
|
||||
Serial.print(F("[LR1110] Sending another packet ... "));
|
||||
transmissionState = radio.startTransmit("Hello World!");
|
||||
transmitFlag = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
RadioLib LR11x0 Blocking Receive Example
|
||||
|
||||
This example listens for LoRa transmissions using LR11x0 Lora modules.
|
||||
To successfully receive data, the following settings have to be the same
|
||||
on both transmitter and receiver:
|
||||
- carrier frequency
|
||||
- bandwidth
|
||||
- spreading factor
|
||||
- coding rate
|
||||
- sync word
|
||||
- preamble length
|
||||
|
||||
Other modules from LR11x0 family can also be used.
|
||||
|
||||
This example assumes Seeed Studio Wio WM1110 is used.
|
||||
For other LR11x0 modules, some configuration such as
|
||||
RF switch control may have to be adjusted.
|
||||
|
||||
Using blocking receive is not recommended, as it will lead
|
||||
to significant amount of timeouts, inefficient use of processor
|
||||
time and can some miss packets!
|
||||
Instead, interrupt receive is recommended.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---lora-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// IRQ pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// set RF switch configuration for Wio WM1110
|
||||
// Wio WM1110 uses DIO5 and DIO6 for RF switching
|
||||
// NOTE: other boards may be different!
|
||||
static const uint32_t rfswitch_dio_pins[] = {
|
||||
RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6,
|
||||
RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC
|
||||
};
|
||||
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
// mode DIO5 DIO6
|
||||
{ LR11x0::MODE_STBY, { LOW, LOW } },
|
||||
{ LR11x0::MODE_RX, { HIGH, LOW } },
|
||||
{ LR11x0::MODE_TX, { HIGH, HIGH } },
|
||||
{ LR11x0::MODE_TX_HP, { LOW, HIGH } },
|
||||
{ LR11x0::MODE_TX_HF, { LOW, LOW } },
|
||||
{ LR11x0::MODE_GNSS, { LOW, LOW } },
|
||||
{ LR11x0::MODE_WIFI, { LOW, LOW } },
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set RF switch control configuration
|
||||
radio.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[LR1110] Waiting for incoming transmission ... "));
|
||||
|
||||
// you can receive data as an Arduino String
|
||||
String str;
|
||||
int state = radio.receive(str);
|
||||
|
||||
// you can also receive data as byte array
|
||||
/*
|
||||
byte byteArr[8];
|
||||
int state = radio.receive(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// packet was successfully received
|
||||
Serial.println(F("success!"));
|
||||
|
||||
// print the data of the packet
|
||||
Serial.print(F("[LR1110] Data:\t\t"));
|
||||
Serial.println(str);
|
||||
|
||||
// print the RSSI (Received Signal Strength Indicator)
|
||||
// of the last received packet
|
||||
Serial.print(F("[LR1110] RSSI:\t\t"));
|
||||
Serial.print(radio.getRSSI());
|
||||
Serial.println(F(" dBm"));
|
||||
|
||||
// print the SNR (Signal-to-Noise Ratio)
|
||||
// of the last received packet
|
||||
Serial.print(F("[LR1110] SNR:\t\t"));
|
||||
Serial.print(radio.getSNR());
|
||||
Serial.println(F(" dB"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
|
||||
// timeout occurred while waiting for a packet
|
||||
Serial.println(F("timeout!"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
|
||||
// packet was received, but is malformed
|
||||
Serial.println(F("CRC error!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
RadioLib LR11x0 Receive with Interrupts Example
|
||||
|
||||
This example listens for LoRa transmissions and tries to
|
||||
receive them. Once a packet is received, an interrupt is
|
||||
triggered. To successfully receive data, the following
|
||||
settings have to be the same on both transmitter
|
||||
and receiver:
|
||||
- carrier frequency
|
||||
- bandwidth
|
||||
- spreading factor
|
||||
- coding rate
|
||||
- sync word
|
||||
|
||||
Other modules from LR11x0 family can also be used.
|
||||
|
||||
This example assumes Seeed Studio Wio WM1110 is used.
|
||||
For other LR11x0 modules, some configuration such as
|
||||
RF switch control may have to be adjusted.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---lora-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// IRQ pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// set RF switch configuration for Wio WM1110
|
||||
// Wio WM1110 uses DIO5 and DIO6 for RF switching
|
||||
// NOTE: other boards may be different!
|
||||
static const uint32_t rfswitch_dio_pins[] = {
|
||||
RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6,
|
||||
RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC
|
||||
};
|
||||
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
// mode DIO5 DIO6
|
||||
{ LR11x0::MODE_STBY, { LOW, LOW } },
|
||||
{ LR11x0::MODE_RX, { HIGH, LOW } },
|
||||
{ LR11x0::MODE_TX, { HIGH, HIGH } },
|
||||
{ LR11x0::MODE_TX_HP, { LOW, HIGH } },
|
||||
{ LR11x0::MODE_TX_HF, { LOW, LOW } },
|
||||
{ LR11x0::MODE_GNSS, { LOW, LOW } },
|
||||
{ LR11x0::MODE_WIFI, { LOW, LOW } },
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
|
||||
// flag to indicate that a packet was received
|
||||
volatile bool receivedFlag = false;
|
||||
|
||||
// this function is called when a complete packet
|
||||
// is received by the module
|
||||
// IMPORTANT: this function MUST be 'void' type
|
||||
// and MUST NOT have any arguments!
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
ICACHE_RAM_ATTR
|
||||
#endif
|
||||
void setFlag(void) {
|
||||
// we got a packet, set the flag
|
||||
receivedFlag = true;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set RF switch control configuration
|
||||
radio.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table);
|
||||
|
||||
// set the function that will be called
|
||||
// when new packet is received
|
||||
radio.setPacketReceivedAction(setFlag);
|
||||
|
||||
// start listening for LoRa packets
|
||||
Serial.print(F("[LR1110] Starting to listen ... "));
|
||||
state = radio.startReceive();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// if needed, 'listen' mode can be disabled by calling
|
||||
// any of the following methods:
|
||||
//
|
||||
// radio.standby()
|
||||
// radio.sleep()
|
||||
// radio.transmit();
|
||||
// radio.receive();
|
||||
// radio.scanChannel();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// check if the flag is set
|
||||
if(receivedFlag) {
|
||||
// reset flag
|
||||
receivedFlag = false;
|
||||
|
||||
// you can read received data as an Arduino String
|
||||
String str;
|
||||
int state = radio.readData(str);
|
||||
|
||||
// you can also read received data as byte array
|
||||
/*
|
||||
byte byteArr[8];
|
||||
int numBytes = radio.getPacketLength();
|
||||
int state = radio.readData(byteArr, numBytes);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// packet was successfully received
|
||||
Serial.println(F("[LR1110] Received packet!"));
|
||||
|
||||
// print data of the packet
|
||||
Serial.print(F("[LR1110] Data:\t\t"));
|
||||
Serial.println(str);
|
||||
|
||||
// print RSSI (Received Signal Strength Indicator)
|
||||
Serial.print(F("[LR1110] RSSI:\t\t"));
|
||||
Serial.print(radio.getRSSI());
|
||||
Serial.println(F(" dBm"));
|
||||
|
||||
// print SNR (Signal-to-Noise Ratio)
|
||||
Serial.print(F("[LR1110] SNR:\t\t"));
|
||||
Serial.print(radio.getSNR());
|
||||
Serial.println(F(" dB"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
|
||||
// packet was received, but is malformed
|
||||
Serial.println(F("CRC error!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
RadioLib LR11x0 Blocking Transmit Example
|
||||
|
||||
This example transmits packets using LR1110 LoRa radio module.
|
||||
Each packet contains up to 256 bytes of data, in the form of:
|
||||
- Arduino String
|
||||
- null-terminated char array (C-string)
|
||||
- arbitrary binary data (byte array)
|
||||
|
||||
Other modules from LR11x0 family can also be used.
|
||||
|
||||
This example assumes Seeed Studio Wio WM1110 is used.
|
||||
For other LR11x0 modules, some configuration such as
|
||||
RF switch control may have to be adjusted.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---lora-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// IRQ pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// set RF switch configuration for Wio WM1110
|
||||
// Wio WM1110 uses DIO5 and DIO6 for RF switching
|
||||
// NOTE: other boards may be different!
|
||||
static const uint32_t rfswitch_dio_pins[] = {
|
||||
RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6,
|
||||
RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC
|
||||
};
|
||||
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
// mode DIO5 DIO6
|
||||
{ LR11x0::MODE_STBY, { LOW, LOW } },
|
||||
{ LR11x0::MODE_RX, { HIGH, LOW } },
|
||||
{ LR11x0::MODE_TX, { HIGH, HIGH } },
|
||||
{ LR11x0::MODE_TX_HP, { LOW, HIGH } },
|
||||
{ LR11x0::MODE_TX_HF, { LOW, LOW } },
|
||||
{ LR11x0::MODE_GNSS, { LOW, LOW } },
|
||||
{ LR11x0::MODE_WIFI, { LOW, LOW } },
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
delay(1000);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set RF switch control configuration
|
||||
radio.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table);
|
||||
}
|
||||
|
||||
// counter to keep track of transmitted packets
|
||||
int count = 0;
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[LR1110] Transmitting packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 256 characters long
|
||||
// NOTE: transmit() is a blocking method!
|
||||
// See example LR11x0_Transmit_Interrupt for details
|
||||
// on non-blocking transmission method.
|
||||
String str = "Hello World! #" + String(count++);
|
||||
int state = radio.transmit(str);
|
||||
|
||||
// you can also transmit byte array up to 256 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x56, 0x78, 0xAB, 0xCD, 0xEF};
|
||||
int state = radio.transmit(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// the packet was successfully transmitted
|
||||
Serial.println(F("success!"));
|
||||
|
||||
// print measured data rate
|
||||
Serial.print(F("[LR1110] Datarate:\t"));
|
||||
Serial.print(radio.getDataRate());
|
||||
Serial.println(F(" bps"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
|
||||
// the supplied packet was longer than 256 bytes
|
||||
Serial.println(F("too long!"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
|
||||
// timeout occured while transmitting packet
|
||||
Serial.println(F("timeout!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
RadioLib LR11x0 Transmit with Interrupts Example
|
||||
|
||||
This example transmits LoRa packets with one second delays
|
||||
between them. Each packet contains up to 256 bytes
|
||||
of data, in the form of:
|
||||
- Arduino String
|
||||
- null-terminated char array (C-string)
|
||||
- arbitrary binary data (byte array)
|
||||
|
||||
Other modules from LR11x0 family can also be used.
|
||||
|
||||
This example assumes Seeed Studio Wio WM1110 is used.
|
||||
For other LR11x0 modules, some configuration such as
|
||||
RF switch control may have to be adjusted.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---lora-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// IRQ pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// set RF switch configuration for Wio WM1110
|
||||
// Wio WM1110 uses DIO5 and DIO6 for RF switching
|
||||
// NOTE: other boards may be different!
|
||||
static const uint32_t rfswitch_dio_pins[] = {
|
||||
RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6,
|
||||
RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC
|
||||
};
|
||||
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
// mode DIO5 DIO6
|
||||
{ LR11x0::MODE_STBY, { LOW, LOW } },
|
||||
{ LR11x0::MODE_RX, { HIGH, LOW } },
|
||||
{ LR11x0::MODE_TX, { HIGH, HIGH } },
|
||||
{ LR11x0::MODE_TX_HP, { LOW, HIGH } },
|
||||
{ LR11x0::MODE_TX_HF, { LOW, LOW } },
|
||||
{ LR11x0::MODE_GNSS, { LOW, LOW } },
|
||||
{ LR11x0::MODE_WIFI, { LOW, LOW } },
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
|
||||
// save transmission state between loops
|
||||
int transmissionState = RADIOLIB_ERR_NONE;
|
||||
|
||||
// flag to indicate that a packet was sent
|
||||
volatile bool transmittedFlag = false;
|
||||
|
||||
// this function is called when a complete packet
|
||||
// is transmitted by the module
|
||||
// IMPORTANT: this function MUST be 'void' type
|
||||
// and MUST NOT have any arguments!
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
ICACHE_RAM_ATTR
|
||||
#endif
|
||||
void setFlag(void) {
|
||||
// we sent a packet, set the flag
|
||||
transmittedFlag = true;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set RF switch control configuration
|
||||
radio.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table);
|
||||
|
||||
// set the function that will be called
|
||||
// when packet transmission is finished
|
||||
radio.setPacketSentAction(setFlag);
|
||||
|
||||
// start transmitting the first packet
|
||||
Serial.print(F("[LR1110] Sending first packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 256 characters long
|
||||
transmissionState = radio.startTransmit("Hello World!");
|
||||
|
||||
// you can also transmit byte array up to 256 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
|
||||
0x89, 0xAB, 0xCD, 0xEF};
|
||||
state = radio.startTransmit(byteArr, 8);
|
||||
*/
|
||||
}
|
||||
|
||||
// counter to keep track of transmitted packets
|
||||
int count = 0;
|
||||
|
||||
void loop() {
|
||||
// check if the previous transmission finished
|
||||
if(transmittedFlag) {
|
||||
// reset flag
|
||||
transmittedFlag = false;
|
||||
|
||||
if (transmissionState == RADIOLIB_ERR_NONE) {
|
||||
// packet was successfully sent
|
||||
Serial.println(F("transmission finished!"));
|
||||
|
||||
// NOTE: when using interrupt-driven transmit method,
|
||||
// it is not possible to automatically measure
|
||||
// transmission data rate using getDataRate()
|
||||
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(transmissionState);
|
||||
|
||||
}
|
||||
|
||||
// clean up after transmission is finished
|
||||
// this will ensure transmitter is disabled,
|
||||
// RF switch is powered down etc.
|
||||
radio.finishTransmit();
|
||||
|
||||
// wait a second before transmitting again
|
||||
delay(1000);
|
||||
|
||||
// send another one
|
||||
Serial.print(F("[LR1110] Sending another packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 256 characters long
|
||||
String str = "Hello World! #" + String(count++);
|
||||
transmissionState = radio.startTransmit(str);
|
||||
|
||||
// you can also transmit byte array up to 256 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
|
||||
0x89, 0xAB, 0xCD, 0xEF};
|
||||
transmissionState = radio.startTransmit(byteArr, 8);
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
RadioLib LR11x0 WiFi scan Blocking Example
|
||||
|
||||
This example performs a passive scan of WiFi networks.
|
||||
The scan shows basic information about the networks,
|
||||
such as the frequency, country code and SSID.
|
||||
|
||||
Other modules from LR11x0 family can also be used.
|
||||
|
||||
This example assumes Seeed Studio Wio WM1110 is used.
|
||||
For other LR11x0 modules, some configuration such as
|
||||
RF switch control may have to be adjusted.
|
||||
|
||||
Using blocking scan is not recommended, as depending
|
||||
on the scan settings, the program may be blocked
|
||||
for several seconds! Instead, interrupt scan is recommended.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---wifi-scan
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO1 pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// set RF switch configuration for Wio WM1110
|
||||
// Wio WM1110 uses DIO5 and DIO6 for RF switching
|
||||
// NOTE: other boards may be different!
|
||||
static const uint32_t rfswitch_dio_pins[] = {
|
||||
RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6,
|
||||
RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC
|
||||
};
|
||||
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
// mode DIO5 DIO6
|
||||
{ LR11x0::MODE_STBY, { LOW, LOW } },
|
||||
{ LR11x0::MODE_RX, { HIGH, LOW } },
|
||||
{ LR11x0::MODE_TX, { HIGH, HIGH } },
|
||||
{ LR11x0::MODE_TX_HP, { LOW, HIGH } },
|
||||
{ LR11x0::MODE_TX_HF, { LOW, LOW } },
|
||||
{ LR11x0::MODE_GNSS, { LOW, LOW } },
|
||||
{ LR11x0::MODE_WIFI, { LOW, LOW } },
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set RF switch control configuration
|
||||
radio.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[LR1110] Running WiFi scan ... "));
|
||||
|
||||
// scan all WiFi signals with default scan configuration
|
||||
uint8_t count = 0;
|
||||
int state = radio.wifiScan('*', &count);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
||||
// print the table header
|
||||
Serial.print(F("[LR1110] Reading "));
|
||||
Serial.print(count);
|
||||
Serial.println(F(" scan results:"));
|
||||
Serial.println(F(" # | WiFi type\t| Frequency\t| MAC Address\t | Country\t| RSSI [dBm]\t| SSID"));
|
||||
|
||||
// read all results one by one
|
||||
// this result type contains the most information, including the SSID
|
||||
LR11x0WifiResultExtended_t result;
|
||||
for(int i = 0; i < count; i++) {
|
||||
if(i < 10) { Serial.print(" "); } Serial.print(i); Serial.print(" | ");
|
||||
state = radio.getWifiScanResult(&result, i);
|
||||
if(state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("Failed to read result, code "));
|
||||
Serial.println(state);
|
||||
continue;
|
||||
}
|
||||
|
||||
// print the basic information
|
||||
Serial.print(F("802.11")); Serial.print(result.type); Serial.print("\t| ");
|
||||
Serial.print(result.channelFreq); Serial.print(" MHz\t| ");
|
||||
|
||||
// print MAC address
|
||||
for(int j = 0; j < 6; j++) {
|
||||
if(result.mac[j] < 0x10) { Serial.print("0"); }
|
||||
Serial.print(result.mac[j], HEX);
|
||||
if(j < 5) { Serial.print(":"); }
|
||||
}
|
||||
Serial.print(" | ");
|
||||
|
||||
// print the two-letter country code
|
||||
String country = result.countryCode;
|
||||
Serial.print(country);
|
||||
Serial.print(" \t| ");
|
||||
|
||||
// print the RSSI
|
||||
Serial.print(result.rssi);
|
||||
Serial.print("\t| ");
|
||||
|
||||
// print the network SSID
|
||||
Serial.println((char*)result.ssid);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
// wait for a second before scanning again
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
RadioLib LR11x0 WiFi scan Interrupt Example
|
||||
|
||||
This example performs a passive scan of WiFi networks.
|
||||
The scan shows basic information about the networks,
|
||||
such as the frequency, country code and SSID.
|
||||
|
||||
Other modules from LR11x0 family can also be used.
|
||||
|
||||
This example assumes Seeed Studio Wio WM1110 is used.
|
||||
For other LR11x0 modules, some configuration such as
|
||||
RF switch control may have to be adjusted.
|
||||
|
||||
Using blocking scan is not recommended, as depending
|
||||
on the scan settings, the program may be blocked
|
||||
for several seconds! Instead, interrupt scan is recommended.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---wifi-scan
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// LR1110 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO1 pin: 2
|
||||
// NRST pin: 3
|
||||
// BUSY pin: 9
|
||||
LR1110 radio = new Module(10, 2, 3, 9);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// set RF switch configuration for Wio WM1110
|
||||
// Wio WM1110 uses DIO5 and DIO6 for RF switching
|
||||
// NOTE: other boards may be different!
|
||||
static const uint32_t rfswitch_dio_pins[] = {
|
||||
RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6,
|
||||
RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC
|
||||
};
|
||||
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
// mode DIO5 DIO6
|
||||
{ LR11x0::MODE_STBY, { LOW, LOW } },
|
||||
{ LR11x0::MODE_RX, { HIGH, LOW } },
|
||||
{ LR11x0::MODE_TX, { HIGH, HIGH } },
|
||||
{ LR11x0::MODE_TX_HP, { LOW, HIGH } },
|
||||
{ LR11x0::MODE_TX_HF, { LOW, LOW } },
|
||||
{ LR11x0::MODE_GNSS, { LOW, LOW } },
|
||||
{ LR11x0::MODE_WIFI, { LOW, LOW } },
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
|
||||
// flag to indicate that a scan was completed
|
||||
volatile bool scanFlag = false;
|
||||
|
||||
// this function is called when a scan is completed
|
||||
// IMPORTANT: this function MUST be 'void' type
|
||||
// and MUST NOT have any arguments!
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
ICACHE_RAM_ATTR
|
||||
#endif
|
||||
void setFlag(void) {
|
||||
// scan is complete, set the flag
|
||||
scanFlag = true;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize LR1110 with default settings
|
||||
Serial.print(F("[LR1110] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set RF switch control configuration
|
||||
radio.setRfSwitchTable(rfswitch_dio_pins, rfswitch_table);
|
||||
|
||||
// set the function that will be called
|
||||
// when WiFi scan is complete
|
||||
radio.setIrqAction(setFlag);
|
||||
|
||||
// scan all WiFi signals with default scan configuration
|
||||
Serial.print(F("[LR1110] Starting passive WiFi scan ... "));
|
||||
state = radio.startWifiScan('*');
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// check if the flag is set
|
||||
if(scanFlag) {
|
||||
// reset flag
|
||||
scanFlag = false;
|
||||
|
||||
// get the number of scan results
|
||||
uint8_t count = 0;
|
||||
Serial.print(F("[LR1110] Reading WiFi scan results ... "));
|
||||
int state = radio.getWifiScanResultsCount(&count);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
||||
// print the table header
|
||||
Serial.print(F("[LR1110] Reading "));
|
||||
Serial.print(count);
|
||||
Serial.println(F(" scan results:"));
|
||||
Serial.println(F(" # | WiFi type\t| Frequency\t| MAC Address\t | Country\t| RSSI [dBm]\t| SSID"));
|
||||
|
||||
// read all results one by one
|
||||
// this result type contains the most information, including the SSID
|
||||
LR11x0WifiResultExtended_t result;
|
||||
for(int i = 0; i < count; i++) {
|
||||
if(i < 10) { Serial.print(" "); } Serial.print(i); Serial.print(" | ");
|
||||
state = radio.getWifiScanResult(&result, i);
|
||||
if(state != RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("Failed to read result, code "));
|
||||
Serial.println(state);
|
||||
continue;
|
||||
}
|
||||
|
||||
// print the basic information
|
||||
Serial.print(F("802.11")); Serial.print(result.type); Serial.print("\t| ");
|
||||
Serial.print(result.channelFreq); Serial.print(" MHz\t| ");
|
||||
|
||||
// print MAC address
|
||||
for(int j = 0; j < 6; j++) {
|
||||
if(result.mac[j] < 0x10) { Serial.print("0"); }
|
||||
Serial.print(result.mac[j], HEX);
|
||||
if(j < 5) { Serial.print(":"); }
|
||||
}
|
||||
Serial.print(" | ");
|
||||
|
||||
// print the two-letter country code
|
||||
String country = result.countryCode;
|
||||
Serial.print(country);
|
||||
Serial.print(" \t| ");
|
||||
|
||||
// print the RSSI
|
||||
Serial.print(result.rssi);
|
||||
Serial.print("\t| ");
|
||||
|
||||
// print the network SSID
|
||||
Serial.println((char*)result.ssid);
|
||||
}
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
// start scanning again
|
||||
Serial.print(F("[LR1110] Starting passive WiFi scan ... "));
|
||||
state = radio.startWifiScan('*');
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
85
RadioLib/examples/LoRaWAN/LoRaWAN_ABP/LoRaWAN_ABP.ino
Normal file
85
RadioLib/examples/LoRaWAN/LoRaWAN_ABP/LoRaWAN_ABP.ino
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
RadioLib LoRaWAN ABP Example
|
||||
|
||||
ABP = Activation by Personalisation, an alternative
|
||||
to OTAA (Over the Air Activation). OTAA is preferable.
|
||||
|
||||
This example will send uplink packets to a LoRaWAN network.
|
||||
Before you start, you will have to register your device at
|
||||
https://www.thethingsnetwork.org/
|
||||
After your device is registered, you can run this example.
|
||||
The device will join the network and start uploading data.
|
||||
|
||||
LoRaWAN v1.0.4/v1.1 requires the use of persistent storage.
|
||||
As this example does not use persistent storage, running this
|
||||
examples REQUIRES you to check "Resets frame counters"
|
||||
on your LoRaWAN dashboard. Refer to the notes or the
|
||||
network's documentation on how to do this.
|
||||
To comply with LoRaWAN's persistent storage, refer to
|
||||
https://github.com/radiolib-org/radiolib-persistence
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
|
||||
For LoRaWAN details, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/LoRaWAN
|
||||
|
||||
*/
|
||||
|
||||
#include "configABP.h"
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
while(!Serial);
|
||||
delay(5000); // Give time to switch to the serial monitor
|
||||
Serial.println(F("\nSetup ... "));
|
||||
|
||||
Serial.println(F("Initialise the radio"));
|
||||
int state = radio.begin();
|
||||
debug(state != RADIOLIB_ERR_NONE, F("Initialise radio failed"), state, true);
|
||||
|
||||
Serial.println(F("Initialise LoRaWAN Network credentials"));
|
||||
node.beginABP(devAddr, fNwkSIntKey, sNwkSIntKey, nwkSEncKey, appSKey);
|
||||
|
||||
node.activateABP();
|
||||
debug(state != RADIOLIB_ERR_NONE, F("Activate ABP failed"), state, true);
|
||||
|
||||
Serial.println(F("Ready!\n"));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.println(F("Sending uplink"));
|
||||
|
||||
// This is the place to gather the sensor inputs
|
||||
// Instead of reading any real sensor, we just generate some random numbers as example
|
||||
uint8_t value1 = radio.random(100);
|
||||
uint16_t value2 = radio.random(2000);
|
||||
|
||||
// Build payload byte array
|
||||
uint8_t uplinkPayload[3];
|
||||
uplinkPayload[0] = value1;
|
||||
uplinkPayload[1] = highByte(value2); // See notes for high/lowByte functions
|
||||
uplinkPayload[2] = lowByte(value2);
|
||||
|
||||
// Perform an uplink
|
||||
int state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload));
|
||||
debug(state < RADIOLIB_ERR_NONE, F("Error in sendReceive"), state, false);
|
||||
|
||||
// Check if a downlink was received
|
||||
// (state 0 = no downlink, state 1/2 = downlink in window Rx1/Rx2)
|
||||
if(state > 0) {
|
||||
Serial.println(F("Received a downlink"));
|
||||
} else {
|
||||
Serial.println(F("No downlink received"));
|
||||
}
|
||||
|
||||
Serial.print(F("Next uplink in "));
|
||||
Serial.print(uplinkIntervalSeconds);
|
||||
Serial.println(F(" seconds\n"));
|
||||
|
||||
// Wait until next uplink - observing legal & TTN FUP constraints
|
||||
delay(uplinkIntervalSeconds * 1000UL); // delay needs milli-seconds
|
||||
}
|
||||
150
RadioLib/examples/LoRaWAN/LoRaWAN_ABP/configABP.h
Normal file
150
RadioLib/examples/LoRaWAN/LoRaWAN_ABP/configABP.h
Normal file
@@ -0,0 +1,150 @@
|
||||
#ifndef _RADIOLIB_EX_LORAWAN_CONFIG_H
|
||||
#define _RADIOLIB_EX_LORAWAN_CONFIG_H
|
||||
|
||||
#include <RadioLib.h>
|
||||
|
||||
// first you have to set your radio model and pin configuration
|
||||
// this is provided just as a default example
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// if you have RadioBoards (https://github.com/radiolib-org/RadioBoards)
|
||||
// and are using one of the supported boards, you can do the following:
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// how often to send an uplink - consider legal & FUP constraints - see notes
|
||||
const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // minutes x seconds
|
||||
|
||||
// device address - either a development address or one assigned
|
||||
// to the LoRaWAN Service Provider - TTN will generate one for you
|
||||
#ifndef RADIOLIB_LORAWAN_DEV_ADDR // Replace with your DevAddr
|
||||
#define RADIOLIB_LORAWAN_DEV_ADDR 0x------
|
||||
#endif
|
||||
|
||||
#ifndef RADIOLIB_LORAWAN_FNWKSINT_KEY // Replace with your FNwkSInt Key
|
||||
#define RADIOLIB_LORAWAN_FNWKSINT_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
|
||||
#endif
|
||||
#ifndef RADIOLIB_LORAWAN_SNWKSINT_KEY // Replace with your SNwkSInt Key
|
||||
#define RADIOLIB_LORAWAN_SNWKSINT_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
|
||||
#endif
|
||||
#ifndef RADIOLIB_LORAWAN_NWKSENC_KEY // Replace with your NwkSEnc Key
|
||||
#define RADIOLIB_LORAWAN_NWKSENC_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
|
||||
#endif
|
||||
#ifndef RADIOLIB_LORAWAN_APPS_KEY // Replace with your AppS Key
|
||||
#define RADIOLIB_LORAWAN_APPS_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
|
||||
#endif
|
||||
|
||||
// for the curious, the #ifndef blocks allow for automated testing &/or you can
|
||||
// put your EUI & keys in to your platformio.ini - see wiki for more tips
|
||||
|
||||
// regional choices: EU868, US915, AU915, AS923, AS923_2, AS923_3, AS923_4, IN865, KR920, CN500
|
||||
const LoRaWANBand_t Region = EU868;
|
||||
const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
|
||||
|
||||
// ============================================================================
|
||||
// Below is to support the sketch - only make changes if the notes say so ...
|
||||
|
||||
// copy over the keys in to the something that will not compile if incorrectly formatted
|
||||
uint32_t devAddr = RADIOLIB_LORAWAN_DEV_ADDR;
|
||||
uint8_t fNwkSIntKey[] = { RADIOLIB_LORAWAN_FNWKSINT_KEY };
|
||||
uint8_t sNwkSIntKey[] = { RADIOLIB_LORAWAN_SNWKSINT_KEY };
|
||||
uint8_t nwkSEncKey[] = { RADIOLIB_LORAWAN_NWKSENC_KEY };
|
||||
uint8_t appSKey[] = { RADIOLIB_LORAWAN_APPS_KEY };
|
||||
|
||||
// create the LoRaWAN node
|
||||
LoRaWANNode node(&radio, &Region, subBand);
|
||||
|
||||
// result code to text - these are error codes that can be raised when using LoRaWAN
|
||||
// however, RadioLib has many more - see https://jgromes.github.io/RadioLib/group__status__codes.html for a complete list
|
||||
String stateDecode(const int16_t result) {
|
||||
switch (result) {
|
||||
case RADIOLIB_ERR_NONE:
|
||||
return "ERR_NONE";
|
||||
case RADIOLIB_ERR_CHIP_NOT_FOUND:
|
||||
return "ERR_CHIP_NOT_FOUND";
|
||||
case RADIOLIB_ERR_PACKET_TOO_LONG:
|
||||
return "ERR_PACKET_TOO_LONG";
|
||||
case RADIOLIB_ERR_RX_TIMEOUT:
|
||||
return "ERR_RX_TIMEOUT";
|
||||
case RADIOLIB_ERR_CRC_MISMATCH:
|
||||
return "ERR_CRC_MISMATCH";
|
||||
case RADIOLIB_ERR_INVALID_BANDWIDTH:
|
||||
return "ERR_INVALID_BANDWIDTH";
|
||||
case RADIOLIB_ERR_INVALID_SPREADING_FACTOR:
|
||||
return "ERR_INVALID_SPREADING_FACTOR";
|
||||
case RADIOLIB_ERR_INVALID_CODING_RATE:
|
||||
return "ERR_INVALID_CODING_RATE";
|
||||
case RADIOLIB_ERR_INVALID_FREQUENCY:
|
||||
return "ERR_INVALID_FREQUENCY";
|
||||
case RADIOLIB_ERR_INVALID_OUTPUT_POWER:
|
||||
return "ERR_INVALID_OUTPUT_POWER";
|
||||
case RADIOLIB_ERR_NETWORK_NOT_JOINED:
|
||||
return "RADIOLIB_ERR_NETWORK_NOT_JOINED";
|
||||
case RADIOLIB_ERR_DOWNLINK_MALFORMED:
|
||||
return "RADIOLIB_ERR_DOWNLINK_MALFORMED";
|
||||
case RADIOLIB_ERR_INVALID_REVISION:
|
||||
return "RADIOLIB_ERR_INVALID_REVISION";
|
||||
case RADIOLIB_ERR_INVALID_PORT:
|
||||
return "RADIOLIB_ERR_INVALID_PORT";
|
||||
case RADIOLIB_ERR_NO_RX_WINDOW:
|
||||
return "RADIOLIB_ERR_NO_RX_WINDOW";
|
||||
case RADIOLIB_ERR_INVALID_CID:
|
||||
return "RADIOLIB_ERR_INVALID_CID";
|
||||
case RADIOLIB_ERR_UPLINK_UNAVAILABLE:
|
||||
return "RADIOLIB_ERR_UPLINK_UNAVAILABLE";
|
||||
case RADIOLIB_ERR_COMMAND_QUEUE_FULL:
|
||||
return "RADIOLIB_ERR_COMMAND_QUEUE_FULL";
|
||||
case RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND:
|
||||
return "RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND";
|
||||
case RADIOLIB_ERR_JOIN_NONCE_INVALID:
|
||||
return "RADIOLIB_ERR_JOIN_NONCE_INVALID";
|
||||
case RADIOLIB_ERR_N_FCNT_DOWN_INVALID:
|
||||
return "RADIOLIB_ERR_N_FCNT_DOWN_INVALID";
|
||||
case RADIOLIB_ERR_A_FCNT_DOWN_INVALID:
|
||||
return "RADIOLIB_ERR_A_FCNT_DOWN_INVALID";
|
||||
case RADIOLIB_ERR_DWELL_TIME_EXCEEDED:
|
||||
return "RADIOLIB_ERR_DWELL_TIME_EXCEEDED";
|
||||
case RADIOLIB_ERR_CHECKSUM_MISMATCH:
|
||||
return "RADIOLIB_ERR_CHECKSUM_MISMATCH";
|
||||
case RADIOLIB_ERR_NO_JOIN_ACCEPT:
|
||||
return "RADIOLIB_ERR_NO_JOIN_ACCEPT";
|
||||
case RADIOLIB_LORAWAN_SESSION_RESTORED:
|
||||
return "RADIOLIB_LORAWAN_SESSION_RESTORED";
|
||||
case RADIOLIB_LORAWAN_NEW_SESSION:
|
||||
return "RADIOLIB_LORAWAN_NEW_SESSION";
|
||||
case RADIOLIB_ERR_NONCES_DISCARDED:
|
||||
return "RADIOLIB_ERR_NONCES_DISCARDED";
|
||||
case RADIOLIB_ERR_SESSION_DISCARDED:
|
||||
return "RADIOLIB_ERR_SESSION_DISCARDED";
|
||||
}
|
||||
return "See https://jgromes.github.io/RadioLib/group__status__codes.html";
|
||||
}
|
||||
|
||||
// helper function to display any issues
|
||||
void debug(bool failed, const __FlashStringHelper* message, int state, bool halt) {
|
||||
if(failed) {
|
||||
Serial.print(message);
|
||||
Serial.print(" - ");
|
||||
Serial.print(stateDecode(state));
|
||||
Serial.print(" (");
|
||||
Serial.print(state);
|
||||
Serial.println(")");
|
||||
while(halt) { delay(1); }
|
||||
}
|
||||
}
|
||||
|
||||
// helper function to display a byte array
|
||||
void arrayDump(uint8_t *buffer, uint16_t len) {
|
||||
for(uint16_t c = 0; c < len; c++) {
|
||||
char b = buffer[c];
|
||||
if(b < 0x10) { Serial.print('0'); }
|
||||
Serial.print(b, HEX);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
RadioLib LoRaWAN End Device Reference Example
|
||||
|
||||
This example joins a LoRaWAN network and will send
|
||||
uplink packets. Before you start, you will have to
|
||||
register your device at https://www.thethingsnetwork.org/
|
||||
After your device is registered, you can run this example.
|
||||
The device will join the network and start uploading data.
|
||||
|
||||
Also, most of the possible and available functions are
|
||||
shown here for reference.
|
||||
|
||||
LoRaWAN v1.0.4/v1.1 requires the use of EEPROM (persistent storage).
|
||||
Running this examples REQUIRES you to check "Resets DevNonces"
|
||||
on your LoRaWAN dashboard. Refer to the notes or the
|
||||
network's documentation on how to do this.
|
||||
To comply with LoRaWAN's persistent storage, refer to
|
||||
https://github.com/radiolib-org/radiolib-persistence
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
|
||||
For LoRaWAN details, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/LoRaWAN
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
while(!Serial); // Wait for serial to be initialised
|
||||
delay(5000); // Give time to switch to the serial monitor
|
||||
Serial.println(F("\nSetup"));
|
||||
|
||||
int16_t state = 0; // return value for calls to RadioLib
|
||||
|
||||
Serial.println(F("Initialise the radio"));
|
||||
state = radio.begin();
|
||||
debug(state != RADIOLIB_ERR_NONE, F("Initialise radio failed"), state, true);
|
||||
|
||||
// Override the default join rate
|
||||
uint8_t joinDR = 4;
|
||||
|
||||
// Setup the OTAA session information
|
||||
node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
|
||||
|
||||
Serial.println(F("Join ('login') the LoRaWAN Network"));
|
||||
state = node.activateOTAA(joinDR);
|
||||
debug(state != RADIOLIB_LORAWAN_NEW_SESSION, F("Join failed"), state, true);
|
||||
|
||||
// Print the DevAddr
|
||||
Serial.print("[LoRaWAN] DevAddr: ");
|
||||
Serial.println((unsigned long)node.getDevAddr(), HEX);
|
||||
|
||||
// Enable the ADR algorithm (on by default which is preferable)
|
||||
node.setADR(true);
|
||||
|
||||
// Set a datarate to start off with
|
||||
node.setDatarate(5);
|
||||
|
||||
// Manages uplink intervals to the TTN Fair Use Policy
|
||||
node.setDutyCycle(true, 1250);
|
||||
|
||||
// Update dwell time limits - 400ms is the limit for the US
|
||||
node.setDwellTime(true, 400);
|
||||
|
||||
Serial.println(F("Ready!\n"));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
int16_t state = RADIOLIB_ERR_NONE;
|
||||
|
||||
// set battery fill level - the LoRaWAN network server
|
||||
// may periodically request this information
|
||||
// 0 = external power source
|
||||
// 1 = lowest (empty battery)
|
||||
// 254 = highest (full battery)
|
||||
// 255 = unable to measure
|
||||
uint8_t battLevel = 146;
|
||||
node.setDeviceStatus(battLevel);
|
||||
|
||||
// This is the place to gather the sensor inputs
|
||||
// Instead of reading any real sensor, we just generate some random numbers as example
|
||||
uint8_t value1 = radio.random(100);
|
||||
uint16_t value2 = radio.random(2000);
|
||||
|
||||
// Build payload byte array
|
||||
uint8_t uplinkPayload[3];
|
||||
uplinkPayload[0] = value1;
|
||||
uplinkPayload[1] = highByte(value2); // See notes for high/lowByte functions
|
||||
uplinkPayload[2] = lowByte(value2);
|
||||
|
||||
uint8_t downlinkPayload[10]; // Make sure this fits your plans!
|
||||
size_t downlinkSize; // To hold the actual payload size received
|
||||
|
||||
// you can also retrieve additional information about an uplink or
|
||||
// downlink by passing a reference to LoRaWANEvent_t structure
|
||||
LoRaWANEvent_t uplinkDetails;
|
||||
LoRaWANEvent_t downlinkDetails;
|
||||
|
||||
uint8_t fPort = 10;
|
||||
|
||||
// Retrieve the last uplink frame counter
|
||||
uint32_t fCntUp = node.getFCntUp();
|
||||
|
||||
// Send a confirmed uplink on the second uplink
|
||||
// and also request the LinkCheck and DeviceTime MAC commands
|
||||
Serial.println(F("Sending uplink"));
|
||||
if(fCntUp == 1) {
|
||||
Serial.println(F("and requesting LinkCheck and DeviceTime"));
|
||||
node.sendMacCommandReq(RADIOLIB_LORAWAN_MAC_LINK_CHECK);
|
||||
node.sendMacCommandReq(RADIOLIB_LORAWAN_MAC_DEVICE_TIME);
|
||||
state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload), fPort, downlinkPayload, &downlinkSize, true, &uplinkDetails, &downlinkDetails);
|
||||
} else {
|
||||
state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload), fPort, downlinkPayload, &downlinkSize, false, &uplinkDetails, &downlinkDetails);
|
||||
}
|
||||
debug(state < RADIOLIB_ERR_NONE, F("Error in sendReceive"), state, false);
|
||||
|
||||
// Check if a downlink was received
|
||||
// (state 0 = no downlink, state 1/2 = downlink in window Rx1/Rx2)
|
||||
if(state > 0) {
|
||||
Serial.println(F("Received a downlink"));
|
||||
// Did we get a downlink with data for us
|
||||
if(downlinkSize > 0) {
|
||||
Serial.println(F("Downlink data: "));
|
||||
arrayDump(downlinkPayload, downlinkSize);
|
||||
} else {
|
||||
Serial.println(F("<MAC commands only>"));
|
||||
}
|
||||
|
||||
// print RSSI (Received Signal Strength Indicator)
|
||||
Serial.print(F("[LoRaWAN] RSSI:\t\t"));
|
||||
Serial.print(radio.getRSSI());
|
||||
Serial.println(F(" dBm"));
|
||||
|
||||
// print SNR (Signal-to-Noise Ratio)
|
||||
Serial.print(F("[LoRaWAN] SNR:\t\t"));
|
||||
Serial.print(radio.getSNR());
|
||||
Serial.println(F(" dB"));
|
||||
|
||||
// print extra information about the event
|
||||
Serial.println(F("[LoRaWAN] Event information:"));
|
||||
Serial.print(F("[LoRaWAN] Confirmed:\t"));
|
||||
Serial.println(downlinkDetails.confirmed);
|
||||
Serial.print(F("[LoRaWAN] Confirming:\t"));
|
||||
Serial.println(downlinkDetails.confirming);
|
||||
Serial.print(F("[LoRaWAN] Datarate:\t"));
|
||||
Serial.println(downlinkDetails.datarate);
|
||||
Serial.print(F("[LoRaWAN] Frequency:\t"));
|
||||
Serial.print(downlinkDetails.freq, 3);
|
||||
Serial.println(F(" MHz"));
|
||||
Serial.print(F("[LoRaWAN] Frame count:\t"));
|
||||
Serial.println(downlinkDetails.fCnt);
|
||||
Serial.print(F("[LoRaWAN] Port:\t\t"));
|
||||
Serial.println(downlinkDetails.fPort);
|
||||
Serial.print(F("[LoRaWAN] Time-on-air: \t"));
|
||||
Serial.print(node.getLastToA());
|
||||
Serial.println(F(" ms"));
|
||||
Serial.print(F("[LoRaWAN] Rx window: \t"));
|
||||
Serial.println(state);
|
||||
|
||||
uint8_t margin = 0;
|
||||
uint8_t gwCnt = 0;
|
||||
if(node.getMacLinkCheckAns(&margin, &gwCnt) == RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("[LoRaWAN] LinkCheck margin:\t"));
|
||||
Serial.println(margin);
|
||||
Serial.print(F("[LoRaWAN] LinkCheck count:\t"));
|
||||
Serial.println(gwCnt);
|
||||
}
|
||||
|
||||
uint32_t networkTime = 0;
|
||||
uint8_t fracSecond = 0;
|
||||
if(node.getMacDeviceTimeAns(&networkTime, &fracSecond, true) == RADIOLIB_ERR_NONE) {
|
||||
Serial.print(F("[LoRaWAN] DeviceTime Unix:\t"));
|
||||
Serial.println(networkTime);
|
||||
Serial.print(F("[LoRaWAN] DeviceTime second:\t1/"));
|
||||
Serial.println(fracSecond);
|
||||
}
|
||||
|
||||
} else {
|
||||
Serial.println(F("[LoRaWAN] No downlink received"));
|
||||
}
|
||||
|
||||
// wait before sending another packet
|
||||
uint32_t minimumDelay = uplinkIntervalSeconds * 1000UL;
|
||||
uint32_t interval = node.timeUntilUplink(); // calculate minimum duty cycle delay (per FUP & law!)
|
||||
uint32_t delayMs = max(interval, minimumDelay); // cannot send faster than duty cycle allows
|
||||
|
||||
Serial.print(F("[LoRaWAN] Next uplink in "));
|
||||
Serial.print(delayMs/1000);
|
||||
Serial.println(F(" seconds\n"));
|
||||
|
||||
delay(delayMs);
|
||||
}
|
||||
145
RadioLib/examples/LoRaWAN/LoRaWAN_Reference/config.h
Normal file
145
RadioLib/examples/LoRaWAN/LoRaWAN_Reference/config.h
Normal file
@@ -0,0 +1,145 @@
|
||||
#ifndef _RADIOLIB_EX_LORAWAN_CONFIG_H
|
||||
#define _RADIOLIB_EX_LORAWAN_CONFIG_H
|
||||
|
||||
#include <RadioLib.h>
|
||||
|
||||
// first you have to set your radio model and pin configuration
|
||||
// this is provided just as a default example
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// if you have RadioBoards (https://github.com/radiolib-org/RadioBoards)
|
||||
// and are using one of the supported boards, you can do the following:
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// how often to send an uplink - consider legal & FUP constraints - see notes
|
||||
const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // minutes x seconds
|
||||
|
||||
// joinEUI - previous versions of LoRaWAN called this AppEUI
|
||||
// for development purposes you can use all zeros - see wiki for details
|
||||
#define RADIOLIB_LORAWAN_JOIN_EUI 0x0000000000000000
|
||||
|
||||
// the Device EUI & two keys can be generated on the TTN console
|
||||
#ifndef RADIOLIB_LORAWAN_DEV_EUI // Replace with your Device EUI
|
||||
#define RADIOLIB_LORAWAN_DEV_EUI 0x---------------
|
||||
#endif
|
||||
#ifndef RADIOLIB_LORAWAN_APP_KEY // Replace with your App Key
|
||||
#define RADIOLIB_LORAWAN_APP_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
|
||||
#endif
|
||||
#ifndef RADIOLIB_LORAWAN_NWK_KEY // Put your Nwk Key here
|
||||
#define RADIOLIB_LORAWAN_NWK_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
|
||||
#endif
|
||||
|
||||
// for the curious, the #ifndef blocks allow for automated testing &/or you can
|
||||
// put your EUI & keys in to your platformio.ini - see wiki for more tips
|
||||
|
||||
// regional choices: EU868, US915, AU915, AS923, AS923_2, AS923_3, AS923_4, IN865, KR920, CN500
|
||||
const LoRaWANBand_t Region = EU868;
|
||||
const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
|
||||
|
||||
// ============================================================================
|
||||
// Below is to support the sketch - only make changes if the notes say so ...
|
||||
|
||||
// copy over the EUI's & keys in to the something that will not compile if incorrectly formatted
|
||||
uint64_t joinEUI = RADIOLIB_LORAWAN_JOIN_EUI;
|
||||
uint64_t devEUI = RADIOLIB_LORAWAN_DEV_EUI;
|
||||
uint8_t appKey[] = { RADIOLIB_LORAWAN_APP_KEY };
|
||||
uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY };
|
||||
|
||||
// create the LoRaWAN node
|
||||
LoRaWANNode node(&radio, &Region, subBand);
|
||||
|
||||
// result code to text - these are error codes that can be raised when using LoRaWAN
|
||||
// however, RadioLib has many more - see https://jgromes.github.io/RadioLib/group__status__codes.html for a complete list
|
||||
String stateDecode(const int16_t result) {
|
||||
switch (result) {
|
||||
case RADIOLIB_ERR_NONE:
|
||||
return "ERR_NONE";
|
||||
case RADIOLIB_ERR_CHIP_NOT_FOUND:
|
||||
return "ERR_CHIP_NOT_FOUND";
|
||||
case RADIOLIB_ERR_PACKET_TOO_LONG:
|
||||
return "ERR_PACKET_TOO_LONG";
|
||||
case RADIOLIB_ERR_RX_TIMEOUT:
|
||||
return "ERR_RX_TIMEOUT";
|
||||
case RADIOLIB_ERR_CRC_MISMATCH:
|
||||
return "ERR_CRC_MISMATCH";
|
||||
case RADIOLIB_ERR_INVALID_BANDWIDTH:
|
||||
return "ERR_INVALID_BANDWIDTH";
|
||||
case RADIOLIB_ERR_INVALID_SPREADING_FACTOR:
|
||||
return "ERR_INVALID_SPREADING_FACTOR";
|
||||
case RADIOLIB_ERR_INVALID_CODING_RATE:
|
||||
return "ERR_INVALID_CODING_RATE";
|
||||
case RADIOLIB_ERR_INVALID_FREQUENCY:
|
||||
return "ERR_INVALID_FREQUENCY";
|
||||
case RADIOLIB_ERR_INVALID_OUTPUT_POWER:
|
||||
return "ERR_INVALID_OUTPUT_POWER";
|
||||
case RADIOLIB_ERR_NETWORK_NOT_JOINED:
|
||||
return "RADIOLIB_ERR_NETWORK_NOT_JOINED";
|
||||
case RADIOLIB_ERR_DOWNLINK_MALFORMED:
|
||||
return "RADIOLIB_ERR_DOWNLINK_MALFORMED";
|
||||
case RADIOLIB_ERR_INVALID_REVISION:
|
||||
return "RADIOLIB_ERR_INVALID_REVISION";
|
||||
case RADIOLIB_ERR_INVALID_PORT:
|
||||
return "RADIOLIB_ERR_INVALID_PORT";
|
||||
case RADIOLIB_ERR_NO_RX_WINDOW:
|
||||
return "RADIOLIB_ERR_NO_RX_WINDOW";
|
||||
case RADIOLIB_ERR_INVALID_CID:
|
||||
return "RADIOLIB_ERR_INVALID_CID";
|
||||
case RADIOLIB_ERR_UPLINK_UNAVAILABLE:
|
||||
return "RADIOLIB_ERR_UPLINK_UNAVAILABLE";
|
||||
case RADIOLIB_ERR_COMMAND_QUEUE_FULL:
|
||||
return "RADIOLIB_ERR_COMMAND_QUEUE_FULL";
|
||||
case RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND:
|
||||
return "RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND";
|
||||
case RADIOLIB_ERR_JOIN_NONCE_INVALID:
|
||||
return "RADIOLIB_ERR_JOIN_NONCE_INVALID";
|
||||
case RADIOLIB_ERR_N_FCNT_DOWN_INVALID:
|
||||
return "RADIOLIB_ERR_N_FCNT_DOWN_INVALID";
|
||||
case RADIOLIB_ERR_A_FCNT_DOWN_INVALID:
|
||||
return "RADIOLIB_ERR_A_FCNT_DOWN_INVALID";
|
||||
case RADIOLIB_ERR_DWELL_TIME_EXCEEDED:
|
||||
return "RADIOLIB_ERR_DWELL_TIME_EXCEEDED";
|
||||
case RADIOLIB_ERR_CHECKSUM_MISMATCH:
|
||||
return "RADIOLIB_ERR_CHECKSUM_MISMATCH";
|
||||
case RADIOLIB_ERR_NO_JOIN_ACCEPT:
|
||||
return "RADIOLIB_ERR_NO_JOIN_ACCEPT";
|
||||
case RADIOLIB_LORAWAN_SESSION_RESTORED:
|
||||
return "RADIOLIB_LORAWAN_SESSION_RESTORED";
|
||||
case RADIOLIB_LORAWAN_NEW_SESSION:
|
||||
return "RADIOLIB_LORAWAN_NEW_SESSION";
|
||||
case RADIOLIB_ERR_NONCES_DISCARDED:
|
||||
return "RADIOLIB_ERR_NONCES_DISCARDED";
|
||||
case RADIOLIB_ERR_SESSION_DISCARDED:
|
||||
return "RADIOLIB_ERR_SESSION_DISCARDED";
|
||||
}
|
||||
return "See https://jgromes.github.io/RadioLib/group__status__codes.html";
|
||||
}
|
||||
|
||||
// helper function to display any issues
|
||||
void debug(bool failed, const __FlashStringHelper* message, int state, bool halt) {
|
||||
if(failed) {
|
||||
Serial.print(message);
|
||||
Serial.print(" - ");
|
||||
Serial.print(stateDecode(state));
|
||||
Serial.print(" (");
|
||||
Serial.print(state);
|
||||
Serial.println(")");
|
||||
while(halt) { delay(1); }
|
||||
}
|
||||
}
|
||||
|
||||
// helper function to display a byte array
|
||||
void arrayDump(uint8_t *buffer, uint16_t len) {
|
||||
for(uint16_t c = 0; c < len; c++) {
|
||||
char b = buffer[c];
|
||||
if(b < 0x10) { Serial.print('0'); }
|
||||
Serial.print(b, HEX);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
RadioLib LoRaWAN Starter Example
|
||||
|
||||
! Please refer to the included notes to get started !
|
||||
|
||||
This example joins a LoRaWAN network and will send
|
||||
uplink packets. Before you start, you will have to
|
||||
register your device at https://www.thethingsnetwork.org/
|
||||
After your device is registered, you can run this example.
|
||||
The device will join the network and start uploading data.
|
||||
|
||||
Running this examples REQUIRES you to check "Resets DevNonces"
|
||||
on your LoRaWAN dashboard. Refer to the network's
|
||||
documentation on how to do this.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
|
||||
For LoRaWAN details, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/LoRaWAN
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
while(!Serial);
|
||||
delay(5000); // Give time to switch to the serial monitor
|
||||
Serial.println(F("\nSetup ... "));
|
||||
|
||||
Serial.println(F("Initialise the radio"));
|
||||
int16_t state = radio.begin();
|
||||
debug(state != RADIOLIB_ERR_NONE, F("Initialise radio failed"), state, true);
|
||||
|
||||
// Setup the OTAA session information
|
||||
state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
|
||||
debug(state != RADIOLIB_ERR_NONE, F("Initialise node failed"), state, true);
|
||||
|
||||
Serial.println(F("Join ('login') the LoRaWAN Network"));
|
||||
state = node.activateOTAA();
|
||||
debug(state != RADIOLIB_LORAWAN_NEW_SESSION, F("Join failed"), state, true);
|
||||
|
||||
Serial.println(F("Ready!\n"));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.println(F("Sending uplink"));
|
||||
|
||||
// This is the place to gather the sensor inputs
|
||||
// Instead of reading any real sensor, we just generate some random numbers as example
|
||||
uint8_t value1 = radio.random(100);
|
||||
uint16_t value2 = radio.random(2000);
|
||||
|
||||
// Build payload byte array
|
||||
uint8_t uplinkPayload[3];
|
||||
uplinkPayload[0] = value1;
|
||||
uplinkPayload[1] = highByte(value2); // See notes for high/lowByte functions
|
||||
uplinkPayload[2] = lowByte(value2);
|
||||
|
||||
// Perform an uplink
|
||||
int16_t state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload));
|
||||
debug(state < RADIOLIB_ERR_NONE, F("Error in sendReceive"), state, false);
|
||||
|
||||
// Check if a downlink was received
|
||||
// (state 0 = no downlink, state 1/2 = downlink in window Rx1/Rx2)
|
||||
if(state > 0) {
|
||||
Serial.println(F("Received a downlink"));
|
||||
} else {
|
||||
Serial.println(F("No downlink received"));
|
||||
}
|
||||
|
||||
Serial.print(F("Next uplink in "));
|
||||
Serial.print(uplinkIntervalSeconds);
|
||||
Serial.println(F(" seconds\n"));
|
||||
|
||||
// Wait until next uplink - observing legal & TTN FUP constraints
|
||||
delay(uplinkIntervalSeconds * 1000UL); // delay needs milli-seconds
|
||||
}
|
||||
145
RadioLib/examples/LoRaWAN/LoRaWAN_Starter/config.h
Normal file
145
RadioLib/examples/LoRaWAN/LoRaWAN_Starter/config.h
Normal file
@@ -0,0 +1,145 @@
|
||||
#ifndef _RADIOLIB_EX_LORAWAN_CONFIG_H
|
||||
#define _RADIOLIB_EX_LORAWAN_CONFIG_H
|
||||
|
||||
#include <RadioLib.h>
|
||||
|
||||
// first you have to set your radio model and pin configuration
|
||||
// this is provided just as a default example
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// if you have RadioBoards (https://github.com/radiolib-org/RadioBoards)
|
||||
// and are using one of the supported boards, you can do the following:
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// how often to send an uplink - consider legal & FUP constraints - see notes
|
||||
const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // minutes x seconds
|
||||
|
||||
// joinEUI - previous versions of LoRaWAN called this AppEUI
|
||||
// for development purposes you can use all zeros - see wiki for details
|
||||
#define RADIOLIB_LORAWAN_JOIN_EUI 0x0000000000000000
|
||||
|
||||
// the Device EUI & two keys can be generated on the TTN console
|
||||
#ifndef RADIOLIB_LORAWAN_DEV_EUI // Replace with your Device EUI
|
||||
#define RADIOLIB_LORAWAN_DEV_EUI 0x---------------
|
||||
#endif
|
||||
#ifndef RADIOLIB_LORAWAN_APP_KEY // Replace with your App Key
|
||||
#define RADIOLIB_LORAWAN_APP_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
|
||||
#endif
|
||||
#ifndef RADIOLIB_LORAWAN_NWK_KEY // Put your Nwk Key here
|
||||
#define RADIOLIB_LORAWAN_NWK_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
|
||||
#endif
|
||||
|
||||
// for the curious, the #ifndef blocks allow for automated testing &/or you can
|
||||
// put your EUI & keys in to your platformio.ini - see wiki for more tips
|
||||
|
||||
// regional choices: EU868, US915, AU915, AS923, AS923_2, AS923_3, AS923_4, IN865, KR920, CN500
|
||||
const LoRaWANBand_t Region = EU868;
|
||||
const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
|
||||
|
||||
// ============================================================================
|
||||
// Below is to support the sketch - only make changes if the notes say so ...
|
||||
|
||||
// copy over the EUI's & keys in to the something that will not compile if incorrectly formatted
|
||||
uint64_t joinEUI = RADIOLIB_LORAWAN_JOIN_EUI;
|
||||
uint64_t devEUI = RADIOLIB_LORAWAN_DEV_EUI;
|
||||
uint8_t appKey[] = { RADIOLIB_LORAWAN_APP_KEY };
|
||||
uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY };
|
||||
|
||||
// create the LoRaWAN node
|
||||
LoRaWANNode node(&radio, &Region, subBand);
|
||||
|
||||
// result code to text - these are error codes that can be raised when using LoRaWAN
|
||||
// however, RadioLib has many more - see https://jgromes.github.io/RadioLib/group__status__codes.html for a complete list
|
||||
String stateDecode(const int16_t result) {
|
||||
switch (result) {
|
||||
case RADIOLIB_ERR_NONE:
|
||||
return "ERR_NONE";
|
||||
case RADIOLIB_ERR_CHIP_NOT_FOUND:
|
||||
return "ERR_CHIP_NOT_FOUND";
|
||||
case RADIOLIB_ERR_PACKET_TOO_LONG:
|
||||
return "ERR_PACKET_TOO_LONG";
|
||||
case RADIOLIB_ERR_RX_TIMEOUT:
|
||||
return "ERR_RX_TIMEOUT";
|
||||
case RADIOLIB_ERR_CRC_MISMATCH:
|
||||
return "ERR_CRC_MISMATCH";
|
||||
case RADIOLIB_ERR_INVALID_BANDWIDTH:
|
||||
return "ERR_INVALID_BANDWIDTH";
|
||||
case RADIOLIB_ERR_INVALID_SPREADING_FACTOR:
|
||||
return "ERR_INVALID_SPREADING_FACTOR";
|
||||
case RADIOLIB_ERR_INVALID_CODING_RATE:
|
||||
return "ERR_INVALID_CODING_RATE";
|
||||
case RADIOLIB_ERR_INVALID_FREQUENCY:
|
||||
return "ERR_INVALID_FREQUENCY";
|
||||
case RADIOLIB_ERR_INVALID_OUTPUT_POWER:
|
||||
return "ERR_INVALID_OUTPUT_POWER";
|
||||
case RADIOLIB_ERR_NETWORK_NOT_JOINED:
|
||||
return "RADIOLIB_ERR_NETWORK_NOT_JOINED";
|
||||
case RADIOLIB_ERR_DOWNLINK_MALFORMED:
|
||||
return "RADIOLIB_ERR_DOWNLINK_MALFORMED";
|
||||
case RADIOLIB_ERR_INVALID_REVISION:
|
||||
return "RADIOLIB_ERR_INVALID_REVISION";
|
||||
case RADIOLIB_ERR_INVALID_PORT:
|
||||
return "RADIOLIB_ERR_INVALID_PORT";
|
||||
case RADIOLIB_ERR_NO_RX_WINDOW:
|
||||
return "RADIOLIB_ERR_NO_RX_WINDOW";
|
||||
case RADIOLIB_ERR_INVALID_CID:
|
||||
return "RADIOLIB_ERR_INVALID_CID";
|
||||
case RADIOLIB_ERR_UPLINK_UNAVAILABLE:
|
||||
return "RADIOLIB_ERR_UPLINK_UNAVAILABLE";
|
||||
case RADIOLIB_ERR_COMMAND_QUEUE_FULL:
|
||||
return "RADIOLIB_ERR_COMMAND_QUEUE_FULL";
|
||||
case RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND:
|
||||
return "RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND";
|
||||
case RADIOLIB_ERR_JOIN_NONCE_INVALID:
|
||||
return "RADIOLIB_ERR_JOIN_NONCE_INVALID";
|
||||
case RADIOLIB_ERR_N_FCNT_DOWN_INVALID:
|
||||
return "RADIOLIB_ERR_N_FCNT_DOWN_INVALID";
|
||||
case RADIOLIB_ERR_A_FCNT_DOWN_INVALID:
|
||||
return "RADIOLIB_ERR_A_FCNT_DOWN_INVALID";
|
||||
case RADIOLIB_ERR_DWELL_TIME_EXCEEDED:
|
||||
return "RADIOLIB_ERR_DWELL_TIME_EXCEEDED";
|
||||
case RADIOLIB_ERR_CHECKSUM_MISMATCH:
|
||||
return "RADIOLIB_ERR_CHECKSUM_MISMATCH";
|
||||
case RADIOLIB_ERR_NO_JOIN_ACCEPT:
|
||||
return "RADIOLIB_ERR_NO_JOIN_ACCEPT";
|
||||
case RADIOLIB_LORAWAN_SESSION_RESTORED:
|
||||
return "RADIOLIB_LORAWAN_SESSION_RESTORED";
|
||||
case RADIOLIB_LORAWAN_NEW_SESSION:
|
||||
return "RADIOLIB_LORAWAN_NEW_SESSION";
|
||||
case RADIOLIB_ERR_NONCES_DISCARDED:
|
||||
return "RADIOLIB_ERR_NONCES_DISCARDED";
|
||||
case RADIOLIB_ERR_SESSION_DISCARDED:
|
||||
return "RADIOLIB_ERR_SESSION_DISCARDED";
|
||||
}
|
||||
return "See https://jgromes.github.io/RadioLib/group__status__codes.html";
|
||||
}
|
||||
|
||||
// helper function to display any issues
|
||||
void debug(bool failed, const __FlashStringHelper* message, int state, bool halt) {
|
||||
if(failed) {
|
||||
Serial.print(message);
|
||||
Serial.print(" - ");
|
||||
Serial.print(stateDecode(state));
|
||||
Serial.print(" (");
|
||||
Serial.print(state);
|
||||
Serial.println(")");
|
||||
while(halt) { delay(1); }
|
||||
}
|
||||
}
|
||||
|
||||
// helper function to display a byte array
|
||||
void arrayDump(uint8_t *buffer, uint16_t len) {
|
||||
for(uint16_t c = 0; c < len; c++) {
|
||||
char b = buffer[c];
|
||||
if(b < 0x10) { Serial.print('0'); }
|
||||
Serial.print(b, HEX);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
#endif
|
||||
180
RadioLib/examples/LoRaWAN/LoRaWAN_Starter/notes.md
Normal file
180
RadioLib/examples/LoRaWAN/LoRaWAN_Starter/notes.md
Normal file
@@ -0,0 +1,180 @@
|
||||
|
||||
|
||||
# RadioLib LoRaWAN on TTN starter script
|
||||
|
||||
## Welcome
|
||||
|
||||
These notes are for someone who has successfully created a few sketches for their Arduino based device but is starting out with LoRaWAN. You don't have to be a C coding ninja but some familarity with C and procedural programming is assumed. The absolutely simplest way to get started is to buy some known good hardware that's all done for you so you can concentrate on the code & configuration.
|
||||
|
||||
|
||||
## Introduction
|
||||
|
||||
LoRaWAN is an amazing system for small battery powered sensors collecting data for years at a time. With great features comes some more complex elements which means it is not quite as simple as just providing WiFi credentials and pushing data through. It is in the range of setting up & customising the settings for a home router but with no wizards to do the heavy lifting for you. So we strongly recommend spending a couple of hours reviewing the TTN Getting Started section so you are aware of the minimum knowledge to make a successful start: https://www.thethingsnetwork.org/docs/lorawan/. Johan's video is amazing but is also drinking from the firehose. Read the text first and then watch the video on Youtube where there are bookmarks to deliver it in small digestable chunks.
|
||||
|
||||
These notes plus a lot more are available in the wiki: https://github.com/jgromes/RadioLib/wiki/LoRaWAN
|
||||
|
||||
For questions about using RadioLib there is the discussions section (https://github.com/jgromes/RadioLib/discussions) and if you believe you've found an issue (aka bug), the issues section (https://github.com/jgromes/RadioLib/issues). If posting an issue please ensure you tell us what hardware you are using and provide a debug log - make sure you enable `RADIOLIB_DEBUG_PROTOCOL`. If the question is more LoRaWAN or firmware related, then you can use the TTN forum: https://www.thethingsnetwork.org/forum/
|
||||
|
||||
|
||||
## Register & setup on TTN
|
||||
|
||||
This sketch isn't particularly aimed at The Things Stack (TTS) but you can get a free Sandbox account and the following instructions are for that. Helium does not support LoRaWAN v1.1 which is the version implemented by RadioLib. Chirpstack & other LoRaWAN Network Server (LNS) stacks have not yet been tried so YMMV.
|
||||
|
||||
Why no screen shots? TTS is a web based app, one that you will need to become familiar with and we will need to direct you to some of the less obvious parts. So much better that you learn the layouts in concept than slavishly follow screen shots that can & will go stale.
|
||||
|
||||
There will be some instructions that you have to take on face value. You didn't learn to run before you walked and it's so much more encouraging to get started and build on success than get bogged down in endless details. Once you are up & running more of the details start to slot in to place.
|
||||
|
||||
### Register on TTN
|
||||
|
||||
Go to https://www.thethingsnetwork.org/get-started and register - just like any other website. These instructions are for TTS Sandbox.
|
||||
|
||||
Once you have confirmed your email address, you can login to the console here: https://console.cloud.thethings.network/. If you allow your browser to share your location the best console will be selected. For most users the best one is the obvious one, if you have any doubts you can ask on the forum here: https://www.thethingsnetwork.org/forum/ - you login with the exact same details.
|
||||
|
||||
It is simpler to register your gateway first. If you don't have a gateway, then a The Things Indoor Gateway (TTIG) is a very affordable option. A gateway gives you a console to see if your device is being heard and is hugely useful when debugging a DIY device. If you are in range of a community gateway you may be lucky with your first device creation but you will never know if you are in range unless you have access to that gateway's console.
|
||||
|
||||
You can read up on key concepts and troubleshooting here: https://www.thethingsindustries.com/docs/gateways/
|
||||
|
||||
LoRa stands for Long Range - having the gateway & device on the same desk tends to overload both receiver circuits when they hear a transmission so close to hand. The gateway should be 5 - 10m away, preferably with a solid wall in the way as well.
|
||||
|
||||
### Create your application
|
||||
|
||||
An application is like a box to keep some devices in - normally doing the same thing - on larger deployments this may be 1,000's of similar devices. Starting out it is likely to be just a few so there is no need to get concerned about how to divide up your use just yet.
|
||||
|
||||
Onced logged in to the console you can go in to Applications to create your first application. The ID must be all lower case or numbers, no spaces, dashes are OK and it has to be unique to the entire TTN community - so `first-app` will be rejected - you could use `your-username-first-app` as that's likely to be unique. The name and description are for your own use and are optional.
|
||||
|
||||
The main menu for an application is in the left hand panel - nothing is needed there just yet.
|
||||
|
||||
### Create your device
|
||||
|
||||
On the right hand side about half way down on your application's summary is a big blue button `+ Register end device`. Click this to create the settings for your first device.
|
||||
|
||||
You are making your own device using a third party LoRaWAN stack so there will not be an entry in the device repository so choose 'Enter end device specifics manually'.
|
||||
|
||||
Choose the Frequency plan appropriate for your region. Consider that almost all countries have laws relating to what frequencies you use so don't get creative. For Europe please use the recommended option. For other regions use the entry marked 'used by TTN'.
|
||||
|
||||
Choose LoRaWAN 1.1.0 - the last one in the list - the latest specfication. RadioLib uses RP001 Regional Parameters 1.1 revision B.
|
||||
|
||||
At this point you will be asked for your JoinEUI. As this is a DIY device and we are using RadioLib, you can use all zero's as recommended by The LoRa Alliance TR007 Technical Recommendations document. Once you've put in all zeros and clicked confirm you will be asked for a DevEUI, AppKey and NwkKey. It is preferable to have the console generate them so they are properly formatted.
|
||||
|
||||
Your End device ID can be changed to make the device more identifiable. Something related to your hardware helps - like devicename-01. The you can click the blue 'Register device'.
|
||||
|
||||
When many sensors are big deployed, a device is registered, batteries put in, it joins and gets on with sending data for the next few years. For development purposes we need to turn off one of the security settings so that you can join & uplink out of the normal sequence that a device in the field would do.
|
||||
|
||||
Click on General Settings, scroll down to Join settings, click the Expand button, scroll down and click the 'Resets join nonces' option. You will see a warning about replay attacks which is entirely proper & correct. If anyone eavesdropping in your area on your LoRa transmissions could fake a join and send uplinks from their device but only if they happened to find out your AppKey & NwkKey which is kept securely on the TTN servers and is never transmitted over the air, so they'd also have to login to your account, which is protected by your password.
|
||||
|
||||
You then need to copy over the device details in to the config file for RadioLib. There are buttons to copy items to the clipboard so you don't have to hand type them.
|
||||
|
||||
### Copy & Paste made easy
|
||||
|
||||
You can copy the EUIs & keys from the device overview section.
|
||||
|
||||
The EUIs are really straightforward - click the clipboard icon at the right hand end of the EUI display field and it will be copied in the format you need. You can then paste it in to the code - you must leave the 0x in place so the compiler knows that it's a hex value.
|
||||
|
||||
The keys are relatively straightforward. Click the eye icon at the right hand end of the field. Then click the <> icon that will appear to the left. This will format the hex values as an array. Then you can click the clipboard icon to copy the array and then paste it between the { } brackets.
|
||||
|
||||
### Secrets to keep safe.
|
||||
|
||||
The Join & Dev EUI's are transmitted in plain text when the device joins a network. The gateway ID is public. If you have an issue and are asked for details, there are only three things to keep private - your password, the keys which are used for encryption and any API keys you create which are used for accessing your data & configuration.
|
||||
|
||||
|
||||
### Monitoring your device
|
||||
|
||||
If you are on your application summary page you'll see uplinks in the small activity box top right with a link to the full size table. If you click the Live Data menu item on the left it will show activity for all the devices registered on the application in the full window.
|
||||
|
||||
If you just want your devices activity, from the summary page click on the device in the list in the middle of the page.
|
||||
|
||||
The main menu for a device is the horizontal band: Overview, Live Data, Messaging etc. You can click Live Data or the link above the small activity box.
|
||||
|
||||
**The console shows LIVE data - not a history of everything that has ever happened. A LNS is a management & relay service, not a database. When you open the console you may see a summary of recent activity - this is a bonus. You must leave the console open, even in another tab, if you want to see live activity.**
|
||||
|
||||
|
||||
### Explore
|
||||
|
||||
Nothing on the console can be upset unless you confirm a warning message, so you are safe to explore the different menus to orientate yourself. This is very good idea so you have an understanding of the layout of the land and shouldn't take more than 10 or 15 minutes. The documentation & volunteers on GitHub and the TTN forum will make refer to parts of the console without giving blow by blow directions.
|
||||
|
||||
|
||||
|
||||
|
||||
## The config.h
|
||||
|
||||
### The uplinkInterval
|
||||
|
||||
LoRaWAN devices typically send small amounts of data at intervals between 15 minutes through to once per day. This allows a device to run on two AA batteries for 2 to 5 years. Hoping that LoRaWAN can move lots of data and your device can regularly receive commands to do something on demand is trying to bend the LoRaWAN system in ways it is not designed for and usually ends up with far too many issues to unravel.
|
||||
|
||||
The radio frequencies that are used are usually shared with other Industrial, Scientific & Medical, known as ISM, users. The LoRa modulation is particularly resistant to interference due to other simultaneous transmissions on the same frequency but too much local activity will mean that not all uplinks get through. The Things Industries suggest designing a system to a potential packet loss rate of 10%. Typically we see 1 or 2% loss. This is entirely down to shared use of the radio waves, once an uplink is heard by a gateway the system is super reliable through The Things Stack.
|
||||
|
||||
To ensure that the shared ISM bands are fairly used there are limits defined in law on how often you can transmit, called Duty Cycle. The details vary by region or country but typically you can only transmit for 1% of the time. Some frequencies you can only use 0.1% of the time. See https://www.thethingsnetwork.org/docs/lorawan/duty-cycle/ for more information.
|
||||
|
||||
Additionally, as The Things Stack Sandbox aka TTN is an array of servers in three locations around the world paid for by The Things Industries, there is a Fair Use Policy so that those learning LoRaWAN, communities, hobbyists & makers are guided on how much of the resource any one device can use. In short, it's 30 seconds of airtime a day and 10 downlinks. When a gateway is transmitting a downlink it can not hear any uplinks (contributing to the potential uplink loss outlined above). The community consensus is that 1 downlink a fortnight to update or adjust settings is appropriate. See https://www.thethingsnetwork.org/docs/lorawan/duty-cycle/#fair-use-policy for more information.
|
||||
|
||||
You can see what intervals can be used with this interactive calculator: https://avbentem.github.io/airtime-calculator/ttn/. Devices further away from gateways will have to use a higher Spread Factor to be heard - do not assume everything will happen at SF7. An uplink takes a minimum of 6 seconds from start to end, sometimes longer if the device is further away from the gateway, so you will need to be patient for just a short while whilst waiting for feedback after seeing "Sending uplink"
|
||||
|
||||
With all these considerations, trying to use LoRaWAN for command & control isn't appropriate and realtime GPS tracking almost always breaches FUP and usually legal limits, leaving aside the challenges of coverage.
|
||||
|
||||
See the hints & tips section on testing your device.
|
||||
|
||||
|
||||
### EUI's & Keys
|
||||
|
||||
In the `config.h` towards the top there are four lines thus:
|
||||
|
||||
// replace-with-your-device-id
|
||||
uint64_t joinEUI = 0x0000000000000000;
|
||||
uint64_t devEUI = 0x0000000000000000;
|
||||
uint8_t appKey[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t nwkKey[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
On the TTN console on the device summary page, click the clipboard icon next to the DevEUI, highlight the 16 0's in the third line after the x and paste.
|
||||
|
||||
The devEUI must start with 0x and will end up looking something like 0x70B3D57ED006544E
|
||||
|
||||
For the appKey we need TTN to format it correctly. Click the eye icon and an extra icon will appear <> - click this and the key will be formatted for you. Click the clipboard icon and then paste over the 32 0x00's in the config file. Then do the same for nwkKey.
|
||||
|
||||
A key will end up something like 0x31, 0x16, 0x6A, 0x22, 0x97, 0x52, 0xB6, 0x34, 0x57, 0x45, 0x1B, 0xC3, 0xC9, 0xD8, 0x83, 0xE8
|
||||
|
||||
|
||||
### Region
|
||||
|
||||
The region value you use MUST match the one you selected on the console.
|
||||
|
||||
If you are using US915 or AU915 then you should change the subBand const to 2.
|
||||
|
||||
### The pinmap
|
||||
|
||||
This is the connection between your microcontroller (ESP32, ATmega, SAMD etc.) and the radio (SX1276, SX1262, LR1110 etc.).
|
||||
You have to select the correct module and set the correct pins.
|
||||
|
||||
Pin maps for commonly used radio modules are kept in a separate library, called RadioBoards: https://github.com/radiolib-org/RadioBoards
|
||||
|
||||
It can automatically detect your microcontroller platform and radio, and configure things for you. If you have a board that is not supported by RadioBoards, feel free to suggest it in the RadioBoards issues, or better yet - open a pull request there!
|
||||
|
||||
|
||||
## Observations on the main sketch
|
||||
|
||||
Most of the sketch has comments that tell you what the various parts are doing. This should add a little more info:
|
||||
|
||||
### The Join
|
||||
|
||||
When a device is first started, it needs to register with the LoRaWAN Network Server (LNS) and setup it's session. With the settings from the console copied over and a gateway an appropriate distance away, most of the time the join will 'just work'.
|
||||
|
||||
If it doesn't, then there is no point trying repeatedly without going through the troubleshootng sequence. So this starter sketch will try once only to save the airwaves & TTN Community servers from repeated misfires.
|
||||
|
||||
|
||||
### The payload
|
||||
|
||||
You may see other starter sketches sending text. Apart from being massively inefficient, the text isn't easily displayed on the TTN console which makes it rather pointless and pro embedded engineers don't send strings. So this sketch sends the data as a sequence of bytes as recommended.
|
||||
|
||||
Further reading on this can be found here, just ignore the pink message about v2, it's all still valid: https://www.thethingsnetwork.org/docs/devices/bytes/
|
||||
|
||||
We've not assumed anything about any sensors you have, so we are just reading a digital & an analog pin. An analog reading is typically a two byte value - an integer - this is split using the Arduino highByte & lowByte function. You'll see how we put it back together in the TTN console below.
|
||||
|
||||
|
||||
## TTN Console Payload Decoder
|
||||
|
||||
Coming soon
|
||||
|
||||
## Hints & Tips
|
||||
|
||||
### Device testing
|
||||
|
||||
The LoRaWAN code base works to a specification and once you are happy your device is able to join & send a few dozen uplinks, continuing to sit around waiting for an uplink to test your sensor code & payload format is a waste of your time. The solution is to write everything else in a different sketch, output the array to the serial console and then you can copy & paste the hex array in to the TTN console Payload Formatters section to test the decoding.
|
||||
37
RadioLib/examples/LoRaWAN/README.md
Normal file
37
RadioLib/examples/LoRaWAN/README.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# LoRaWAN examples
|
||||
RadioLib LoRaWAN examples.
|
||||
|
||||
* [LoRaWAN_Starter](https://github.com/jgromes/RadioLib/tree/master/examples/LoRaWAN/LoRaWAN_Starter): this is the recommended entry point for new users. Please read the [`notes`](https://github.com/jgromes/RadioLib/blob/master/examples/LoRaWAN/LoRaWAN_Starter/notes.md) that come with this example to learn more about LoRaWAN and how to use it in RadioLib!
|
||||
* [LoRaWAN_Reference](https://github.com/jgromes/RadioLib/tree/master/examples/LoRaWAN/LoRaWAN_Reference): this sketch showcases most of the available API for LoRaWAN in RadioLib. Be frightened by the possibilities! It is recommended you have read all the [`notes`](https://github.com/jgromes/RadioLib/blob/master/examples/LoRaWAN/LoRaWAN_Starter/notes.md) for the Starter sketch first, as well as the [Learn section on The Things Network](https://www.thethingsnetwork.org/docs/lorawan/)!
|
||||
* [LoRaWAN_ABP](https://github.com/jgromes/RadioLib/tree/master/examples/LoRaWAN/LoRaWAN_ABP): if you wish to use ABP instead of OTAA (but why?), this example shows how you can do this using RadioLib.
|
||||
|
||||
## LoRaWAN versions & regional parameters
|
||||
RadioLib implements both LoRaWAN Specification 1.1 and 1.0.4. Confusingly, 1.0.4 is newer than 1.1, but 1.1 includes more security checks and as such **LoRaWAN 1.1 is preferred**.
|
||||
The catch is in the Regional Parameters: as RP002 1.0.4 is newer than RP001 1.1, it is more up to date regarding local laws & regulations. Therefore, RadioLib implements 1.0.4 as baseline and 1.1 (revision B) as fallback, and as such **RP002 Regional Parameters 1.0.4 is preferred**.
|
||||
_Note: the CN500 band is implemented as specified in RP001 1.1 revision B, as the RP002 1.0.4 version is much too complex._
|
||||
|
||||
To activate a LoRaWAN 1.1 session, supply all the required keys:
|
||||
```cpp
|
||||
node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
|
||||
node.beginABP(devAddr, fNwkSIntKey, sNwkSIntKey, nwkSEncKey, appSKey);
|
||||
```
|
||||
|
||||
To activate a LoRaWAN 1.0.4 session, set the keys that are not available to `NULL`:
|
||||
```cpp
|
||||
node.beginOTAA(joinEUI, devEUI, NULL, appKey);
|
||||
node.beginABP(devAddr, NULL, NULL, nwkSEncKey, appSKey);
|
||||
```
|
||||
|
||||
The device doesn't need to know the Regional Parameters version - that is of importance on the console.
|
||||
|
||||
## LoRaWAN persistence
|
||||
> [!WARNING]
|
||||
> These examples do not actually comply with LoRaWAN 1.0.4/1.1: for that, persistent storage is necessary. As the implementation of persistent storage differs between different platforms, these are not given here, but in a separate repository, see below:
|
||||
|
||||
In [this repository](https://github.com/radiolib-org/radiolib-persistence), examples are provided that do comply with the required persistence of certain parameters for LoRaWAN 1.1. Examples are (or will become) available for some of the most popular platforms. **These examples assume you have successfully used the Starter sketch and understood (most of) the accompanying notes!**
|
||||
Currently, examples are available for the following platforms:
|
||||
|
||||
* [LoRaWAN for ESP32](https://github.com/radiolib-org/radiolib-persistence/tree/main/examples/LoRaWAN_ESP32)
|
||||
* [LoRaWAN for ESP8266](https://github.com/radiolib-org/radiolib-persistence/tree/main/examples/LoRaWAN_ESP8266)
|
||||
|
||||
_This list is last updated at 30/03/2024._
|
||||
119
RadioLib/examples/Morse/Morse_Receive_AM/Morse_Receive_AM.ino
Normal file
119
RadioLib/examples/Morse/Morse_Receive_AM/Morse_Receive_AM.ino
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
RadioLib SX127x Morse Receive AM Example
|
||||
|
||||
This example receives Morse code message using
|
||||
SX1278's FSK modem. The signal is expected to be
|
||||
modulated as OOK, to be demodulated in AM mode.
|
||||
|
||||
Other modules that can be used for Morse Code
|
||||
with AFSK modulation:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- Si443x/RFM2x
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create AFSK client instance using the FSK module
|
||||
// pin 5 is connected to SX1278 DIO2
|
||||
AFSKClient audio(&radio, 5);
|
||||
|
||||
// create Morse client instance using the AFSK instance
|
||||
MorseClient morse(&audio);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// when using one of the non-LoRa modules for Morse code
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
// initialize Morse client
|
||||
Serial.print(F("[Morse] Initializing ... "));
|
||||
// AFSK tone frequency: 400 Hz
|
||||
// speed: 20 words per minute
|
||||
state = morse.begin(400);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// after that, set mode to OOK to emulate AM modulation
|
||||
Serial.print(F("[SX1278] Switching to OOK ... "));
|
||||
state = radio.setOOK(true);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// start direct mode reception
|
||||
radio.receiveDirect();
|
||||
}
|
||||
|
||||
// save symbol and length between loops
|
||||
byte symbol = 0;
|
||||
byte len = 0;
|
||||
|
||||
void loop() {
|
||||
// try to read a new symbol
|
||||
int state = morse.read(&symbol, &len);
|
||||
|
||||
// check if we have something to decode
|
||||
if(state != RADIOLIB_MORSE_INTER_SYMBOL) {
|
||||
// decode and print
|
||||
Serial.print(MorseClient::decode(symbol, len));
|
||||
|
||||
// reset the symbol buffer
|
||||
symbol = 0;
|
||||
len = 0;
|
||||
|
||||
// check if we have a complete word
|
||||
if(state == RADIOLIB_MORSE_WORD_COMPLETE) {
|
||||
// inter-word space, interpret that as a new line
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
135
RadioLib/examples/Morse/Morse_Transmit_AM/Morse_Transmit_AM.ino
Normal file
135
RadioLib/examples/Morse/Morse_Transmit_AM/Morse_Transmit_AM.ino
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
RadioLib Morse Transmit AM Example
|
||||
|
||||
This example sends Morse code message using
|
||||
SX1278's FSK modem. The signal is modulated
|
||||
as OOK, and may be demodulated in AM mode.
|
||||
|
||||
Other modules that can be used for Morse Code
|
||||
with AM modulation:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- Si443x/RFM2x
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create AFSK client instance using the FSK module
|
||||
// pin 5 is connected to SX1278 DIO2
|
||||
AFSKClient audio(&radio, 5);
|
||||
|
||||
// create Morse client instance using the AFSK instance
|
||||
MorseClient morse(&audio);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
|
||||
// when using one of the non-LoRa modules for Morse code
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize Morse client
|
||||
Serial.print(F("[Morse] Initializing ... "));
|
||||
// tone frequency: 400 Hz
|
||||
// speed: 20 words per minute
|
||||
state = morse.begin(400);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// after that, set mode to OOK to emulate AM modulation
|
||||
Serial.print(F("[SX1278] Switching to OOK ... "));
|
||||
state = radio.setOOK(true);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[Morse] Sending Morse data ... "));
|
||||
|
||||
// MorseClient supports all methods of the Serial class
|
||||
// NOTE: Characters that do not have ITU-R M.1677-1
|
||||
// representation will not be sent! Lower case
|
||||
// letters will be capitalized.
|
||||
|
||||
// send start signal first
|
||||
morse.startSignal();
|
||||
|
||||
// Arduino String class
|
||||
String aStr = "Arduino String";
|
||||
morse.print(aStr);
|
||||
|
||||
// character array (C-String)
|
||||
morse.print("C-String");
|
||||
|
||||
// string saved in flash
|
||||
morse.print(F("Flash String"));
|
||||
|
||||
// character
|
||||
morse.print('c');
|
||||
|
||||
// byte
|
||||
// formatting DEC/HEX/OCT/BIN is supported for
|
||||
// any integer type (byte/int/long)
|
||||
morse.print(255, HEX);
|
||||
|
||||
// integer number
|
||||
int i = 1000;
|
||||
morse.print(i);
|
||||
|
||||
// floating point number
|
||||
// NOTE: When using println(), the transmission will be
|
||||
// terminated with end-of-work signal (...-.-).
|
||||
float f = -3.1415;
|
||||
morse.println(f, 3);
|
||||
|
||||
Serial.println(F("done!"));
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
||||
132
RadioLib/examples/Morse/Morse_Transmit_FM/Morse_Transmit_FM.ino
Normal file
132
RadioLib/examples/Morse/Morse_Transmit_FM/Morse_Transmit_FM.ino
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
RadioLib Morse Transmit AFSK Example
|
||||
|
||||
This example sends Morse code message using
|
||||
SX1278's FSK modem. The signal is modulated
|
||||
as AFSK, and may be demodulated in FM mode.
|
||||
|
||||
Other modules that can be used for Morse Code
|
||||
with AFSK modulation:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- Si443x/RFM2x
|
||||
- SX126x/LLCC68
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create AFSK client instance using the FSK module
|
||||
// this requires connection to the module direct
|
||||
// input pin, here connected to Arduino pin 5
|
||||
// SX127x/RFM9x: DIO2
|
||||
// RF69: DIO2
|
||||
// SX1231: DIO2
|
||||
// CC1101: GDO2
|
||||
// Si443x/RFM2x: GPIO
|
||||
// SX126x/LLCC68: DIO2
|
||||
AFSKClient audio(&radio, 5);
|
||||
|
||||
// create Morse client instance using the AFSK instance
|
||||
MorseClient morse(&audio);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
|
||||
// when using one of the non-LoRa modules for Morse code
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize Morse client
|
||||
Serial.print(F("[Morse] Initializing ... "));
|
||||
// tone frequency: 400 Hz
|
||||
// speed: 20 words per minute
|
||||
state = morse.begin(400);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[Morse] Sending Morse data ... "));
|
||||
|
||||
// MorseClient supports all methods of the Serial class
|
||||
// NOTE: Characters that do not have ITU-R M.1677-1
|
||||
// representation will not be sent! Lower case
|
||||
// letters will be capitalized.
|
||||
|
||||
// send start signal first
|
||||
morse.startSignal();
|
||||
|
||||
// Arduino String class
|
||||
String aStr = "Arduino String";
|
||||
morse.print(aStr);
|
||||
|
||||
// character array (C-String)
|
||||
morse.print("C-String");
|
||||
|
||||
// string saved in flash
|
||||
morse.print(F("Flash String"));
|
||||
|
||||
// character
|
||||
morse.print('c');
|
||||
|
||||
// byte
|
||||
// formatting DEC/HEX/OCT/BIN is supported for
|
||||
// any integer type (byte/int/long)
|
||||
morse.print(255, HEX);
|
||||
|
||||
// integer number
|
||||
int i = 1000;
|
||||
morse.print(i);
|
||||
|
||||
// floating point number
|
||||
// NOTE: When using println(), the transmission will be
|
||||
// terminated with end-of-work signal (...-.-).
|
||||
float f = -3.1415;
|
||||
morse.println(f, 3);
|
||||
|
||||
Serial.println(F("done!"));
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
RadioLib Morse Transmit SSB Example
|
||||
|
||||
This example sends Morse code message using
|
||||
SX1278's FSK modem. The signal is an unmodulated
|
||||
carrier wave, and may be demodulated in SSB mode.
|
||||
|
||||
Other modules that can be used for Morse Code:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- SX126x
|
||||
- nRF24
|
||||
- Si443x/RFM2x
|
||||
- SX128x
|
||||
- LR11x0
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create Morse client instance using the FSK module
|
||||
MorseClient morse(&radio);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
|
||||
// when using one of the non-LoRa modules for Morse code
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize Morse client
|
||||
Serial.print(F("[Morse] Initializing ... "));
|
||||
// carrier wave frequency: 434.0 MHz
|
||||
// speed: 20 words per minute
|
||||
state = morse.begin(434.0);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[Morse] Sending Morse data ... "));
|
||||
|
||||
// MorseClient supports all methods of the Serial class
|
||||
// NOTE: Characters that do not have ITU-R M.1677-1
|
||||
// representation will not be sent! Lower case
|
||||
// letters will be capitalized.
|
||||
|
||||
// send start signal first
|
||||
morse.startSignal();
|
||||
|
||||
// Arduino String class
|
||||
String aStr = "Arduino String";
|
||||
morse.print(aStr);
|
||||
|
||||
// character array (C-String)
|
||||
morse.print("C-String");
|
||||
|
||||
// string saved in flash
|
||||
morse.print(F("Flash String"));
|
||||
|
||||
// character
|
||||
morse.print('c');
|
||||
|
||||
// byte
|
||||
// formatting DEC/HEX/OCT/BIN is supported for
|
||||
// any integer type (byte/int/long)
|
||||
morse.print(255, HEX);
|
||||
|
||||
// integer number
|
||||
int i = 1000;
|
||||
morse.print(i);
|
||||
|
||||
// floating point number
|
||||
// NOTE: When using println(), the transmission will be
|
||||
// terminated with end-of-work signal (...-.-).
|
||||
float f = -3.1415;
|
||||
morse.println(f, 3);
|
||||
|
||||
Serial.println(F("done!"));
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
||||
7
RadioLib/examples/NonArduino/ESP-IDF/CMakeLists.txt
Normal file
7
RadioLib/examples/NonArduino/ESP-IDF/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# include the top-level cmake
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
|
||||
# name the project something nice
|
||||
project(esp-sx1261)
|
||||
10
RadioLib/examples/NonArduino/ESP-IDF/README.md
Normal file
10
RadioLib/examples/NonArduino/ESP-IDF/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# RadioLib ESP-IDF example
|
||||
|
||||
This example shows how to use RadioLib as ESP-IDF component, without the Arduino framework. To run in ESP-IDF (or on any other platform), RadioLib includes an internal hardware abstraction layer (HAL). This software layer takes care of basic interaction with the hardware, such as performing SPI transaction or GPIO operations. To run on your chosen ESP microcontroller, you will likely have to customize the example HAL for your specific ESP type.
|
||||
|
||||
## Structure of the example
|
||||
|
||||
* `main/CMakeLists.txt` - IDF component CMake file
|
||||
* `main/EspHal.h` - RadioLib HAL example implementation
|
||||
* `main/idf_component.yml` - declaration of the RadioLib dependency for this example
|
||||
* `main/main.cpp` - the example source code
|
||||
4
RadioLib/examples/NonArduino/ESP-IDF/main/CMakeLists.txt
Normal file
4
RadioLib/examples/NonArduino/ESP-IDF/main/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
# register the component and set "RadioLib", "esp_timer" and "driver" as required
|
||||
idf_component_register(SRCS "main.cpp"
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES RadioLib esp_timer driver)
|
||||
322
RadioLib/examples/NonArduino/ESP-IDF/main/EspHal.h
Normal file
322
RadioLib/examples/NonArduino/ESP-IDF/main/EspHal.h
Normal file
@@ -0,0 +1,322 @@
|
||||
#ifndef ESP_HAL_H
|
||||
#define ESP_HAL_H
|
||||
|
||||
// include RadioLib
|
||||
#include <RadioLib.h>
|
||||
|
||||
// this example only works on ESP32 and is unlikely to work on ESP32S2/S3 etc.
|
||||
// if you need high portability, you should probably use Arduino anyway ...
|
||||
#if CONFIG_IDF_TARGET_ESP32 == 0
|
||||
#error This example HAL only supports ESP32 targets. Support for ESP32S2/S3 etc. can be added by adjusting this file to user needs.
|
||||
#endif
|
||||
|
||||
// include all the dependencies
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp32/rom/gpio.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/spi_reg.h"
|
||||
#include "soc/spi_struct.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "hal/gpio_hal.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
// define Arduino-style macros
|
||||
#define LOW (0x0)
|
||||
#define HIGH (0x1)
|
||||
#define INPUT (0x01)
|
||||
#define OUTPUT (0x03)
|
||||
#define RISING (0x01)
|
||||
#define FALLING (0x02)
|
||||
#define NOP() asm volatile ("nop")
|
||||
|
||||
#define MATRIX_DETACH_OUT_SIG (0x100)
|
||||
#define MATRIX_DETACH_IN_LOW_PIN (0x30)
|
||||
|
||||
// all of the following is needed to calculate SPI clock divider
|
||||
#define ClkRegToFreq(reg) (apb_freq / (((reg)->clkdiv_pre + 1) * ((reg)->clkcnt_n + 1)))
|
||||
|
||||
typedef union {
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint32_t clkcnt_l: 6;
|
||||
uint32_t clkcnt_h: 6;
|
||||
uint32_t clkcnt_n: 6;
|
||||
uint32_t clkdiv_pre: 13;
|
||||
uint32_t clk_equ_sysclk: 1;
|
||||
};
|
||||
} spiClk_t;
|
||||
|
||||
uint32_t getApbFrequency() {
|
||||
rtc_cpu_freq_config_t conf;
|
||||
rtc_clk_cpu_freq_get_config(&conf);
|
||||
|
||||
if(conf.freq_mhz >= 80) {
|
||||
return(80 * MHZ);
|
||||
}
|
||||
|
||||
return((conf.source_freq_mhz * MHZ) / conf.div);
|
||||
}
|
||||
|
||||
uint32_t spiFrequencyToClockDiv(uint32_t freq) {
|
||||
uint32_t apb_freq = getApbFrequency();
|
||||
if(freq >= apb_freq) {
|
||||
return SPI_CLK_EQU_SYSCLK;
|
||||
}
|
||||
|
||||
const spiClk_t minFreqReg = { 0x7FFFF000 };
|
||||
uint32_t minFreq = ClkRegToFreq((spiClk_t*) &minFreqReg);
|
||||
if(freq < minFreq) {
|
||||
return minFreqReg.value;
|
||||
}
|
||||
|
||||
uint8_t calN = 1;
|
||||
spiClk_t bestReg = { 0 };
|
||||
int32_t bestFreq = 0;
|
||||
while(calN <= 0x3F) {
|
||||
spiClk_t reg = { 0 };
|
||||
int32_t calFreq;
|
||||
int32_t calPre;
|
||||
int8_t calPreVari = -2;
|
||||
|
||||
reg.clkcnt_n = calN;
|
||||
|
||||
while(calPreVari++ <= 1) {
|
||||
calPre = (((apb_freq / (reg.clkcnt_n + 1)) / freq) - 1) + calPreVari;
|
||||
if(calPre > 0x1FFF) {
|
||||
reg.clkdiv_pre = 0x1FFF;
|
||||
} else if(calPre <= 0) {
|
||||
reg.clkdiv_pre = 0;
|
||||
} else {
|
||||
reg.clkdiv_pre = calPre;
|
||||
}
|
||||
reg.clkcnt_l = ((reg.clkcnt_n + 1) / 2);
|
||||
calFreq = ClkRegToFreq(®);
|
||||
if(calFreq == (int32_t) freq) {
|
||||
memcpy(&bestReg, ®, sizeof(bestReg));
|
||||
break;
|
||||
} else if(calFreq < (int32_t) freq) {
|
||||
if(RADIOLIB_ABS(freq - calFreq) < RADIOLIB_ABS(freq - bestFreq)) {
|
||||
bestFreq = calFreq;
|
||||
memcpy(&bestReg, ®, sizeof(bestReg));
|
||||
}
|
||||
}
|
||||
}
|
||||
if(calFreq == (int32_t) freq) {
|
||||
break;
|
||||
}
|
||||
calN++;
|
||||
}
|
||||
return(bestReg.value);
|
||||
}
|
||||
|
||||
// create a new ESP-IDF hardware abstraction layer
|
||||
// the HAL must inherit from the base RadioLibHal class
|
||||
// and implement all of its virtual methods
|
||||
// this is pretty much just copied from Arduino ESP32 core
|
||||
class EspHal : public RadioLibHal {
|
||||
public:
|
||||
// default constructor - initializes the base HAL and any needed private members
|
||||
EspHal(int8_t sck, int8_t miso, int8_t mosi)
|
||||
: RadioLibHal(INPUT, OUTPUT, LOW, HIGH, RISING, FALLING),
|
||||
spiSCK(sck), spiMISO(miso), spiMOSI(mosi) {
|
||||
}
|
||||
|
||||
void init() override {
|
||||
// we only need to init the SPI here
|
||||
spiBegin();
|
||||
}
|
||||
|
||||
void term() override {
|
||||
// we only need to stop the SPI here
|
||||
spiEnd();
|
||||
}
|
||||
|
||||
// GPIO-related methods (pinMode, digitalWrite etc.) should check
|
||||
// RADIOLIB_NC as an alias for non-connected pins
|
||||
void pinMode(uint32_t pin, uint32_t mode) override {
|
||||
if(pin == RADIOLIB_NC) {
|
||||
return;
|
||||
}
|
||||
|
||||
gpio_hal_context_t gpiohal;
|
||||
gpiohal.dev = GPIO_LL_GET_HW(GPIO_PORT_0);
|
||||
|
||||
gpio_config_t conf = {
|
||||
.pin_bit_mask = (1ULL<<pin),
|
||||
.mode = (gpio_mode_t)mode,
|
||||
.pull_up_en = GPIO_PULLUP_DISABLE,
|
||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||
.intr_type = (gpio_int_type_t)gpiohal.dev->pin[pin].int_type,
|
||||
};
|
||||
gpio_config(&conf);
|
||||
}
|
||||
|
||||
void digitalWrite(uint32_t pin, uint32_t value) override {
|
||||
if(pin == RADIOLIB_NC) {
|
||||
return;
|
||||
}
|
||||
|
||||
gpio_set_level((gpio_num_t)pin, value);
|
||||
}
|
||||
|
||||
uint32_t digitalRead(uint32_t pin) override {
|
||||
if(pin == RADIOLIB_NC) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(gpio_get_level((gpio_num_t)pin));
|
||||
}
|
||||
|
||||
void attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) override {
|
||||
if(interruptNum == RADIOLIB_NC) {
|
||||
return;
|
||||
}
|
||||
|
||||
gpio_install_isr_service((int)ESP_INTR_FLAG_IRAM);
|
||||
gpio_set_intr_type((gpio_num_t)interruptNum, (gpio_int_type_t)(mode & 0x7));
|
||||
|
||||
// this uses function typecasting, which is not defined when the functions have different signatures
|
||||
// untested and might not work
|
||||
gpio_isr_handler_add((gpio_num_t)interruptNum, (void (*)(void*))interruptCb, NULL);
|
||||
}
|
||||
|
||||
void detachInterrupt(uint32_t interruptNum) override {
|
||||
if(interruptNum == RADIOLIB_NC) {
|
||||
return;
|
||||
}
|
||||
|
||||
gpio_isr_handler_remove((gpio_num_t)interruptNum);
|
||||
gpio_wakeup_disable((gpio_num_t)interruptNum);
|
||||
gpio_set_intr_type((gpio_num_t)interruptNum, GPIO_INTR_DISABLE);
|
||||
}
|
||||
|
||||
void delay(unsigned long ms) override {
|
||||
vTaskDelay(ms / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
void delayMicroseconds(unsigned long us) override {
|
||||
uint64_t m = (uint64_t)esp_timer_get_time();
|
||||
if(us) {
|
||||
uint64_t e = (m + us);
|
||||
if(m > e) { // overflow
|
||||
while((uint64_t)esp_timer_get_time() > e) {
|
||||
NOP();
|
||||
}
|
||||
}
|
||||
while((uint64_t)esp_timer_get_time() < e) {
|
||||
NOP();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long millis() override {
|
||||
return((unsigned long)(esp_timer_get_time() / 1000ULL));
|
||||
}
|
||||
|
||||
unsigned long micros() override {
|
||||
return((unsigned long)(esp_timer_get_time()));
|
||||
}
|
||||
|
||||
long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override {
|
||||
if(pin == RADIOLIB_NC) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
this->pinMode(pin, INPUT);
|
||||
uint32_t start = this->micros();
|
||||
uint32_t curtick = this->micros();
|
||||
|
||||
while(this->digitalRead(pin) == state) {
|
||||
if((this->micros() - curtick) > timeout) {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
return(this->micros() - start);
|
||||
}
|
||||
|
||||
void spiBegin() {
|
||||
// enable peripheral
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI2_CLK_EN);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI2_RST);
|
||||
|
||||
// reset the control struct
|
||||
this->spi->slave.trans_done = 0;
|
||||
this->spi->slave.val = 0;
|
||||
this->spi->pin.val = 0;
|
||||
this->spi->user.val = 0;
|
||||
this->spi->user1.val = 0;
|
||||
this->spi->ctrl.val = 0;
|
||||
this->spi->ctrl1.val = 0;
|
||||
this->spi->ctrl2.val = 0;
|
||||
this->spi->clock.val = 0;
|
||||
this->spi->user.usr_mosi = 1;
|
||||
this->spi->user.usr_miso = 1;
|
||||
this->spi->user.doutdin = 1;
|
||||
for(uint8_t i = 0; i < 16; i++) {
|
||||
this->spi->data_buf[i] = 0x00000000;
|
||||
}
|
||||
|
||||
// set SPI mode 0
|
||||
this->spi->pin.ck_idle_edge = 0;
|
||||
this->spi->user.ck_out_edge = 0;
|
||||
|
||||
// set bit order to MSB first
|
||||
this->spi->ctrl.wr_bit_order = 0;
|
||||
this->spi->ctrl.rd_bit_order = 0;
|
||||
|
||||
// set the clock
|
||||
this->spi->clock.val = spiFrequencyToClockDiv(2000000);
|
||||
|
||||
// initialize pins
|
||||
this->pinMode(this->spiSCK, OUTPUT);
|
||||
this->pinMode(this->spiMISO, INPUT);
|
||||
this->pinMode(this->spiMOSI, OUTPUT);
|
||||
gpio_matrix_out(this->spiSCK, HSPICLK_OUT_IDX, false, false);
|
||||
gpio_matrix_in(this->spiMISO, HSPIQ_OUT_IDX, false);
|
||||
gpio_matrix_out(this->spiMOSI, HSPID_IN_IDX, false, false);
|
||||
}
|
||||
|
||||
void spiBeginTransaction() {
|
||||
// not needed - in ESP32 Arduino core, this function
|
||||
// repeats clock div, mode and bit order configuration
|
||||
}
|
||||
|
||||
uint8_t spiTransferByte(uint8_t b) {
|
||||
this->spi->mosi_dlen.usr_mosi_dbitlen = 7;
|
||||
this->spi->miso_dlen.usr_miso_dbitlen = 7;
|
||||
this->spi->data_buf[0] = b;
|
||||
this->spi->cmd.usr = 1;
|
||||
while(this->spi->cmd.usr);
|
||||
return(this->spi->data_buf[0] & 0xFF);
|
||||
}
|
||||
|
||||
void spiTransfer(uint8_t* out, size_t len, uint8_t* in) {
|
||||
for(size_t i = 0; i < len; i++) {
|
||||
in[i] = this->spiTransferByte(out[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void spiEndTransaction() {
|
||||
// nothing needs to be done here
|
||||
}
|
||||
|
||||
void spiEnd() {
|
||||
// detach pins
|
||||
gpio_matrix_out(this->spiSCK, MATRIX_DETACH_OUT_SIG, false, false);
|
||||
gpio_matrix_in(this->spiMISO, MATRIX_DETACH_IN_LOW_PIN, false);
|
||||
gpio_matrix_out(this->spiMOSI, MATRIX_DETACH_OUT_SIG, false, false);
|
||||
}
|
||||
|
||||
private:
|
||||
// the HAL can contain any additional private members
|
||||
int8_t spiSCK;
|
||||
int8_t spiMISO;
|
||||
int8_t spiMOSI;
|
||||
spi_dev_t * spi = (volatile spi_dev_t *)(DR_REG_SPI2_BASE);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
dependencies:
|
||||
RadioLib:
|
||||
# referenced locally because the example is a part of the repository itself
|
||||
# under normal circumstances, it's preferable to reference the repository instead
|
||||
# for other options, see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html
|
||||
path: ../../../../../RadioLib
|
||||
#git: https://github.com/jgromes/RadioLib.git
|
||||
67
RadioLib/examples/NonArduino/ESP-IDF/main/main.cpp
Normal file
67
RadioLib/examples/NonArduino/ESP-IDF/main/main.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
RadioLib Non-Arduino ESP-IDF Example
|
||||
|
||||
This example shows how to use RadioLib without Arduino.
|
||||
In this case, a Liligo T-BEAM (ESP32 and SX1276)
|
||||
is used.
|
||||
|
||||
Can be used as a starting point to port RadioLib to any platform!
|
||||
See this API reference page for details on the RadioLib hardware abstraction
|
||||
https://jgromes.github.io/RadioLib/class_hal.html
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// include the hardware abstraction layer
|
||||
#include "EspHal.h"
|
||||
|
||||
// create a new instance of the HAL class
|
||||
EspHal* hal = new EspHal(5, 19, 27);
|
||||
|
||||
// now we can create the radio module
|
||||
// NSS pin: 18
|
||||
// DIO0 pin: 26
|
||||
// NRST pin: 14
|
||||
// DIO1 pin: 33
|
||||
SX1276 radio = new Module(hal, 18, 26, 14, 33);
|
||||
|
||||
static const char *TAG = "main";
|
||||
|
||||
// the entry point for the program
|
||||
// it must be declared as "extern C" because the compiler assumes this will be a C function
|
||||
extern "C" void app_main(void) {
|
||||
// initialize just like with Arduino
|
||||
ESP_LOGI(TAG, "[SX1276] Initializing ... ");
|
||||
int state = radio.begin();
|
||||
if (state != RADIOLIB_ERR_NONE) {
|
||||
ESP_LOGI(TAG, "failed, code %d\n", state);
|
||||
while(true) {
|
||||
hal->delay(1000);
|
||||
}
|
||||
}
|
||||
ESP_LOGI(TAG, "success!\n");
|
||||
|
||||
// loop forever
|
||||
for(;;) {
|
||||
// send a packet
|
||||
ESP_LOGI(TAG, "[SX1276] Transmitting packet ... ");
|
||||
state = radio.transmit("Hello World!");
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
// the packet was successfully transmitted
|
||||
ESP_LOGI(TAG, "success!");
|
||||
|
||||
} else {
|
||||
ESP_LOGI(TAG, "failed, code %d\n", state);
|
||||
|
||||
}
|
||||
|
||||
// wait for a second before transmitting again
|
||||
hal->delay(1000);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
1669
RadioLib/examples/NonArduino/ESP-IDF/sdkconfig
Normal file
1669
RadioLib/examples/NonArduino/ESP-IDF/sdkconfig
Normal file
File diff suppressed because it is too large
Load Diff
33
RadioLib/examples/NonArduino/Pico/CMakeLists.txt
Normal file
33
RadioLib/examples/NonArduino/Pico/CMakeLists.txt
Normal file
@@ -0,0 +1,33 @@
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
# Pull in SDK (must be before project)
|
||||
include(pico_sdk_import.cmake)
|
||||
|
||||
project(pico-sx1276 C CXX ASM)
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
# Initialize the SDK
|
||||
pico_sdk_init()
|
||||
|
||||
add_compile_options(
|
||||
-Wall
|
||||
-Wno-format
|
||||
-Wno-unused-function
|
||||
)
|
||||
|
||||
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../../../RadioLib" "${CMAKE_CURRENT_BINARY_DIR}/RadioLib")
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
main.cpp
|
||||
)
|
||||
|
||||
# Pull in common dependencies
|
||||
target_link_libraries(${PROJECT_NAME} pico_stdlib hardware_spi hardware_gpio hardware_timer pico_multicore hardware_pwm RadioLib)
|
||||
|
||||
|
||||
pico_enable_stdio_usb(${PROJECT_NAME} 1)
|
||||
pico_enable_stdio_uart(${PROJECT_NAME} 0)
|
||||
|
||||
# Create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(${PROJECT_NAME})
|
||||
8
RadioLib/examples/NonArduino/Pico/build.sh
Normal file
8
RadioLib/examples/NonArduino/Pico/build.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
cd ..
|
||||
3
RadioLib/examples/NonArduino/Pico/clean.sh
Normal file
3
RadioLib/examples/NonArduino/Pico/clean.sh
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
rm -rf ./build
|
||||
86
RadioLib/examples/NonArduino/Pico/main.cpp
Normal file
86
RadioLib/examples/NonArduino/Pico/main.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
RadioLib Non-Arduino Raspberry Pi Pico library example
|
||||
|
||||
Licensed under the MIT License
|
||||
|
||||
Copyright (c) 2024 Cameron Goddard
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// define pins to be used
|
||||
#define SPI_PORT spi0
|
||||
#define SPI_MISO 4
|
||||
#define SPI_MOSI 3
|
||||
#define SPI_SCK 2
|
||||
|
||||
#define RFM_NSS 26
|
||||
#define RFM_RST 22
|
||||
#define RFM_DIO0 14
|
||||
#define RFM_DIO1 15
|
||||
|
||||
#include <pico/stdlib.h>
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// include the hardware abstraction layer
|
||||
#include "hal/RPiPico/PicoHal.h"
|
||||
|
||||
// create a new instance of the HAL class
|
||||
PicoHal* hal = new PicoHal(SPI_PORT, SPI_MISO, SPI_MOSI, SPI_SCK);
|
||||
|
||||
// now we can create the radio module
|
||||
// NSS pin: 26
|
||||
// DIO0 pin: 14
|
||||
// RESET pin: 22
|
||||
// DIO1 pin: 15
|
||||
SX1276 radio = new Module(hal, RFM_NSS, RFM_DIO0, RFM_RST, RFM_DIO1);
|
||||
|
||||
int main() {
|
||||
// initialize just like with Arduino
|
||||
printf("[SX1276] Initializing ... ");
|
||||
int state = radio.begin();
|
||||
if (state != RADIOLIB_ERR_NONE) {
|
||||
printf("failed, code %d\n", state);
|
||||
return(1);
|
||||
}
|
||||
printf("success!\n");
|
||||
|
||||
// loop forever
|
||||
for(;;) {
|
||||
// send a packet
|
||||
printf("[SX1276] Transmitting packet ... ");
|
||||
state = radio.transmit("Hello World!");
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
// the packet was successfully transmitted
|
||||
printf("success!\n");
|
||||
|
||||
// wait for a second before transmitting again
|
||||
hal->delay(1000);
|
||||
|
||||
} else {
|
||||
printf("failed, code %d\n", state);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
73
RadioLib/examples/NonArduino/Pico/pico_sdk_import.cmake
Normal file
73
RadioLib/examples/NonArduino/Pico/pico_sdk_import.cmake
Normal file
@@ -0,0 +1,73 @@
|
||||
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake
|
||||
|
||||
# This can be dropped into an external project to help locate this SDK
|
||||
# It should be include()ed prior to project()
|
||||
|
||||
if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
|
||||
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
|
||||
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
|
||||
endif ()
|
||||
|
||||
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
|
||||
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
|
||||
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
|
||||
endif ()
|
||||
|
||||
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
|
||||
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
|
||||
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
|
||||
endif ()
|
||||
|
||||
set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
|
||||
set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable")
|
||||
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")
|
||||
|
||||
if (NOT PICO_SDK_PATH)
|
||||
if (PICO_SDK_FETCH_FROM_GIT)
|
||||
include(FetchContent)
|
||||
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
|
||||
if (PICO_SDK_FETCH_FROM_GIT_PATH)
|
||||
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
|
||||
endif ()
|
||||
# GIT_SUBMODULES_RECURSE was added in 3.17
|
||||
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0")
|
||||
FetchContent_Declare(
|
||||
pico_sdk
|
||||
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
|
||||
GIT_TAG master
|
||||
GIT_SUBMODULES_RECURSE FALSE
|
||||
)
|
||||
else ()
|
||||
FetchContent_Declare(
|
||||
pico_sdk
|
||||
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
|
||||
GIT_TAG master
|
||||
)
|
||||
endif ()
|
||||
|
||||
if (NOT pico_sdk)
|
||||
message("Downloading Raspberry Pi Pico SDK")
|
||||
FetchContent_Populate(pico_sdk)
|
||||
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
|
||||
endif ()
|
||||
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
|
||||
else ()
|
||||
message(FATAL_ERROR
|
||||
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
|
||||
if (NOT EXISTS ${PICO_SDK_PATH})
|
||||
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
|
||||
endif ()
|
||||
|
||||
set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
|
||||
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
|
||||
endif ()
|
||||
|
||||
set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)
|
||||
|
||||
include(${PICO_SDK_INIT_CMAKE_FILE})
|
||||
22
RadioLib/examples/NonArduino/Raspberry/CMakeLists.txt
Normal file
22
RadioLib/examples/NonArduino/Raspberry/CMakeLists.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
# create the project
|
||||
project(rpi-sx1261)
|
||||
|
||||
# when using debuggers such as gdb, the following line can be used
|
||||
#set(CMAKE_BUILD_TYPE Debug)
|
||||
|
||||
# if you did not build RadioLib as shared library (see wiki),
|
||||
# you will have to add it as source directory
|
||||
# the following is just an example, yours will likely be different
|
||||
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../../../RadioLib" "${CMAKE_CURRENT_BINARY_DIR}/RadioLib")
|
||||
|
||||
# add the executable
|
||||
add_executable(${PROJECT_NAME} main.cpp)
|
||||
|
||||
# link both libraries
|
||||
target_link_libraries(${PROJECT_NAME} RadioLib lgpio)
|
||||
|
||||
# you can also specify RadioLib compile-time flags here
|
||||
#target_compile_definitions(RadioLib PUBLIC RADIOLIB_DEBUG_BASIC RADIOLIB_DEBUG_SPI)
|
||||
#target_compile_definitions(RadioLib PUBLIC RADIOLIB_DEBUG_PORT=stdout)
|
||||
9
RadioLib/examples/NonArduino/Raspberry/build.sh
Normal file
9
RadioLib/examples/NonArduino/Raspberry/build.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
mkdir -p build
|
||||
cd build
|
||||
cmake -G "CodeBlocks - Unix Makefiles" ..
|
||||
make
|
||||
cd ..
|
||||
size build/rpi-sx1261
|
||||
3
RadioLib/examples/NonArduino/Raspberry/clean.sh
Normal file
3
RadioLib/examples/NonArduino/Raspberry/clean.sh
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
rm -rf ./build
|
||||
70
RadioLib/examples/NonArduino/Raspberry/main.cpp
Normal file
70
RadioLib/examples/NonArduino/Raspberry/main.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
RadioLib Non-Arduino Raspberry Pi Example
|
||||
|
||||
This example shows how to use RadioLib without Arduino.
|
||||
In this case, a Raspberry Pi with WaveShare SX1302 LoRaWAN Hat
|
||||
using the lgpio library
|
||||
https://abyz.me.uk/lg/lgpio.html
|
||||
|
||||
Can be used as a starting point to port RadioLib to any platform!
|
||||
See this API reference page for details on the RadioLib hardware abstraction
|
||||
https://jgromes.github.io/RadioLib/class_hal.html
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// include the hardware abstraction layer
|
||||
#include "hal/RPi/PiHal.h"
|
||||
|
||||
// create a new instance of the HAL class
|
||||
// use SPI channel 1, because on Waveshare LoRaWAN Hat,
|
||||
// the SX1261 CS is connected to CE1
|
||||
PiHal* hal = new PiHal(1);
|
||||
|
||||
// now we can create the radio module
|
||||
// pinout corresponds to the Waveshare LoRaWAN Hat
|
||||
// NSS pin: 7
|
||||
// DIO1 pin: 17
|
||||
// NRST pin: 22
|
||||
// BUSY pin: not connected
|
||||
SX1261 radio = new Module(hal, 7, 17, 22, RADIOLIB_NC);
|
||||
|
||||
// the entry point for the program
|
||||
int main(int argc, char** argv) {
|
||||
// initialize just like with Arduino
|
||||
printf("[SX1261] Initializing ... ");
|
||||
int state = radio.begin();
|
||||
if (state != RADIOLIB_ERR_NONE) {
|
||||
printf("failed, code %d\n", state);
|
||||
return(1);
|
||||
}
|
||||
printf("success!\n");
|
||||
|
||||
// loop forever
|
||||
int count = 0;
|
||||
for(;;) {
|
||||
// send a packet
|
||||
printf("[SX1261] Transmitting packet ... ");
|
||||
char str[64];
|
||||
sprintf(str, "Hello World! #%d", count++);
|
||||
state = radio.transmit(str);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
// the packet was successfully transmitted
|
||||
printf("success!\n");
|
||||
|
||||
// wait for a second before transmitting again
|
||||
hal->delay(1000);
|
||||
|
||||
} else {
|
||||
printf("failed, code %d\n", state);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
137
RadioLib/examples/NonArduino/Tock/CMakeLists.txt
Normal file
137
RadioLib/examples/NonArduino/Tock/CMakeLists.txt
Normal file
@@ -0,0 +1,137 @@
|
||||
# RadioLib Non-Arduino Tock Library CMake script
|
||||
#
|
||||
# Licensed under the MIT License
|
||||
#
|
||||
# Copyright (c) 2023 Alistair Francis <alistair@alistair23.me>
|
||||
#
|
||||
# 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.
|
||||
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
|
||||
# create the project
|
||||
project(tock-sx1261)
|
||||
|
||||
set(LINKER_SCRIPT $ENV{LIBTOCK_C_DIRECTORY}/userland_generic.ld)
|
||||
|
||||
if (RISCV_BUILD)
|
||||
include("tock-riscv.cmake")
|
||||
else()
|
||||
include("tock-arm.cmake")
|
||||
endif()
|
||||
|
||||
# when using debuggers such as gdb, the following line can be used
|
||||
#set(CMAKE_BUILD_TYPE Debug)
|
||||
|
||||
# if you did not build RadioLib as shared library (see wiki),
|
||||
# you will have to add it as source directory
|
||||
# the following is just an example, yours will likely be different
|
||||
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../../../RadioLib" "${CMAKE_CURRENT_BINARY_DIR}/RadioLib")
|
||||
|
||||
# add the executable
|
||||
add_executable(${PROJECT_NAME} main.cpp)
|
||||
|
||||
# link with RadioLib and libtock-c
|
||||
# The build system for libtock-c is a bit odd and the version of libraries
|
||||
# built changes based on compiler version.
|
||||
if (RISCV_BUILD)
|
||||
if(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0")
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
RadioLib
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/rv32imc/libtock.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/rv32imc/libtocksync.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0/riscv/lib/gcc/riscv64-unknown-elf/14.1.0/rv32i/ilp32/libgcc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libstdc++.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.4.0.20231231/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.4.0.20231231/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libm.a
|
||||
)
|
||||
|
||||
target_include_directories(RadioLib AFTER PUBLIC
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/riscv/riscv64-unknown-elf/include/
|
||||
)
|
||||
elseif(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0")
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
RadioLib
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/rv32imc/libtock.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/rv32imc/libtocksync.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0/riscv/lib/gcc/riscv64-unknown-elf/13.2.0/rv32i/ilp32/libgcc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libstdc++.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libm.a
|
||||
)
|
||||
|
||||
target_include_directories(RadioLib AFTER PUBLIC
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/riscv/riscv64-unknown-elf/include/
|
||||
)
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
RadioLib
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/rv32imc/libtock.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/rv32imc/libtocksync.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-10.5.0/riscv/lib/gcc/riscv64-unknown-elf/10.5.0/rv32i/ilp32/libgcc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-10.5.0/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libstdc++.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.2.0.20211231/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.2.0.20211231/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libm.a
|
||||
)
|
||||
|
||||
target_include_directories(RadioLib AFTER PUBLIC
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.2.0.20211231/riscv/riscv64-unknown-elf/include/
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
if (EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0")
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
RadioLib
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/cortex-m4/libtock.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/cortex-m4/libtocksync.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0/arm/lib/gcc/arm-none-eabi/14.1.0/libgcc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0/arm/arm-none-eabi/lib/libstdc++.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.4.0.20231231/arm/arm-none-eabi/lib/libc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.4.0.20231231/arm/arm-none-eabi/lib/libm.a
|
||||
)
|
||||
elseif(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0")
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
RadioLib
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/cortex-m4/libtock.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/cortex-m4/libtocksync.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0/arm/lib/gcc/arm-none-eabi/13.2.0/libgcc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0/arm/arm-none-eabi/lib/libstdc++.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/arm/arm-none-eabi/lib/libc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/arm/arm-none-eabi/lib/libm.a
|
||||
)
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
RadioLib
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/cortex-m4/libtock.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/cortex-m4/libtocksync.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-10.5.0/arm/lib/gcc/arm-none-eabi/10.5.0/libgcc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-10.5.0/arm/arm-none-eabi/lib/libstdc++.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.2.0.20211231/arm/arm-none-eabi/lib/libc.a
|
||||
$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.2.0.20211231/arm/arm-none-eabi/lib/libm.a
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/
|
||||
$ENV{LIBTOCK_C_DIRECTORY}
|
||||
)
|
||||
|
||||
# you can also specify RadioLib compile-time flags here
|
||||
#target_compile_definitions(${PROJECT_NAME} PUBLIC RADIOLIB_DEBUG RADIOLIB_VERBOSE)
|
||||
34
RadioLib/examples/NonArduino/Tock/README.md
Normal file
34
RadioLib/examples/NonArduino/Tock/README.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# RadioLib as Tock application
|
||||
|
||||
[Tock](https://github.com/tock/tock) is an embedded operating system designed
|
||||
for running multiple concurrent, mutually distrustful applications on Cortex-M
|
||||
and RISC-V based embedded platforms.
|
||||
|
||||
RadioLib can be built as a Tock application using
|
||||
[libtock-c](https://github.com/tock/libtock-c). This is an example of running
|
||||
RadioLib as a Tock application.
|
||||
|
||||
This has been tested on the
|
||||
[SparkFun LoRa Thing Plus - expLoRaBLE board] (https://github.com/tock/tock/tree/master/boards/apollo3/lora_things_plus)
|
||||
but will work on any LoRa compatible Tock board (currently only the
|
||||
expLoRaBLE board).
|
||||
|
||||
libtock-c by default is bulit for RISC-V and ARM. RadioLib is also built
|
||||
for both architectures by default. You can skip the RISC-V RadioLib build
|
||||
by setting the `SKIP_RISCV` varaible.
|
||||
|
||||
The RadioLib example can be built with:
|
||||
|
||||
```shell
|
||||
$ git clone https://github.com/jgromes/RadioLib.git
|
||||
$ cd RadioLib/examples/NonArduino/Tock/
|
||||
$ git clone https://github.com/tock/libtock-c.git
|
||||
$ cd libtock-c; git checkout c0202f9ab78da4a6e95f136cf5250701e3778f63; cd ../
|
||||
$ LIBTOCK_C_DIRECTORY="$(pwd)/libtock-c" ./build.sh
|
||||
```
|
||||
|
||||
Then in the Tock repo you can flash the kernel and app with:
|
||||
|
||||
```shell
|
||||
$ make flash; APP=RadioLib/examples/NonArduino/Tock/build-arm/tock-sx1261.tbf make flash-app
|
||||
```
|
||||
30
RadioLib/examples/NonArduino/Tock/build.sh
Normal file
30
RadioLib/examples/NonArduino/Tock/build.sh
Normal file
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
rm -rf ./build-*
|
||||
|
||||
pushd ${LIBTOCK_C_DIRECTORY}/examples/cxx_hello
|
||||
make -j4
|
||||
popd
|
||||
|
||||
mkdir -p build-arm
|
||||
cd build-arm
|
||||
|
||||
cmake -G "CodeBlocks - Unix Makefiles" ..
|
||||
make -j4
|
||||
|
||||
cd ..
|
||||
|
||||
if ! env | grep SKIP_RISCV; then
|
||||
mkdir -p build-riscv
|
||||
cd build-riscv
|
||||
|
||||
cmake -G "CodeBlocks - Unix Makefiles" -DRISCV_BUILD=1 ..
|
||||
make -j4
|
||||
|
||||
cd ..
|
||||
fi
|
||||
|
||||
elf2tab -n radio-lib --stack 4096 --app-heap 2048 --kernel-heap 2048 \
|
||||
--kernel-major 2 --kernel-minor 1 \
|
||||
-v ./build-arm/tock-sx1261
|
||||
81
RadioLib/examples/NonArduino/Tock/main.cpp
Normal file
81
RadioLib/examples/NonArduino/Tock/main.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
RadioLib Non-Arduino Tock Library test application
|
||||
|
||||
Licensed under the MIT License
|
||||
|
||||
Copyright (c) 2023 Alistair Francis <alistair@alistair23.me>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// include the hardware abstraction layer
|
||||
#include "RadioLib/libtockHal.h"
|
||||
|
||||
// the entry point for the program
|
||||
int main(void) {
|
||||
printf("[SX1261] Initialising Radio ... \r\n");
|
||||
|
||||
// create a new instance of the HAL class
|
||||
TockRadioLibHal* hal = new TockRadioLibHal();
|
||||
|
||||
// now we can create the radio module
|
||||
// pinout corresponds to the SparkFun LoRa Thing Plus - expLoRaBLE
|
||||
// NSS pin: 0
|
||||
// DIO1 pin: 2
|
||||
// NRST pin: 4
|
||||
// BUSY pin: 1
|
||||
Module* tock_module = new Module(hal, RADIOLIB_RADIO_NSS, RADIOLIB_RADIO_DIO_1, RADIOLIB_RADIO_RESET, RADIOLIB_RADIO_BUSY);
|
||||
SX1262* radio = new SX1262(tock_module);
|
||||
|
||||
// Setup the radio
|
||||
// The settings here work for the SparkFun LoRa Thing Plus - expLoRaBLE
|
||||
radio->XTAL = true;
|
||||
int state = radio->begin(915.0);
|
||||
|
||||
if (state != RADIOLIB_ERR_NONE) {
|
||||
printf("failed, code %d\r\n", state);
|
||||
return 1;
|
||||
}
|
||||
printf("success!\r\n");
|
||||
|
||||
// loop forever
|
||||
for(;;) {
|
||||
yield_no_wait();
|
||||
// send a packet
|
||||
printf("[SX1261] Transmitting\r\n");
|
||||
|
||||
state = radio->transmit("Hello World!");
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
// the packet was successfully transmitted
|
||||
printf("success!\r\n");
|
||||
|
||||
// wait for a second before transmitting again
|
||||
hal->delay(1000);
|
||||
} else {
|
||||
printf("failed, code %d\r\n", state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
65
RadioLib/examples/NonArduino/Tock/tock-arm.cmake
Normal file
65
RadioLib/examples/NonArduino/Tock/tock-arm.cmake
Normal file
@@ -0,0 +1,65 @@
|
||||
# Tock target specific CMake file
|
||||
#
|
||||
# Licensed under the MIT License
|
||||
#
|
||||
# Copyright (c) 2023 Alistair Francis <alistair@alistair23.me>
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# This is copied from https://github.com/Lora-net/LoRaMac-node/pull/1390
|
||||
# and has been relicensed by the original author
|
||||
|
||||
if(NOT DEFINED LINKER_SCRIPT)
|
||||
message(FATAL_ERROR "No linker script defined")
|
||||
endif(NOT DEFINED LINKER_SCRIPT)
|
||||
message("Linker script: ${LINKER_SCRIPT}")
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
# Set compiler/linker flags
|
||||
#---------------------------------------------------------------------------------------
|
||||
|
||||
set(STACK_SIZE 4096)
|
||||
set(APP_HEAP_SIZE 2048)
|
||||
set(KERNEL_HEAP_SIZE 2048)
|
||||
|
||||
set(TOOLCHAIN arm-none-eabi)
|
||||
|
||||
find_program(TOOLCHAIN_PREFIX ${TOOLCHAIN}-gcc NO_CACHE)
|
||||
get_filename_component(TOOLCHAIN_PREFIX ${TOOLCHAIN_PREFIX} DIRECTORY)
|
||||
|
||||
set(TOOLCHAIN_BIN_DIR ${TOOLCHAIN_PREFIX}/../bin)
|
||||
set(TOOLCHAIN_INC_DIR ${TOOLCHAIN_PREFIX}/../${TOOLCHAIN}/include)
|
||||
set(TOOLCHAIN_LIB_DIR ${TOOLCHAIN_PREFIX}/../${TOOLCHAIN}/lib)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
# Set compilers
|
||||
#---------------------------------------------------------------------------------------
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc CACHE INTERNAL "C Compiler")
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-g++ CACHE INTERNAL "C++ Compiler")
|
||||
set(CMAKE_ASM_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc CACHE INTERNAL "ASM Compiler")
|
||||
|
||||
# Object build options
|
||||
set(OBJECT_GEN_FLAGS "-mthumb -g2 -fno-builtin -mcpu=cortex-m4 -Wall -Wextra -pedantic -Wno-unused-parameter -ffunction-sections -fdata-sections -fomit-frame-pointer -mabi=aapcs -fno-unroll-loops -ffast-math -ftree-vectorize -frecord-gcc-switches -gdwarf-2 -Os -fdata-sections -ffunction-sections -fstack-usage -Wl,--emit-relocs -fPIC -mthumb -mfloat-abi=soft -msingle-pic-base -mpic-register=r9 -mno-pic-data-is-text-relative -D__TOCK__ -DSVCALL_AS_NORMAL_FUNCTION -DSOFTDEVICE_s130")
|
||||
|
||||
set(CMAKE_C_FLAGS "${OBJECT_GEN_FLAGS} -std=gnu99 " CACHE INTERNAL "C Compiler options")
|
||||
set(CMAKE_CXX_FLAGS "${OBJECT_GEN_FLAGS} -std=c++20 " CACHE INTERNAL "C++ Compiler options")
|
||||
set(CMAKE_ASM_FLAGS "${OBJECT_GEN_FLAGS} -x assembler-with-cpp " CACHE INTERNAL "ASM Compiler options")
|
||||
|
||||
# Linker flags
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--gc-sections --specs=nano.specs --specs=nosys.specs -mthumb -g2 -mcpu=cortex-m4 -mabi=aapcs -T${LINKER_SCRIPT} -Wl,-Map=${CMAKE_PROJECT_NAME}.map -Xlinker --defsym=STACK_SIZE=${STACK_SIZE} -Xlinker --defsym=APP_HEAP_SIZE=${APP_HEAP_SIZE} -Xlinker --defsym=KERNEL_HEAP_SIZE=${KERNEL_HEAP_SIZE} -nostdlib -Wl,--start-group" CACHE INTERNAL "Linker options")
|
||||
76
RadioLib/examples/NonArduino/Tock/tock-riscv.cmake
Normal file
76
RadioLib/examples/NonArduino/Tock/tock-riscv.cmake
Normal file
@@ -0,0 +1,76 @@
|
||||
# Tock target specific CMake file
|
||||
#
|
||||
# Licensed under the MIT License
|
||||
#
|
||||
# Copyright (c) 2023 Alistair Francis <alistair@alistair23.me>
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# This is copied from https://github.com/Lora-net/LoRaMac-node/pull/1390
|
||||
# and has been relicensed by the original author
|
||||
|
||||
if(NOT DEFINED LINKER_SCRIPT)
|
||||
message(FATAL_ERROR "No linker script defined")
|
||||
endif(NOT DEFINED LINKER_SCRIPT)
|
||||
message("Linker script: ${LINKER_SCRIPT}")
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
# Set compiler/linker flags
|
||||
#---------------------------------------------------------------------------------------
|
||||
|
||||
set(STACK_SIZE 4096)
|
||||
set(APP_HEAP_SIZE 2048)
|
||||
set(KERNEL_HEAP_SIZE 2048)
|
||||
|
||||
find_program(TOOLCHAIN
|
||||
NAMES
|
||||
riscv64-none-elf-gcc
|
||||
riscv32-none-elf-gcc
|
||||
riscv64-elf-gcc
|
||||
riscv32-unknown-elf-gcc
|
||||
riscv64-unknown-elf-gcc
|
||||
riscv64-unknown-elf-clang
|
||||
riscv32-unknown-elf-clang
|
||||
NO_CACHE)
|
||||
|
||||
get_filename_component(TOOLCHAIN_PREFIX ${TOOLCHAIN} DIRECTORY)
|
||||
|
||||
get_filename_component(TOOLCHAIN ${TOOLCHAIN} NAME)
|
||||
string(REPLACE "-gcc" "" TOOLCHAIN ${TOOLCHAIN})
|
||||
|
||||
set(TOOLCHAIN_BIN_DIR ${TOOLCHAIN_PREFIX}/../bin)
|
||||
set(TOOLCHAIN_INC_DIR ${TOOLCHAIN_PREFIX}/../${TOOLCHAIN}/include)
|
||||
set(TOOLCHAIN_LIB_DIR ${TOOLCHAIN_PREFIX}/../${TOOLCHAIN}/lib)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
# Set compilers
|
||||
#---------------------------------------------------------------------------------------
|
||||
set(CMAKE_C_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc CACHE INTERNAL "C Compiler")
|
||||
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-g++ CACHE INTERNAL "C++ Compiler")
|
||||
set(CMAKE_ASM_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc CACHE INTERNAL "ASM Compiler")
|
||||
|
||||
# Object build options
|
||||
set(OBJECT_GEN_FLAGS "-march=rv32i -mabi=ilp32 -mcmodel=medlow -g2 -fno-builtin -Wall -Wextra -pedantic -Wno-unused-parameter -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-unroll-loops -ffast-math -ftree-vectorize -frecord-gcc-switches -gdwarf-2 -Os -fdata-sections -ffunction-sections -fstack-usage -Wl,--emit-relocs -D__TOCK__ -DSVCALL_AS_NORMAL_FUNCTION -DSOFTDEVICE_s130")
|
||||
|
||||
set(CMAKE_C_FLAGS "${OBJECT_GEN_FLAGS} -std=gnu99 " CACHE INTERNAL "C Compiler options")
|
||||
set(CMAKE_CXX_FLAGS "${OBJECT_GEN_FLAGS} -std=c++20 " CACHE INTERNAL "C++ Compiler options")
|
||||
set(CMAKE_ASM_FLAGS "${OBJECT_GEN_FLAGS} -x assembler-with-cpp " CACHE INTERNAL "ASM Compiler options")
|
||||
|
||||
# Linker flags
|
||||
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--gc-sections -march=rv32i -mabi=ilp32 -mcmodel=medlow -T${LINKER_SCRIPT} -Wl,-Map=${CMAKE_PROJECT_NAME}.map -Xlinker --defsym=STACK_SIZE=${STACK_SIZE} -Xlinker --defsym=APP_HEAP_SIZE=${APP_HEAP_SIZE} -Xlinker --defsym=KERNEL_HEAP_SIZE=${KERNEL_HEAP_SIZE} -nostdlib -Wl,--start-group" CACHE INTERNAL "Linker options")
|
||||
133
RadioLib/examples/Pager/Pager_Receive/Pager_Receive.ino
Normal file
133
RadioLib/examples/Pager/Pager_Receive/Pager_Receive.ino
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
RadioLib Pager (POCSAG) Receive Example
|
||||
|
||||
This example shows how to receive FSK packets without using
|
||||
SX127x packet engine.
|
||||
|
||||
This example receives POCSAG messages using SX1278's
|
||||
FSK modem in direct mode.
|
||||
|
||||
Other modules that can be used to receive POCSAG:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- Si443x/RFM2x
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// receiving packets requires connection
|
||||
// to the module direct output pin,
|
||||
// here connected to Arduino pin 5
|
||||
// SX127x/RFM9x: DIO2
|
||||
// RF69: DIO2
|
||||
// SX1231: DIO2
|
||||
// CC1101: GDO2
|
||||
// Si443x/RFM2x: GPIO
|
||||
// SX126x/LLCC68: DIO2
|
||||
const int pin = 5;
|
||||
|
||||
// create Pager client instance using the FSK module
|
||||
PagerClient pager(&radio);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
|
||||
// when using one of the non-LoRa modules
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize Pager client
|
||||
Serial.print(F("[Pager] Initializing ... "));
|
||||
// base (center) frequency: 434.0 MHz
|
||||
// speed: 1200 bps
|
||||
state = pager.begin(434.0, 1200);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// start receiving POCSAG messages
|
||||
Serial.print(F("[Pager] Starting to listen ... "));
|
||||
// address of this "pager": 1234567
|
||||
state = pager.startReceive(pin, 1234567);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// the number of batches to wait for
|
||||
// 2 batches will usually be enough to fit short and medium messages
|
||||
if (pager.available() >= 2) {
|
||||
Serial.print(F("[Pager] Received pager data, decoding ... "));
|
||||
|
||||
// you can read the data as an Arduino String
|
||||
String str;
|
||||
int state = pager.readData(str);
|
||||
|
||||
// you can also receive data as byte array
|
||||
/*
|
||||
byte byteArr[8];
|
||||
size_t numBytes = 0;
|
||||
int state = radio.receive(byteArr, &numBytes);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
|
||||
// print the received data
|
||||
Serial.print(F("[Pager] Data:\t"));
|
||||
Serial.println(str);
|
||||
|
||||
} else {
|
||||
// some error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
106
RadioLib/examples/Pager/Pager_Transmit/Pager_Transmit.ino
Normal file
106
RadioLib/examples/Pager/Pager_Transmit/Pager_Transmit.ino
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
RadioLib Pager (POCSAG) Transmit Example
|
||||
|
||||
This example sends POCSAG messages using SX1278's
|
||||
FSK modem.
|
||||
|
||||
Other modules that can be used to send POCSAG:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- SX126x
|
||||
- nRF24
|
||||
- Si443x/RFM2x
|
||||
- SX128x
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create Pager client instance using the FSK module
|
||||
PagerClient pager(&radio);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
|
||||
// when using one of the non-LoRa modules
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize Pager client
|
||||
Serial.print(F("[Pager] Initializing ... "));
|
||||
// base (center) frequency: 434.0 MHz
|
||||
// speed: 1200 bps
|
||||
state = pager.begin(434.0, 1200);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[Pager] Transmitting messages ... "));
|
||||
|
||||
// the simples form of "message" is just a tone on the destination pager
|
||||
int state = pager.sendTone(1234567);
|
||||
delay(500);
|
||||
|
||||
// next, transmit numeric (BCD) message to the destination pager
|
||||
// NOTE: Only characters 0123456789*U-() and space
|
||||
// can be sent in a BCD message!
|
||||
state |= pager.transmit("0123456789*U -()", 1234567);
|
||||
delay(500);
|
||||
|
||||
// finally, let's transmit an ASCII message now
|
||||
state |= pager.transmit("Hello World!", 1234567, RADIOLIB_PAGER_ASCII);
|
||||
delay(500);
|
||||
|
||||
// we can also send only a tone
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(3000);
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
RadioLib PhysicalLayer Interface Example
|
||||
|
||||
This example shows how to use the common PhysicalLayer
|
||||
to interface with different radio modules using the same
|
||||
methods.
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// select which radio to use
|
||||
// this can be any radio supported by RadioLib!
|
||||
#define RADIO_TYPE SX1278
|
||||
|
||||
// set the pinout depending on the wiring and module type
|
||||
// SPI NSS pin: 10
|
||||
// interrupt pin: 2
|
||||
// reset pin: 9 (unused on some modules)
|
||||
// extra GPIO/interrupt pin: 3 (unused on some modules)
|
||||
RADIO_TYPE radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// get pointer to the common layer
|
||||
PhysicalLayer* phy = (PhysicalLayer*)&radio;
|
||||
|
||||
void dummyISR(void) {
|
||||
// nothing here, this example is just a showcase
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// now we can use "radio" to access the features
|
||||
// specific to that radio type, such as the begin() method
|
||||
Serial.print(F("[Radio] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// or we can use the "phy" pointer to access the common layer
|
||||
// PhysicalLayer has some common configuration
|
||||
Serial.print(F("[PHY] Changing frequency ... "));
|
||||
state = phy->setFrequency(433.5);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// PhysicalLayer also contains basic functionality
|
||||
// like transmitting and receiving packets
|
||||
Serial.print(F("[PHY] Sending packet ... "));
|
||||
state = phy->transmit("Hello World!");
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// try to receive now - this will almost certainly timeout
|
||||
// unless by chance there is a transmitter nearby,
|
||||
// but the point of this example is to showcase the interface
|
||||
String str;
|
||||
Serial.print(F("[PHY] Listening for packets ... "));
|
||||
state = phy->receive(str);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else if(state == RADIOLIB_ERR_RX_TIMEOUT) {
|
||||
Serial.println(F("timeout!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// interrupt-driven versions of Rx/Tx are supported as well
|
||||
// for these to work, you have to configure the interrupt actions
|
||||
phy->setPacketReceivedAction(dummyISR);
|
||||
phy->setPacketSentAction(dummyISR);
|
||||
|
||||
// now you can use methods like startTransmit(), startReceive(),
|
||||
// readData() etc.
|
||||
|
||||
// interrupt actions can be cleared as well
|
||||
phy->clearPacketReceivedAction();
|
||||
phy->clearPacketSentAction();
|
||||
|
||||
// PhysicalLayer supports basic mode changes like sleep ...
|
||||
Serial.print(F("[PHY] Going to sleep ... "));
|
||||
state = phy->sleep();
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// ... or standby
|
||||
Serial.print(F("[PHY] Going to standby ... "));
|
||||
state = phy->standby();
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// there are also common SNR/RSSI measurement functions
|
||||
Serial.print(F("[PHY] Measured SNR = "));
|
||||
Serial.print(phy->getSNR());
|
||||
Serial.println(F(" dB"));
|
||||
Serial.print(F("[PHY] Measured RSSI = "));
|
||||
Serial.print(phy->getRSSI());
|
||||
Serial.println(F(" dBm"));
|
||||
|
||||
// and also a true random number generator
|
||||
Serial.print(F("[PHY] Random number between 0 and 100 = "));
|
||||
Serial.println(phy->random(100));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// nothing here, the example is just a showcase
|
||||
}
|
||||
96
RadioLib/examples/RF69/RF69_Receive_AES/RF69_Receive_AES.ino
Normal file
96
RadioLib/examples/RF69/RF69_Receive_AES/RF69_Receive_AES.ino
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
RadioLib RF69 Receive with AES Example
|
||||
|
||||
This example receives packets using RF69 FSK radio module.
|
||||
Packets are decrypted using hardware AES.
|
||||
NOTE: When using address filtering, the address byte is NOT encrypted!
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// RF69 has the following connections:
|
||||
// CS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 3
|
||||
RF69 radio = new Module(10, 2, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize RF69 with default settings
|
||||
Serial.print(F("[RF69] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set AES key that will be used to decrypt the packet
|
||||
// NOTE: the key must be exactly 16 bytes long!
|
||||
uint8_t key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
|
||||
radio.setAESKey(key);
|
||||
|
||||
// enable AES encryption
|
||||
radio.enableAES();
|
||||
|
||||
// AES encryption can also be disabled
|
||||
/*
|
||||
radio.disableAES();
|
||||
*/
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[RF69] Waiting for incoming transmission ... "));
|
||||
|
||||
// you can receive data as an Arduino String
|
||||
String str;
|
||||
int state = radio.receive(str);
|
||||
|
||||
// you can also receive data as byte array
|
||||
/*
|
||||
byte byteArr[8];
|
||||
int state = radio.receive(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// packet was successfully received
|
||||
Serial.println(F("success!"));
|
||||
|
||||
// print the data of the packet
|
||||
Serial.print(F("[RF69] Data:\t\t"));
|
||||
Serial.println(str);
|
||||
|
||||
} else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
|
||||
// timeout occurred while waiting for a packet
|
||||
Serial.println(F("timeout!"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
|
||||
// packet was received, but is malformed
|
||||
Serial.println(F("CRC error!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
RadioLib RF69 Receive with Address Example
|
||||
|
||||
This example receives packets using RF69 FSK radio module.
|
||||
Packets can have 1-byte address of the destination node.
|
||||
After setting node (or broadcast) address, this node will
|
||||
automatically filter out any packets that do not contain
|
||||
either node address or broadcast address.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// RF69 has the following connections:
|
||||
// CS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 3
|
||||
RF69 radio = new Module(10, 2, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize RF69 with default settings
|
||||
Serial.print(F("[RF69] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set node address
|
||||
// NOTE: calling this method will automatically enable
|
||||
// address filtering (node address only)
|
||||
Serial.print(F("[RF69] Setting node address ... "));
|
||||
state = radio.setNodeAddress(0x02);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set broadcast address
|
||||
// NOTE: calling this method will automatically enable
|
||||
// address filtering (node or broadcast address)
|
||||
Serial.print(F("[RF69] Setting broadcast address ... "));
|
||||
state = radio.setBroadcastAddress(0xFF);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// address filtering can also be disabled
|
||||
// NOTE: calling this method will also erase previously set
|
||||
// node and broadcast address
|
||||
/*
|
||||
Serial.print(F("[RF69] Disabling address filtering ... "));
|
||||
state == radio.disableAddressFiltering();
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[RF69] Waiting for incoming transmission ... "));
|
||||
|
||||
// you can receive data as an Arduino String
|
||||
String str;
|
||||
int state = radio.receive(str);
|
||||
|
||||
// you can also receive data as byte array
|
||||
/*
|
||||
byte byteArr[8];
|
||||
int state = radio.receive(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// packet was successfully received
|
||||
Serial.println(F("success!"));
|
||||
|
||||
// print the data of the packet
|
||||
Serial.print(F("[RF69] Data:\t\t"));
|
||||
Serial.println(str);
|
||||
|
||||
} else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
|
||||
// timeout occurred while waiting for a packet
|
||||
Serial.println(F("timeout!"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
|
||||
// packet was received, but is malformed
|
||||
Serial.println(F("CRC error!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
RadioLib RF69 Blocking Receive Example
|
||||
|
||||
This example receives packets using RF69 FSK radio module.
|
||||
To successfully receive data, the following settings have to be the same
|
||||
on both transmitter and receiver:
|
||||
- carrier frequency
|
||||
- bit rate
|
||||
- frequency deviation
|
||||
- sync word
|
||||
|
||||
Using blocking receive is not recommended, as it will lead
|
||||
to significant amount of timeouts, inefficient use of processor
|
||||
time and can miss some packets!
|
||||
Instead, interrupt receive is recommended.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// RF69 has the following connections:
|
||||
// CS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 3
|
||||
RF69 radio = new Module(10, 2, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize RF69 with default settings
|
||||
Serial.print(F("[RF69] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[RF69] Waiting for incoming transmission ... "));
|
||||
|
||||
// you can receive data as an Arduino String
|
||||
String str;
|
||||
int state = radio.receive(str);
|
||||
|
||||
// you can also receive data as byte array
|
||||
/*
|
||||
byte byteArr[8];
|
||||
int state = radio.receive(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// packet was successfully received
|
||||
Serial.println(F("success!"));
|
||||
|
||||
// print the data of the packet
|
||||
Serial.print(F("[RF69] Data:\t\t"));
|
||||
Serial.println(str);
|
||||
|
||||
// print RSSI (Received Signal Strength Indicator)
|
||||
// of the last received packet
|
||||
Serial.print(F("[RF69] RSSI:\t\t"));
|
||||
Serial.print(radio.getRSSI());
|
||||
Serial.println(F(" dBm"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
|
||||
// timeout occurred while waiting for a packet
|
||||
Serial.println(F("timeout!"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
|
||||
// packet was received, but is malformed
|
||||
Serial.println(F("CRC error!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
RadioLib RF69 Receive with Interrupts Example
|
||||
|
||||
This example listens for FSK transmissions and tries to
|
||||
receive them. Once a packet is received, an interrupt is
|
||||
triggered.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// RF69 has the following connections:
|
||||
// CS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 3
|
||||
RF69 radio = new Module(10, 2, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// flag to indicate that a packet was received
|
||||
volatile bool receivedFlag = false;
|
||||
|
||||
// this function is called when a complete packet
|
||||
// is received by the module
|
||||
// IMPORTANT: this function MUST be 'void' type
|
||||
// and MUST NOT have any arguments!
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
ICACHE_RAM_ATTR
|
||||
#endif
|
||||
void setFlag(void) {
|
||||
// we got a packet, set the flag
|
||||
receivedFlag = true;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize RF69 with default settings
|
||||
Serial.print(F("[RF69] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set the function that will be called
|
||||
// when new packet is received
|
||||
radio.setPacketReceivedAction(setFlag);
|
||||
|
||||
// start listening for packets
|
||||
Serial.print(F("[RF69] Starting to listen ... "));
|
||||
state = radio.startReceive();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// if needed, 'listen' mode can be disabled by calling
|
||||
// any of the following methods:
|
||||
//
|
||||
// radio.standby()
|
||||
// radio.sleep()
|
||||
// radio.transmit();
|
||||
// radio.receive();
|
||||
// radio.readData();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// check if the flag is set
|
||||
if(receivedFlag) {
|
||||
// reset flag
|
||||
receivedFlag = false;
|
||||
|
||||
// you can read received data as an Arduino String
|
||||
String str;
|
||||
int state = radio.readData(str);
|
||||
|
||||
// you can also read received data as byte array
|
||||
/*
|
||||
byte byteArr[8];
|
||||
int numBytes = radio.getPacketLength();
|
||||
int state = radio.readData(byteArr, numBytes);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// packet was successfully received
|
||||
Serial.println(F("[RF69] Received packet!"));
|
||||
|
||||
// print data of the packet
|
||||
Serial.print(F("[RF69] Data:\t\t"));
|
||||
Serial.println(str);
|
||||
|
||||
// print RSSI (Received Signal Strength Indicator)
|
||||
// of the last received packet
|
||||
Serial.print(F("[RF69] RSSI:\t\t"));
|
||||
Serial.print(radio.getRSSI());
|
||||
Serial.println(F(" dBm"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
|
||||
// packet was received, but is malformed
|
||||
Serial.println(F("CRC error!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
// put module back to listen mode
|
||||
radio.startReceive();
|
||||
}
|
||||
}
|
||||
143
RadioLib/examples/RF69/RF69_Settings/RF69_Settings.ino
Normal file
143
RadioLib/examples/RF69/RF69_Settings/RF69_Settings.ino
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
RadioLib RF69 Settings Example
|
||||
|
||||
This example shows how to change all the properties of RF69 radio.
|
||||
RadioLib currently supports the following settings:
|
||||
- pins (SPI slave select, digital IO 0, digital IO 1)
|
||||
- carrier frequency
|
||||
- bit rate
|
||||
- receiver bandwidth
|
||||
- allowed frequency deviation
|
||||
- output power during transmission
|
||||
- sync word
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// RF69 has the following connections:
|
||||
// CS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 3
|
||||
RF69 radio1 = new Module(10, 2, 3);
|
||||
|
||||
// second CC1101 has different connections:
|
||||
// CS pin: 9
|
||||
// DIO0 pin: 4
|
||||
// RESET pin: 5
|
||||
RF69 radio2 = new Module(9, 4, 5);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio3 = new RadioModule();
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize RF69 with default settings
|
||||
Serial.print(F("[RF69] Initializing ... "));
|
||||
int state = radio1.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize RF69 with non-default settings
|
||||
Serial.print(F("[RF69] Initializing ... "));
|
||||
// carrier frequency: 868.0 MHz
|
||||
// bit rate: 300.0 kbps
|
||||
// frequency deviation: 60.0 kHz
|
||||
// Rx bandwidth: 250.0 kHz
|
||||
// output power: 17 dBm
|
||||
// preamble length: 32 bits
|
||||
state = radio2.begin(868.0, 300.0, 60.0, 250.0, 17, 32);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// you can also change the settings at runtime
|
||||
// and check if the configuration was changed successfully
|
||||
|
||||
// set carrier frequency to 433.5 MHz
|
||||
if (radio1.setFrequency(433.5) == RADIOLIB_ERR_INVALID_FREQUENCY) {
|
||||
Serial.println(F("[RF69] Selected frequency is invalid for this module!"));
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set bit rate to 100.0 kbps
|
||||
state = radio1.setBitRate(100.0);
|
||||
if (state == RADIOLIB_ERR_INVALID_BIT_RATE) {
|
||||
Serial.println(F("[RF69] Selected bit rate is invalid for this module!"));
|
||||
while (true) { delay(10); }
|
||||
} else if (state == RADIOLIB_ERR_INVALID_BIT_RATE_BW_RATIO) {
|
||||
Serial.println(F("[RF69] Selected bit rate to bandwidth ratio is invalid!"));
|
||||
Serial.println(F("[RF69] Increase receiver bandwidth to set this bit rate."));
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set receiver bandwidth to 250.0 kHz
|
||||
state = radio1.setRxBandwidth(250.0);
|
||||
if (state == RADIOLIB_ERR_INVALID_RX_BANDWIDTH) {
|
||||
Serial.println(F("[RF69] Selected receiver bandwidth is invalid for this module!"));
|
||||
while (true) { delay(10); }
|
||||
} else if (state == RADIOLIB_ERR_INVALID_BIT_RATE_BW_RATIO) {
|
||||
Serial.println(F("[RF69] Selected bit rate to bandwidth ratio is invalid!"));
|
||||
Serial.println(F("[RF69] Decrease bit rate to set this receiver bandwidth."));
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set allowed frequency deviation to 10.0 kHz
|
||||
if (radio1.setFrequencyDeviation(10.0) == RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION) {
|
||||
Serial.println(F("[RF69] Selected frequency deviation is invalid for this module!"));
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set output power to 2 dBm
|
||||
if (radio1.setOutputPower(2) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) {
|
||||
Serial.println(F("[RF69] Selected output power is invalid for this module!"));
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// up to 8 bytes can be set as sync word
|
||||
// NOTE: sync word must not contain any zero bytes
|
||||
// set sync word to 0x0123456789ABCDEF
|
||||
uint8_t syncWord[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
||||
if (radio1.setSyncWord(syncWord, 8) == RADIOLIB_ERR_INVALID_SYNC_WORD) {
|
||||
Serial.println(F("[RF69] Selected sync word is invalid for this module!"));
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
Serial.println(F("[RF69] All settings changed successfully!"));
|
||||
|
||||
// RF69 can also measure temperature (roughly)
|
||||
// to get correct temperature measurements, the sensor must be calibrated
|
||||
// at ambient temperature
|
||||
radio1.setAmbientTemperature(25); // replace 25 with your ambient temperature
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// measure temperature
|
||||
Serial.print(F("[RF69] Measured temperature: "));
|
||||
Serial.print(radio1.getTemperature());
|
||||
Serial.println(F(" deg C"));
|
||||
|
||||
// wait 100 ms before the next measurement
|
||||
delay(100);
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
RadioLib RF69 Transmit with AES Example
|
||||
|
||||
This example transmits packets using RF69 FSK radio module.
|
||||
Packets are encrypted using hardware AES.
|
||||
NOTE: When using address filtering, the address byte is NOT encrypted!
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// RF69 has the following connections:
|
||||
// CS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 3
|
||||
RF69 radio = new Module(10, 2, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize RF69 with default settings
|
||||
Serial.print(F("[RF69] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set AES key to encrypt the packet
|
||||
// NOTE: the key must be exactly 16 bytes long!
|
||||
uint8_t key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
|
||||
radio.setAESKey(key);
|
||||
|
||||
// enable AES encryption
|
||||
radio.enableAES();
|
||||
|
||||
// AES encryption can also be disabled
|
||||
/*
|
||||
radio.disableAES();
|
||||
*/
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[RF69] Transmitting packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to 64 characters long
|
||||
int state = radio.transmit("Hello World!");
|
||||
|
||||
// you can also transmit byte array up to 64 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
||||
int state = radio.transmit(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// the packet was successfully transmitted
|
||||
Serial.println(F("success!"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
|
||||
// the supplied packet was longer than 64 bytes
|
||||
Serial.println(F("too long!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
RadioLib RF69 Transmit to Address Example
|
||||
|
||||
This example transmits packets using RF69 FSK radio module.
|
||||
Packets can have 1-byte address of the destination node.
|
||||
After setting node (or broadcast) address, this node will
|
||||
automatically filter out any packets that do not contain
|
||||
either node address or broadcast address.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// RF69 has the following connections:
|
||||
// CS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 3
|
||||
RF69 radio = new Module(10, 2, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize RF69 with default settings
|
||||
Serial.print(F("[RF69] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set node address
|
||||
// NOTE: calling this method will automatically enable
|
||||
// address filtering (node address only)
|
||||
Serial.print(F("[RF69] Setting node address ... "));
|
||||
state = radio.setNodeAddress(0x01);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set broadcast address
|
||||
// NOTE: calling this method will automatically enable
|
||||
// address filtering (node or broadcast address)
|
||||
Serial.print(F("[RF69] Setting broadcast address ... "));
|
||||
state = radio.setBroadcastAddress(0xFF);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// address filtering can also be disabled
|
||||
// NOTE: calling this method will also erase previously set
|
||||
// node and broadcast address
|
||||
/*
|
||||
Serial.print(F("[RF69] Disabling address filtering ... "));
|
||||
state = radio.disableAddressFiltering();
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[RF69] Transmitting packet ... "));
|
||||
|
||||
// transmit C-string or Arduino string to node with address 0x02
|
||||
int state = radio.transmit("Hello World!", 0x02);
|
||||
|
||||
// transmit byte array to node with address 0x02
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
||||
int state = radio.transmit(byteArr, 8, 0x02);
|
||||
*/
|
||||
|
||||
// transmit C-string or Arduino string in broadcast mode
|
||||
/*
|
||||
int state = radio.transmit("Hello World!", 0xFF);
|
||||
*/
|
||||
|
||||
// transmit byte array in broadcast mode
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
||||
int state = radio.transmit(byteArr, 8, 0xFF);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// the packet was successfully transmitted
|
||||
Serial.println(F("success!"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
|
||||
// the supplied packet was longer than 64 bytes
|
||||
Serial.println(F("too long!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
RadioLib RF69 Blocking Transmit Example
|
||||
|
||||
This example transmits packets using RF69 FSK radio module.
|
||||
Each packet contains up to 64 bytes of data, in the form of:
|
||||
- Arduino String
|
||||
- null-terminated char array (C-string)
|
||||
- arbitrary binary data (byte array)
|
||||
|
||||
Using blocking transmit is not recommended, as it will lead
|
||||
to inefficient use of processor time!
|
||||
Instead, interrupt transmit is recommended.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// RF69 has the following connections:
|
||||
// CS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 3
|
||||
RF69 radio = new Module(10, 2, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize RF69 with default settings
|
||||
Serial.print(F("[RF69] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// NOTE: some RF69 modules use high power output,
|
||||
// those are usually marked RF69H(C/CW).
|
||||
// To configure RadioLib for these modules,
|
||||
// you must call setOutputPower() with
|
||||
// second argument set to true.
|
||||
/*
|
||||
Serial.print(F("[RF69] Setting high power module ... "));
|
||||
state = radio.setOutputPower(20, true);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// counter to keep track of transmitted packets
|
||||
int count = 0;
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[RF69] Transmitting packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to 64 characters long
|
||||
String str = "Hello World! #" + String(count++);
|
||||
int state = radio.transmit(str);
|
||||
|
||||
// you can also transmit byte array up to 64 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
|
||||
int state = radio.transmit(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// the packet was successfully transmitted
|
||||
Serial.println(F("success!"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
|
||||
// the supplied packet was longer than 64 bytes
|
||||
Serial.println(F("too long!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
RadioLib RF69 Transmit with Interrupts Example
|
||||
|
||||
This example transmits FSK packets with one second delays
|
||||
between them. Each packet contains up to 64 bytes
|
||||
of data, in the form of:
|
||||
- Arduino String
|
||||
- null-terminated char array (C-string)
|
||||
- arbitrary binary data (byte array)
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// RF69 has the following connections:
|
||||
// CS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 3
|
||||
RF69 radio = new Module(10, 2, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// save transmission state between loops
|
||||
int transmissionState = RADIOLIB_ERR_NONE;
|
||||
|
||||
// flag to indicate that a packet was sent
|
||||
volatile bool transmittedFlag = false;
|
||||
|
||||
// this function is called when a complete packet
|
||||
// is transmitted by the module
|
||||
// IMPORTANT: this function MUST be 'void' type
|
||||
// and MUST NOT have any arguments!
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
ICACHE_RAM_ATTR
|
||||
#endif
|
||||
void setFlag(void) {
|
||||
// we sent a packet, set the flag
|
||||
transmittedFlag = true;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize RF69 with default settings
|
||||
Serial.print(F("[RF69] Initializing ... "));
|
||||
int state = radio.begin();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set the function that will be called
|
||||
// when packet transmission is finished
|
||||
radio.setPacketSentAction(setFlag);
|
||||
|
||||
// NOTE: some RF69 modules use high power output,
|
||||
// those are usually marked RF69H(C/CW).
|
||||
// To configure RadioLib for these modules,
|
||||
// you must call setOutputPower() with
|
||||
// second argument set to true.
|
||||
/*
|
||||
Serial.print(F("[RF69] Setting high power module ... "));
|
||||
state = radio.setOutputPower(20, true);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
*/
|
||||
|
||||
// start transmitting the first packet
|
||||
Serial.print(F("[RF69] Sending first packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 64 characters long
|
||||
transmissionState = radio.startTransmit("Hello World!");
|
||||
|
||||
// you can also transmit byte array up to 64 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
|
||||
0x89, 0xAB, 0xCD, 0xEF};
|
||||
state = radio.startTransmit(byteArr, 8);
|
||||
*/
|
||||
}
|
||||
|
||||
// counter to keep track of transmitted packets
|
||||
int count = 0;
|
||||
|
||||
void loop() {
|
||||
// check if the previous transmission finished
|
||||
if(transmittedFlag) {
|
||||
// reset flag
|
||||
transmittedFlag = false;
|
||||
|
||||
if (transmissionState == RADIOLIB_ERR_NONE) {
|
||||
// packet was successfully sent
|
||||
Serial.println(F("transmission finished!"));
|
||||
|
||||
// NOTE: when using interrupt-driven transmit method,
|
||||
// it is not possible to automatically measure
|
||||
// transmission data rate using getDataRate()
|
||||
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(transmissionState);
|
||||
|
||||
}
|
||||
|
||||
// clean up after transmission is finished
|
||||
// this will ensure transmitter is disabled,
|
||||
// RF switch is powered down etc.
|
||||
radio.finishTransmit();
|
||||
|
||||
// wait a second before transmitting again
|
||||
delay(1000);
|
||||
|
||||
// send another one
|
||||
Serial.print(F("[RF69] Sending another packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 64 characters long
|
||||
String str = "Hello World! #" + String(count++);
|
||||
transmissionState = radio.startTransmit(str);
|
||||
|
||||
// you can also transmit byte array up to 64 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
|
||||
0x89, 0xAB, 0xCD, 0xEF};
|
||||
transmissionState = radio.startTransmit(byteArr, 8);
|
||||
*/
|
||||
}
|
||||
}
|
||||
145
RadioLib/examples/RTTY/RTTY_Transmit/RTTY_Transmit.ino
Normal file
145
RadioLib/examples/RTTY/RTTY_Transmit/RTTY_Transmit.ino
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
RadioLib RTTY Transmit Example
|
||||
|
||||
This example sends RTTY message using SX1278's
|
||||
FSK modem.
|
||||
|
||||
Other modules that can be used for RTTY:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- SX126x
|
||||
- nRF24
|
||||
- Si443x/RFM2x
|
||||
- SX128x
|
||||
- LR11x0
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create RTTY client instance using the FSK module
|
||||
RTTYClient rtty(&radio);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
|
||||
// when using one of the non-LoRa modules for RTTY
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize RTTY client
|
||||
// NOTE: RTTY frequency shift will be rounded
|
||||
// to the nearest multiple of frequency step size.
|
||||
// The exact value depends on the module:
|
||||
// SX127x/RFM9x - 61 Hz
|
||||
// RF69 - 61 Hz
|
||||
// CC1101 - 397 Hz
|
||||
// SX126x - 1 Hz
|
||||
// nRF24 - 1000000 Hz
|
||||
// Si443x/RFM2x - 156 Hz
|
||||
// SX128x - 198 Hz
|
||||
Serial.print(F("[RTTY] Initializing ... "));
|
||||
// low ("space") frequency: 434.0 MHz
|
||||
// frequency shift: 183 Hz
|
||||
// baud rate: 45 baud
|
||||
// encoding: ASCII (7-bit)
|
||||
// stop bits: 1
|
||||
state = rtty.begin(434.0, 183, 45);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
/*
|
||||
// RadioLib also provides ITA2 ("Baudot") support
|
||||
rtty.begin(434, 183, 45, ITA2);
|
||||
|
||||
// All transmissions in loop() (strings and numbers)
|
||||
// will now be encoded using ITA2 code
|
||||
|
||||
// ASCII characters that do not have ITA2 equivalent
|
||||
// will be sent as NUL (including lower case letters!)
|
||||
*/
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[RTTY] Sending RTTY data ... "));
|
||||
|
||||
// send out idle condition for 500 ms
|
||||
rtty.idle();
|
||||
delay(500);
|
||||
|
||||
// RTTYClient supports all methods of the Serial class
|
||||
|
||||
// Arduino String class
|
||||
String aStr = "Arduino String";
|
||||
rtty.println(aStr);
|
||||
|
||||
// character array (C-String)
|
||||
rtty.println("C-String");
|
||||
|
||||
// string saved in flash
|
||||
rtty.println(F("Flash String"));
|
||||
|
||||
// character
|
||||
rtty.println('c');
|
||||
|
||||
// byte
|
||||
// formatting DEC/HEX/OCT/BIN is supported for
|
||||
// any integer type (byte/int/long)
|
||||
rtty.println(255, HEX);
|
||||
|
||||
// integer number
|
||||
int i = 1000;
|
||||
rtty.println(i);
|
||||
|
||||
// floating point number
|
||||
float f = -3.1415;
|
||||
rtty.println(f, 3);
|
||||
|
||||
// turn the transmitter off
|
||||
rtty.standby();
|
||||
|
||||
Serial.println(F("done!"));
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
||||
145
RadioLib/examples/RTTY/RTTY_Transmit_AFSK/RTTY_Transmit_AFSK.ino
Normal file
145
RadioLib/examples/RTTY/RTTY_Transmit_AFSK/RTTY_Transmit_AFSK.ino
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
RadioLib RTTY Transmit AFSK Example
|
||||
|
||||
This example sends RTTY message using SX1278's
|
||||
FSK modem. The data is modulated as AFSK.
|
||||
|
||||
Other modules that can be used for RTTY:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- Si443x/RFM2x
|
||||
- SX126x/LLCC68
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create AFSK client instance using the FSK module
|
||||
// this requires connection to the module direct
|
||||
// input pin, here connected to Arduino pin 5
|
||||
// SX127x/RFM9x: DIO2
|
||||
// RF69: DIO2
|
||||
// SX1231: DIO2
|
||||
// CC1101: GDO2
|
||||
// Si443x/RFM2x: GPIO
|
||||
// SX126x/LLCC68: DIO2
|
||||
AFSKClient audio(&radio, 5);
|
||||
|
||||
// create RTTY client instance using the AFSK instance
|
||||
RTTYClient rtty(&audio);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
|
||||
// when using one of the non-LoRa modules for RTTY
|
||||
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// initialize RTTY client
|
||||
// NOTE: Unlike FSK RTTY, AFSK requires no rounding of
|
||||
// the frequency shift.
|
||||
Serial.print(F("[RTTY] Initializing ... "));
|
||||
// space frequency: 400 Hz
|
||||
// frequency shift: 170 Hz
|
||||
// baud rate: 45 baud
|
||||
// encoding: ASCII (7-bit)
|
||||
// stop bits: 1
|
||||
state = rtty.begin(400, 170, 45);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
/*
|
||||
// RadioLib also provides ITA2 ("Baudot") support
|
||||
rtty.begin(400, 170, 45, ITA2);
|
||||
|
||||
// All transmissions in loop() (strings and numbers)
|
||||
// will now be encoded using ITA2 code
|
||||
|
||||
// ASCII characters that do not have ITA2 equivalent
|
||||
// will be sent as NUL (including lower case letters!)
|
||||
*/
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[RTTY] Sending RTTY data ... "));
|
||||
|
||||
// send out idle condition for 500 ms
|
||||
rtty.idle();
|
||||
delay(500);
|
||||
|
||||
// RTTYClient supports all methods of the Serial class
|
||||
|
||||
// Arduino String class
|
||||
String aStr = "Arduino String";
|
||||
rtty.println(aStr);
|
||||
|
||||
// character array (C-String)
|
||||
rtty.println("C-String");
|
||||
|
||||
// string saved in flash
|
||||
rtty.println(F("Flash String"));
|
||||
|
||||
// character
|
||||
rtty.println('c');
|
||||
|
||||
// byte
|
||||
// formatting DEC/HEX/OCT/BIN is supported for
|
||||
// any integer type (byte/int/long)
|
||||
rtty.println(255, HEX);
|
||||
|
||||
// integer number
|
||||
int i = 1000;
|
||||
rtty.println(i);
|
||||
|
||||
// floating point number
|
||||
float f = -3.1415;
|
||||
rtty.println(f, 3);
|
||||
|
||||
// turn the transmitter off
|
||||
rtty.standby();
|
||||
|
||||
Serial.println(F("done!"));
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
||||
170
RadioLib/examples/SSTV/SSTV_Transmit/SSTV_Transmit.ino
Normal file
170
RadioLib/examples/SSTV/SSTV_Transmit/SSTV_Transmit.ino
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
RadioLib SSTV Transmit Example
|
||||
|
||||
The following example sends SSTV picture using
|
||||
SX1278's FSK modem.
|
||||
|
||||
Other modules that can be used for SSTV:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- SX126x
|
||||
|
||||
NOTE: SSTV is an analog modulation, and
|
||||
requires precise frequency control.
|
||||
Some of the above modules can only
|
||||
set their frequency in rough steps,
|
||||
so the result can be distorted.
|
||||
Using high-precision radio with TCXO
|
||||
(like SX126x) is recommended.
|
||||
|
||||
NOTE: Some platforms (such as Arduino Uno)
|
||||
might not be fast enough to correctly
|
||||
send pictures via high-speed modes
|
||||
like Scottie2 or Martin2. For those,
|
||||
lower speed modes such as Wrasse,
|
||||
Scottie1 or Martin1 are recommended.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create SSTV client instance using the FSK module
|
||||
SSTVClient sstv(&radio);
|
||||
|
||||
// test "image" - actually just a single 320px line
|
||||
// will be sent over and over again, to create vertical color stripes at the receiver
|
||||
uint32_t line[320] = {
|
||||
// black
|
||||
0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
|
||||
0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
|
||||
|
||||
// blue
|
||||
0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF,
|
||||
0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF,
|
||||
|
||||
// green
|
||||
0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00,
|
||||
0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00,
|
||||
|
||||
// cyan
|
||||
0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF,
|
||||
0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF,
|
||||
|
||||
// red
|
||||
0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000,
|
||||
0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000,
|
||||
|
||||
// magenta
|
||||
0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF,
|
||||
0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF,
|
||||
|
||||
// yellow
|
||||
0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00,
|
||||
0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00,
|
||||
|
||||
// white
|
||||
0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF,
|
||||
0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF
|
||||
};
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// when using one of the non-LoRa modules for SSTV
|
||||
// (RF69, SX1231 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
// initialize SSTV client
|
||||
Serial.print(F("[SSTV] Initializing ... "));
|
||||
// 0 Hz tone frequency: 434.0 MHz
|
||||
// SSTV mode: Wrasse (SC2-180)
|
||||
state = sstv.begin(434.0, Wrasse);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set correction factor
|
||||
// NOTE: Due to different speeds of various platforms
|
||||
// supported by RadioLib (Arduino Uno, ESP32 etc),
|
||||
// and because SSTV is analog protocol, incorrect
|
||||
// timing of pulses can lead to distortions.
|
||||
// To compensate, correction factor can be used
|
||||
// to adjust the length of timing pulses
|
||||
// (lower number = shorter pulses).
|
||||
// The value is usually around 0.95 (95%).
|
||||
Serial.print(F("[SSTV] Setting correction ... "));
|
||||
state = sstv.setCorrection(0.95);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// to help tune the receiver, SSTVClient can send
|
||||
// continuous beep at the frequency corresponding to
|
||||
// 1900 Hz in upper sideband (aka USB) modulation
|
||||
// (SSTV header "leader tone")
|
||||
/*
|
||||
sstv.idle();
|
||||
while (true) { delay(10); }
|
||||
*/
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// send picture with 8 color stripes
|
||||
Serial.print(F("[SSTV] Sending test picture ... "));
|
||||
|
||||
// send synchronization header first
|
||||
sstv.sendHeader();
|
||||
|
||||
// send all picture lines
|
||||
for(uint16_t i = 0; i < sstv.getPictureHeight(); i++) {
|
||||
sstv.sendLine(line);
|
||||
}
|
||||
|
||||
// turn off transmitter
|
||||
radio.standby();
|
||||
|
||||
Serial.println(F("done!"));
|
||||
|
||||
delay(30000);
|
||||
}
|
||||
174
RadioLib/examples/SSTV/SSTV_Transmit_AFSK/SSTV_Transmit_AFSK.ino
Normal file
174
RadioLib/examples/SSTV/SSTV_Transmit_AFSK/SSTV_Transmit_AFSK.ino
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
RadioLib SSTV Transmit AFSK Example
|
||||
|
||||
The following example sends SSTV picture using
|
||||
SX1278's FSK modem. The data is modulated
|
||||
as AFSK.
|
||||
|
||||
Other modules that can be used for SSTV:
|
||||
with AFSK modulation:
|
||||
- SX127x/RFM9x
|
||||
- RF69
|
||||
- SX1231
|
||||
- CC1101
|
||||
- Si443x/RFM2x
|
||||
- SX126x/LLCC68
|
||||
|
||||
NOTE: Some platforms (such as Arduino Uno)
|
||||
might not be fast enough to correctly
|
||||
send pictures via high-speed modes
|
||||
like Scottie2 or Martin2. For those,
|
||||
lower speed modes such as Wrasse,
|
||||
Scottie1 or Martin1 are recommended.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// SX1278 has the following connections:
|
||||
// NSS pin: 10
|
||||
// DIO0 pin: 2
|
||||
// RESET pin: 9
|
||||
// DIO1 pin: 3
|
||||
SX1278 radio = new Module(10, 2, 9, 3);
|
||||
|
||||
// or detect the pinout automatically using RadioBoards
|
||||
// https://github.com/radiolib-org/RadioBoards
|
||||
/*
|
||||
#define RADIO_BOARD_AUTO
|
||||
#include <RadioBoards.h>
|
||||
Radio radio = new RadioModule();
|
||||
*/
|
||||
|
||||
// create AFSK client instance using the FSK module
|
||||
// this requires connection to the module direct
|
||||
// input pin, here connected to Arduino pin 5
|
||||
// SX127x/RFM9x: DIO2
|
||||
// RF69: DIO2
|
||||
// SX1231: DIO2
|
||||
// CC1101: GDO2
|
||||
// Si443x/RFM2x: GPIO
|
||||
// SX126x/LLCC68: DIO2
|
||||
AFSKClient audio(&radio, 5);
|
||||
|
||||
// create SSTV client instance using the AFSK instance
|
||||
SSTVClient sstv(&audio);
|
||||
|
||||
// test "image" - actually just a single 320px line
|
||||
// will be sent over and over again, to create vertical color stripes at the receiver
|
||||
uint32_t line[320] = {
|
||||
// black
|
||||
0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
|
||||
0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
|
||||
|
||||
// blue
|
||||
0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF,
|
||||
0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF, 0x0000FF,
|
||||
|
||||
// green
|
||||
0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00,
|
||||
0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00, 0x00FF00,
|
||||
|
||||
// cyan
|
||||
0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF,
|
||||
0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF, 0x00FFFF,
|
||||
|
||||
// red
|
||||
0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000,
|
||||
0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000, 0xFF0000,
|
||||
|
||||
// magenta
|
||||
0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF,
|
||||
0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF, 0xFF00FF,
|
||||
|
||||
// yellow
|
||||
0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00,
|
||||
0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00, 0xFFFF00,
|
||||
|
||||
// white
|
||||
0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF,
|
||||
0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF, 0xFFFFFF
|
||||
};
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// initialize SX1278 with default settings
|
||||
Serial.print(F("[SX1278] Initializing ... "));
|
||||
int state = radio.beginFSK();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// when using one of the non-LoRa modules for SSTV
|
||||
// (RF69, SX1231 etc.), use the basic begin() method
|
||||
// int state = radio.begin();
|
||||
|
||||
// initialize SSTV client
|
||||
Serial.print(F("[SSTV] Initializing ... "));
|
||||
// SSTV mode: Wrasse (SC2-180)
|
||||
state = sstv.begin(Wrasse);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set correction factor
|
||||
// NOTE: Due to different speeds of various platforms
|
||||
// supported by RadioLib (Arduino Uno, ESP32 etc),
|
||||
// and because SSTV is analog protocol, incorrect
|
||||
// timing of pulses can lead to distortions.
|
||||
// To compensate, correction factor can be used
|
||||
// to adjust the length of timing pulses
|
||||
// (lower number = shorter pulses).
|
||||
// The value is usually around 0.95 (95%).
|
||||
Serial.print(F("[SSTV] Setting correction ... "));
|
||||
state = sstv.setCorrection(0.95);
|
||||
if(state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// to help tune the receiver, SSTVClient can send
|
||||
// continuous 1900 Hz beep
|
||||
/*
|
||||
sstv.idle();
|
||||
while (true) { delay(10); }
|
||||
*/
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// send picture with 8 color stripes
|
||||
Serial.print(F("[SSTV] Sending test picture ... "));
|
||||
|
||||
// send synchronization header first
|
||||
sstv.sendHeader();
|
||||
|
||||
// send all picture lines
|
||||
for(uint16_t i = 0; i < sstv.getPictureHeight(); i++) {
|
||||
sstv.sendLine(line);
|
||||
}
|
||||
|
||||
// turn off transmitter
|
||||
radio.standby();
|
||||
|
||||
Serial.println(F("done!"));
|
||||
|
||||
delay(30000);
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
RadioLib STM32WLx Channel Activity Detection Example
|
||||
|
||||
This example uses STM32WLx to scan the current LoRa
|
||||
channel and detect ongoing LoRa transmissions.
|
||||
Unlike SX127x CAD, SX126x/STM32WLx can detect any part
|
||||
of LoRa transmission, not just the preamble.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// no need to configure pins, signals are routed to the radio internally
|
||||
STM32WLx radio = new STM32WLx_Module();
|
||||
|
||||
// set RF switch configuration for Nucleo WL55JC1
|
||||
// NOTE: other boards may be different!
|
||||
// Some boards may not have either LP or HP.
|
||||
// For those, do not set the LP/HP entry in the table.
|
||||
static const uint32_t rfswitch_pins[] =
|
||||
{PC3, PC4, PC5, RADIOLIB_NC, RADIOLIB_NC};
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
{STM32WLx::MODE_IDLE, {LOW, LOW, LOW}},
|
||||
{STM32WLx::MODE_RX, {HIGH, HIGH, LOW}},
|
||||
{STM32WLx::MODE_TX_LP, {HIGH, HIGH, HIGH}},
|
||||
{STM32WLx::MODE_TX_HP, {HIGH, LOW, HIGH}},
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// set RF switch control configuration
|
||||
// this has to be done prior to calling begin()
|
||||
radio.setRfSwitchTable(rfswitch_pins, rfswitch_table);
|
||||
|
||||
// initialize STM32WLx with default settings, except frequency
|
||||
Serial.print(F("[STM32WLx] Initializing ... "));
|
||||
int state = radio.begin(868.0);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[STM32WLx] Scanning channel for LoRa transmission ... "));
|
||||
|
||||
// start scanning current channel
|
||||
int state = radio.scanChannel();
|
||||
|
||||
if (state == RADIOLIB_LORA_DETECTED) {
|
||||
// LoRa preamble was detected
|
||||
Serial.println(F("detected!"));
|
||||
|
||||
} else if (state == RADIOLIB_CHANNEL_FREE) {
|
||||
// no preamble was detected, channel is free
|
||||
Serial.println(F("channel is free!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
// wait 100 ms before new scan
|
||||
delay(100);
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
RadioLib STM32WLx Channel Activity Detection Example
|
||||
|
||||
This example uses STM32WLx to scan the current LoRa
|
||||
channel and detect ongoing LoRa transmissions.
|
||||
Unlike SX127x CAD, SX126x/STM32WLx can detect any part
|
||||
of LoRa transmission, not just the preamble.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// no need to configure pins, signals are routed to the radio internally
|
||||
STM32WLx radio = new STM32WLx_Module();
|
||||
|
||||
// set RF switch configuration for Nucleo WL55JC1
|
||||
// NOTE: other boards may be different!
|
||||
// Some boards may not have either LP or HP.
|
||||
// For those, do not set the LP/HP entry in the table.
|
||||
static const uint32_t rfswitch_pins[] =
|
||||
{PC3, PC4, PC5, RADIOLIB_NC, RADIOLIB_NC};
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
{STM32WLx::MODE_IDLE, {LOW, LOW, LOW}},
|
||||
{STM32WLx::MODE_RX, {HIGH, HIGH, LOW}},
|
||||
{STM32WLx::MODE_TX_LP, {HIGH, HIGH, HIGH}},
|
||||
{STM32WLx::MODE_TX_HP, {HIGH, LOW, HIGH}},
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
|
||||
// flag to indicate that a packet was detected or CAD timed out
|
||||
volatile bool scanFlag = false;
|
||||
|
||||
// this function is called when a complete packet
|
||||
// is received by the module
|
||||
// IMPORTANT: this function MUST be 'void' type
|
||||
// and MUST NOT have any arguments!
|
||||
void setFlag(void) {
|
||||
// something happened, set the flag
|
||||
scanFlag = true;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// set RF switch control configuration
|
||||
// this has to be done prior to calling begin()
|
||||
radio.setRfSwitchTable(rfswitch_pins, rfswitch_table);
|
||||
|
||||
// initialize STM32WLx with default settings, except frequency
|
||||
Serial.print(F("[STM32WLx] Initializing ... "));
|
||||
int state = radio.begin(868.0);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set the function that will be called
|
||||
// when LoRa packet or timeout is detected
|
||||
radio.setDio1Action(setFlag);
|
||||
|
||||
// start scanning the channel
|
||||
Serial.print(F("[STM32WLx] Starting scan for LoRa preamble ... "));
|
||||
state = radio.startChannelScan();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// check if the flag is set
|
||||
if(scanFlag) {
|
||||
// reset flag
|
||||
scanFlag = false;
|
||||
|
||||
// check CAD result
|
||||
int state = radio.getChannelScanResult();
|
||||
|
||||
if (state == RADIOLIB_LORA_DETECTED) {
|
||||
// LoRa packet was detected
|
||||
Serial.println(F("[STM32WLx] Packet detected!"));
|
||||
|
||||
} else if (state == RADIOLIB_CHANNEL_FREE) {
|
||||
// channel is free
|
||||
Serial.println(F("[STM32WLx] Channel is free!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("[STM32WLx] Failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
// start scanning the channel again
|
||||
Serial.print(F("[STM32WLx] Starting scan for LoRa preamble ... "));
|
||||
state = radio.startChannelScan();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
RadioLib STM32WLx Blocking Receive Example
|
||||
|
||||
This example listens for LoRa transmissions using STM32WL MCU with
|
||||
integrated (SX126x) LoRa radio.
|
||||
|
||||
To successfully receive data, the following settings have to be the same
|
||||
on both transmitter and receiver:
|
||||
- carrier frequency
|
||||
- bandwidth
|
||||
- spreading factor
|
||||
- coding rate
|
||||
- sync word
|
||||
- preamble length
|
||||
|
||||
This example assumes Nucleo WL55JC1 is used. For other Nucleo boards
|
||||
or standalone STM32WL, some configuration such as TCXO voltage and
|
||||
RF switch control may have to be adjusted.
|
||||
|
||||
Using blocking receive is not recommended, as it will lead
|
||||
to significant amount of timeouts, inefficient use of processor
|
||||
time and can some miss packets!
|
||||
Instead, interrupt receive is recommended.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// no need to configure pins, signals are routed to the radio internally
|
||||
STM32WLx radio = new STM32WLx_Module();
|
||||
|
||||
// set RF switch configuration for Nucleo WL55JC1
|
||||
// NOTE: other boards may be different!
|
||||
// Some boards may not have either LP or HP.
|
||||
// For those, do not set the LP/HP entry in the table.
|
||||
static const uint32_t rfswitch_pins[] =
|
||||
{PC3, PC4, PC5, RADIOLIB_NC, RADIOLIB_NC};
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
{STM32WLx::MODE_IDLE, {LOW, LOW, LOW}},
|
||||
{STM32WLx::MODE_RX, {HIGH, HIGH, LOW}},
|
||||
{STM32WLx::MODE_TX_LP, {HIGH, HIGH, HIGH}},
|
||||
{STM32WLx::MODE_TX_HP, {HIGH, LOW, HIGH}},
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// set RF switch control configuration
|
||||
// this has to be done prior to calling begin()
|
||||
radio.setRfSwitchTable(rfswitch_pins, rfswitch_table);
|
||||
|
||||
// initialize STM32WL with default settings, except frequency
|
||||
Serial.print(F("[STM32WL] Initializing ... "));
|
||||
int state = radio.begin(868.0);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set appropriate TCXO voltage for Nucleo WL55JC1
|
||||
state = radio.setTCXO(1.7);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[STM32WL] Waiting for incoming transmission ... "));
|
||||
|
||||
// you can receive data as an Arduino String
|
||||
String str;
|
||||
int state = radio.receive(str);
|
||||
|
||||
// you can also receive data as byte array
|
||||
/*
|
||||
byte byteArr[8];
|
||||
int state = radio.receive(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// packet was successfully received
|
||||
Serial.println(F("success!"));
|
||||
|
||||
// print the data of the packet
|
||||
Serial.print(F("[STM32WL] Data:\t\t"));
|
||||
Serial.println(str);
|
||||
|
||||
// print the RSSI (Received Signal Strength Indicator)
|
||||
// of the last received packet
|
||||
Serial.print(F("[STM32WL] RSSI:\t\t"));
|
||||
Serial.print(radio.getRSSI());
|
||||
Serial.println(F(" dBm"));
|
||||
|
||||
// print the SNR (Signal-to-Noise Ratio)
|
||||
// of the last received packet
|
||||
Serial.print(F("[STM32WL] SNR:\t\t"));
|
||||
Serial.print(radio.getSNR());
|
||||
Serial.println(F(" dB"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
|
||||
// timeout occurred while waiting for a packet
|
||||
Serial.println(F("timeout!"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
|
||||
// packet was received, but is malformed
|
||||
Serial.println(F("CRC error!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
RadioLib STM32WLx Receive with Interrupts Example
|
||||
|
||||
This example listens for LoRa transmissions and tries to
|
||||
receive them. Once a packet is received, an interrupt is
|
||||
triggered. To successfully receive data, the following
|
||||
settings have to be the same on both transmitter
|
||||
and receiver:
|
||||
- carrier frequency
|
||||
- bandwidth
|
||||
- spreading factor
|
||||
- coding rate
|
||||
- sync word
|
||||
|
||||
This example assumes Nucleo WL55JC1 is used. For other Nucleo boards
|
||||
or standalone STM32WL, some configuration such as TCXO voltage and
|
||||
RF switch control may have to be adjusted.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// no need to configure pins, signals are routed to the radio internally
|
||||
STM32WLx radio = new STM32WLx_Module();
|
||||
|
||||
// set RF switch configuration for Nucleo WL55JC1
|
||||
// NOTE: other boards may be different!
|
||||
// Some boards may not have either LP or HP.
|
||||
// For those, do not set the LP/HP entry in the table.
|
||||
static const uint32_t rfswitch_pins[] =
|
||||
{PC3, PC4, PC5, RADIOLIB_NC, RADIOLIB_NC};
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
{STM32WLx::MODE_IDLE, {LOW, LOW, LOW}},
|
||||
{STM32WLx::MODE_RX, {HIGH, HIGH, LOW}},
|
||||
{STM32WLx::MODE_TX_LP, {HIGH, HIGH, HIGH}},
|
||||
{STM32WLx::MODE_TX_HP, {HIGH, LOW, HIGH}},
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
|
||||
// flag to indicate that a packet was received
|
||||
volatile bool receivedFlag = false;
|
||||
|
||||
// this function is called when a complete packet
|
||||
// is received by the module
|
||||
// IMPORTANT: this function MUST be 'void' type
|
||||
// and MUST NOT have any arguments!
|
||||
void setFlag(void) {
|
||||
// we got a packet, set the flag
|
||||
receivedFlag = true;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// set RF switch control configuration
|
||||
// this has to be done prior to calling begin()
|
||||
radio.setRfSwitchTable(rfswitch_pins, rfswitch_table);
|
||||
|
||||
// initialize STM32WL with default settings, except frequency
|
||||
Serial.print(F("[STM32WL] Initializing ... "));
|
||||
int state = radio.begin(868.0);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set appropriate TCXO voltage for Nucleo WL55JC1
|
||||
state = radio.setTCXO(1.7);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set the function that will be called
|
||||
// when new packet is received
|
||||
radio.setDio1Action(setFlag);
|
||||
|
||||
// start listening for LoRa packets
|
||||
Serial.print(F("[STM32WL] Starting to listen ... "));
|
||||
state = radio.startReceive();
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// if needed, 'listen' mode can be disabled by calling
|
||||
// any of the following methods:
|
||||
//
|
||||
// radio.standby()
|
||||
// radio.sleep()
|
||||
// radio.transmit();
|
||||
// radio.receive();
|
||||
// radio.readData();
|
||||
// radio.scanChannel();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// check if the flag is set
|
||||
if(receivedFlag) {
|
||||
// reset flag
|
||||
receivedFlag = false;
|
||||
|
||||
// you can read received data as an Arduino String
|
||||
String str;
|
||||
int state = radio.readData(str);
|
||||
|
||||
// you can also read received data as byte array
|
||||
/*
|
||||
byte byteArr[8];
|
||||
int numBytes = radio.getPacketLength();
|
||||
int state = radio.readData(byteArr, numBytes);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// packet was successfully received
|
||||
Serial.println(F("[STM32WL] Received packet!"));
|
||||
|
||||
// print data of the packet
|
||||
Serial.print(F("[STM32WL] Data:\t\t"));
|
||||
Serial.println(str);
|
||||
|
||||
// print RSSI (Received Signal Strength Indicator)
|
||||
Serial.print(F("[STM32WL] RSSI:\t\t"));
|
||||
Serial.print(radio.getRSSI());
|
||||
Serial.println(F(" dBm"));
|
||||
|
||||
// print SNR (Signal-to-Noise Ratio)
|
||||
Serial.print(F("[STM32WL] SNR:\t\t"));
|
||||
Serial.print(radio.getSNR());
|
||||
Serial.println(F(" dB"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
|
||||
// packet was received, but is malformed
|
||||
Serial.println(F("CRC error!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
RadioLib STM32WLx Blocking Transmit Example
|
||||
|
||||
This example transmits packets using STM32WL MCU with integrated
|
||||
(SX126x) LoRa radio.
|
||||
|
||||
Each packet contains up to 256 bytes of data, in the form of:
|
||||
- Arduino String
|
||||
- null-terminated char array (C-string)
|
||||
- arbitrary binary data (byte array)
|
||||
|
||||
This example assumes Nucleo WL55JC1 is used. For other Nucleo boards
|
||||
or standalone STM32WL, some configuration such as TCXO voltage and
|
||||
RF switch control may have to be adjusted.
|
||||
|
||||
Using blocking transmit is not recommended, as it will lead
|
||||
to inefficient use of processor time!
|
||||
Instead, interrupt transmit is recommended.
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// no need to configure pins, signals are routed to the radio internally
|
||||
STM32WLx radio = new STM32WLx_Module();
|
||||
|
||||
// set RF switch configuration for Nucleo WL55JC1
|
||||
// NOTE: other boards may be different!
|
||||
// Some boards may not have either LP or HP.
|
||||
// For those, do not set the LP/HP entry in the table.
|
||||
static const uint32_t rfswitch_pins[] =
|
||||
{PC3, PC4, PC5, RADIOLIB_NC, RADIOLIB_NC};
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
{STM32WLx::MODE_IDLE, {LOW, LOW, LOW}},
|
||||
{STM32WLx::MODE_RX, {HIGH, HIGH, LOW}},
|
||||
{STM32WLx::MODE_TX_LP, {HIGH, HIGH, HIGH}},
|
||||
{STM32WLx::MODE_TX_HP, {HIGH, LOW, HIGH}},
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// set RF switch control configuration
|
||||
// this has to be done prior to calling begin()
|
||||
radio.setRfSwitchTable(rfswitch_pins, rfswitch_table);
|
||||
|
||||
// initialize STM32WL with default settings, except frequency
|
||||
Serial.print(F("[STM32WL] Initializing ... "));
|
||||
int state = radio.begin(868.0);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set appropriate TCXO voltage for Nucleo WL55JC1
|
||||
state = radio.setTCXO(1.7);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
}
|
||||
|
||||
// counter to keep track of transmitted packets
|
||||
int count = 0;
|
||||
|
||||
void loop() {
|
||||
Serial.print(F("[STM32WL] Transmitting packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 256 characters long
|
||||
String str = "Hello World! #" + String(count++);
|
||||
int state = radio.transmit(str);
|
||||
|
||||
// you can also transmit byte array up to 256 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x56, 0x78, 0xAB, 0xCD, 0xEF};
|
||||
int state = radio.transmit(byteArr, 8);
|
||||
*/
|
||||
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
// the packet was successfully transmitted
|
||||
Serial.println(F("success!"));
|
||||
|
||||
// print measured data rate
|
||||
Serial.print(F("[STM32WL] Datarate:\t"));
|
||||
Serial.print(radio.getDataRate());
|
||||
Serial.println(F(" bps"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
|
||||
// the supplied packet was longer than 256 bytes
|
||||
Serial.println(F("too long!"));
|
||||
|
||||
} else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
|
||||
// timeout occured while transmitting packet
|
||||
Serial.println(F("timeout!"));
|
||||
|
||||
} else {
|
||||
// some other error occurred
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
|
||||
}
|
||||
|
||||
// wait for a second before transmitting again
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
RadioLib STM32WLx Transmit with Interrupts Example
|
||||
|
||||
This example transmits LoRa packets with one second delays
|
||||
between them. Each packet contains up to 256 bytes
|
||||
of data, in the form of:
|
||||
- Arduino String
|
||||
- null-terminated char array (C-string)
|
||||
- arbitrary binary data (byte array)
|
||||
|
||||
For default module settings, see the wiki page
|
||||
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
|
||||
|
||||
For full API reference, see the GitHub Pages
|
||||
https://jgromes.github.io/RadioLib/
|
||||
*/
|
||||
|
||||
// include the library
|
||||
#include <RadioLib.h>
|
||||
|
||||
// no need to configure pins, signals are routed to the radio internally
|
||||
STM32WLx radio = new STM32WLx_Module();
|
||||
|
||||
// set RF switch configuration for Nucleo WL55JC1
|
||||
// NOTE: other boards may be different!
|
||||
// Some boards may not have either LP or HP.
|
||||
// For those, do not set the LP/HP entry in the table.
|
||||
static const uint32_t rfswitch_pins[] =
|
||||
{PC3, PC4, PC5, RADIOLIB_NC, RADIOLIB_NC};
|
||||
static const Module::RfSwitchMode_t rfswitch_table[] = {
|
||||
{STM32WLx::MODE_IDLE, {LOW, LOW, LOW}},
|
||||
{STM32WLx::MODE_RX, {HIGH, HIGH, LOW}},
|
||||
{STM32WLx::MODE_TX_LP, {HIGH, HIGH, HIGH}},
|
||||
{STM32WLx::MODE_TX_HP, {HIGH, LOW, HIGH}},
|
||||
END_OF_MODE_TABLE,
|
||||
};
|
||||
|
||||
// save transmission state between loops
|
||||
int transmissionState = RADIOLIB_ERR_NONE;
|
||||
|
||||
// flag to indicate that a packet was sent
|
||||
volatile bool transmittedFlag = false;
|
||||
|
||||
// this function is called when a complete packet
|
||||
// is transmitted by the module
|
||||
// IMPORTANT: this function MUST be 'void' type
|
||||
// and MUST NOT have any arguments!
|
||||
void setFlag(void) {
|
||||
// we sent a packet, set the flag
|
||||
transmittedFlag = true;
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
// set RF switch control configuration
|
||||
// this has to be done prior to calling begin()
|
||||
radio.setRfSwitchTable(rfswitch_pins, rfswitch_table);
|
||||
|
||||
// initialize STM32WL with default settings, except frequency
|
||||
Serial.print(F("[STM32WL] Initializing ... "));
|
||||
int state = radio.begin(868.0);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set appropriate TCXO voltage for Nucleo WL55JC1
|
||||
state = radio.setTCXO(1.7);
|
||||
if (state == RADIOLIB_ERR_NONE) {
|
||||
Serial.println(F("success!"));
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(state);
|
||||
while (true) { delay(10); }
|
||||
}
|
||||
|
||||
// set the function that will be called
|
||||
// when packet transmission is finished
|
||||
radio.setDio1Action(setFlag);
|
||||
|
||||
// start transmitting the first packet
|
||||
Serial.print(F("[STM32WL] Sending first packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 256 characters long
|
||||
transmissionState = radio.startTransmit("Hello World!");
|
||||
|
||||
// you can also transmit byte array up to 256 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
|
||||
0x89, 0xAB, 0xCD, 0xEF};
|
||||
state = radio.startTransmit(byteArr, 8);
|
||||
*/
|
||||
}
|
||||
|
||||
// counter to keep track of transmitted packets
|
||||
int count = 0;
|
||||
|
||||
void loop() {
|
||||
// check if the previous transmission finished
|
||||
if(transmittedFlag) {
|
||||
// reset flag
|
||||
transmittedFlag = false;
|
||||
|
||||
if (transmissionState == RADIOLIB_ERR_NONE) {
|
||||
// packet was successfully sent
|
||||
Serial.println(F("transmission finished!"));
|
||||
|
||||
// NOTE: when using interrupt-driven transmit method,
|
||||
// it is not possible to automatically measure
|
||||
// transmission data rate using getDataRate()
|
||||
|
||||
} else {
|
||||
Serial.print(F("failed, code "));
|
||||
Serial.println(transmissionState);
|
||||
|
||||
}
|
||||
|
||||
// clean up after transmission is finished
|
||||
// this will ensure transmitter is disabled,
|
||||
// RF switch is powered down etc.
|
||||
radio.finishTransmit();
|
||||
|
||||
// wait a second before transmitting again
|
||||
delay(1000);
|
||||
|
||||
// send another one
|
||||
Serial.print(F("[STM32WL] Sending another packet ... "));
|
||||
|
||||
// you can transmit C-string or Arduino string up to
|
||||
// 256 characters long
|
||||
String str = "Hello World! #" + String(count++);
|
||||
transmissionState = radio.startTransmit(str);
|
||||
|
||||
// you can also transmit byte array up to 256 bytes long
|
||||
/*
|
||||
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
|
||||
0x89, 0xAB, 0xCD, 0xEF};
|
||||
transmissionState = radio.startTransmit(byteArr, 8);
|
||||
*/
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user