Compare commits

..

No commits in common. "master" and "6.4.1" have entirely different histories.

308 changed files with 9761 additions and 99262 deletions

3
.gitattributes vendored
View file

@ -1,3 +0,0 @@
# exclude binary patch files from language detection
src/modules/SX126x/patches/*.h linguist-detectable=false
src/modules/LR11x0/firmware/*.h linguist-detectable=false

View file

@ -7,35 +7,15 @@ assignees: ''
--- ---
**IMPORTANT: Check the docs** **IMPORTANT: Check the wiki**
Before submitting new issue, please check the [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and the [API documentation](https://jgromes.github.io/RadioLib/). If you are seeing an error code, we have [online status code decoder](https://radiolib-org.github.io/status_decoder/decode.html). Before submitting new issue, please check the [Wiki](https://github.com/jgromes/RadioLib/wiki) and the [API documentation](https://jgromes.github.io/RadioLib/). You might find a solution to your issue there.
**Describe the bug** **Describe the bug**
A clear and concise description of what the bug is. When applicable, please include [debug mode output](https://github.com/jgromes/RadioLib/wiki/Debug-mode) **using the appropriate debug mode**. A clear and concise description of what the bug is. When applicable, please include [debug mode output](https://github.com/jgromes/RadioLib/wiki/Debug-mode).
<details><summary>Debug mode output</summary>
<p>
```
paste the debug output here
```
</p>
</details>
**To Reproduce** **To Reproduce**
Minimal Arduino sketch to reproduce the behavior. Please use Markdown to style the code to make it readable (see [Markdown Cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code)). Minimal Arduino sketch to reproduce the behavior. Please use Markdown to style the code to make it readable (see [Markdown Cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code)).
<details><summary>Sketch that is causing the module fail</summary>
<p>
```c++
paste the sketch here, even if it is an unmodified example code
```
</p>
</details>
**Expected behavior** **Expected behavior**
A clear and concise description of what you expected to happen. A clear and concise description of what you expected to happen.
@ -47,4 +27,4 @@ If applicable, add screenshots to help explain your problem.
- Link to Arduino core: [e.g. https://github.com/stm32duino/Arduino_Core_STM32 when using official STM32 core. See readme for links to all supported cores] - Link to Arduino core: [e.g. https://github.com/stm32duino/Arduino_Core_STM32 when using official STM32 core. See readme for links to all supported cores]
- Wireless module type [e.g. CC1101, SX1268, etc.] - Wireless module type [e.g. CC1101, SX1268, etc.]
- Arduino IDE version [e.g. 1.8.5] - Arduino IDE version [e.g. 1.8.5]
- Library version [e.g. 3.0.0 or git hash] - Library version [e.g. 3.0.0]

View file

@ -7,8 +7,8 @@ assignees: ''
--- ---
**IMPORTANT: Check the docs** **IMPORTANT: Check the wiki**
Before submitting new issue, please check the [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and the [API documentation](https://jgromes.github.io/RadioLib/). If you are seeing an error code, we have [online status code decoder](https://radiolib-org.github.io/status_decoder/decode.html). Before submitting new issue, please check the [Wiki](https://github.com/jgromes/RadioLib/wiki) and the [API documentation](https://jgromes.github.io/RadioLib/). You might find a solution to your issue there.
**Is your feature request related to a problem? Please describe.** **Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

View file

@ -9,40 +9,26 @@ assignees: ''
**IMPORTANT: Before submitting an issue, please check the following:** **IMPORTANT: Before submitting an issue, please check the following:**
1. **Read [CONTRIBUTING.md](https://github.com/jgromes/RadioLib/blob/master/CONTRIBUTING.md)!** Issues that do not follow this document will be closed/locked/deleted/ignored. 1. **Read [CONTRIBUTING.md](https://github.com/jgromes/RadioLib/blob/master/CONTRIBUTING.md)!** Issues that do not follow this document will be closed/locked/deleted/ignored.
2. RadioLib has a [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and an extensive [API documentation](https://jgromes.github.io/RadioLib/). If you are seeing an error code, we have [online status code decoder](https://radiolib-org.github.io/status_decoder/decode.html). 2. RadioLib has a [Wiki](https://github.com/jgromes/RadioLib/wiki) and an extensive [API documentation](https://jgromes.github.io/RadioLib/). You might find a solution to your issue there.
3. Make sure you're using the latest release of the library! Releases can be found [here](https://github.com/jgromes/RadioLib/releases). 3. Make sure you're using the latest release of the library! Releases can be found [here](https://github.com/jgromes/RadioLib/releases).
4. Use [Arduino forums](https://forum.arduino.cc/) to ask generic questions about wireless modules, wiring, usage, etc. Only create issues for problems specific to RadioLib! 4. Use [Arduino forums](https://forum.arduino.cc/) to ask generic questions about wireless modules, wiring, usage, etc. Only create issues for problems specific to RadioLib!
5. Error codes, their meaning and how to fix them can be found on [this page](https://jgromes.github.io/RadioLib/group__status__codes.html). 5. Error codes, their meaning and how to fix them can be found on [this page](https://jgromes.github.io/RadioLib/group__status__codes.html).
<details><summary>Sketch that is causing the module fail</summary> **Sketch that is causing the module fail**
<p>
```c++ ```c++
paste the sketch here, even if it is an unmodified example code paste the sketch here, even if it is an unmodified example code
``` ```
</p>
</details>
**Hardware setup** **Hardware setup**
Wiring diagram, schematic, pictures etc. Wiring diagram, schematic, pictures etc.
**Debug mode output** **Debug mode output**
Enable the appropriate [debug levels](https://github.com/jgromes/RadioLib/wiki/Debug-mode) and paste the Serial monitor output here. For debugging protocols, enable `RADIOLIB_DEBUG_PROTOCOL`. For debugging issues with the radio module itself, enable `RADIOLIB_DEBUG_SPI`. Enable all [debug levels](https://github.com/jgromes/RadioLib/wiki/Debug-mode) and paste the Serial monitor output here.
<details><summary>Debug mode output</summary>
<p>
```
paste the debug output here
```
</p>
</details>
**Additional info (please complete):** **Additional info (please complete):**
- MCU: [e.g. Arduino Uno, ESP8266 etc.] - MCU: [e.g. Arduino Uno, ESP8266 etc.]
- Link to Arduino core: [e.g. https://github.com/stm32duino/Arduino_Core_STM32 when using official STM32 core. See readme for links to all supported cores] - Link to Arduino core: [e.g. https://github.com/stm32duino/Arduino_Core_STM32 when using official STM32 core. See readme for links to all supported cores]
- Wireless module type [e.g. CC1101, SX1268, etc.] - Wireless module type [e.g. CC1101, SX1268, etc.]
- Arduino IDE version [e.g. 1.8.5] - Arduino IDE version [e.g. 1.8.5]
- Library version [e.g. 3.0.0 or git hash] - Library version [e.g. 3.0.0]

View file

@ -9,7 +9,7 @@ assignees: ''
**IMPORTANT: Before submitting an issue, please check the following:** **IMPORTANT: Before submitting an issue, please check the following:**
1. **Read [CONTRIBUTING.md](https://github.com/jgromes/RadioLib/blob/master/CONTRIBUTING.md)!** Issues that do not follow this document will be closed/locked/deleted/ignored. 1. **Read [CONTRIBUTING.md](https://github.com/jgromes/RadioLib/blob/master/CONTRIBUTING.md)!** Issues that do not follow this document will be closed/locked/deleted/ignored.
2. RadioLib has a [Troubleshooting Guide](https://github.com/jgromes/RadioLib/wiki/Troubleshooting-Guide) Wiki page and an extensive [API documentation](https://jgromes.github.io/RadioLib/). If you are seeing an error code, we have [online status code decoder](https://radiolib-org.github.io/status_decoder/decode.html). 2. RadioLib has a [Wiki](https://github.com/jgromes/RadioLib/wiki) and an extensive [API documentation](https://jgromes.github.io/RadioLib/). You might find a solution to your issue there.
3. Make sure you're using the latest release of the library! Releases can be found [here](https://github.com/jgromes/RadioLib/releases). 3. Make sure you're using the latest release of the library! Releases can be found [here](https://github.com/jgromes/RadioLib/releases).
4. Use [Arduino forums](https://forum.arduino.cc/) to ask generic questions about wireless modules, wiring, usage, etc. Only create issues for problems specific to RadioLib! 4. Use [Arduino forums](https://forum.arduino.cc/) to ask generic questions about wireless modules, wiring, usage, etc. Only create issues for problems specific to RadioLib!
5. Error codes, their meaning and how to fix them can be found on [this page](https://jgromes.github.io/RadioLib/group__status__codes.html). 5. Error codes, their meaning and how to fix them can be found on [this page](https://jgromes.github.io/RadioLib/group__status__codes.html).

View file

@ -1,14 +0,0 @@
## Pull request template
Thank you for taking the time to contribute to RadioLib development!
To keep this library organized, please follow these rules.
1. Make sure the the code in your PR is tested and that you understand all its impacts.
2. Ensure that all CI actions pass - PRs with failed CI will not be merged. CI actions run automatically for every commit pushed to the PR and test the following:
a. Compilation for Arduino, ESP-IDF and on Raspberry Pi
b. Runtime test on Raspberry Pi
c. GitHub CodeQL check
d. Cppcheck static code scan
3. Follow code style guidelines in [CONTRIBUTING.md](https://github.com/jgromes/RadioLib/blob/master/CONTRIBUTING.md)
4. Heads up - all PRs undergo review, during which you may be asked to correct or change some things. The purpose of this review is to keep regressions and bugs at the minimum, and to keep consistent coding style. Please take them as constructive criticism from people who may have a different point-of-view than you do.
After addressing/accepting the points above, delete the contents of this template and replace it with text explaining what is the goal of your PR, why you want to add it to the upstream and what are the foreseen impacts. Once again, thank you for taking the time to contribute!

View file

@ -5,14 +5,11 @@ on:
branches: [master] branches: [master]
pull_request: pull_request:
branches: [master] branches: [master]
workflow_dispatch:
jobs: jobs:
analyze: analyze:
name: Analyze name: Analyze
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
security-events: write
strategy: strategy:
fail-fast: false fail-fast: false
@ -21,11 +18,20 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v2
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v3 uses: github/codeql-action/init@v1
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
@ -54,7 +60,7 @@ jobs:
- name: Build example - name: Build example
run: run:
arduino-cli compile --libraries /home/runner/work/RadioLib --fqbn arduino:avr:uno $PWD/examples/SX123x/SX123x_Transmit_Blocking/SX123x_Transmit_Blocking.ino --warnings=all arduino-cli compile --libraries /home/runner/work/RadioLib --fqbn arduino:avr:uno $PWD/examples/SX126x/SX126x_Transmit_Blocking/SX126x_Transmit_Blocking.ino --warnings=all
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3 uses: github/codeql-action/analyze@v1

View file

@ -1,25 +0,0 @@
name: "Cppcheck"
on:
push:
branches: [master]
pull_request:
branches: [master]
workflow_dispatch:
jobs:
check:
name: Perform static code check
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install cppcheck
run: |
sudo apt-get update
sudo apt-get install -y cppcheck
- name: Run cppcheck
run: ./extras/cppcheck/cppcheck.sh

View file

@ -13,7 +13,7 @@ jobs:
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install -y doxygen sudo apt-get install -y doxygen
- uses: actions/checkout@v4 - uses: actions/checkout@v2
- name: Generate docs - name: Generate docs
run: doxygen Doxyfile run: doxygen Doxyfile

View file

@ -10,11 +10,12 @@ on:
id: id:
description: The ID of the platform on which the build is run description: The ID of the platform on which the build is run
required: true required: true
default: arduino:avr:mega default: arduino:avr:uno
type: choice type: choice
options: options:
- all - all
- none - none
- arduino:avr:uno
- arduino:avr:mega - arduino:avr:mega
- arduino:mbed:nano33ble - arduino:mbed:nano33ble
- arduino:mbed:envie_m4 - arduino:mbed:envie_m4
@ -26,6 +27,7 @@ on:
- esp32:esp32:esp32 - esp32:esp32:esp32
- esp8266:esp8266:generic - esp8266:esp8266:generic
- Intel:arc32:arduino_101 - Intel:arc32:arduino_101
- SparkFun:apollo3:sfe_artemis
- STMicroelectronics:stm32:GenF3:pnum=BLACKPILL_F303CC - STMicroelectronics:stm32:GenF3:pnum=BLACKPILL_F303CC
- STMicroelectronics:stm32:Nucleo_64:pnum=NUCLEO_WL55JC1 - STMicroelectronics:stm32:Nucleo_64:pnum=NUCLEO_WL55JC1
- stm32duino:STM32F1:mapleMini - stm32duino:STM32F1:mapleMini
@ -36,7 +38,6 @@ on:
- MegaCore:avr:1281 - MegaCore:avr:1281
- teensy:avr:teensy41 - teensy:avr:teensy41
- arduino:renesas_uno:minima - arduino:renesas_uno:minima
- SiliconLabs:silabs:xg24explorerkit
jobs: jobs:
build: build:
@ -44,25 +45,27 @@ jobs:
matrix: matrix:
# platform-dependent settings - extra board options, board index URLs, skip patterns etc. # platform-dependent settings - extra board options, board index URLs, skip patterns etc.
include: include:
- id: arduino:avr:uno
run: echo "skip-pattern=(STM32WL|SSTV|LoRaWAN)" >> $GITHUB_OUTPUT
- id: arduino:avr:mega - id: arduino:avr:mega
run: | run: echo "options=':cpu=atmega2560'" >> $GITHUB_OUTPUT
echo "options=':cpu=atmega2560'" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
- id: arduino:mbed:nano33ble - id: arduino:mbed:nano33ble
run: echo "skip-pattern=(STM32WL|LoRaWAN_End_Device_Persistent)" >> $GITHUB_OUTPUT
- id: arduino:mbed:envie_m4 - id: arduino:mbed:envie_m4
run: echo "skip-pattern=(STM32WL|LoRaWAN_End_Device_Persistent)" >> $GITHUB_OUTPUT
- id: arduino:megaavr:uno2018 - id: arduino:megaavr:uno2018
run: | run: |
echo "options=':mode=on'" >> $GITHUB_OUTPUT echo "options=':mode=on'" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LoRaWAN|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT echo "skip-pattern=(STM32WL|LoRaWAN)" >> $GITHUB_OUTPUT
- id: arduino:sam:arduino_due_x - id: arduino:sam:arduino_due_x
run: echo "skip-pattern=(STM32WL|LoRaWAN_End_Device_Persistent)" >> $GITHUB_OUTPUT
- id: arduino:samd:arduino_zero_native - id: arduino:samd:arduino_zero_native
run: | run: echo "skip-pattern=(STM32WL|LoRaWAN_End_Device_Persistent)" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
- id: adafruit:samd:adafruit_feather_m0 - id: adafruit:samd:adafruit_feather_m0
run: | run: |
echo "options=':usbstack=arduino,debug=off'" >> $GITHUB_OUTPUT echo "options=':usbstack=arduino,debug=off'" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls https://adafruit.github.io/arduino-board-index/package_adafruit_index.json" >> $GITHUB_OUTPUT echo "index-url=--additional-urls https://adafruit.github.io/arduino-board-index/package_adafruit_index.json" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT echo "skip-pattern=(STM32WL|LoRaWAN_End_Device_Persistent)" >> $GITHUB_OUTPUT
- id: adafruit:nrf52:feather52832 - id: adafruit:nrf52:feather52832
run: | run: |
sudo apt-get update sudo apt-get update
@ -72,68 +75,51 @@ jobs:
echo "/home/runner/.local/bin" >> $GITHUB_PATH echo "/home/runner/.local/bin" >> $GITHUB_PATH
echo "options=':softdevice=s132v6,debug=l0'" >> $GITHUB_OUTPUT echo "options=':softdevice=s132v6,debug=l0'" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls https://adafruit.github.io/arduino-board-index/package_adafruit_index.json" >> $GITHUB_OUTPUT echo "index-url=--additional-urls https://adafruit.github.io/arduino-board-index/package_adafruit_index.json" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT echo "skip-pattern=(STM32WL|LoRaWAN_End_Device_Persistent)" >> $GITHUB_OUTPUT
- id: esp32:esp32:esp32 - id: esp32:esp32:esp32
run: | run: |
python -m pip install pyserial python -m pip install pyserial
echo "version=2.0.17" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json" >> $GITHUB_OUTPUT echo "index-url=--additional-urls https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json" >> $GITHUB_OUTPUT
- id: esp8266:esp8266:generic - id: esp8266:esp8266:generic
run: | run: |
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
echo "options=':xtal=80,ResetMethod=ck,CrystalFreq=26,FlashFreq=40,FlashMode=qio,eesz=512K'" >> $GITHUB_OUTPUT echo "options=':xtal=80,ResetMethod=ck,CrystalFreq=26,FlashFreq=40,FlashMode=qio,eesz=512K'" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls http://arduino.esp8266.com/stable/package_esp8266com_index.json" >> $GITHUB_OUTPUT echo "index-url=--additional-urls http://arduino.esp8266.com/stable/package_esp8266com_index.json" >> $GITHUB_OUTPUT
- id: STMicroelectronics:stm32:GenF3 - id: Intel:arc32:arduino_101
- id: SparkFun:apollo3:sfe_artemis
run: | run: |
echo "options=':pnum=BLACKPILL_F303CC'" >> $GITHUB_OUTPUT echo "warnings='none'" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls https://raw.githubusercontent.com/stm32duino/BoardManagerFiles/main/package_stmicroelectronics_index.json" >> $GITHUB_OUTPUT echo "index-url=--additional-urls https://raw.githubusercontent.com/sparkfun/Arduino_Apollo3/master/package_sparkfun_apollo3_index.json" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT - id: STMicroelectronics:stm32:GenF3:pnum=BLACKPILL_F303CC
- id: STMicroelectronics:stm32:Nucleo_64 run: echo "index-url=--additional-urls https://raw.githubusercontent.com/stm32duino/BoardManagerFiles/main/package_stmicroelectronics_index.json" >> $GITHUB_OUTPUT
- id: STMicroelectronics:stm32:Nucleo_64:pnum=NUCLEO_WL55JC1
run: | run: |
echo "options=':pnum=NUCLEO_WL55JC1'" >> $GITHUB_OUTPUT
# Do *not* skip STM32WL examples # Do *not* skip STM32WL examples
echo "skip-pattern=(LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT echo "skip-pattern=''" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls https://raw.githubusercontent.com/stm32duino/BoardManagerFiles/main/package_stmicroelectronics_index.json" >> $GITHUB_OUTPUT echo "index-url=--additional-urls https://raw.githubusercontent.com/stm32duino/BoardManagerFiles/main/package_stmicroelectronics_index.json" >> $GITHUB_OUTPUT
- id: stm32duino:STM32F1:mapleMini - id: stm32duino:STM32F1:mapleMini
run: | run: |
echo "options=':bootloader_version=original,cpu_speed=speed_72mhz'" >> $GITHUB_OUTPUT echo "options=':bootloader_version=original,cpu_speed=speed_72mhz'" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls http://dan.drown.org/stm32duino/package_STM32duino_index.json" >> $GITHUB_OUTPUT echo "index-url=--additional-urls http://dan.drown.org/stm32duino/package_STM32duino_index.json" >> $GITHUB_OUTPUT
- id: MegaCoreX:megaavr:4809 - id: MegaCoreX:megaavr:4809
run: | run: |
echo "skip-pattern=(STM32WL|LoRaWAN)" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls https://mcudude.github.io/MegaCoreX/package_MCUdude_MegaCoreX_index.json" >> $GITHUB_OUTPUT echo "index-url=--additional-urls https://mcudude.github.io/MegaCoreX/package_MCUdude_MegaCoreX_index.json" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update|LoRaWAN)" >> $GITHUB_OUTPUT
- id: arduino:mbed_rp2040:pico - id: arduino:mbed_rp2040:pico
run: echo "skip-pattern=(STM32WL|LoRaWAN_End_Device_Persistent)" >> $GITHUB_OUTPUT
- id: rp2040:rp2040:rpipico - id: rp2040:rp2040:rpipico
run: echo "index-url=--additional-urls https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json" >> $GITHUB_OUTPUT run: echo "index-url=--additional-urls https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json" >> $GITHUB_OUTPUT
- id: CubeCell:CubeCell:CubeCell-Board - id: CubeCell:CubeCell:CubeCell-Board
run: | run: echo "index-url=--additional-urls https://resource.heltec.cn/download/package_CubeCell_index.json" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls https://resource.heltec.cn/download/package_CubeCell_index.json" >> $GITHUB_OUTPUT
- id: MegaCore:avr:1281 - id: MegaCore:avr:1281
run: | run: echo "index-url=--additional-urls https://mcudude.github.io/MegaCore/package_MCUdude_MegaCore_index.json" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls https://mcudude.github.io/MegaCore/package_MCUdude_MegaCore_index.json" >> $GITHUB_OUTPUT
echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
- id: teensy:avr:teensy41
run: |
echo "skip-pattern=(STM32WL|LoRaWAN)" >> $GITHUB_OUTPUT
echo "index-url=--additional-urls https://www.pjrc.com/teensy/package_teensy_index.json" >> $GITHUB_OUTPUT
- id: arduino:renesas_uno:minima - id: arduino:renesas_uno:minima
run: |
echo "skip-pattern=(STM32WL|LoRaWAN|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
- id: SiliconLabs:silabs:xg24explorerkit
run: |
echo "index-url=--additional-urls https://siliconlabs.github.io/arduino/package_arduinosilabs_index.json" >> $GITHUB_OUTPUT
runs-on: ubuntu-latest runs-on: ubuntu-latest
name: ${{ matrix.id }} name: ${{ matrix.id }}
env: env:
run-build: ${{ (inputs.id != 'none' && matrix.id == 'arduino:avr:mega') || contains(github.event.head_commit.message, 'CI_BUILD_ALL') || contains(github.event.head_commit.message, 'Bump version to') || contains(github.event.head_commit.message, format('{0}', matrix.id)) || inputs.id == 'all' || inputs.id == matrix.id }} run-build: ${{ (inputs.id != 'none' && matrix.id == 'arduino:avr:uno') || contains(github.event.head_commit.message, 'CI_BUILD_ALL') || contains(github.event.head_commit.message, 'Bump version to') || contains(github.event.head_commit.message, format('{0}', matrix.id)) || inputs.id == 'all' || inputs.id == matrix.id }}
steps: steps:
- name: Free Disk Space (Ubuntu)
uses: jlumbroso/free-disk-space@v1.3.1
- name: Install arduino-cli - name: Install arduino-cli
if: ${{ env.run-build == 'true' }} if: ${{ env.run-build == 'true' }}
run: run:
@ -168,89 +154,42 @@ jobs:
run: run:
| |
arduino-cli core update-index ${{ format('{0}', steps.prep.outputs.index-url) }} arduino-cli core update-index ${{ format('{0}', steps.prep.outputs.index-url) }}
if [ -z '${{ steps.prep.outputs.version }}' ]; then arduino-cli core install ${{ format('{0}:{1} {2}', steps.split.outputs._0, steps.split.outputs._1, steps.prep.outputs.index-url) }}
arduino-cli core install ${{ format('{0}:{1} {2}', steps.split.outputs._0, steps.split.outputs._1, steps.prep.outputs.index-url) }}
else
arduino-cli core install ${{ format('{0}:{1}@{3} {2}', steps.split.outputs._0, steps.split.outputs._1, steps.prep.outputs.index-url, steps.prep.outputs.version) }}
fi
- name: Checkout repository - name: Checkout repository
if: ${{ env.run-build == 'true' }} if: ${{ env.run-build == 'true' }}
uses: actions/checkout@v4 uses: actions/checkout@v2
- name: Build examples - name: Build examples
if: ${{ env.run-build == 'true' }} if: ${{ env.run-build == 'true' }}
run: run:
| |
cd $PWD/extras/test/ci for example in $(find $PWD/examples -name '*.ino' | sort); do
./build_examples.sh ${{ matrix.id }} "${{ steps.prep.outputs.skip-pattern }}" ${{ steps.prep.outputs.options }} # check whether to skip this sketch
if [ ! -z '${{ steps.prep.outputs.skip-pattern }}' ] && [[ ${example} =~ ${{ steps.prep.outputs.skip-pattern }} ]]; then
- name: Extract short commit hash # skip sketch
id: short-hash echo -e "\n\033[1;33mSkipped ${example##*/} (matched with ${{ steps.prep.outputs.skip-pattern }})\033[0m";
run: echo "::set-output name=short_sha::$(git rev-parse --short HEAD)" else
# build sketch
- name: Parse sizes echo -e "\n\033[1;33mBuilding ${example##*/} ... \033[0m";
if: ${{ env.run-build == 'true' }} arduino-cli compile --libraries /home/runner/work/RadioLib --fqbn ${{ matrix.id }}${{ steps.prep.outputs.options }} $example --warnings=${{ steps.prep.outputs.warnings }}
run: if [ $? -ne 0 ]; then
| echo -e "\033[1;31m${example##*/} build FAILED\033[0m\n";
cd $PWD/extras/test/ci exit 1;
./parse_size.sh ${{ matrix.id }} else
cat size_${{ steps.short-hash.outputs.short_sha }}_${{ steps.split.outputs._0 }}-${{ steps.split.outputs._1 }}-${{ steps.split.outputs._2 }}.csv echo -e "\033[1;32m${example##*/} build PASSED\033[0m\n";
fi
- name: Upload size report as artifact fi
uses: actions/upload-artifact@v4 done
with:
name: size-file-${{ steps.split.outputs._0 }}-${{ steps.split.outputs._1 }}-${{ steps.split.outputs._2 }}
path: extras/test/ci/size_${{ steps.short-hash.outputs.short_sha }}_${{ steps.split.outputs._0 }}-${{ steps.split.outputs._1 }}-${{ steps.split.outputs._2 }}.csv
metrics:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/master'
steps:
- name: Set up SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.ACTIONS_METRICS_DEPLOY_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan github.com >> ~/.ssh/known_hosts
- name: Clone artifact repo
run:
|
cd $PWD/..
git clone git@github.com:radiolib-org/artifacts.git
cd artifacts
git config --global user.name "${{ github.actor }}"
git config --global user.email "${{ github.actor }}@users.noreply.github.com"
- name: Download size artifacts
uses: actions/download-artifact@v4
with:
path: aggregated-sizes
- name: Push size files
run:
|
ls -R aggregated-sizes
mkdir -p $PWD/../artifacts/radiolib-ci/l0
cp aggregated-sizes/*/size_*.csv $PWD/../artifacts/radiolib-ci/l0/.
cd $PWD/../artifacts/radiolib-ci
git add .
COMMIT_URL="https://github.com/jgromes/RadioLib/commit/$GITHUB_SHA"
git commit -m "Push artifacts from $COMMIT_URL"
git push origin main
esp-build: esp-build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v2
- name: Install dependencies - name: Install dependencies
run: | run: sudo apt-get install -y git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0
sudo apt-get update
sudo apt-get install -y git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0
- name: Clone ESP-IDF - name: Clone ESP-IDF
run: | run: |
@ -273,7 +212,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v2
with: with:
submodules: recursive submodules: recursive
@ -282,34 +221,24 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt-get install -y gcc-arm-none-eabi gcc-riscv64-unknown-elf sudo apt-get install -y gcc-arm-none-eabi
cargo install elf2tab cargo install elf2tab
- name: Build the example - name: Build the example
run: | run: |
cd $PWD/examples/NonArduino/Tock cd $PWD/examples/NonArduino/Tock
git clone https://github.com/tock/libtock-c.git ./build.sh
cd libtock-c; git checkout c0202f9ab78da4a6e95f136cf5250701e3778f63; cd ../
LIBTOCK_C_DIRECTORY="$(pwd)/libtock-c" ./build.sh
rpi-build: rpi-build:
if: false # self-hosted runner temporarily disabled
runs-on: [self-hosted, ARM64] runs-on: [self-hosted, ARM64]
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v2
- name: Install dependencies - name: Install dependencies
run: | run: |
sudo apt-get update sudo apt-get update
sudo apt-get install -y cmake wget swig python-dev python3-dev python-setuptools python3-setuptools sudo apt-get install -y pigpio cmake
wget http://abyz.me.uk/lg/lg.zip
unzip lg.zip
cd lg
make
sudo make install
cd ..
sudo rm -rf lg
- name: Install the library - name: Install the library
run: | run: |
@ -325,7 +254,6 @@ jobs:
./build.sh ./build.sh
rpi-test: rpi-test:
if: false # self-hosted runner temporarily disabled
needs: rpi-build needs: rpi-build
runs-on: [self-hosted, ARM64] runs-on: [self-hosted, ARM64]
steps: steps:
@ -340,7 +268,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v2
- name: Install dependencies - name: Install dependencies
run: | run: |

View file

@ -1,37 +0,0 @@
name: "Release"
on: workflow_dispatch
jobs:
release:
name: Release RadioLib update
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Checkout latest tag
run: git checkout $(git describe --tags $(git rev-list --tags --max-count=1))
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
- name: Install PlatformIO and ESP-IDF
run: |
pip install --upgrade platformio
pip install --upgrade idf-component-manager
- name: PlatformIO publish
env:
PLATFORMIO_AUTH_TOKEN: ${{ secrets.PLATFORMIO_AUTH_TOKEN }}
run: pio pkg publish --no-interactive
- name: ESP-IDF publish
env:
IDF_COMPONENT_API_TOKEN: ${{ secrets.IDF_COMPONENT_API_TOKEN }}
run: compote component upload --name RadioLib --namespace jgromes

View file

@ -1,48 +0,0 @@
name: "Unit test"
on:
push:
branches: [master]
pull_request:
branches: [master]
workflow_dispatch:
jobs:
unit-test:
name: Build and run unit test
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y libboost-all-dev libfmt-dev lcov
- name: Run unit test
run: |
cd extras/test/unit
./test.sh
- name: Measure test coverage
run: |
cd extras/test/unit
./coverage.sh
- name: Upload coverage report as artifact
uses: actions/upload-artifact@v4
with:
name: coverage_report
path: extras/test/unit/lcov.report
- name: Deploy to GitHub Pages
if: github.ref == 'refs/heads/master'
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_branch: gh-pages
publish_dir: extras/test/unit/lcov.report
destination_dir: coverage
keep_files: true

10
.gitignore vendored
View file

@ -11,11 +11,15 @@
# Jetbrain IDEs # Jetbrain IDEs
.idea .idea
# Debug decoder
extras/decoder/log.txt
extras/decoder/out.txt
# Spectrum scan
extras/SX126x_Spectrum_Scan/out/*
# PlatformIO # PlatformIO
.pio* .pio*
# cmake # cmake
build/ build/
# Compote build output
dist

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "examples/NonArduino/Tock/libtock-c"]
path = examples/NonArduino/Tock/libtock-c
url = https://github.com/tock/libtock-c.git

View file

@ -32,12 +32,6 @@ target_include_directories(RadioLib
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src> PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>) $<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 -Wpedantic -Wdouble-promotion)
include(GNUInstallDirs) include(GNUInstallDirs)
install(TARGETS RadioLib install(TARGETS RadioLib

View file

@ -1,9 +1,11 @@
# RadioLib ![Build Status](https://github.com/jgromes/RadioLib/workflows/CI/badge.svg) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/jgromes/library/RadioLib.svg)](https://registry.platformio.org/libraries/jgromes/RadioLib) [![Component Registry](https://components.espressif.com/components/jgromes/radiolib/badge.svg)](https://components.espressif.com/components/jgromes/radiolib) # RadioLib ![Build Status](https://github.com/jgromes/RadioLib/workflows/CI/badge.svg) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/jgromes/library/RadioLib.svg)](https://registry.platformio.org/libraries/jgromes/RadioLib)
### _One radio library to rule them all!_ ### _One radio library to rule them all!_
## Universal wireless communication library for embedded devices ## Universal wireless communication library for embedded devices
## See the [Wiki](https://github.com/jgromes/RadioLib/wiki) and [FAQ](https://github.com/jgromes/RadioLib/wiki/Frequently-Asked-Questions) for further information. See the [GitHub Pages](https://jgromes.github.io/RadioLib) for detailed and up-to-date API reference.
RadioLib allows its users to integrate all sorts of different wireless communication modules, protocols and even digital modes into a single consistent system. 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! 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!
@ -11,17 +13,9 @@ RadioLib natively supports Arduino, but can run in non-Arduino environments as w
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! 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: ### Supported modules:
* __CC1101__ FSK radio module * __CC1101__ FSK radio module
* __LLCC68__ LoRa module * __LLCC68__ LoRa module
* __LR11x0__ series LoRa/GFSK modules (LR1110, LR1120, LR1121)
* __nRF24L01__ 2.4 GHz module * __nRF24L01__ 2.4 GHz module
* __RF69__ FSK/OOK radio module * __RF69__ FSK/OOK radio module
* __RFM2x__ series FSK modules (RFM22, RM23) * __RFM2x__ series FSK modules (RFM22, RM23)
@ -35,26 +29,26 @@ RadioLib was originally created as a driver for [__RadioShield__](https://github
### Supported protocols and digital modes: ### Supported protocols and digital modes:
* [__AX.25__](https://www.sigidwiki.com/wiki/PACKET) using 2-FSK or AFSK for modules: * [__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 SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, RFM2x and Si443x
* [__RTTY__](https://www.sigidwiki.com/wiki/RTTY) using 2-FSK or AFSK for modules: * [__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 SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x and SX128x
* [__Morse Code__](https://www.sigidwiki.com/wiki/Morse_Code_(CW)) using 2-FSK or AFSK for modules: * [__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 SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x and SX128x
* [__SSTV__](https://www.sigidwiki.com/wiki/SSTV) using 2-FSK or AFSK for modules: * [__SSTV__](https://www.sigidwiki.com/wiki/SSTV) using 2-FSK or AFSK for modules:
SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, RFM2x and Si443x SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, RFM2x and Si443x
* [__Hellschreiber__](https://www.sigidwiki.com/wiki/Hellschreiber) using 2-FSK or AFSK for modules: * [__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 SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x and SX128x
* [__APRS__](https://www.sigidwiki.com/wiki/APRS) using AFSK for modules: * [__APRS__](https://www.sigidwiki.com/wiki/APRS) using AFSK for modules:
SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x and SX128x SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x and SX128x
* [__POCSAG__](https://www.sigidwiki.com/wiki/POCSAG) using 2-FSK for modules: * [__POCSAG__](https://www.sigidwiki.com/wiki/POCSAG) using 2-FSK for modules:
SX127x, RFM9x, RF69, SX1231, CC1101, nRF24L01, RFM2x and Si443x SX127x, RFM9x, RF69, SX1231, CC1101, nRF24L01, RFM2x and Si443x
* [__LoRaWAN__](https://lora-alliance.org/) using LoRa and FSK for modules: * [__LoRaWAN__](https://lora-alliance.org/) using LoRa for modules:
SX127x, RFM9x, SX126x, LR11x0 and SX128x SX127x, RFM9x, SX126x and SX128x
* NOTE: LoRaWAN support is currently in beta, feedback via [Issues](https://github.com/jgromes/RadioLib/issues) and [Discussions](https://github.com/jgromes/RadioLib/discussions) is appreciated!
### Supported Arduino platforms: ### Supported Arduino platforms:
* __Arduino__ * __Arduino__
* [__AVR__](https://github.com/arduino/ArduinoCore-avr) - Arduino Uno, Mega, Leonardo, Pro Mini, Nano etc. * [__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 * [__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 * [__megaAVR__](https://github.com/arduino/ArduinoCore-megaavr) - Arduino Uno WiFi Rev.2 and Nano Every
* [__SAM__](https://github.com/arduino/ArduinoCore-sam) - Arduino Due * [__SAM__](https://github.com/arduino/ArduinoCore-sam) - Arduino Due
@ -94,7 +88,4 @@ SX127x, RFM9x, SX126x, LR11x0 and SX128x
* __PJRC__ * __PJRC__
* [__Teensy__](https://github.com/PaulStoffregen/cores) - Teensy 2.x, 3.x and 4.x boards * [__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. 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.

View file

@ -1,19 +1,19 @@
/* /*
RadioLib AFSK External Radio example RadioLib AFSK External Radio example
This example shows how to use your Arduino This example shows how to use your Arduino
as modulator for an external analogue FM radio. as modulator for an external analogue FM radio.
The example sends APRS position reports with The example sends APRS position reports with
audio modulated as AFSK at 1200 baud using audio modulated as AFSK at 1200 baud using
Bell 202 tones. However, any other AFSK Bell 202 tones. However, any other AFSK
protocol (RTTY, SSTV, etc.) may be used as well. protocol (RTTY, SSTV, etc.) may be used as well.
DO NOT transmit in APRS bands unless DO NOT transmit in APRS bands unless
you have a ham radio license! you have a ham radio license!
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -46,7 +46,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize APRS client // initialize APRS client
@ -58,7 +58,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
} }
@ -66,20 +66,15 @@ void loop() {
Serial.print(F("[APRS] Sending position ... ")); Serial.print(F("[APRS] Sending position ... "));
// send a location without message or timestamp // send a location without message or timestamp
char destination[] = "N0CALL"; int state = aprs.sendPosition("N0CALL", 0, "4911.67N", "01635.96E");
char latitude[] = "4911.67N";
char longitude[] = "01635.96E";
int state = aprs.sendPosition(destination, 0, latitude, longitude);
delay(500); delay(500);
// send a location with message and without timestamp // send a location with message and without timestamp
char message[] = "I'm here!"; state |= aprs.sendPosition("N0CALL", 0, "4911.67N", "01635.96E", "I'm here!");
state |= aprs.sendPosition(destination, 0, latitude, longitude, message);
delay(500); delay(500);
// send a location with message and timestamp // send a location with message and timestamp
char timestamp[] = "093045z"; state |= aprs.sendPosition("N0CALL", 0, "4911.67N", "01635.96E", "I'm here!", "093045z");
state |= aprs.sendPosition(destination, 0, latitude, longitude, message, timestamp);
delay(500); delay(500);
if(state == RADIOLIB_ERR_NONE) { if(state == RADIOLIB_ERR_NONE) {

View file

@ -1,21 +1,21 @@
/* /*
RadioLib AFSK Imperial March Example RadioLib AFSK Imperial March Example
This example shows how to EXECUTE ORDER 66 This example shows how to EXECUTE ORDER 66
Other modules that can be used for AFSK: Other modules that can be used for AFSK:
- SX127x/RFM9x - SX127x/RFM9x
- RF69 - RF69
- SX1231 - SX1231
- CC1101 - CC1101
- Si443x/RFM2x - Si443x/RFM2x
- SX126x/LLCC68 - SX126x/LLCC68 (only devices without TCXO!)
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -58,7 +58,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize AFSK client // initialize AFSK client
@ -69,7 +69,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
} }

View file

@ -1,7 +1,7 @@
/* /*
Note definitions, melody and melody-related functions Note definitions, melody and melody-related functions
adapted from https://github.com/robsoncouto/arduino-songs adapted from https://github.com/robsoncouto/arduino-songs
by Robson Couto, 2019 by Robson Couto, 2019
*/ */
#define NOTE_B0 31 #define NOTE_B0 31

View file

@ -1,22 +1,22 @@
/* /*
RadioLib AFSK Example RadioLib AFSK Example
This example shows hot to send audio FSK tones This example shows hot to send audio FSK tones
using SX1278's FSK modem. using SX1278's FSK modem.
Other modules that can be used for AFSK: Other modules that can be used for AFSK:
- SX127x/RFM9x - SX127x/RFM9x
- RF69 - RF69
- SX1231 - SX1231
- CC1101 - CC1101
- Si443x/RFM2x - Si443x/RFM2x
- SX126x/LLCC68 - SX126x/LLCC68 (only devices without TCXO!)
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -56,7 +56,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize AFSK client // initialize AFSK client
@ -67,7 +67,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
} }

View file

@ -1,20 +1,20 @@
/* /*
RadioLib AM-modulated AFSK Example RadioLib AM-modulated AFSK Example
This example shows hot to send AM-modulated This example shows hot to send AM-modulated
audio FSK tones using SX1278's OOK modem. audio FSK tones using SX1278's OOK modem.
Other modules that can be used for AFSK: Other modules that can be used for AFSK:
- SX127x/RFM9x - SX127x/RFM9x
- RF69 - RF69
- SX1231 - SX1231
- CC1101 - CC1101
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -51,7 +51,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize AFSK client // initialize AFSK client
@ -62,7 +62,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// after that, set mode to OOK // after that, set mode to OOK
@ -73,7 +73,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
} }

View file

@ -1,28 +1,28 @@
/* /*
RadioLib APRS Mic-E Example RadioLib APRS Mic-E Example
This example sends APRS position reports This example sends APRS position reports
encoded in the Mic-E format using SX1278's encoded in the Mic-E format using SX1278's
FSK modem. The data is modulated as AFSK FSK modem. The data is modulated as AFSK
at 1200 baud using Bell 202 tones. at 1200 baud using Bell 202 tones.
DO NOT transmit in APRS bands unless DO NOT transmit in APRS bands unless
you have a ham radio license! you have a ham radio license!
Other modules that can be used for APRS: Other modules that can be used for APRS:
- SX127x/RFM9x - SX127x/RFM9x
- RF69 - RF69
- SX1231 - SX1231
- CC1101 - CC1101
- nRF24 - nRF24
- Si443x/RFM2x - Si443x/RFM2x
- SX126x/LLCC68 - SX126x/LLCC68 (only devices without TCXO!)
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -35,13 +35,9 @@
// DIO1 pin: 3 // DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3); SX1278 radio = new Module(10, 2, 9, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //SX1278 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// create AFSK client instance using the FSK module // create AFSK client instance using the FSK module
// this requires connection to the module direct // this requires connection to the module direct
@ -78,7 +74,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize AX.25 client // initialize AX.25 client
@ -92,7 +88,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize APRS client // initialize APRS client
@ -104,7 +100,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
} }

View file

@ -1,28 +1,28 @@
/* /*
RadioLib APRS Position Example RadioLib APRS Position Example
This example sends APRS position reports This example sends APRS position reports
using SX1278's FSK modem. The data is using SX1278's FSK modem. The data is
modulated as AFSK at 1200 baud using Bell modulated as AFSK at 1200 baud using Bell
202 tones. 202 tones.
DO NOT transmit in APRS bands unless DO NOT transmit in APRS bands unless
you have a ham radio license! you have a ham radio license!
Other modules that can be used for APRS: Other modules that can be used for APRS:
- SX127x/RFM9x - SX127x/RFM9x
- RF69 - RF69
- SX1231 - SX1231
- CC1101 - CC1101
- nRF24 - nRF24
- Si443x/RFM2x - Si443x/RFM2x
- SX126x/LLCC68 - SX126x/LLCC68 (only devices without TCXO!)
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -35,13 +35,9 @@
// DIO1 pin: 3 // DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3); SX1278 radio = new Module(10, 2, 9, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //SX1278 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// create AFSK client instance using the FSK module // create AFSK client instance using the FSK module
// this requires connection to the module direct // this requires connection to the module direct
@ -78,7 +74,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize AX.25 client // initialize AX.25 client
@ -92,7 +88,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize APRS client // initialize APRS client
@ -104,54 +100,32 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
} }
void loop() { void loop() {
Serial.println(F("[APRS] Sending location reports")); Serial.print(F("[APRS] Sending position ... "));
// send a location without message or timestamp // send a location without message or timestamp
char destination[] = "N0CALL"; int state = aprs.sendPosition("N0CALL", 0, "4911.67N", "01635.96E");
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); delay(500);
// send a location with message and without timestamp // send a location with message and without timestamp
char message[] = "I'm here!"; state |= aprs.sendPosition("N0CALL", 0, "4911.67N", "01635.96E", "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); 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 // send a location with message and timestamp
char timestamp[] = "093045z"; state |= aprs.sendPosition("N0CALL", 0, "4911.67N", "01635.96E", "I'm here!", "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); delay(500);
// when repeaters are no longer needed, they can be dropped if(state == RADIOLIB_ERR_NONE) {
aprs.dropRepeaters(); Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
}
// wait one minute before transmitting again // wait one minute before transmitting again
Serial.println(F("[APRS] All done!"));
delay(60000); delay(60000);
} }

View file

@ -1,20 +1,19 @@
/* /*
RadioLib APRS Position over LoRa Example RadioLib APRS Position over LoRa Example
This example sends APRS position reports This example sends APRS position reports
using SX1278's LoRa modem. using SX1278's LoRa modem.
Other modules that can be used for APRS: Other modules that can be used for APRS:
- SX127x/RFM9x - SX127x/RFM9x
- SX126x/LLCC68 - SX126x/LLCC68
- SX128x - SX128x
- LR11x0
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -27,13 +26,9 @@
// DIO1 pin: 3 // DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3); SX1278 radio = new Module(10, 2, 9, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //SX1278 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// create APRS client instance using the LoRa radio // create APRS client instance using the LoRa radio
APRSClient aprs(&radio); APRSClient aprs(&radio);
@ -58,7 +53,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize APRS client // initialize APRS client
@ -66,14 +61,13 @@ void setup() {
// symbol: '>' (car) // symbol: '>' (car)
// callsign "N7LEM" // callsign "N7LEM"
// SSID 1 // SSID 1
char source[] = "N7LEM"; state = aprs.begin('>', "N7LEM", 1);
state = aprs.begin('>', source, 1);
if(state == RADIOLIB_ERR_NONE) { if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!")); Serial.println(F("success!"));
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
} }
@ -82,12 +76,7 @@ void loop() {
// send a location with message and timestamp // send a location with message and timestamp
// SSID is set to 1, as APRS over LoRa uses WIDE1-1 path by default // SSID is set to 1, as APRS over LoRa uses WIDE1-1 path by default
char destination[] = "GPS"; int state = aprs.sendPosition("GPS", 1, "4911.67N", "01635.96E", "I'm here!", "093045z");
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); delay(500);
// you can also send Mic-E encoded messages // you can also send Mic-E encoded messages

View file

@ -1,31 +1,30 @@
/* /*
RadioLib AX.25 Frame Example RadioLib AX.25 Frame Example
This example shows how to send various This example shows how to send various
AX.25 frames using SX1278's FSK modem. AX.25 frames using SX1278's FSK modem.
Other modules that can be used for AX.25: Other modules that can be used for AX.25:
- SX127x/RFM9x - SX127x/RFM9x
- RF69 - RF69
- SX1231 - SX1231
- CC1101 - CC1101
- SX126x - SX126x
- nRF24 - nRF24
- Si443x/RFM2x - Si443x/RFM2x
- LR11x0
Using raw AX.25 frames requires some Using raw AX.25 frames requires some
knowledge of the protocol, refer to knowledge of the protocol, refer to
AX25_Transmit for basic operation. AX25_Transmit for basic operation.
Frames shown in this example are not Frames shown in this example are not
exhaustive; all possible AX.25 frames exhaustive; all possible AX.25 frames
should be supported. should be supported.
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -38,13 +37,9 @@
// DIO1 pin: 3 // DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3); SX1278 radio = new Module(10, 2, 9, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //SX1278 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// create AX.25 client instance using the FSK module // create AX.25 client instance using the FSK module
AX25Client ax25(&radio); AX25Client ax25(&radio);
@ -68,7 +63,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize AX.25 client // initialize AX.25 client
@ -82,7 +77,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
} }

View file

@ -1,24 +1,23 @@
/* /*
RadioLib AX.25 Transmit Example RadioLib AX.25 Transmit Example
This example sends AX.25 messages using This example sends AX.25 messages using
SX1278's FSK modem. SX1278's FSK modem.
Other modules that can be used for AX.25: Other modules that can be used for AX.25:
- SX127x/RFM9x - SX127x/RFM9x
- RF69 - RF69
- SX1231 - SX1231
- CC1101 - CC1101
- SX126x - SX126x
- nRF24 - nRF24
- Si443x/RFM2x - Si443x/RFM2x
- LR11x0
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -31,13 +30,9 @@
// DIO1 pin: 3 // DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3); SX1278 radio = new Module(10, 2, 9, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //SX1278 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// create AX.25 client instance using the FSK module // create AX.25 client instance using the FSK module
AX25Client ax25(&radio); AX25Client ax25(&radio);
@ -60,7 +55,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize AX.25 client // initialize AX.25 client
@ -74,7 +69,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
} }

View file

@ -1,25 +1,25 @@
/* /*
RadioLib AX.25 Transmit AFSK Example RadioLib AX.25 Transmit AFSK Example
This example sends AX.25 messages using This example sends AX.25 messages using
SX1278's FSK modem. The data is modulated SX1278's FSK modem. The data is modulated
as AFSK at 1200 baud using Bell 202 tones. as AFSK at 1200 baud using Bell 202 tones.
Other modules that can be used for AX.25 Other modules that can be used for AX.25
with AFSK modulation: with AFSK modulation:
- SX127x/RFM9x - SX127x/RFM9x
- RF69 - RF69
- SX1231 - SX1231
- CC1101 - CC1101
- nRF24 - nRF24
- Si443x/RFM2x - Si443x/RFM2x
- SX126x/LLCC68 - SX126x/LLCC68 (only devices without TCXO!)
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -32,13 +32,9 @@
// DIO1 pin: 3 // DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3); SX1278 radio = new Module(10, 2, 9, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //SX1278 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// create AFSK client instance using the FSK module // create AFSK client instance using the FSK module
// this requires connection to the module direct // this requires connection to the module direct
@ -70,7 +66,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize AX.25 client // initialize AX.25 client
@ -84,7 +80,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// Sometimes, it may be required to adjust audio // Sometimes, it may be required to adjust audio
@ -99,7 +95,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
*/ */
} }

View file

@ -1,18 +1,18 @@
/* /*
RadioLib Bell Modem Transmit Example RadioLib Bell Modem Transmit Example
This example shows how to transmit binary data This example shows how to transmit binary data
using audio Bell 202 tones. using audio Bell 202 tones.
Other implemented Bell modems Other implemented Bell modems
- Bell 101 - Bell 101
- Bell 103 - Bell 103
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -33,7 +33,7 @@ SX1278 radio = new Module(10, 2, 9, 3);
// SX1231: DIO2 // SX1231: DIO2
// CC1101: GDO2 // CC1101: GDO2
// Si443x/RFM2x: GPIO // Si443x/RFM2x: GPIO
// SX126x/LLCC68: DIO2 // SX126x/LLCC68: DIO2 (only devices without TCXO!)
BellClient bell(&radio, 5); BellClient bell(&radio, 5);
void setup() { void setup() {
@ -52,7 +52,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize Bell 202 modem // initialize Bell 202 modem
@ -63,7 +63,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
} }

View file

@ -1,17 +1,17 @@
/* /*
RadioLib CC1101 Receive with Address Example RadioLib CC1101 Receive with Address Example
This example receives packets using CC1101 FSK radio This example receives packets using CC1101 FSK radio
module. Packets can have 1-byte address of the module. Packets can have 1-byte address of the
destination node. After setting node address, this node destination node. After setting node address, this node
will automatically filter out any packets that do not will automatically filter out any packets that do not
contain either node address or broadcast addresses. contain either node address or broadcast addresses.
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101 https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -24,13 +24,9 @@
// GDO2 pin: 3 (optional) // GDO2 pin: 3 (optional)
CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3); CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //CC1101 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
void setup() { void setup() {
Serial.begin(9600); Serial.begin(9600);
@ -43,7 +39,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// set node address // set node address
@ -60,7 +56,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// address filtering can also be disabled // address filtering can also be disabled
@ -74,7 +70,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
*/ */
} }

View file

@ -31,13 +31,9 @@
// GDO2 pin: 3 (optional) // GDO2 pin: 3 (optional)
CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3); CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //CC1101 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
void setup() { void setup() {
Serial.begin(9600); Serial.begin(9600);
@ -50,7 +46,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
} }

View file

@ -1,22 +1,22 @@
/* /*
RadioLib CC1101 Receive with Interrupts Example RadioLib CC1101 Receive with Interrupts Example
This example listens for FSK transmissions and tries to This example listens for FSK transmissions and tries to
receive them. Once a packet is received, an interrupt is receive them. Once a packet is received, an interrupt is
triggered. triggered.
To successfully receive data, the following settings have to be the same To successfully receive data, the following settings have to be the same
on both transmitter and receiver: on both transmitter and receiver:
- carrier frequency - carrier frequency
- bit rate - bit rate
- frequency deviation - frequency deviation
- sync word - sync word
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101 https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -29,28 +29,9 @@
// GDO2 pin: 3 (optional) // GDO2 pin: 3 (optional)
CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3); CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //CC1101 radio = RadioShield.ModuleA;
#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() { void setup() {
Serial.begin(9600); Serial.begin(9600);
@ -63,7 +44,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// set the function that will be called // set the function that will be called
@ -78,7 +59,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// if needed, 'listen' mode can be disabled by calling // if needed, 'listen' mode can be disabled by calling
@ -91,6 +72,21 @@ void setup() {
// radio.readData(); // radio.readData();
} }
// 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 loop() { void loop() {
// check if the flag is set // check if the flag is set
if(receivedFlag) { if(receivedFlag) {

View file

@ -1,21 +1,21 @@
/* /*
RadioLib CC1101 Settings Example RadioLib CC1101 Settings Example
This example shows how to change all the properties of RF69 radio. This example shows how to change all the properties of RF69 radio.
RadioLib currently supports the following settings: RadioLib currently supports the following settings:
- pins (SPI slave select, digital IO 0, digital IO 1) - pins (SPI slave select, digital IO 0, digital IO 1)
- carrier frequency - carrier frequency
- bit rate - bit rate
- receiver bandwidth - receiver bandwidth
- allowed frequency deviation - allowed frequency deviation
- output power during transmission - output power during transmission
- sync word - sync word
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101 https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -35,13 +35,9 @@ CC1101 radio1 = new Module(10, 2, RADIOLIB_NC, 3);
// GDO2 pin: 5 (optional) // GDO2 pin: 5 (optional)
CC1101 radio2 = new Module(9, 4, RADIOLIB_NC, 5); CC1101 radio2 = new Module(9, 4, RADIOLIB_NC, 5);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //CC1101 radio3 = RadioShield.ModuleB;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio3 = new RadioModule();
*/
void setup() { void setup() {
Serial.begin(9600); Serial.begin(9600);
@ -54,7 +50,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// initialize CC1101 with non-default settings // initialize CC1101 with non-default settings
@ -71,7 +67,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// you can also change the settings at runtime // you can also change the settings at runtime
@ -80,42 +76,42 @@ void setup() {
// set carrier frequency to 433.5 MHz // set carrier frequency to 433.5 MHz
if (radio1.setFrequency(433.5) == RADIOLIB_ERR_INVALID_FREQUENCY) { if (radio1.setFrequency(433.5) == RADIOLIB_ERR_INVALID_FREQUENCY) {
Serial.println(F("[CC1101] Selected frequency is invalid for this module!")); Serial.println(F("[CC1101] Selected frequency is invalid for this module!"));
while (true) { delay(10); } while (true);
} }
// set bit rate to 100.0 kbps // set bit rate to 100.0 kbps
state = radio1.setBitRate(100.0); state = radio1.setBitRate(100.0);
if (state == RADIOLIB_ERR_INVALID_BIT_RATE) { if (state == RADIOLIB_ERR_INVALID_BIT_RATE) {
Serial.println(F("[CC1101] Selected bit rate is invalid for this module!")); Serial.println(F("[CC1101] Selected bit rate is invalid for this module!"));
while (true) { delay(10); } while (true);
} else if (state == RADIOLIB_ERR_INVALID_BIT_RATE_BW_RATIO) { } 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] Selected bit rate to bandwidth ratio is invalid!"));
Serial.println(F("[CC1101] Increase receiver bandwidth to set this bit rate.")); Serial.println(F("[CC1101] Increase receiver bandwidth to set this bit rate."));
while (true) { delay(10); } while (true);
} }
// set receiver bandwidth to 250.0 kHz // set receiver bandwidth to 250.0 kHz
if (radio1.setRxBandwidth(250.0) == RADIOLIB_ERR_INVALID_RX_BANDWIDTH) { if (radio1.setRxBandwidth(250.0) == RADIOLIB_ERR_INVALID_RX_BANDWIDTH) {
Serial.println(F("[CC1101] Selected receiver bandwidth is invalid for this module!")); Serial.println(F("[CC1101] Selected receiver bandwidth is invalid for this module!"));
while (true) { delay(10); } while (true);
} }
// set allowed frequency deviation to 10.0 kHz // set allowed frequency deviation to 10.0 kHz
if (radio1.setFrequencyDeviation(10.0) == RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION) { if (radio1.setFrequencyDeviation(10.0) == RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION) {
Serial.println(F("[CC1101] Selected frequency deviation is invalid for this module!")); Serial.println(F("[CC1101] Selected frequency deviation is invalid for this module!"));
while (true) { delay(10); } while (true);
} }
// set output power to 5 dBm // set output power to 5 dBm
if (radio1.setOutputPower(5) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) { if (radio1.setOutputPower(5) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) {
Serial.println(F("[CC1101] Selected output power is invalid for this module!")); Serial.println(F("[CC1101] Selected output power is invalid for this module!"));
while (true) { delay(10); } while (true);
} }
// 2 bytes can be set as sync word // 2 bytes can be set as sync word
if (radio1.setSyncWord(0x01, 0x23) == RADIOLIB_ERR_INVALID_SYNC_WORD) { if (radio1.setSyncWord(0x01, 0x23) == RADIOLIB_ERR_INVALID_SYNC_WORD) {
Serial.println(F("[CC1101] Selected sync word is invalid for this module!")); Serial.println(F("[CC1101] Selected sync word is invalid for this module!"));
while (true) { delay(10); } while (true);
} }
} }

View file

@ -1,17 +1,17 @@
/* /*
RadioLib CC1101 Transmit to Address Example RadioLib CC1101 Transmit to Address Example
This example transmits packets using CC1101 FSK radio This example transmits packets using CC1101 FSK radio
module. Packets can have 1-byte address of the module. Packets can have 1-byte address of the
destination node. After setting node address, this node destination node. After setting node address, this node
will automatically filter out any packets that do not will automatically filter out any packets that do not
contain either node address or broadcast addresses. contain either node address or broadcast addresses.
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101 https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -24,13 +24,9 @@
// GDO2 pin: 3 (optional) // GDO2 pin: 3 (optional)
CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3); CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //CC1101 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
void setup() { void setup() {
Serial.begin(9600); Serial.begin(9600);
@ -43,7 +39,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// set node address // set node address
@ -60,7 +56,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// address filtering can also be disabled // address filtering can also be disabled
@ -74,7 +70,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
*/ */
} }
@ -82,11 +78,10 @@ void setup() {
void loop() { void loop() {
Serial.print(F("[CC1101] Transmitting packet ... ")); Serial.print(F("[CC1101] Transmitting packet ... "));
// you can transmit C-string or Arduino string up to 255 characters long // you can transmit C-string or Arduino string up to 63 characters long
int state = radio.transmit("Hello World!"); int state = radio.transmit("Hello World!");
// you can also transmit byte array up to 255 bytes long // you can also transmit byte array up to 63 bytes long
// With some limitations see here: https://github.com/jgromes/RadioLib/discussions/1138
/* /*
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
int state = radio.transmit(byteArr, 8); int state = radio.transmit(byteArr, 8);

View file

@ -2,7 +2,7 @@
RadioLib CC1101 Blocking Transmit Example RadioLib CC1101 Blocking Transmit Example
This example transmits packets using CC1101 FSK radio module. This example transmits packets using CC1101 FSK radio module.
Each packet contains up to 255 bytes of data with some limitations (https://github.com/jgromes/RadioLib/discussions/1138), in the form of: Each packet contains up to 64 bytes of data, in the form of:
- Arduino String - Arduino String
- null-terminated char array (C-string) - null-terminated char array (C-string)
- arbitrary binary data (byte array) - arbitrary binary data (byte array)
@ -28,13 +28,9 @@
// GDO2 pin: 3 // GDO2 pin: 3
CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3); CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //CC1101 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
void setup() { void setup() {
Serial.begin(9600); Serial.begin(9600);
@ -47,7 +43,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
} }
@ -57,11 +53,11 @@ int count = 0;
void loop() { void loop() {
Serial.print(F("[CC1101] Transmitting packet ... ")); Serial.print(F("[CC1101] Transmitting packet ... "));
// you can transmit C-string or Arduino string up to 255 characters long // you can transmit C-string or Arduino string up to 63 characters long
String str = "Hello World! #" + String(count++); String str = "Hello World! #" + String(count++);
int state = radio.transmit(str); int state = radio.transmit(str);
// you can also transmit byte array up to 255 bytes long with some limitations; https://github.com/jgromes/RadioLib/discussions/1138 // you can also transmit byte array up to 63 bytes long
/* /*
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
int state = radio.transmit(byteArr, 8); int state = radio.transmit(byteArr, 8);
@ -72,7 +68,7 @@ void loop() {
Serial.println(F("success!")); Serial.println(F("success!"));
} else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) { } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
// the supplied packet was longer than 255 bytes // the supplied packet was longer than 64 bytes
Serial.println(F("too long!")); Serial.println(F("too long!"));
} else { } else {

View file

@ -1,18 +1,18 @@
/* /*
RadioLib CC1101 Transmit with Interrupts Example RadioLib CC1101 Transmit with Interrupts Example
This example transmits packets using CC1101 FSK radio module. This example transmits packets using CC1101 FSK radio module.
Once a packet is transmitted, an interrupt is triggered. Once a packet is transmitted, an interrupt is triggered.
Each packet contains up to 255 bytes of data with some limitations (https://github.com/jgromes/RadioLib/discussions/1138), in the form of: Each packet contains up to 64 bytes of data, in the form of:
- Arduino String - Arduino String
- null-terminated char array (C-string) - null-terminated char array (C-string)
- arbitrary binary data (byte array) - arbitrary binary data (byte array)
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101 https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -25,17 +25,46 @@
// GDO2 pin: 3 // GDO2 pin: 3
CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3); CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //CC1101 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// save transmission state between loops // save transmission state between loops
int transmissionState = RADIOLIB_ERR_NONE; int transmissionState = RADIOLIB_ERR_NONE;
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);
}
// 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);
*/
}
// flag to indicate that a packet was sent // flag to indicate that a packet was sent
volatile bool transmittedFlag = false; volatile bool transmittedFlag = false;
@ -51,41 +80,6 @@ void setFlag(void) {
transmittedFlag = true; 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
// 255 characters long
transmissionState = radio.startTransmit("Hello World!");
// you can also transmit byte array up to 255 bytes long
// When transmitting more than 64 bytes startTransmit blocks to refill the FIFO.
// Blocking ceases once the last bytes have been placed in the FIFO
/*
byte byteArr[] = {0x01, 0x23, 0x45, 0x56,
0x78, 0xAB, 0xCD, 0xEF};
state = radio.startTransmit(byteArr, 8);
*/
}
// counter to keep track of transmitted packets // counter to keep track of transmitted packets
int count = 0; int count = 0;
@ -121,11 +115,11 @@ void loop() {
Serial.print(F("[CC1101] Sending another packet ... ")); Serial.print(F("[CC1101] Sending another packet ... "));
// you can transmit C-string or Arduino string up to // you can transmit C-string or Arduino string up to
// 255 characters long // 256 characters long
String str = "Hello World! #" + String(count++); String str = "Hello World! #" + String(count++);
transmissionState = radio.startTransmit(str); transmissionState = radio.startTransmit(str);
// you can also transmit byte array up to 255 bytes long with limitations https://github.com/jgromes/RadioLib/discussions/1138 // you can also transmit byte array up to 256 bytes long
/* /*
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
0x89, 0xAB, 0xCD, 0xEF}; 0x89, 0xAB, 0xCD, 0xEF};

View file

@ -1,27 +1,27 @@
/* /*
RadioLib FSK4 Transmit Example RadioLib FSK4 Transmit Example
This example sends an example FSK-4 'Horus Binary' message This example sends an example FSK-4 'Horus Binary' message
using SX1278's FSK modem. using SX1278's FSK modem.
This signal can be demodulated using a SSB demodulator (SDR or otherwise), This signal can be demodulated using a SSB demodulator (SDR or otherwise),
and horusdemodlib: https://github.com/projecthorus/horusdemodlib/wiki and horusdemodlib: https://github.com/projecthorus/horusdemodlib/wiki
Other modules that can be used for FSK4: Other modules that can be used for FSK4:
- SX127x/RFM9x - SX127x/RFM9x
- RF69 - RF69
- SX1231 - SX1231
- CC1101 - CC1101
- SX126x - SX126x
- nRF24 - nRF24
- Si443x/RFM2x - Si443x/RFM2x
- SX128x - SX128x
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -34,13 +34,9 @@
// DIO1 pin: 3 // DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3); SX1278 radio = new Module(10, 2, 9, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //SX1278 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// create FSK4 client instance using the FSK module // create FSK4 client instance using the FSK module
FSK4Client fsk4(&radio); FSK4Client fsk4(&radio);
@ -77,7 +73,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize FSK4 client // initialize FSK4 client
@ -101,7 +97,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// sometimes, it may be needed to set some manual corrections // sometimes, it may be needed to set some manual corrections
@ -117,7 +113,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
*/ */
} }

View file

@ -1,25 +1,25 @@
/* /*
RadioLib FSK4 Transmit AFSK Example RadioLib FSK4 Transmit AFSK Example
This example sends an example FSK-4 'Horus Binary' message This example sends an example FSK-4 'Horus Binary' message
using SX1278's FSK modem. The data is modulated as AFSK. using SX1278's FSK modem. The data is modulated as AFSK.
This signal can be demodulated using an FM demodulator (SDR or otherwise), This signal can be demodulated using an FM demodulator (SDR or otherwise),
and horusdemodlib: https://github.com/projecthorus/horusdemodlib/wiki and horusdemodlib: https://github.com/projecthorus/horusdemodlib/wiki
Other modules that can be used for FSK4: Other modules that can be used for FSK4:
- SX127x/RFM9x - SX127x/RFM9x
- RF69 - RF69
- SX1231 - SX1231
- CC1101 - CC1101
- Si443x/RFM2x - Si443x/RFM2x
- SX126x/LLCC68 - SX126x/LLCC68 (only devices without TCXO!)
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -32,13 +32,9 @@
// DIO1 pin: 3 // DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3); SX1278 radio = new Module(10, 2, 9, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //SX1278 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// create AFSK client instance using the FSK module // create AFSK client instance using the FSK module
// this requires connection to the module direct // this requires connection to the module direct
@ -86,7 +82,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize FSK4 client // initialize FSK4 client
@ -102,7 +98,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// sometimes, it may be needed to set some manual corrections // sometimes, it may be needed to set some manual corrections
@ -118,7 +114,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
*/ */
} }

View file

@ -1,25 +1,24 @@
/* /*
RadioLib Hellschreiber Transmit Example RadioLib Hellschreiber Transmit Example
This example sends Hellschreiber message using This example sends Hellschreiber message using
SX1278's FSK modem. SX1278's FSK modem.
Other modules that can be used for Hellschreiber: Other modules that can be used for Hellschreiber:
- SX127x/RFM9x - SX127x/RFM9x
- RF69 - RF69
- SX1231 - SX1231
- CC1101 - CC1101
- SX126x - SX126x
- nRF24 - nRF24
- Si443x/RFM2x - Si443x/RFM2x
- SX128x - SX128x
- LR11x0
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -32,13 +31,9 @@
// DIO1 pin: 3 // DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3); SX1278 radio = new Module(10, 2, 9, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //SX1278 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// create Hellschreiber client instance using the FSK module // create Hellschreiber client instance using the FSK module
HellClient hell(&radio); HellClient hell(&radio);
@ -59,7 +54,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize Hellschreiber client // initialize Hellschreiber client
@ -72,7 +67,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
} }

View file

@ -1,24 +1,24 @@
/* /*
RadioLib Hellschreiber Transmit AFSK Example RadioLib Hellschreiber Transmit AFSK Example
This example sends Hellschreiber message using This example sends Hellschreiber message using
SX1278's FSK modem. The data is modulated SX1278's FSK modem. The data is modulated
as AFSK. as AFSK.
Other modules that can be used for Hellschreiber Other modules that can be used for Hellschreiber
with AFSK modulation: with AFSK modulation:
- SX127x/RFM9x - SX127x/RFM9x
- RF69 - RF69
- SX1231 - SX1231
- CC1101 - CC1101
- Si443x/RFM2x - Si443x/RFM2x
- SX126x/LLCC68 - SX126x/LLCC68 (only devices without TCXO!)
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -31,13 +31,9 @@
// DIO1 pin: 3 // DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3); SX1278 radio = new Module(10, 2, 9, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //SX1278 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// create AFSK client instance using the FSK module // create AFSK client instance using the FSK module
// this requires connection to the module direct // this requires connection to the module direct
@ -69,7 +65,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize Hellschreiber client // initialize Hellschreiber client
@ -82,7 +78,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
} }

View file

@ -1,106 +0,0 @@
/*
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);
}

View file

@ -1,141 +0,0 @@
/*
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);
}
}
}

View file

@ -1,136 +0,0 @@
/*
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() {
}

View file

@ -1,157 +0,0 @@
/*
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 "));
}
*/
}

View file

@ -1,182 +0,0 @@
/*
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);
}

View file

@ -1,134 +0,0 @@
/*
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);
}

View file

@ -1,133 +0,0 @@
/*
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);
}

View file

@ -1,96 +0,0 @@
/*
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);
}
}

View file

@ -1,173 +0,0 @@
/*
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;
}
}
}

View file

@ -1,135 +0,0 @@
/*
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);
}
}

View file

@ -1,169 +0,0 @@
/*
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);
}
}
}

View file

@ -1,126 +0,0 @@
/*
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);
}

View file

@ -1,162 +0,0 @@
/*
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);
*/
}
}

View file

@ -1,143 +0,0 @@
/*
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);
}

View file

@ -1,181 +0,0 @@
/*
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);
}
}
}

View file

@ -1,85 +0,0 @@
/*
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
}

View file

@ -1,152 +0,0 @@
#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, CN470
const LoRaWANBand_t Region = EU868;
// subband choice: for US915/AU915 set to 2, for CN470 set to 1, otherwise leave on 0
const uint8_t subBand = 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

View file

@ -0,0 +1,164 @@
/*
RadioLib LoRaWAN End Device 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.
LoRaWAN v1.1 requires the use of EEPROM (persistent storage).
Please refer to the 'persistent' example once you are familiar
with LoRaWAN.
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/
*/
// include the library
#include <RadioLib.h>
// SX1262 has the following pin order:
// Module(NSS/CS, DIO1, RESET, BUSY)
// SX1262 radio = new Module(8, 14, 12, 13);
// SX1278 has the following pin order:
// Module(NSS/CS, DIO0, RESET, DIO1)
SX1278 radio = new Module(10, 2, 9, 3);
// create the node instance on the EU-868 band
// using the radio module and the encryption key
// make sure you are using the correct band
// based on your geographical location!
LoRaWANNode node(&radio, &EU868);
// for fixed bands with subband selection
// such as US915 and AU915, you must specify
// the subband that matches the Frequency Plan
// that you selected on your LoRaWAN console
/*
LoRaWANNode node(&radio, &US915, 2);
*/
void setup() {
Serial.begin(9600);
// initialize SX1278 with default settings
Serial.print(F("[SX1278] 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);
}
// application identifier - pre-LoRaWAN 1.1.0, this was called appEUI
// when adding new end device in TTN, you will have to enter this number
// you can pick any number you want, but it has to be unique
uint64_t joinEUI = 0x12AD1011B0C0FFEE;
// device identifier - this number can be anything
// when adding new end device in TTN, you can generate this number,
// or you can set any value you want, provided it is also unique
uint64_t devEUI = 0x70B3D57ED005E120;
// select some encryption keys which will be used to secure the communication
// there are two of them - network key and application key
// because LoRaWAN uses AES-128, the key MUST be 16 bytes (or characters) long
// network key is the ASCII string "topSecretKey1234"
uint8_t nwkKey[] = { 0x74, 0x6F, 0x70, 0x53, 0x65, 0x63, 0x72, 0x65,
0x74, 0x4B, 0x65, 0x79, 0x31, 0x32, 0x33, 0x34 };
// application key is the ASCII string "aDifferentKeyABC"
uint8_t appKey[] = { 0x61, 0x44, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65,
0x6E, 0x74, 0x4B, 0x65, 0x79, 0x41, 0x42, 0x43 };
// prior to LoRaWAN 1.1.0, only a single "nwkKey" is used
// when connecting to LoRaWAN 1.0 network, "appKey" will be disregarded
// and can be set to NULL
// on EEPROM-enabled boards, after the device has been activated,
// the session can be restored without rejoining after device power cycle
// this is intrinsically done when calling `beginOTAA()` with the same keys
// in that case, the function will not need to transmit a JoinRequest
// now we can start the activation
// this can take up to 10 seconds, and requires a LoRaWAN gateway in range
// a specific starting-datarate can be selected in dynamic bands (e.g. EU868):
/*
uint8_t joinDr = 4;
state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey, joinDr);
*/
Serial.print(F("[LoRaWAN] Attempting over-the-air activation ... "));
state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
if(state >= RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
while(true);
}
}
// counter to keep track of transmitted packets
int count = 0;
void loop() {
// send uplink to port 10
Serial.print(F("[LoRaWAN] Sending uplink packet ... "));
String strUp = "Hello World! #" + String(count++);
String strDown;
int state = node.sendReceive(strUp, 10, strDown);
if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("received a downlink!"));
// print data of the packet (if there are any)
Serial.print(F("[LoRaWAN] Data:\t\t"));
if(strDown.length() > 0) {
Serial.println(strDown);
} 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 frequency error
Serial.print(F("[LoRaWAN] Frequency error:\t"));
Serial.print(radio.getFrequencyError());
Serial.println(F(" Hz"));
} else if(state == RADIOLIB_ERR_RX_TIMEOUT) {
Serial.println(F("no downlink!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
}
// wait before sending another packet
uint32_t minimumDelay = 60000; // try to send once every minute
uint32_t interval = node.timeUntilUplink(); // calculate minimum duty cycle delay (per law!)
uint32_t delayMs = max(interval, minimumDelay); // cannot send faster than duty cycle allows
delay(delayMs);
}

View file

@ -0,0 +1,172 @@
/*
RadioLib LoRaWAN End Device ABP Example
This example sets up a LoRaWAN node using ABP (activation
by personalization). 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 start uploading data directly,
without having to join the network.
LoRaWAN v1.1 requires the use of EEPROM (persistent storage).
Please refer to the 'persistent' example once you are familiar
with LoRaWAN.
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/
*/
// include the library
#include <RadioLib.h>
// SX1262 has the following pin order:
// Module(NSS/CS, DIO1, RESET, BUSY)
// SX1262 radio = new Module(8, 14, 12, 13);
// SX1278 has the following pin order:
// Module(NSS/CS, DIO0, RESET, DIO1)
SX1278 radio = new Module(10, 2, 9, 3);
// create the node instance on the EU-868 band
// using the radio module and the encryption key
// make sure you are using the correct band
// based on your geographical location!
LoRaWANNode node(&radio, &EU868);
// for fixed bands with subband selection
// such as US915 and AU915, you must specify
// the subband that matches the Frequency Plan
// that you selected on your LoRaWAN console
/*
LoRaWANNode node(&radio, &US915, 2);
*/
void setup() {
Serial.begin(9600);
// initialize SX1278 with default settings
Serial.print(F("[SX1278] 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);
}
// device address - this number can be anything
// when adding new end device in TTN, you can generate this number,
// or you can set any value you want, provided it is unique
uint32_t devAddr = 0x12345678;
// select some encryption keys which will be used to secure the communication
// there are two of them - network key and application key
// because LoRaWAN uses AES-128, the key MUST be 16 bytes (or characters) long
// network key is the ASCII string "topSecretKey1234"
uint8_t nwkSKey[] = { 0x74, 0x6F, 0x70, 0x53, 0x65, 0x63, 0x72, 0x65,
0x74, 0x4B, 0x65, 0x79, 0x31, 0x32, 0x33, 0x34 };
// application key is the ASCII string "aDifferentKeyABC"
uint8_t appSKey[] = { 0x61, 0x44, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65,
0x6E, 0x74, 0x4B, 0x65, 0x79, 0x41, 0x42, 0x43 };
// network key 2 is the ASCII string "topSecretKey5678"
uint8_t fNwkSIntKey[] = { 0x61, 0x44, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65,
0x6E, 0x74, 0x4B, 0x65, 0x35, 0x36, 0x37, 0x38 };
// network key 3 is the ASCII string "aDifferentKeyDEF"
uint8_t sNwkSIntKey[] = { 0x61, 0x44, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65,
0x6E, 0x74, 0x4B, 0x65, 0x79, 0x44, 0x45, 0x46 };
// prior to LoRaWAN 1.1.0, only a single "nwkKey" is used
// when connecting to LoRaWAN 1.0 network, "appKey" will be disregarded
// and can be set to NULL
// if using EU868 on ABP in TTN, you need to set the SF for RX2 window manually
/*
node.rx2.drMax = 3;
*/
// on EEPROM-enabled boards, after the device has been activated,
// the session can be restored without rejoining after device power cycle
// this is intrinsically done when calling `beginABP()` with the same keys
// in that case, the function will not need to transmit a JoinRequest
// to start a LoRaWAN v1.0 session,
// the user can remove the fNwkSIntKey and sNwkSIntKey
/*
state = node.beginABP(devAddr, nwkSKey, appSKey);
*/
// start the device by directly providing the encryption keys and device address
Serial.print(F("[LoRaWAN] Attempting over-the-air activation ... "));
state = node.beginABP(devAddr, nwkSKey, appSKey, fNwkSIntKey, sNwkSIntKey);
if(state >= RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
while(true);
}
}
// counter to keep track of transmitted packets
int count = 0;
void loop() {
// send uplink to port 10
Serial.print(F("[LoRaWAN] Sending uplink packet ... "));
String strUp = "Hello World! #" + String(count++);
String strDown;
int state = node.sendReceive(strUp, 10, strDown);
if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("received a downlink!"));
// print data of the packet (if there are any)
Serial.print(F("[LoRaWAN] Data:\t\t"));
if(strDown.length() > 0) {
Serial.println(strDown);
} 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 frequency error
Serial.print(F("[LoRaWAN] Frequency error:\t"));
Serial.print(radio.getFrequencyError());
Serial.println(F(" Hz"));
} else if(state == RADIOLIB_ERR_RX_TIMEOUT) {
Serial.println(F("no downlink!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
}
// wait before sending another packet
uint32_t minimumDelay = 60000; // try to send once every minute
uint32_t interval = node.timeUntilUplink(); // calculate minimum duty cycle delay (per law!)
uint32_t delayMs = max(interval, minimumDelay); // cannot send faster than duty cycle allows
delay(delayMs);
}

View file

@ -0,0 +1,156 @@
/*
RadioLib LoRaWAN End Device Persistent Example
This example assumes you have tried one of the OTAA or ABP
examples and are familiar with the required keys and procedures.
This example restores and saves a session such that you can use
deepsleep or survive power cycles. Before you start, you will
have to register your device at https://www.thethingsnetwork.org/
and join the network using either OTAA or ABP.
Please refer to one of the other LoRaWAN examples for more
information regarding joining a network.
NOTE: LoRaWAN requires storing some parameters persistently!
RadioLib does this by using EEPROM, by default
starting at address 0 and using 448 bytes.
If you already use EEPROM in your application,
you will have to either avoid this range, or change it
by setting a different start address by changing the value of
RADIOLIB_HAL_PERSISTENT_STORAGE_BASE macro, either
during build or in src/BuildOpt.h.
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>
// SX1262 has the following pin order:
// Module(NSS/CS, DIO1, RESET, BUSY)
// SX1262 radio = new Module(8, 14, 12, 13);
// SX1278 has the following pin order:
// Module(NSS/CS, DIO0, RESET, DIO1)
SX1278 radio = new Module(10, 2, 9, 3);
// create the node instance on the EU-868 band
// using the radio module and the encryption key
// make sure you are using the correct band
// based on your geographical location!
LoRaWANNode node(&radio, &EU868);
// for fixed bands with subband selection
// such as US915 and AU915, you must specify
// the subband that matches the Frequency Plan
// that you selected on your LoRaWAN console
/*
LoRaWANNode node(&radio, &US915, 2);
*/
void setup() {
Serial.begin(9600);
// initialize SX1278 with default settings
Serial.print(F("[SX1278] 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);
}
// start the activation
// Serial.print(F("[LoRaWAN] Attempting over-the-air activation ... "));
// uint64_t joinEUI = 0x12AD1011B0C0FFEE;
// uint64_t devEUI = 0x70B3D57ED005E120;
// uint8_t nwkKey[] = { 0x74, 0x6F, 0x70, 0x53, 0x65, 0x63, 0x72, 0x65,
// 0x74, 0x4B, 0x65, 0x79, 0x31, 0x32, 0x33, 0x34 };
// uint8_t appKey[] = { 0x61, 0x44, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65,
// 0x6E, 0x74, 0x4B, 0x65, 0x79, 0x41, 0x42, 0x43 };
// state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
// on EEPROM-enabled boards, after the device has been activated,
// the session can be restored without rejoining after device power cycle
// by calling the same `beginOTAA()` or `beginABP()` function with the same keys
// or call `restore()` where it will restore any existing session
// `restore()` returns the active mode if it succeeded (OTAA or ABP)
Serial.print(F("[LoRaWAN] Resuming previous session ... "));
state = node.restore();
if(state >= RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
Serial.print(F("Restored an "));
if(state == RADIOLIB_LORAWAN_MODE_OTAA)
Serial.println(F("OTAA session."));
else {
Serial.println(F("ABP session."));
}
} else {
Serial.print(F("failed, code "));
Serial.println(state);
while(true);
}
}
// counter to keep track of transmitted packets
int count = 0;
void loop() {
// send uplink to port 10
Serial.print(F("[LoRaWAN] Sending uplink packet ... "));
String strUp = "Hello World! #" + String(count++);
String strDown;
int state = node.sendReceive(strUp, 10, strDown);
if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("received a downlink!"));
// print data of the packet (if there are any)
Serial.print(F("[LoRaWAN] Data:\t\t"));
if(strDown.length() > 0) {
Serial.println(strDown);
} 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 frequency error
Serial.print(F("[LoRaWAN] Frequency error:\t"));
Serial.print(radio.getFrequencyError());
Serial.println(F(" Hz"));
} else if(state == RADIOLIB_ERR_RX_TIMEOUT) {
Serial.println(F("no downlink!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
}
// on EEPROM enabled boards, you can save the current session
// by calling "saveSession" which allows retrieving the session after reboot or deepsleep
node.saveSession();
// wait before sending another packet
// alternatively, call a deepsleep function here
// make sure to send the radio to sleep as well using radio.sleep()
uint32_t minimumDelay = 60000; // try to send once every minute
uint32_t interval = node.timeUntilUplink(); // calculate minimum duty cycle delay (per law!)
uint32_t delayMs = max(interval, minimumDelay); // cannot send faster than duty cycle allows
delay(delayMs);
}

View file

@ -0,0 +1,294 @@
/*
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.1 requires the use of EEPROM (persistent storage).
Please refer to the 'persistent' example once you are familiar
with LoRaWAN.
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/
*/
// include the library
#include <RadioLib.h>
// SX1262 has the following pin order:
// Module(NSS/CS, DIO1, RESET, BUSY)
// SX1262 radio = new Module(8, 14, 12, 13);
// SX1278 has the following pin order:
// Module(NSS/CS, DIO0, RESET, DIO1)
SX1278 radio = new Module(10, 2, 9, 3);
// create the node instance on the EU-868 band
// using the radio module and the encryption key
// make sure you are using the correct band
// based on your geographical location!
LoRaWANNode node(&radio, &EU868);
// for fixed bands with subband selection
// such as US915 and AU915, you must specify
// the subband that matches the Frequency Plan
// that you selected on your LoRaWAN console
/*
LoRaWANNode node(&radio, &US915, 2);
*/
void setup() {
Serial.begin(9600);
// initialize SX1278 with default settings
Serial.print(F("[SX1278] 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);
}
// application identifier - pre-LoRaWAN 1.1.0, this was called appEUI
// when adding new end device in TTN, you will have to enter this number
// you can pick any number you want, but it has to be unique
uint64_t joinEUI = 0x12AD1011B0C0FFEE;
// device identifier - this number can be anything
// when adding new end device in TTN, you can generate this number,
// or you can set any value you want, provided it is also unique
uint64_t devEUI = 0x70B3D57ED005E120;
// select some encryption keys which will be used to secure the communication
// there are two of them - network key and application key
// because LoRaWAN uses AES-128, the key MUST be 16 bytes (or characters) long
// network key is the ASCII string "topSecretKey1234"
uint8_t nwkKey[] = { 0x74, 0x6F, 0x70, 0x53, 0x65, 0x63, 0x72, 0x65,
0x74, 0x4B, 0x65, 0x79, 0x31, 0x32, 0x33, 0x34 };
// application key is the ASCII string "aDifferentKeyABC"
uint8_t appKey[] = { 0x61, 0x44, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65,
0x6E, 0x74, 0x4B, 0x65, 0x79, 0x41, 0x42, 0x43 };
// prior to LoRaWAN 1.1.0, only a single "nwkKey" is used
// when connecting to LoRaWAN 1.0 network, "appKey" will be disregarded
// and can be set to NULL
// now we can start the activation
// this can take up to 10 seconds, and requires a LoRaWAN gateway in range
// a specific starting-datarate can be selected in dynamic bands (e.g. EU868):
/*
uint8_t joinDr = 4;
state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey, joinDr);
*/
Serial.print(F("[LoRaWAN] Attempting over-the-air activation ... "));
state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
if(state >= RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
while(true);
}
// on EEPROM-enabled boards, after the device has been activated,
// the session can be restored without rejoining after device power cycle
// this is intrinsically done when calling `beginOTAA()` with the same keys
// or if you 'lost' the keys or don't want them included in your sketch
// you can call `restore()`
/*
Serial.print(F("[LoRaWAN] Resuming previous session ... "));
state = node.restore();
if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
while(true);
}
*/
// disable the ADR algorithm
node.setADR(false);
// set a fixed datarate
node.setDatarate(5);
// in order to save the datarate persistent across reboot/deepsleep, use the following:
/*
node.setDatarate(5, true);
*/
// enable CSMA
// this tries to minimize packet loss by searching for a free channel
// before actually sending an uplink
node.setCSMA(6, 2, true);
// enable or disable the dutycycle
// the second argument specific allowed airtime per hour in milliseconds
// 1250 = TTN FUP (30 seconds / 24 hours)
// if not called, this corresponds to setDutyCycle(true, 0)
// setting this to 0 corresponds to the band's maximum allowed dutycycle by law
node.setDutyCycle(true, 1250);
// enable or disable the dwell time limits
// the second argument specific allowed airtime per uplink in milliseconds
// if not called, this corresponds to setDwellTime(true, 0)
// setting this to 0 corresponds to the band's maximum allowed dwell time by law
node.setDwellTime(true, 1000);
}
void loop() {
int 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);
// retrieve the last uplink frame counter
uint32_t fcntUp = node.getFcntUp();
Serial.print(F("[LoRaWAN] Sending uplink packet ... "));
String strUp = "Hello World! #" + String(fcntUp);
// send a confirmed uplink to port 10 every 64th frame
// and also request the LinkCheck and DeviceTime MAC commands
if(fcntUp % 64 == 0) {
state = node.uplink(strUp, 10, true);
node.sendMacCommandReq(RADIOLIB_LORAWAN_MAC_LINK_CHECK);
node.sendMacCommandReq(RADIOLIB_LORAWAN_MAC_DEVICE_TIME);
} else {
state = node.uplink(strUp, 10);
}
if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
}
// after uplink, you can call downlink(),
// to receive any possible reply from the server
// this function must be called within a few seconds
// after uplink to receive the downlink!
Serial.print(F("[LoRaWAN] Waiting for downlink ... "));
String strDown;
// you can also retrieve additional information about
// uplink or downlink by passing a reference to
// LoRaWANEvent_t structure
LoRaWANEvent_t event;
state = node.downlink(strDown, &event);
if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
// print data of the packet (if there are any)
Serial.print(F("[LoRaWAN] Data:\t\t"));
if(strDown.length() > 0) {
Serial.println(strDown);
} 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 frequency error
Serial.print(F("[LoRaWAN] Frequency error:\t"));
Serial.print(radio.getFrequencyError());
Serial.println(F(" Hz"));
// print extra information about the event
Serial.println(F("[LoRaWAN] Event information:"));
Serial.print(F("[LoRaWAN] Direction:\t"));
if(event.dir == RADIOLIB_LORAWAN_CHANNEL_DIR_UPLINK) {
Serial.println(F("uplink"));
} else {
Serial.println(F("downlink"));
}
Serial.print(F("[LoRaWAN] Confirmed:\t"));
Serial.println(event.confirmed);
Serial.print(F("[LoRaWAN] Confirming:\t"));
Serial.println(event.confirming);
Serial.print(F("[LoRaWAN] Datarate:\t"));
Serial.print(event.datarate);
Serial.print(F("[LoRaWAN] Frequency:\t"));
Serial.print(event.freq, 3);
Serial.println(F(" MHz"));
Serial.print(F("[LoRaWAN] Output power:\t"));
Serial.print(event.power);
Serial.println(F(" dBm"));
Serial.print(F("[LoRaWAN] Frame count:\t"));
Serial.println(event.fcnt);
Serial.print(F("[LoRaWAN] Port:\t\t"));
Serial.println(event.port);
Serial.print(radio.getFrequencyError());
uint8_t margin = 0;
uint8_t gwCnt = 0;
if(node.getMacLinkCheckAns(&margin, &gwCnt)) {
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)) {
Serial.print(F("[LoRaWAN] DeviceTime Unix:\t"));
Serial.println(networkTime);
Serial.print(F("[LoRaWAN] LinkCheck second:\t1/"));
Serial.println(fracSecond);
}
} else if(state == RADIOLIB_ERR_RX_TIMEOUT) {
Serial.println(F("timeout!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
}
// on EEPROM enabled boards, you can save the current session
// by calling "saveSession" which allows retrieving the session after reboot or deepsleep
/*
node.saveSession();
*/
// wait before sending another packet
uint32_t minimumDelay = 60000; // try to send once every minute
uint32_t interval = node.timeUntilUplink(); // calculate minimum duty cycle delay (per law!)
uint32_t delayMs = max(interval, minimumDelay); // cannot send faster than duty cycle allows
delay(delayMs);
}

View file

@ -1,204 +0,0 @@
/*
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;
// Optionally provide a custom sleep function - see config.h
//node.setSleepFunction(customDelay);
// 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);
}

View file

@ -1,162 +0,0 @@
#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, CN470
const LoRaWANBand_t Region = EU868;
// subband choice: for US915/AU915 set to 2, for CN470 set to 1, otherwise leave on 0
const uint8_t subBand = 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();
}
// Custom delay function:
// Communication over LoRaWAN includes a lot of delays.
// By default, RadioLib will use the Arduino delay() function,
// which will waste a lot of power. However, you can put your
// microcontroller to sleep instead by customizing the function below,
// and providing it to RadioLib via "node.setSleepFunction".
// NOTE: You ahve to ensure that this function is timed precisely, and
// does actually wait for the amount of time specified!
// Failure to do so will result in missed downlinks or failed join!
void customDelay(RadioLibTime_t ms) {
// this is just an example, so we use the Arduino delay() function,
// but you can put your microcontroller to sleep here
::delay(ms);
}
#endif

View file

@ -1,82 +0,0 @@
/*
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
}

View file

@ -1,147 +0,0 @@
#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, CN470
const LoRaWANBand_t Region = EU868;
// subband choice: for US915/AU915 set to 2, for CN470 set to 1, otherwise leave on 0
const uint8_t subBand = 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

View file

@ -1,180 +0,0 @@
# 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.

View file

@ -1,37 +0,0 @@
# 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 CN470 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._

View file

@ -1,23 +1,23 @@
/* /*
RadioLib SX127x Morse Receive AM Example RadioLib SX127x Morse Receive AM Example
This example receives Morse code message using This example receives Morse code message using
SX1278's FSK modem. The signal is expected to be SX1278's FSK modem. The signal is expected to be
modulated as OOK, to be demodulated in AM mode. modulated as OOK, to be demodulated in AM mode.
Other modules that can be used for Morse Code Other modules that can be used for Morse Code
with AFSK modulation: with AFSK modulation:
- SX127x/RFM9x - SX127x/RFM9x
- RF69 - RF69
- SX1231 - SX1231
- CC1101 - CC1101
- Si443x/RFM2x - Si443x/RFM2x
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -30,13 +30,9 @@
// DIO1 pin: 3 // DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3); SX1278 radio = new Module(10, 2, 9, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //SX1278 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// create AFSK client instance using the FSK module // create AFSK client instance using the FSK module
// pin 5 is connected to SX1278 DIO2 // pin 5 is connected to SX1278 DIO2
@ -56,7 +52,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// when using one of the non-LoRa modules for Morse code // when using one of the non-LoRa modules for Morse code
@ -73,7 +69,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// after that, set mode to OOK to emulate AM modulation // after that, set mode to OOK to emulate AM modulation
@ -84,7 +80,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// start direct mode reception // start direct mode reception

View file

@ -1,23 +1,23 @@
/* /*
RadioLib Morse Transmit AM Example RadioLib Morse Transmit AM Example
This example sends Morse code message using This example sends Morse code message using
SX1278's FSK modem. The signal is modulated SX1278's FSK modem. The signal is modulated
as OOK, and may be demodulated in AM mode. as OOK, and may be demodulated in AM mode.
Other modules that can be used for Morse Code Other modules that can be used for Morse Code
with AM modulation: with AM modulation:
- SX127x/RFM9x - SX127x/RFM9x
- RF69 - RF69
- SX1231 - SX1231
- CC1101 - CC1101
- Si443x/RFM2x - Si443x/RFM2x
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -30,13 +30,9 @@
// DIO1 pin: 3 // DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3); SX1278 radio = new Module(10, 2, 9, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //SX1278 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// create AFSK client instance using the FSK module // create AFSK client instance using the FSK module
// pin 5 is connected to SX1278 DIO2 // pin 5 is connected to SX1278 DIO2
@ -61,7 +57,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize Morse client // initialize Morse client
@ -74,7 +70,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// after that, set mode to OOK to emulate AM modulation // after that, set mode to OOK to emulate AM modulation
@ -85,7 +81,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
} }

View file

@ -1,24 +1,24 @@
/* /*
RadioLib Morse Transmit AFSK Example RadioLib Morse Transmit AFSK Example
This example sends Morse code message using This example sends Morse code message using
SX1278's FSK modem. The signal is modulated SX1278's FSK modem. The signal is modulated
as AFSK, and may be demodulated in FM mode. as AFSK, and may be demodulated in FM mode.
Other modules that can be used for Morse Code Other modules that can be used for Morse Code
with AFSK modulation: with AFSK modulation:
- SX127x/RFM9x - SX127x/RFM9x
- RF69 - RF69
- SX1231 - SX1231
- CC1101 - CC1101
- Si443x/RFM2x - Si443x/RFM2x
- SX126x/LLCC68 - SX126x/LLCC68 (only devices without TCXO!)
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -31,13 +31,9 @@
// DIO1 pin: 3 // DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3); SX1278 radio = new Module(10, 2, 9, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //SX1278 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// create AFSK client instance using the FSK module // create AFSK client instance using the FSK module
// this requires connection to the module direct // this requires connection to the module direct
@ -69,7 +65,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize Morse client // initialize Morse client
@ -82,7 +78,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
} }

View file

@ -1,26 +1,25 @@
/* /*
RadioLib Morse Transmit SSB Example RadioLib Morse Transmit SSB Example
This example sends Morse code message using This example sends Morse code message using
SX1278's FSK modem. The signal is an unmodulated SX1278's FSK modem. The signal is an unmodulated
carrier wave, and may be demodulated in SSB mode. carrier wave, and may be demodulated in SSB mode.
Other modules that can be used for Morse Code: Other modules that can be used for Morse Code:
- SX127x/RFM9x - SX127x/RFM9x
- RF69 - RF69
- SX1231 - SX1231
- CC1101 - CC1101
- SX126x - SX126x
- nRF24 - nRF24
- Si443x/RFM2x - Si443x/RFM2x
- SX128x - SX128x
- LR11x0
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -33,13 +32,9 @@
// DIO1 pin: 3 // DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3); SX1278 radio = new Module(10, 2, 9, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //SX1278 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// create Morse client instance using the FSK module // create Morse client instance using the FSK module
MorseClient morse(&radio); MorseClient morse(&radio);
@ -60,7 +55,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize Morse client // initialize Morse client
@ -73,7 +68,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
} }

View file

@ -1,10 +0,0 @@
# 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

View file

@ -7,7 +7,7 @@
// this example only works on ESP32 and is unlikely to work on ESP32S2/S3 etc. // 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 you need high portability, you should probably use Arduino anyway ...
#if CONFIG_IDF_TARGET_ESP32 == 0 #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. #error Target is not ESP32!
#endif #endif
// include all the dependencies // include all the dependencies

View file

@ -1,7 +1,7 @@
dependencies: dependencies:
RadioLib: RadioLib:
# referenced locally because the example is a part of the repository itself # referenced locally because the example is a part of the repository itself
# under normal circumstances, it's preferable to reference the repository instead # under normal circumstances, it's preferrable 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 # for other options, see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html
path: ../../../../../RadioLib path: ../../../../../RadioLib
#git: https://github.com/jgromes/RadioLib.git #git: https://github.com/jgromes/RadioLib.git

View file

@ -23,7 +23,7 @@ add_executable(${PROJECT_NAME}
) )
# Pull in common dependencies # Pull in common dependencies
target_link_libraries(${PROJECT_NAME} pico_stdlib hardware_spi hardware_gpio hardware_timer pico_multicore hardware_pwm RadioLib) target_link_libraries(${PROJECT_NAME} pico_stdlib hardware_spi hardware_gpio hardware_timer RadioLib)
pico_enable_stdio_usb(${PROJECT_NAME} 1) pico_enable_stdio_usb(${PROJECT_NAME} 1)

View file

@ -8,45 +8,6 @@
#include <pico/stdlib.h> #include <pico/stdlib.h>
#include "hardware/spi.h" #include "hardware/spi.h"
#include "hardware/timer.h" #include "hardware/timer.h"
#include "hardware/pwm.h"
#include "hardware/clocks.h"
#include "pico/multicore.h"
uint32_t toneLoopPin;
unsigned int toneLoopFrequency;
unsigned long toneLoopDuration;
// pre-calculated pulse-widths for 1200 and 2200Hz
// we do this to save calculation time (see https://github.com/khoih-prog/RP2040_PWM/issues/6)
#define SLEEP_1200 416.666
#define SLEEP_2200 227.272
// === NOTE ===
// The tone(...) implementation uses the second core on the RPi Pico. This is to diminish as much
// jitter in the output tones as possible.
void toneLoop(){
gpio_set_dir(toneLoopPin, GPIO_OUT);
uint32_t sleep_dur;
if (toneLoopFrequency == 1200) {
sleep_dur = SLEEP_1200;
} else if (toneLoopFrequency == 2200) {
sleep_dur = SLEEP_2200;
} else {
sleep_dur = 500000 / toneLoopFrequency;
}
// tone bitbang
while(1){
gpio_put(toneLoopPin, 1);
sleep_us(sleep_dur);
gpio_put(toneLoopPin, 0);
sleep_us(sleep_dur);
tight_loop_contents();
}
}
// create a new Raspberry Pi Pico hardware abstraction // create a new Raspberry Pi Pico hardware abstraction
// layer using the Pico SDK // layer using the Pico SDK
@ -60,7 +21,8 @@ public:
_spiSpeed(spiSpeed), _spiSpeed(spiSpeed),
_misoPin(misoPin), _misoPin(misoPin),
_mosiPin(mosiPin), _mosiPin(mosiPin),
_sckPin(sckPin){} _sckPin(sckPin) {
}
void init() override { void init() override {
stdio_init_all(); stdio_init_all();
@ -148,19 +110,6 @@ public:
return (this->micros() - start); return (this->micros() - start);
} }
void tone(uint32_t pin, unsigned int frequency, unsigned long duration = 0) override {
// tones on the Pico are generated using bitbanging. This process is offloaded to the Pico's second core
multicore_reset_core1();
toneLoopPin = pin;
toneLoopFrequency = frequency;
toneLoopDuration = duration;
multicore_launch_core1(toneLoop);
}
void noTone(uint32_t pin) override {
multicore_reset_core1();
}
void spiBegin() { void spiBegin() {
spi_init(_spiChannel, _spiSpeed); spi_init(_spiChannel, _spiSpeed);
spi_set_format(_spiChannel, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST); spi_set_format(_spiChannel, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
@ -176,10 +125,6 @@ public:
spi_write_read_blocking(_spiChannel, out, in, len); spi_write_read_blocking(_spiChannel, out, in, len);
} }
void yield() override {
tight_loop_contents();
}
void spiEndTransaction() {} void spiEndTransaction() {}
void spiEnd() { void spiEnd() {

View file

@ -41,7 +41,7 @@
#include <RadioLib.h> #include <RadioLib.h>
// include the hardware abstraction layer // include the hardware abstraction layer
#include "hal/RPiPico/PicoHal.h" #include "PicoHal.h"
// create a new instance of the HAL class // create a new instance of the HAL class
PicoHal* hal = new PicoHal(SPI_PORT, SPI_MISO, SPI_MOSI, SPI_SCK); PicoHal* hal = new PicoHal(SPI_PORT, SPI_MISO, SPI_MOSI, SPI_SCK);

View file

@ -15,8 +15,7 @@ add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../../../RadioLib" "${CMAKE_CUR
add_executable(${PROJECT_NAME} main.cpp) add_executable(${PROJECT_NAME} main.cpp)
# link both libraries # link both libraries
target_link_libraries(${PROJECT_NAME} RadioLib lgpio) target_link_libraries(${PROJECT_NAME} RadioLib pigpio)
# you can also specify RadioLib compile-time flags here # you can also specify RadioLib compile-time flags here
#target_compile_definitions(RadioLib PUBLIC RADIOLIB_DEBUG_BASIC RADIOLIB_DEBUG_SPI) #target_compile_definitions(${PROJECT_NAME} PUBLIC RADIOLIB_DEBUG RADIOLIB_VERBOSE)
#target_compile_definitions(RadioLib PUBLIC RADIOLIB_DEBUG_PORT=stdout)

View file

@ -0,0 +1,151 @@
#ifndef PI_HAL_H
#define PI_HAL_H
// include RadioLib
#include <RadioLib.h>
// include the library for Raspberry GPIO pins
#include "pigpio.h"
// create a new Raspberry Pi hardware abstraction layer
// using the pigpio library
// the HAL must inherit from the base RadioLibHal class
// and implement all of its virtual methods
class PiHal : public RadioLibHal {
public:
// default constructor - initializes the base HAL and any needed private members
PiHal(uint8_t spiChannel, uint32_t spiSpeed = 2000000)
: RadioLibHal(PI_INPUT, PI_OUTPUT, PI_LOW, PI_HIGH, RISING_EDGE, FALLING_EDGE),
_spiChannel(spiChannel),
_spiSpeed(spiSpeed) {
}
void init() override {
// first initialise pigpio library
gpioInitialise();
// now the SPI
spiBegin();
// Waveshare LoRaWAN Hat also needs pin 18 to be pulled high to enable the radio
gpioSetMode(18, PI_OUTPUT);
gpioWrite(18, PI_HIGH);
}
void term() override {
// stop the SPI
spiEnd();
// pull the enable pin low
gpioSetMode(18, PI_OUTPUT);
gpioWrite(18, PI_LOW);
// finally, stop the pigpio library
gpioTerminate();
}
// 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;
}
gpioSetMode(pin, mode);
}
void digitalWrite(uint32_t pin, uint32_t value) override {
if(pin == RADIOLIB_NC) {
return;
}
gpioWrite(pin, value);
}
uint32_t digitalRead(uint32_t pin) override {
if(pin == RADIOLIB_NC) {
return(0);
}
return(gpioRead(pin));
}
void attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) override {
if(interruptNum == RADIOLIB_NC) {
return;
}
gpioSetISRFunc(interruptNum, mode, 0, (gpioISRFunc_t)interruptCb);
}
void detachInterrupt(uint32_t interruptNum) override {
if(interruptNum == RADIOLIB_NC) {
return;
}
gpioSetISRFunc(interruptNum, 0, 0, NULL);
}
void delay(unsigned long ms) override {
gpioDelay(ms * 1000);
}
void delayMicroseconds(unsigned long us) override {
gpioDelay(us);
}
unsigned long millis() override {
return(gpioTick() / 1000);
}
unsigned long micros() override {
return(gpioTick());
}
long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override {
if(pin == RADIOLIB_NC) {
return(0);
}
this->pinMode(pin, PI_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() {
if(_spiHandle < 0) {
_spiHandle = spiOpen(_spiChannel, _spiSpeed, 0);
}
}
void spiBeginTransaction() {}
void spiTransfer(uint8_t* out, size_t len, uint8_t* in) {
spiXfer(_spiHandle, (char*)out, (char*)in, len);
}
void spiEndTransaction() {}
void spiEnd() {
if(_spiHandle >= 0) {
spiClose(_spiHandle);
_spiHandle = -1;
}
}
private:
// the HAL can contain any additional private members
const unsigned int _spiSpeed;
const uint8_t _spiChannel;
int _spiHandle = -1;
};
#endif

View file

@ -6,4 +6,3 @@ cd build
cmake -G "CodeBlocks - Unix Makefiles" .. cmake -G "CodeBlocks - Unix Makefiles" ..
make make
cd .. cd ..
size build/rpi-sx1261

View file

@ -3,8 +3,7 @@
This example shows how to use RadioLib without Arduino. This example shows how to use RadioLib without Arduino.
In this case, a Raspberry Pi with WaveShare SX1302 LoRaWAN Hat In this case, a Raspberry Pi with WaveShare SX1302 LoRaWAN Hat
using the lgpio library using the pigpio library.
https://abyz.me.uk/lg/lgpio.html
Can be used as a starting point to port RadioLib to any platform! 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 See this API reference page for details on the RadioLib hardware abstraction
@ -18,7 +17,7 @@
#include <RadioLib.h> #include <RadioLib.h>
// include the hardware abstraction layer // include the hardware abstraction layer
#include "hal/RPi/PiHal.h" #include "PiHal.h"
// create a new instance of the HAL class // create a new instance of the HAL class
// use SPI channel 1, because on Waveshare LoRaWAN Hat, // use SPI channel 1, because on Waveshare LoRaWAN Hat,
@ -45,13 +44,10 @@ int main(int argc, char** argv) {
printf("success!\n"); printf("success!\n");
// loop forever // loop forever
int count = 0;
for(;;) { for(;;) {
// send a packet // send a packet
printf("[SX1261] Transmitting packet ... "); printf("[SX1261] Transmitting packet ... ");
char str[64]; state = radio.transmit("Hello World!");
sprintf(str, "Hello World! #%d", count++);
state = radio.transmit(str);
if(state == RADIOLIB_ERR_NONE) { if(state == RADIOLIB_ERR_NONE) {
// the packet was successfully transmitted // the packet was successfully transmitted
printf("success!\n"); printf("success!\n");

View file

@ -1,2 +1,2 @@
build-* build/
TockApp.tab TockApp.tab

View file

@ -27,13 +27,9 @@ cmake_minimum_required(VERSION 3.18)
# create the project # create the project
project(tock-sx1261) project(tock-sx1261)
set(LINKER_SCRIPT $ENV{LIBTOCK_C_DIRECTORY}/userland_generic.ld) set(LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/libtock-c/userland_generic.ld)
if (RISCV_BUILD) include("tock.cmake")
include("tock-riscv.cmake")
else()
include("tock-arm.cmake")
endif()
# when using debuggers such as gdb, the following line can be used # when using debuggers such as gdb, the following line can be used
#set(CMAKE_BUILD_TYPE Debug) #set(CMAKE_BUILD_TYPE Debug)
@ -47,90 +43,18 @@ add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../../../RadioLib" "${CMAKE_CUR
add_executable(${PROJECT_NAME} main.cpp) add_executable(${PROJECT_NAME} main.cpp)
# link with RadioLib and libtock-c # link with RadioLib and libtock-c
# The build system for libtock-c is a bit odd and the version of libraries target_link_libraries(${PROJECT_NAME} PUBLIC
# built changes based on compiler version. RadioLib
if (RISCV_BUILD) ${CMAKE_CURRENT_SOURCE_DIR}/libtock-c/libtock/build/cortex-m4/libtock.a
if(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0") ${CMAKE_CURRENT_SOURCE_DIR}/libtock-c/libc++/cortex-m/libgcc.a
target_link_libraries(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/libtock-c/libc++/cortex-m/libstdc++.a
RadioLib ${CMAKE_CURRENT_SOURCE_DIR}/libtock-c/newlib/cortex-m/v7-m/libc.a
$ENV{LIBTOCK_C_DIRECTORY}/libtock/build/rv32imc/libtock.a ${CMAKE_CURRENT_SOURCE_DIR}/libtock-c/newlib/cortex-m/v7-m/libm.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 target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/ ${CMAKE_CURRENT_SOURCE_DIR}/libtock-c
$ENV{LIBTOCK_C_DIRECTORY}
) )
# you can also specify RadioLib compile-time flags here # you can also specify RadioLib compile-time flags here

View file

@ -13,22 +13,16 @@ This has been tested on the
but will work on any LoRa compatible Tock board (currently only the but will work on any LoRa compatible Tock board (currently only the
expLoRaBLE board). 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: The RadioLib example can be built with:
```shell ```shell
$ git clone https://github.com/jgromes/RadioLib.git $ git clone https://github.com/jgromes/RadioLib.git
$ cd RadioLib/examples/NonArduino/Tock/ $ cd RadioLib/examples/NonArduino/Tock/
$ git clone https://github.com/tock/libtock-c.git $ ./build.sh
$ 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: Then in the Tock repo you can flash the kernel and app with:
```shell ```shell
$ make flash; APP=RadioLib/examples/NonArduino/Tock/build-arm/tock-sx1261.tbf make flash-app $ make flash; APP=RadioLib/examples/NonArduino/Tock/build/tock-sx1261.tbf make flash-app
``` ```

View file

@ -1,30 +1,20 @@
#!/bin/bash #!/bin/bash
set -e set -e
rm -rf ./build-* rm -rf ./build
pushd ${LIBTOCK_C_DIRECTORY}/examples/cxx_hello cd libtock-c/libtock
make -j4 make -j4
popd cd ../../
mkdir -p build-arm mkdir -p build
cd build-arm cd build
cmake -G "CodeBlocks - Unix Makefiles" .. cmake -G "CodeBlocks - Unix Makefiles" ..
make -j4 make -j4
cd .. 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 \ elf2tab -n radio-lib --stack 4096 --app-heap 2048 --kernel-heap 2048 \
--kernel-major 2 --kernel-minor 1 \ --kernel-major 2 --kernel-minor 1 \
-v ./build-arm/tock-sx1261 -v ./build/tock-sx1261

@ -0,0 +1 @@
Subproject commit 1c1f4c0810aa0fbd50aa91a11aaa7c05d2abb1bc

View file

@ -0,0 +1,200 @@
/*
RadioLib Non-Arduino Tock Library helper functions
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.
*/
#ifndef TOCK_HAL_H
#define TOCK_HAL_H
// include RadioLib
#include <RadioLib.h>
// include all the dependencies
#include "libtock/lora_phy.h"
#include "libtock/gpio.h"
#include "libtock/timer.h"
#include "libtock/read_only_state.h"
#define RADIO_BUSY 1
#define RADIO_DIO_1 2
#define RADIO_DIO_3 3
#define RADIO_RESET 4
// Skip the chips select as Tock handles this for us
#define RADIO_NSS RADIOLIB_NC
// define Arduino-style macros
#define PIN_LOW (0x0)
#define PIN_HIGH (0x1)
#define PIN_INPUT (0x01)
#define PIN_OUTPUT (0x03)
#define PIN_RISING (0x01)
#define PIN_FALLING (0x02)
typedef void (*gpioIrqFn)(void);
/*
* Get the the timer frequency in Hz.
*/
int alarm_internal_frequency(uint32_t* frequency) {
syscall_return_t rval = command(0x0, 1, 0, 0);
return tock_command_return_u32_to_returncode(rval, frequency);
}
int alarm_internal_read(uint32_t* time) {
syscall_return_t rval = command(0x0, 2, 0, 0);
return tock_command_return_u32_to_returncode(rval, time);
}
static void lora_phy_gpio_Callback (int gpioPin,
__attribute__ ((unused)) int arg2,
__attribute__ ((unused)) int arg3,
void* userdata)
{
gpioIrqFn fn = *(gpioIrqFn*)(&userdata);
if (fn != NULL ) {
fn();
}
}
class TockHal : public RadioLibHal {
public:
// default constructor - initializes the base HAL and any needed private members
TockHal()
: RadioLibHal(PIN_INPUT, PIN_OUTPUT, PIN_LOW, PIN_HIGH, PIN_RISING, PIN_FALLING) {
}
void init() override {
}
void term() override {
}
// 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;
}
if (mode == PIN_OUTPUT) {
lora_phy_gpio_enable_output(pin);
} else if (mode == PIN_INPUT) {
lora_phy_gpio_enable_input(pin, PullDown);
}
}
void digitalWrite(uint32_t pin, uint32_t value) override {
if(pin == RADIOLIB_NC) {
return;
}
if (value) {
lora_phy_gpio_set(pin);
} else {
lora_phy_gpio_clear(pin);
}
}
uint32_t digitalRead(uint32_t pin) override {
int value;
if(pin == RADIOLIB_NC) {
return 0;
}
lora_phy_gpio_read(pin, &value);
return value;
}
void attachInterrupt(uint32_t interruptNum, gpioIrqFn interruptCb, uint32_t mode) override {
if(interruptNum == RADIOLIB_NC) {
return;
}
lora_phy_gpio_interrupt_callback(lora_phy_gpio_Callback, &interruptCb);
// set GPIO as input and enable interrupts on it
lora_phy_gpio_enable_input(interruptNum, PullDown);
lora_phy_gpio_enable_interrupt(interruptNum, Change);
}
void detachInterrupt(uint32_t interruptNum) override {
if(interruptNum == RADIOLIB_NC) {
return;
}
lora_phy_gpio_disable_interrupt(interruptNum);
}
void delay(unsigned long ms) override {
delay_ms( ms );
}
void delayMicroseconds(unsigned long us) override {
delay_ms( us / 1000 );
}
unsigned long millis() override {
uint32_t frequency, now;
alarm_internal_frequency(&frequency);
alarm_internal_read(&now);
return (now / frequency) / 1000;
}
unsigned long micros() override {
return millis() / 1000;
}
long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override {
return 0;
}
void spiBegin() {
}
void spiBeginTransaction() {
}
void spiTransfer(uint8_t* out, size_t len, uint8_t* in) {
lora_phy_read_write_sync((const char*) out, (char*) in, len);
}
void spiEndTransaction() {
}
void spiEnd() {
}
void yield() {
::yield_no_wait();
}
private:
};
#endif

View file

@ -28,14 +28,14 @@
#include <RadioLib.h> #include <RadioLib.h>
// include the hardware abstraction layer // include the hardware abstraction layer
#include "RadioLib/libtockHal.h" #include "libtockHal.h"
// the entry point for the program // the entry point for the program
int main(void) { int main(void) {
printf("[SX1261] Initialising Radio ... \r\n"); printf("[SX1261] Initialising Radio ... \r\n");
// create a new instance of the HAL class // create a new instance of the HAL class
TockRadioLibHal* hal = new TockRadioLibHal(); TockHal* hal = new TockHal();
// now we can create the radio module // now we can create the radio module
// pinout corresponds to the SparkFun LoRa Thing Plus - expLoRaBLE // pinout corresponds to the SparkFun LoRa Thing Plus - expLoRaBLE
@ -43,7 +43,7 @@ int main(void) {
// DIO1 pin: 2 // DIO1 pin: 2
// NRST pin: 4 // NRST pin: 4
// BUSY pin: 1 // BUSY pin: 1
Module* tock_module = new Module(hal, RADIOLIB_RADIO_NSS, RADIOLIB_RADIO_DIO_1, RADIOLIB_RADIO_RESET, RADIOLIB_RADIO_BUSY); Module* tock_module = new Module(hal, RADIO_NSS, RADIO_DIO_1, RADIO_RESET, RADIO_BUSY);
SX1262* radio = new SX1262(tock_module); SX1262* radio = new SX1262(tock_module);
// Setup the radio // Setup the radio

View file

@ -1,76 +0,0 @@
# 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")

View file

@ -25,6 +25,8 @@
# This is copied from https://github.com/Lora-net/LoRaMac-node/pull/1390 # This is copied from https://github.com/Lora-net/LoRaMac-node/pull/1390
# and has been relicensed by the original author # and has been relicensed by the original author
include("toolchain-arm-none-eabi.cmake")
if(NOT DEFINED LINKER_SCRIPT) if(NOT DEFINED LINKER_SCRIPT)
message(FATAL_ERROR "No linker script defined") message(FATAL_ERROR "No linker script defined")
endif(NOT DEFINED LINKER_SCRIPT) endif(NOT DEFINED LINKER_SCRIPT)
@ -38,22 +40,6 @@ set(STACK_SIZE 4096)
set(APP_HEAP_SIZE 2048) set(APP_HEAP_SIZE 2048)
set(KERNEL_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 # 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(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")

View file

@ -0,0 +1,90 @@
# Arm specific CMake file
#
# This is copied from:
# https://github.com/Lora-net/LoRaMac-node/blob/2bf36bde72f68257eb96b5c00900619546bedca8/cmake/toolchain-arm-none-eabi.cmake
#
# The below file is licensed as Revised BSD License
# See https://github.com/Lora-net/LoRaMac-node/blob/master/LICENSE for details
##
## ______ _
## / _____) _ | |
## ( (____ _____ ____ _| |_ _____ ____| |__
## \____ \| ___ | (_ _) ___ |/ ___) _ \
## _____) ) ____| | | || |_| ____( (___| | | |
## (______/|_____)_|_|_| \__)_____)\____)_| |_|
## (C)2013-2017 Semtech
## ___ _____ _ ___ _ _____ ___ ___ ___ ___
## / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
## \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
## |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
## embedded.connectivity.solutions.==============
##
## License: Revised BSD License, see LICENSE.TXT file included in the project
## Authors: Johannes Bruder ( STACKFORCE ), Miguel Luis ( Semtech )
##
##
## CMake arm-none-eabi toolchain file
##
# Append current directory to CMAKE_MODULE_PATH for making device specific cmake modules visible
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
# Target definition
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR ARM)
#---------------------------------------------------------------------------------------
# Set toolchain paths
#---------------------------------------------------------------------------------------
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 system depended extensions
if(WIN32)
set(TOOLCHAIN_EXT ".exe" )
else()
set(TOOLCHAIN_EXT "" )
endif()
# Perform compiler test with static library
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
#---------------------------------------------------------------------------------------
# Preset some general GCC Options
#---------------------------------------------------------------------------------------
# Options for DEBUG build
# -Og enables optimizations that do not interfere with debugging
# -g produce debugging information in the operating system's native format
set(CMAKE_C_FLAGS_DEBUG "-Og -g -DDEBUG" CACHE INTERNAL "C Compiler options for debug build type")
set(CMAKE_CXX_FLAGS_DEBUG "-Og -g -DDEBUG" CACHE INTERNAL "C++ Compiler options for debug build type")
set(CMAKE_ASM_FLAGS_DEBUG "-g" CACHE INTERNAL "ASM Compiler options for debug build type")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "" CACHE INTERNAL "Linker options for debug build type")
# Options for RELEASE build
# -Os Optimize for size. -Os enables all -O2 optimizations
set(CMAKE_C_FLAGS_RELEASE "-Os" CACHE INTERNAL "C Compiler options for release build type")
set(CMAKE_CXX_FLAGS_RELEASE "-Os" CACHE INTERNAL "C++ Compiler options for release build type")
set(CMAKE_ASM_FLAGS_RELEASE "" CACHE INTERNAL "ASM Compiler options for release build type")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "" CACHE INTERNAL "Linker options for release build type")
#---------------------------------------------------------------------------------------
# Set compilers
#---------------------------------------------------------------------------------------
set(CMAKE_C_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc${TOOLCHAIN_EXT} CACHE INTERNAL "C Compiler")
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-g++${TOOLCHAIN_EXT} CACHE INTERNAL "C++ Compiler")
set(CMAKE_ASM_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc${TOOLCHAIN_EXT} CACHE INTERNAL "ASM Compiler")
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_PREFIX}/${${TOOLCHAIN}} ${CMAKE_PREFIX_PATH})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

View file

@ -1,24 +1,24 @@
/* /*
RadioLib Pager (POCSAG) Receive Example RadioLib Pager (POCSAG) Receive Example
This example shows how to receive FSK packets without using This example shows how to receive FSK packets without using
SX127x packet engine. SX127x packet engine.
This example receives POCSAG messages using SX1278's This example receives POCSAG messages using SX1278's
FSK modem in direct mode. FSK modem in direct mode.
Other modules that can be used to receive POCSAG: Other modules that can be used to receive POCSAG:
- SX127x/RFM9x - SX127x/RFM9x
- RF69 - RF69
- SX1231 - SX1231
- CC1101 - CC1101
- Si443x/RFM2x - Si443x/RFM2x
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -45,13 +45,9 @@ const int pin = 5;
// create Pager client instance using the FSK module // create Pager client instance using the FSK module
PagerClient pager(&radio); PagerClient pager(&radio);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //SX1278 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
void setup() { void setup() {
Serial.begin(9600); Serial.begin(9600);
@ -69,7 +65,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// initialize Pager client // initialize Pager client
@ -82,7 +78,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// start receiving POCSAG messages // start receiving POCSAG messages
@ -94,7 +90,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
} }

View file

@ -1,24 +1,24 @@
/* /*
RadioLib Pager (POCSAG) Transmit Example RadioLib Pager (POCSAG) Transmit Example
This example sends POCSAG messages using SX1278's This example sends POCSAG messages using SX1278's
FSK modem. FSK modem.
Other modules that can be used to send POCSAG: Other modules that can be used to send POCSAG:
- SX127x/RFM9x - SX127x/RFM9x
- RF69 - RF69
- SX1231 - SX1231
- CC1101 - CC1101
- SX126x - SX126x
- nRF24 - nRF24
- Si443x/RFM2x - Si443x/RFM2x
- SX128x - SX128x
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration https://github.com/jgromes/RadioLib/wiki/Default-configuration
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -31,13 +31,9 @@
// DIO1 pin: 3 // DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3); SX1278 radio = new Module(10, 2, 9, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //SX1278 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
// create Pager client instance using the FSK module // create Pager client instance using the FSK module
PagerClient pager(&radio); PagerClient pager(&radio);
@ -58,7 +54,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// initialize Pager client // initialize Pager client
@ -71,7 +67,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
} }

View file

@ -1,12 +1,12 @@
/* /*
RadioLib PhysicalLayer Interface Example RadioLib PhysicalLayer Interface Example
This example shows how to use the common PhysicalLayer This example shows how to use the common PhysicalLayer
to interface with different radio modules using the same to interface with different radio modules using the same
methods. methods.
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -23,14 +23,6 @@
// extra GPIO/interrupt pin: 3 (unused on some modules) // extra GPIO/interrupt pin: 3 (unused on some modules)
RADIO_TYPE radio = new Module(10, 2, 9, 3); 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 // get pointer to the common layer
PhysicalLayer* phy = (PhysicalLayer*)&radio; PhysicalLayer* phy = (PhysicalLayer*)&radio;
@ -50,7 +42,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// or we can use the "phy" pointer to access the common layer // or we can use the "phy" pointer to access the common layer
@ -62,7 +54,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// PhysicalLayer also contains basic functionality // PhysicalLayer also contains basic functionality
@ -74,7 +66,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// try to receive now - this will almost certainly timeout // try to receive now - this will almost certainly timeout
@ -90,7 +82,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// interrupt-driven versions of Rx/Tx are supported as well // interrupt-driven versions of Rx/Tx are supported as well
@ -113,7 +105,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// ... or standby // ... or standby
@ -124,7 +116,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
// there are also common SNR/RSSI measurement functions // there are also common SNR/RSSI measurement functions

View file

@ -1,15 +1,15 @@
/* /*
RadioLib RF69 Receive with AES Example RadioLib RF69 Receive with AES Example
This example receives packets using RF69 FSK radio module. This example receives packets using RF69 FSK radio module.
Packets are decrypted using hardware AES. Packets are decrypted using hardware AES.
NOTE: When using address filtering, the address byte is NOT encrypted! NOTE: When using address filtering, the address byte is NOT encrypted!
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231 https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -21,13 +21,9 @@
// RESET pin: 3 // RESET pin: 3
RF69 radio = new Module(10, 2, 3); RF69 radio = new Module(10, 2, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //RF69 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
void setup() { void setup() {
Serial.begin(9600); Serial.begin(9600);
@ -40,7 +36,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// set AES key that will be used to decrypt the packet // set AES key that will be used to decrypt the packet

View file

@ -1,17 +1,17 @@
/* /*
RadioLib RF69 Receive with Address Example RadioLib RF69 Receive with Address Example
This example receives packets using RF69 FSK radio module. This example receives packets using RF69 FSK radio module.
Packets can have 1-byte address of the destination node. Packets can have 1-byte address of the destination node.
After setting node (or broadcast) address, this node will After setting node (or broadcast) address, this node will
automatically filter out any packets that do not contain automatically filter out any packets that do not contain
either node address or broadcast address. either node address or broadcast address.
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231 https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -23,13 +23,9 @@
// RESET pin: 3 // RESET pin: 3
RF69 radio = new Module(10, 2, 3); RF69 radio = new Module(10, 2, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //RF69 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
void setup() { void setup() {
Serial.begin(9600); Serial.begin(9600);
@ -42,7 +38,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// set node address // set node address
@ -55,7 +51,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// set broadcast address // set broadcast address
@ -68,7 +64,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// address filtering can also be disabled // address filtering can also be disabled
@ -82,7 +78,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
*/ */
} }

View file

@ -30,13 +30,9 @@
// RESET pin: 3 // RESET pin: 3
RF69 radio = new Module(10, 2, 3); RF69 radio = new Module(10, 2, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //RF69 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
void setup() { void setup() {
Serial.begin(9600); Serial.begin(9600);
@ -49,7 +45,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
} }

View file

@ -1,15 +1,15 @@
/* /*
RadioLib RF69 Receive with Interrupts Example RadioLib RF69 Receive with Interrupts Example
This example listens for FSK transmissions and tries to This example listens for FSK transmissions and tries to
receive them. Once a packet is received, an interrupt is receive them. Once a packet is received, an interrupt is
triggered. triggered.
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231 https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -21,28 +21,9 @@
// RESET pin: 3 // RESET pin: 3
RF69 radio = new Module(10, 2, 3); RF69 radio = new Module(10, 2, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //RF69 radio = RadioShield.ModuleA;
#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() { void setup() {
Serial.begin(9600); Serial.begin(9600);
@ -55,7 +36,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// set the function that will be called // set the function that will be called
@ -70,7 +51,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// if needed, 'listen' mode can be disabled by calling // if needed, 'listen' mode can be disabled by calling
@ -83,6 +64,21 @@ void setup() {
// radio.readData(); // radio.readData();
} }
// 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 loop() { void loop() {
// check if the flag is set // check if the flag is set
if(receivedFlag) { if(receivedFlag) {

View file

@ -1,21 +1,21 @@
/* /*
RadioLib RF69 Settings Example RadioLib RF69 Settings Example
This example shows how to change all the properties of RF69 radio. This example shows how to change all the properties of RF69 radio.
RadioLib currently supports the following settings: RadioLib currently supports the following settings:
- pins (SPI slave select, digital IO 0, digital IO 1) - pins (SPI slave select, digital IO 0, digital IO 1)
- carrier frequency - carrier frequency
- bit rate - bit rate
- receiver bandwidth - receiver bandwidth
- allowed frequency deviation - allowed frequency deviation
- output power during transmission - output power during transmission
- sync word - sync word
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231 https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -33,13 +33,9 @@ RF69 radio1 = new Module(10, 2, 3);
// RESET pin: 5 // RESET pin: 5
RF69 radio2 = new Module(9, 4, 5); RF69 radio2 = new Module(9, 4, 5);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //RF69 radio3 = RadioShield.ModuleB;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio3 = new RadioModule();
*/
void setup() { void setup() {
Serial.begin(9600); Serial.begin(9600);
@ -52,7 +48,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// initialize RF69 with non-default settings // initialize RF69 with non-default settings
@ -69,7 +65,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// you can also change the settings at runtime // you can also change the settings at runtime
@ -78,41 +74,41 @@ void setup() {
// set carrier frequency to 433.5 MHz // set carrier frequency to 433.5 MHz
if (radio1.setFrequency(433.5) == RADIOLIB_ERR_INVALID_FREQUENCY) { if (radio1.setFrequency(433.5) == RADIOLIB_ERR_INVALID_FREQUENCY) {
Serial.println(F("[RF69] Selected frequency is invalid for this module!")); Serial.println(F("[RF69] Selected frequency is invalid for this module!"));
while (true) { delay(10); } while (true);
} }
// set bit rate to 100.0 kbps // set bit rate to 100.0 kbps
state = radio1.setBitRate(100.0); state = radio1.setBitRate(100.0);
if (state == RADIOLIB_ERR_INVALID_BIT_RATE) { if (state == RADIOLIB_ERR_INVALID_BIT_RATE) {
Serial.println(F("[RF69] Selected bit rate is invalid for this module!")); Serial.println(F("[RF69] Selected bit rate is invalid for this module!"));
while (true) { delay(10); } while (true);
} else if (state == RADIOLIB_ERR_INVALID_BIT_RATE_BW_RATIO) { } 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] Selected bit rate to bandwidth ratio is invalid!"));
Serial.println(F("[RF69] Increase receiver bandwidth to set this bit rate.")); Serial.println(F("[RF69] Increase receiver bandwidth to set this bit rate."));
while (true) { delay(10); } while (true);
} }
// set receiver bandwidth to 250.0 kHz // set receiver bandwidth to 250.0 kHz
state = radio1.setRxBandwidth(250.0); state = radio1.setRxBandwidth(250.0);
if (state == RADIOLIB_ERR_INVALID_RX_BANDWIDTH) { if (state == RADIOLIB_ERR_INVALID_RX_BANDWIDTH) {
Serial.println(F("[RF69] Selected receiver bandwidth is invalid for this module!")); Serial.println(F("[RF69] Selected receiver bandwidth is invalid for this module!"));
while (true) { delay(10); } while (true);
} else if (state == RADIOLIB_ERR_INVALID_BIT_RATE_BW_RATIO) { } 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] Selected bit rate to bandwidth ratio is invalid!"));
Serial.println(F("[RF69] Decrease bit rate to set this receiver bandwidth.")); Serial.println(F("[RF69] Decrease bit rate to set this receiver bandwidth."));
while (true) { delay(10); } while (true);
} }
// set allowed frequency deviation to 10.0 kHz // set allowed frequency deviation to 10.0 kHz
if (radio1.setFrequencyDeviation(10.0) == RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION) { if (radio1.setFrequencyDeviation(10.0) == RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION) {
Serial.println(F("[RF69] Selected frequency deviation is invalid for this module!")); Serial.println(F("[RF69] Selected frequency deviation is invalid for this module!"));
while (true) { delay(10); } while (true);
} }
// set output power to 2 dBm // set output power to 2 dBm
if (radio1.setOutputPower(2) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) { if (radio1.setOutputPower(2) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) {
Serial.println(F("[RF69] Selected output power is invalid for this module!")); Serial.println(F("[RF69] Selected output power is invalid for this module!"));
while (true) { delay(10); } while (true);
} }
// up to 8 bytes can be set as sync word // up to 8 bytes can be set as sync word
@ -121,7 +117,7 @@ void setup() {
uint8_t syncWord[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; uint8_t syncWord[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
if (radio1.setSyncWord(syncWord, 8) == RADIOLIB_ERR_INVALID_SYNC_WORD) { if (radio1.setSyncWord(syncWord, 8) == RADIOLIB_ERR_INVALID_SYNC_WORD) {
Serial.println(F("[RF69] Selected sync word is invalid for this module!")); Serial.println(F("[RF69] Selected sync word is invalid for this module!"));
while (true) { delay(10); } while (true);
} }
Serial.println(F("[RF69] All settings changed successfully!")); Serial.println(F("[RF69] All settings changed successfully!"));

View file

@ -1,15 +1,15 @@
/* /*
RadioLib RF69 Transmit with AES Example RadioLib RF69 Transmit with AES Example
This example transmits packets using RF69 FSK radio module. This example transmits packets using RF69 FSK radio module.
Packets are encrypted using hardware AES. Packets are encrypted using hardware AES.
NOTE: When using address filtering, the address byte is NOT encrypted! NOTE: When using address filtering, the address byte is NOT encrypted!
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231 https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -21,13 +21,9 @@
// RESET pin: 3 // RESET pin: 3
RF69 radio = new Module(10, 2, 3); RF69 radio = new Module(10, 2, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //RF69 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
void setup() { void setup() {
Serial.begin(9600); Serial.begin(9600);
@ -40,7 +36,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// set AES key to encrypt the packet // set AES key to encrypt the packet

View file

@ -1,17 +1,17 @@
/* /*
RadioLib RF69 Transmit to Address Example RadioLib RF69 Transmit to Address Example
This example transmits packets using RF69 FSK radio module. This example transmits packets using RF69 FSK radio module.
Packets can have 1-byte address of the destination node. Packets can have 1-byte address of the destination node.
After setting node (or broadcast) address, this node will After setting node (or broadcast) address, this node will
automatically filter out any packets that do not contain automatically filter out any packets that do not contain
either node address or broadcast address. either node address or broadcast address.
For default module settings, see the wiki page For default module settings, see the wiki page
https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231 https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
For full API reference, see the GitHub Pages For full API reference, see the GitHub Pages
https://jgromes.github.io/RadioLib/ https://jgromes.github.io/RadioLib/
*/ */
// include the library // include the library
@ -23,13 +23,9 @@
// RESET pin: 3 // RESET pin: 3
RF69 radio = new Module(10, 2, 3); RF69 radio = new Module(10, 2, 3);
// or detect the pinout automatically using RadioBoards // or using RadioShield
// https://github.com/radiolib-org/RadioBoards // https://github.com/jgromes/RadioShield
/* //RF69 radio = RadioShield.ModuleA;
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/
void setup() { void setup() {
Serial.begin(9600); Serial.begin(9600);
@ -42,7 +38,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// set node address // set node address
@ -55,7 +51,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// set broadcast address // set broadcast address
@ -68,7 +64,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while (true);
} }
// address filtering can also be disabled // address filtering can also be disabled
@ -82,7 +78,7 @@ void setup() {
} else { } else {
Serial.print(F("failed, code ")); Serial.print(F("failed, code "));
Serial.println(state); Serial.println(state);
while (true) { delay(10); } while(true);
} }
*/ */
} }

Some files were not shown because too many files have changed in this diff Show more