diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000..bbf0d98075
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,3 @@
+# exclude binary patch files from language detection
+src/modules/SX126x/patches/*.h linguist-detectable=false
+src/modules/LR11x0/firmware/*.h linguist-detectable=false
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 0258df195f..486e056dfd 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -7,14 +7,34 @@ assignees: ''
---
-**IMPORTANT: Check the wiki**
-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.
+**IMPORTANT: Check the docs**
+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).
**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).
+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**.
+
+Debug mode output
+
+
+```
+paste the debug output here
+```
+
+
+
**To Reproduce**
-Minimal Arduino sketch to reproduce the behavior. Please user 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)).
+
+Sketch that is causing the module fail
+
+
+```c++
+paste the sketch here, even if it is an unmodified example code
+```
+
+
+
**Expected behavior**
A clear and concise description of what you expected to happen.
@@ -27,4 +47,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]
- Wireless module type [e.g. CC1101, SX1268, etc.]
- Arduino IDE version [e.g. 1.8.5]
- - Library version [e.g. 3.0.0]
+ - Library version [e.g. 3.0.0 or git hash]
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000000..8f41cab9f4
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,5 @@
+blank_issues_enabled: false
+contact_links:
+ - name: RadioLib Discussions
+ url: https://github.com/jgromes/RadioLib/discussions
+ about: Please ask generic questions here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index 4d2c9a3c7e..a01ef1684c 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -7,8 +7,8 @@ assignees: ''
---
-**IMPORTANT: Check the wiki**
-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.
+**IMPORTANT: Check the docs**
+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).
**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 [...]
diff --git a/.github/ISSUE_TEMPLATE/module-not-working.md b/.github/ISSUE_TEMPLATE/module-not-working.md
index 1b67e8d6fe..be93f67097 100644
--- a/.github/ISSUE_TEMPLATE/module-not-working.md
+++ b/.github/ISSUE_TEMPLATE/module-not-working.md
@@ -9,26 +9,40 @@ assignees: ''
**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.
-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.
+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).
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!
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).
-**Sketch that is causing the module fail**
+Sketch that is causing the module fail
+
```c++
paste the sketch here, even if it is an unmodified example code
```
+
+
+
**Hardware setup**
Wiring diagram, schematic, pictures etc.
**Debug mode output**
-Enable all [debug levels](https://github.com/jgromes/RadioLib/wiki/Debug-mode) and paste the Serial monitor output here.
+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`.
+
+Debug mode output
+
+
+```
+paste the debug output here
+```
+
+
+
**Additional info (please complete):**
- 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]
- Wireless module type [e.g. CC1101, SX1268, etc.]
- Arduino IDE version [e.g. 1.8.5]
- - Library version [e.g. 3.0.0]
+ - Library version [e.g. 3.0.0 or git hash]
diff --git a/.github/ISSUE_TEMPLATE/regular-issue.md b/.github/ISSUE_TEMPLATE/regular-issue.md
index 4e488b9a78..3e1b8d0742 100644
--- a/.github/ISSUE_TEMPLATE/regular-issue.md
+++ b/.github/ISSUE_TEMPLATE/regular-issue.md
@@ -9,7 +9,7 @@ assignees: ''
**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.
-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.
+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).
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!
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).
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 0000000000..0855981a27
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,14 @@
+## 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!
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index d95c71d9b6..a658899a2b 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -5,11 +5,14 @@ on:
branches: [master]
pull_request:
branches: [master]
+ workflow_dispatch:
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
+ permissions:
+ security-events: write
strategy:
fail-fast: false
@@ -18,20 +21,11 @@ jobs:
steps:
- name: Checkout repository
- 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' }}
+ uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
- uses: github/codeql-action/init@v1
+ uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
@@ -60,7 +54,7 @@ jobs:
- name: Build example
run:
- arduino-cli compile --libraries /home/runner/work/RadioLib --fqbn arduino:avr:uno $PWD/examples/SX126x/SX126x_Transmit/SX126x_Transmit.ino --warnings=all
+ arduino-cli compile --libraries /home/runner/work/RadioLib --fqbn arduino:avr:uno $PWD/examples/SX123x/SX123x_Transmit_Blocking/SX123x_Transmit_Blocking.ino --warnings=all
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v1
+ uses: github/codeql-action/analyze@v3
diff --git a/.github/workflows/cppcheck.yml b/.github/workflows/cppcheck.yml
new file mode 100644
index 0000000000..2c3edf88e4
--- /dev/null
+++ b/.github/workflows/cppcheck.yml
@@ -0,0 +1,25 @@
+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
diff --git a/.github/workflows/doxygen.yml b/.github/workflows/doxygen.yml
index ae64566798..5ebdd8608d 100644
--- a/.github/workflows/doxygen.yml
+++ b/.github/workflows/doxygen.yml
@@ -13,7 +13,7 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install -y doxygen
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Generate docs
run: doxygen Doxyfile
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 1933b5bd70..977edb42a4 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -6,16 +6,16 @@ on:
pull_request:
branches: [ master ]
workflow_dispatch:
-
-jobs:
-
- build:
- strategy:
- matrix:
- board:
- - arduino:avr:uno
+ inputs:
+ id:
+ description: The ID of the platform on which the build is run
+ required: true
+ default: arduino:avr:mega
+ type: choice
+ options:
+ - all
+ - none
- arduino:avr:mega
- - arduino:avr:leonardo
- arduino:mbed:nano33ble
- arduino:mbed:envie_m4
- arduino:megaavr:uno2018
@@ -26,18 +26,114 @@ jobs:
- esp32:esp32:esp32
- esp8266:esp8266:generic
- Intel:arc32:arduino_101
- - SparkFun:apollo3:sfe_artemis
- - STM32:stm32:GenF3
+ - STMicroelectronics:stm32:GenF3:pnum=BLACKPILL_F303CC
+ - STMicroelectronics:stm32:Nucleo_64:pnum=NUCLEO_WL55JC1
- stm32duino:STM32F1:mapleMini
- MegaCoreX:megaavr:4809
- arduino:mbed_rp2040:pico
+ - rp2040:rp2040:rpipico
+ - CubeCell:CubeCell:CubeCell-Board
+ - MegaCore:avr:1281
+ - teensy:avr:teensy41
+ - arduino:renesas_uno:minima
+ - SiliconLabs:silabs:xg24explorerkit
+
+jobs:
+ build:
+ strategy:
+ matrix:
+ # platform-dependent settings - extra board options, board index URLs, skip patterns etc.
+ include:
+ - id: arduino:avr:mega
+ run: |
+ echo "options=':cpu=atmega2560'" >> $GITHUB_OUTPUT
+ echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
+ - id: arduino:mbed:nano33ble
+ - id: arduino:mbed:envie_m4
+ - id: arduino:megaavr:uno2018
+ run: |
+ echo "options=':mode=on'" >> $GITHUB_OUTPUT
+ echo "skip-pattern=(STM32WL|LoRaWAN|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
+ - id: arduino:sam:arduino_due_x
+ - id: arduino:samd:arduino_zero_native
+ run: |
+ echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
+ - id: adafruit:samd:adafruit_feather_m0
+ run: |
+ 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 "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
+ - id: adafruit:nrf52:feather52832
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y python3 python3-pip python3-setuptools
+ pip3 install wheel
+ pip3 install --user adafruit-nrfutil
+ echo "/home/runner/.local/bin" >> $GITHUB_PATH
+ 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 "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
+ - id: esp32:esp32:esp32
+ run: |
+ 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
+ - id: esp8266:esp8266:generic
+ 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 "index-url=--additional-urls http://arduino.esp8266.com/stable/package_esp8266com_index.json" >> $GITHUB_OUTPUT
+ - id: STMicroelectronics:stm32:GenF3
+ run: |
+ echo "options=':pnum=BLACKPILL_F303CC'" >> $GITHUB_OUTPUT
+ echo "index-url=--additional-urls https://raw.githubusercontent.com/stm32duino/BoardManagerFiles/main/package_stmicroelectronics_index.json" >> $GITHUB_OUTPUT
+ echo "skip-pattern=(STM32WL|LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
+ - id: STMicroelectronics:stm32:Nucleo_64
+ run: |
+ echo "options=':pnum=NUCLEO_WL55JC1'" >> $GITHUB_OUTPUT
+ # Do *not* skip STM32WL examples
+ echo "skip-pattern=(LR11x0_Firmware_Update)" >> $GITHUB_OUTPUT
+ echo "index-url=--additional-urls https://raw.githubusercontent.com/stm32duino/BoardManagerFiles/main/package_stmicroelectronics_index.json" >> $GITHUB_OUTPUT
+ - id: stm32duino:STM32F1:mapleMini
+ run: |
+ 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
+ - id: MegaCoreX:megaavr:4809
+ run: |
+ 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: rp2040:rp2040:rpipico
+ 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
+ run: |
+ 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
+ run: |
+ 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
+ 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
- name: ${{ matrix.board }}
+ name: ${{ matrix.id }}
env:
- run-build: ${{ (matrix.board == '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.board)) }}
+ 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 }}
steps:
+ - name: Free Disk Space (Ubuntu)
+ uses: jlumbroso/free-disk-space@v1.3.1
+
- name: Install arduino-cli
if: ${{ env.run-build == 'true' }}
run:
@@ -51,7 +147,7 @@ jobs:
uses: jungwinter/split@v1
id: split
with:
- msg: ${{ matrix.board }}
+ msg: ${{ matrix.id }}
seperator: ':'
- name: Prepare platform-specific settings
@@ -59,105 +155,211 @@ jobs:
id: prep
run:
|
- # common settings - no extra options, skip nothing, all warnings
- echo "::set-output name=options::"
- echo "::set-output name=skip-pattern::''"
- echo "::set-output name=warnings::'all'"
-
- # platform-dependent settings - extra board options, board index URLs, skip patterns etc.
- if [[ "${{ contains(matrix.board, 'arduino:avr:mega') }}" == "true" ]]; then
- # Arduino Mega
- echo "::set-output name=options:::cpu=atmega2560"
-
- elif [[ "${{ contains(matrix.board, 'arduino:mbed') }}" == "true" ]]; then
- # Arduino Nano 33 BLE
- echo "::set-output name=skip-pattern::(HTTP|MQTT).*ino"
-
- elif [[ "${{ contains(matrix.board, 'arduino-beta:mbed') }}" == "true" ]]; then
- # Arduino Portenta H7
- echo "::set-output name=skip-pattern::(HTTP|MQTT).*ino"
-
- elif [[ "${{ contains(matrix.board, 'arduino:megaavr:uno2018') }}" == "true" ]]; then
- # Arduino Uno WiFi
- echo "::set-output name=options:::mode=on"
-
- elif [[ "${{ contains(matrix.board, 'adafruit:samd') }}" == "true" ]]; then
- # Adafruit SAMD
- echo "::set-output name=options:::usbstack=arduino,debug=off"
- echo "::set-output name=index-url::--additional-urls https://www.adafruit.com/package_adafruit_index.json"
-
- elif [[ "${{ contains(matrix.board, 'adafruit:nrf52') }}" == "true" ]]; then
- # Adafruit Feather nRF52
- sudo apt-get update
- sudo apt-get install -y python3 python3-pip python3-setuptools
- pip3 install wheel
- pip3 install --user adafruit-nrfutil
- echo "/home/runner/.local/bin" >> $GITHUB_PATH
- echo "::set-output name=options:::softdevice=s132v6,debug=l0"
- echo "::set-output name=index-url::--additional-urls https://www.adafruit.com/package_adafruit_index.json"
-
- elif [[ "${{ contains(matrix.board, 'esp32:esp32') }}" == "true" ]]; then
- # ESP32
- python -m pip install pyserial
- echo "::set-output name=index-url::--additional-urls https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json"
-
- elif [[ "${{ contains(matrix.board, 'esp8266:esp8266') }}" == "true" ]]; then
- # ESP8266
- echo "::set-output name=options:::xtal=80,ResetMethod=ck,CrystalFreq=26,FlashFreq=40,FlashMode=qio,eesz=512K"
- echo "::set-output name=index-url::--additional-urls http://arduino.esp8266.com/stable/package_esp8266com_index.json"
- echo "::set-output name=skip-pattern::(HTTP|MQTT).*ino"
-
- elif [[ "${{ contains(matrix.board, 'SparkFun:apollo3') }}" == "true" ]]; then
- # SparkFun Apollo
- echo "::set-output name=index-url::--additional-urls https://raw.githubusercontent.com/sparkfun/Arduino_Apollo3/master/package_sparkfun_apollo3_index.json"
- echo "::set-output name=warnings::'none'"
- echo "::set-output name=skip-pattern::(HTTP|MQTT).*ino"
-
- elif [[ "${{ contains(matrix.board, 'STM32:stm32') }}" == "true" ]]; then
- # STM32 (official core)
- echo "::set-output name=options:::pnum=BLACKPILL_F303CC"
- echo "::set-output name=index-url::--additional-urls https://github.com/stm32duino/BoardManagerFiles/raw/master/STM32/package_stm_index.json"
-
- elif [[ "${{ contains(matrix.board, 'stm32duino:STM32F1') }}" == "true" ]]; then
- # STM32 (unofficial core)
- echo "::set-output name=options:::bootloader_version=original,cpu_speed=speed_72mhz"
- echo "::set-output name=index-url::--additional-urls http://dan.drown.org/stm32duino/package_STM32duino_index.json"
-
- elif [[ "${{ contains(matrix.board, 'MegaCoreX:megaavr') }}" == "true" ]]; then
- # MegaCoreX
- echo "::set-output name=index-url::--additional-urls https://mcudude.github.io/MegaCoreX/package_MCUdude_MegaCoreX_index.json"
+ # common settings - no extra options, skip STM32WL examples, all warnings
+ echo "options=''" >> $GITHUB_OUTPUT
+ echo "skip-pattern=STM32WL" >> $GITHUB_OUTPUT
+ echo "warnings=all" >> $GITHUB_OUTPUT
- fi
+ # run platform-dependent scripts defined in matrix
+ ${{ matrix.run }}
- name: Install platform
if: ${{ env.run-build == 'true' }}
run:
|
arduino-cli core update-index ${{ format('{0}', 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) }}
+ 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) }}
+ 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
if: ${{ env.run-build == 'true' }}
- uses: actions/checkout@v2
+ uses: actions/checkout@v4
- name: Build examples
if: ${{ env.run-build == 'true' }}
run:
|
- for example in $(find $PWD/examples -name '*.ino' | sort); do
- # check whether to skip this sketch
- if [ ! -z '${{ steps.prep.outputs.skip-pattern }}' ] && [[ ${example} =~ ${{ steps.prep.outputs.skip-pattern }} ]]; then
- # skip sketch
- echo -e "\n\033[1;33mSkipped ${example##*/} (matched with ${{ steps.prep.outputs.skip-pattern }})\033[0m";
- else
- # build sketch
- echo -e "\n\033[1;33mBuilding ${example##*/} ... \033[0m";
- arduino-cli compile --libraries /home/runner/work/RadioLib --fqbn ${{ matrix.board }}${{ steps.prep.outputs.options }} $example --warnings=${{ steps.prep.outputs.warnings }}
- if [ $? -ne 0 ]; then
- echo -e "\033[1;31m${example##*/} build FAILED\033[0m\n";
- exit 1;
- else
- echo -e "\033[1;32m${example##*/} build PASSED\033[0m\n";
- fi
- fi
- done
+ cd $PWD/extras/test/ci
+ ./build_examples.sh ${{ matrix.id }} "${{ steps.prep.outputs.skip-pattern }}" ${{ steps.prep.outputs.options }}
+
+ - name: Extract short commit hash
+ id: short-hash
+ run: echo "::set-output name=short_sha::$(git rev-parse --short HEAD)"
+
+ - name: Parse sizes
+ if: ${{ env.run-build == 'true' }}
+ run:
+ |
+ cd $PWD/extras/test/ci
+ ./parse_size.sh ${{ matrix.id }}
+ cat size_${{ steps.short-hash.outputs.short_sha }}_${{ steps.split.outputs._0 }}-${{ steps.split.outputs._1 }}-${{ steps.split.outputs._2 }}.csv
+
+ - name: Upload size report as artifact
+ uses: actions/upload-artifact@v4
+ 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:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Install dependencies
+ run: |
+ 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
+ run: |
+ rm -rf ~/esp
+ mkdir -p ~/esp
+ cd ~/esp
+ git clone https://github.com/espressif/esp-idf.git
+ cd esp-idf
+ git checkout v5.4.3
+ git submodule update --init --recursive
+
+ - name: Install ESP-IDF
+ run: |
+ cd ~/esp/esp-idf
+ ./install.sh esp32
+
+ - name: Build the example
+ run: |
+ cd $PWD/examples/NonArduino/ESP-IDF
+ . ~/esp/esp-idf/export.sh
+ idf.py build
+
+ tock-build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ submodules: recursive
+
+ - name: Setup Rust
+ uses: dtolnay/rust-toolchain@stable
+
+ - name: Install dependencies
+ run: |
+ sudo apt-get install -y gcc-arm-none-eabi gcc-riscv64-unknown-elf
+ cargo install elf2tab
+
+ - name: Build the example
+ run: |
+ cd $PWD/examples/NonArduino/Tock
+ git clone https://github.com/tock/libtock-c.git
+ cd libtock-c; git checkout c0202f9ab78da4a6e95f136cf5250701e3778f63; cd ../
+ LIBTOCK_C_DIRECTORY="$(pwd)/libtock-c" ./build.sh
+
+ rpi-build:
+ if: false # self-hosted runner temporarily disabled
+ runs-on: [self-hosted, ARM64]
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y cmake wget swig python-dev python3-dev python-setuptools python3-setuptools
+ 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
+ run: |
+ cd $PWD
+ mkdir build
+ cd build
+ cmake ..
+ sudo make install
+
+ - name: Build the example
+ run: |
+ cd $PWD/examples/NonArduino/Raspberry
+ ./build.sh
+
+ rpi-test:
+ if: false # self-hosted runner temporarily disabled
+ needs: rpi-build
+ runs-on: [self-hosted, ARM64]
+ steps:
+ - name: SX126x test
+ run: |
+ cd $PWD/extras/test/SX126x
+ ./clean.sh
+ ./build.sh
+ sudo ./build/rpi-sx1261
+
+ rpi-pico-build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Install dependencies
+ run: |
+ sudo apt update
+ sudo apt install git cmake gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib
+
+ - name: Clone the SDK
+ run: |
+ mkdir -p ~/rpi-pico
+ cd ~/rpi-pico
+ git clone https://github.com/raspberrypi/pico-sdk.git
+ cd pico-sdk && git checkout 2.2.0
+
+ - name: Build the example
+ run: |
+ export PICO_SDK_PATH=~/rpi-pico/pico-sdk
+ cd $PWD/examples/NonArduino/Pico
+ ./build.sh
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000000..c8ce82d0e1
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,37 @@
+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
diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml
new file mode 100644
index 0000000000..74b53f2d14
--- /dev/null
+++ b/.github/workflows/static.yml
@@ -0,0 +1,46 @@
+name: "Static Memory Management Test"
+
+on:
+ push:
+ branches: [master]
+ pull_request:
+ branches: [master]
+ workflow_dispatch:
+
+jobs:
+ static-memory:
+ name: Build Arduino and non-Arduino with enabled static memory management
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Install dependencies for unit test
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y libboost-all-dev libfmt-dev lcov
+
+ - name: Run unit test for static memory management
+ run: |
+ cd extras/test/unit
+ ./test.sh -DRADIOLIB_STATIC_ONLY
+
+ - name: Install arduino-cli
+ run:
+ |
+ mkdir -p ~/.local/bin
+ echo "~/.local/bin" >> $GITHUB_PATH
+ curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=~/.local/bin sh
+
+ - name: Install platform
+ run:
+ |
+ arduino-cli core update-index
+ arduino-cli core install arduino:avr
+
+ - name: Build Arduino example
+ run:
+ arduino-cli compile --libraries /home/runner/work/RadioLib --fqbn arduino:avr:mega $PWD/examples/SX123x/SX123x_Transmit_Blocking/SX123x_Transmit_Blocking.ino --warnings=all --build-property compiler.cpp.extra_flags="-DRADIOLIB_STATIC_ONLY"
+
+
diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml
new file mode 100644
index 0000000000..b46a5160f0
--- /dev/null
+++ b/.github/workflows/unit-test.yml
@@ -0,0 +1,48 @@
+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
diff --git a/.gitignore b/.gitignore
index 58d337967a..db0e8bbf71 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,12 +5,17 @@
*.tags
*.tags1
+# VS Code
+.vscode
+
# Jetbrain IDEs
.idea
-# Debug decoder
-extras/decoder/log.txt
-extras/decoder/out.txt
-
# PlatformIO
.pio*
+
+# cmake
+build/
+
+# Compote build output
+dist
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000000..b208f79d37
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,52 @@
+cmake_minimum_required(VERSION 3.13)
+
+# first gather the files since this is needed for both ESP-IDF as well as other builds
+file(GLOB_RECURSE RADIOLIB_SOURCES
+ "src/*.cpp"
+)
+
+# exclude all HAL source files
+list(FILTER RADIOLIB_SOURCES EXCLUDE REGEX "src/hal/.*\\.cpp")
+
+if(ESP_PLATFORM)
+ # Build RadioLib as an ESP-IDF component
+ # required because ESP-IDF runs cmake in script mode
+ # and needs idf_component_register()
+
+ idf_component_register(
+ SRCS ${RADIOLIB_SOURCES}
+ INCLUDE_DIRS . src
+ )
+
+ return()
+endif()
+
+if(CMAKE_SCRIPT_MODE_FILE)
+ message(FATAL_ERROR "Attempted to build RadioLib in script mode")
+endif()
+
+project(radiolib)
+
+add_library(RadioLib ${RADIOLIB_SOURCES})
+
+target_include_directories(RadioLib
+ PUBLIC $
+ $)
+
+# 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)
+
+install(TARGETS RadioLib
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/RadioLib
+ FILES_MATCHING PATTERN "*.h"
+)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 563d444fb5..71e69586a6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -16,6 +16,19 @@ Issues with generic titles (e.g. "not working", "lora", etc.) will be **CLOSED**
4. **Issues deserve some attention too.**
Issues that are left for 2 weeks without response by the original author when asked for further information will be closed due to inactivity. This is to keep track of important issues, the author is encouraged to reopen the issue at a later date.
+## AI Use
+
+**RadioLib was written by humans, for humans**. Its authors, contributors, maintainers and community members were not asked for permission or approval when billion-dollar companies decided to scrape our hard work for training data, to be sold back to the world at a profit. While we consider this approach to be bordering on violating our license, this seems to be the world we live in. Therefore, if you decide to contribute to RadioLib while using an AI-based tool, please follow the rules below.
+
+1. **Mark the slop**
+The issue or pull request must be clearly marked as fully or partially AI-generated. If you don't do it, we'll do it for you by the means of a dedicated label - and then consider whether to process your input at all. Since people like that have not even bothered to read this statement, it would be unreasonable to expect they will read the code the machine generated and that is not code we want.
+2. **Less is more**
+If your AI has produced a novel-length wall of text to describe a miniscule change, we consider it somewhat rude to copy-paste that output into the issue/PR description. Not only are you ignoring the templates which are asking for generally useful info; this approach also has the added bonus of explaining our own codebase back to us, while trying to sound as simple as possible. In reality though, it sounds like a junior developer giving us a lecture on a project that is older then they are. So please, try to get the actual point across in your own, human-generated words.
+3. **Discuss first**
+It is usually not a great idea to hit us with a large, unsolicited pull request. Especially if it changes APIs or tries to work around something. It's a lot easier to discuss these things in advance and agree on an approach in an issue. Your AI can write the PR quickly; but then we need to spend our free time on reviewing something that we did not ask for.
+
+RadioLib maintainers reserve the right to reject your contribution if it is not following these rules without further explanation other than directing you to this guideline document.
+
## Code style guidelines
I like pretty code! Or at least, I like *consistent* code style. When creating pull requests, please follow these style guidelines, they're in place to keep high code readability.
@@ -52,7 +65,7 @@ It is very easy to write code that machine can read. It is much harder to write
// build a temporary buffer (first block)
uint8_t* data = new uint8_t[len + 1];
if(!data) {
- return(ERR_MEMORY_ALLOCATION_FAILED);
+ return(RADIOLIB_ERR_MEMORY_ALLOCATION_FAILED);
}
// read the received data (second block)
@@ -73,12 +86,12 @@ Sometimes, RadioLib might be used in critical applications where dynamic memory
```c++
// build a temporary buffer
-#ifdef RADIOLIB_STATIC_ONLY
+#if defined(RADIOLIB_STATIC_ONLY)
uint8_t data[RADIOLIB_STATIC_ARRAY_SIZE + 1];
#else
uint8_t* data = new uint8_t[length + 1];
if(!data) {
- return(ERR_MEMORY_ALLOCATION_FAILED);
+ return(RADIOLIB_ERR_MEMORY_ALLOCATION_FAILED);
}
#endif
@@ -86,7 +99,7 @@ Sometimes, RadioLib might be used in critical applications where dynamic memory
readData(data, length);
// deallocate temporary buffer
-#ifndef RADIOLIB_STATIC_ONLY
+#if !defined(RADIOLIB_STATIC_ONLY)
delete[] data;
#endif
```
@@ -98,7 +111,7 @@ During development, it can be useful to have access to the low level drivers, su
class Module {
void publicMethod();
-#ifndef RADIOLIB_GODMODE
+#if defined(RADIOLIB_GODMODE)
private:
#endif
diff --git a/Doxyfile b/Doxyfile
index 3c1d2d186c..db6d223b33 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -2172,7 +2172,8 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-PREDEFINED = protected=private
+PREDEFINED = protected=private \
+ DOXYGEN
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
diff --git a/README.md b/README.md
index 5f15e08111..218bb151fd 100644
--- a/README.md
+++ b/README.md
@@ -1,56 +1,70 @@
-# RadioLib 
+# RadioLib  [](https://registry.platformio.org/libraries/jgromes/RadioLib) [](https://components.espressif.com/components/jgromes/radiolib)
### _One radio library to rule them all!_
-## Universal wireless communication library for Arduino
-
-## See the [Wiki](https://github.com/jgromes/RadioLib/wiki) for further information. See the [GitHub Pages](https://jgromes.github.io/RadioLib) for detailed and up-to-date API reference.
+## Universal wireless communication library for embedded devices
RadioLib allows its users to integrate all sorts of different wireless communication modules, protocols and even digital modes into a single consistent system.
Want to add a Bluetooth interface to your LoRa network? Sure thing! Do you just want to go really old-school and play around with radio teletype, slow-scan TV, or even Hellschreiber using nothing but a cheap radio module? Why not!
-RadioLib 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 Arduino can handle!
+RadioLib natively supports Arduino, but can run in non-Arduino environments as well! See [this Wiki page](https://github.com/jgromes/RadioLib/wiki/Porting-to-non-Arduino-Platforms) and [examples/NonArduino](https://github.com/jgromes/RadioLib/tree/master/examples/NonArduino).
+
+RadioLib was originally created as a driver for [__RadioShield__](https://github.com/jgromes/RadioShield), but it can be used to control as many different wireless modules as you like - or at least as many as your microcontroller can handle!
+
+### Quick links:
+* [__Wiki__](https://github.com/jgromes/RadioLib/wiki) - contains useful general information on using this library
+* [__FAQ__](https://github.com/jgromes/RadioLib/wiki/Frequently-Asked-Questions) - frequently asked questions, and answers
+* [__API Reference__](https://jgromes.github.io/RadioLib) - full API reference, automatically generated from the source code
+* [__Status Code Decoder__](https://radiolib-org.github.io/status_decoder/decode.html) - decoder for status codes returned by RadioLib methods
+* [__Debug Log Decoder__](https://radiolib-org.github.io/debug_decoder/decode.html) - decoder for RadioLib SPI debug logs
### Supported modules:
* __CC1101__ FSK radio module
-* __ESP8266__ WiFi module
-* __HC05__ Bluetooth module
-* __JDY08__ BLE module
* __LLCC68__ LoRa module
+* __LR11x0__ series LoRa/GFSK modules (LR1110, LR1120, LR1121)
+* __LR2021__ series LoRa/GFSK/LR-FHSS/FLRC/OOK modules
* __nRF24L01__ 2.4 GHz module
* __RF69__ FSK/OOK radio module
-* __RFM2x__ series FSK modules (RFM22, RM23)
-* __RFM9x__ series LoRa modules (RFM95, RM96, RFM97, RFM98)
+* __RFM2x__ series FSK modules (RFM22, RFM23)
+* __RFM9x__ series LoRa modules (RFM95, RFM96, RFM97, RFM98)
* __Si443x__ series FSK modules (Si4430, Si4431, Si4432)
+* __STM32WL__ integrated microcontroller/LoRa module
* __SX126x__ series LoRa modules (SX1261, SX1262, SX1268)
* __SX127x__ series LoRa modules (SX1272, SX1273, SX1276, SX1277, SX1278, SX1279)
* __SX128x__ series LoRa/GFSK/BLE/FLRC modules (SX1280, SX1281, SX1282)
-* __SX1231__ FSK/OOK radio module
-* __XBee__ modules (S2B)
+* __SX123x__ FSK/OOK radio modules (SX1231, SX1233)
### Supported protocols and digital modes:
-* __MQTT__ for modules:
-ESP8266
-* __HTTP__ for modules:
-ESP8266
-* __AX.25__ using 2-FSK or AFSK for modules:
-SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, RFM2x and Si443x
+* [__ADS-B__](https://mode-s.org/1090mhz/content/ads-b/1-basics.html) using OOK for LR2021
+* [__AX.25__](https://www.sigidwiki.com/wiki/PACKET) using 2-FSK or AFSK for modules:
+SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, RFM2x, Si443x, LR11x0, LR2021 and SX128x
* [__RTTY__](https://www.sigidwiki.com/wiki/RTTY) using 2-FSK or AFSK for modules:
-SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x and SX128x
+SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x, LR11x0, LR2021 and SX128x
* [__Morse Code__](https://www.sigidwiki.com/wiki/Morse_Code_(CW)) using 2-FSK or AFSK for modules:
-SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x and SX128x
+SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x, LR11x0, LR2021 and SX128x
* [__SSTV__](https://www.sigidwiki.com/wiki/SSTV) using 2-FSK or AFSK for modules:
SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, RFM2x and Si443x
* [__Hellschreiber__](https://www.sigidwiki.com/wiki/Hellschreiber) using 2-FSK or AFSK for modules:
+SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x, LR11x0, LR2021 and SX128x
+* [__APRS__](https://www.sigidwiki.com/wiki/APRS) using AFSK for modules:
SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x and SX128x
-
-### Supported platforms:
+* [__POCSAG__](https://www.sigidwiki.com/wiki/POCSAG) using 2-FSK for modules:
+SX127x, RFM9x, RF69, SX1231, CC1101, nRF24L01, RFM2x and Si443x
+* [__LoRaWAN__](https://lora-alliance.org/) using LoRa and FSK for modules:
+SX127x, RFM9x, SX126x, LR11x0, LR2021 and SX128x
+ * Supports Class A and C (and Multicast over C).
+ * Pre-certified for Class A.
+ * See the [wiki](https://github.com/jgromes/RadioLib/wiki/LoRaWAN) and [notes](https://github.com/jgromes/RadioLib/blob/master/examples/LoRaWAN/LoRaWAN_Starter/notes.md) for more information.
+
+### Supported Arduino platforms:
* __Arduino__
* [__AVR__](https://github.com/arduino/ArduinoCore-avr) - Arduino Uno, Mega, Leonardo, Pro Mini, Nano etc.
+ * NOTE: Arduino boards based on ATmega328 (Uno, Pro Mini, Nano etc.) and smaller are NOT recommended. This is because the ATmega328 MCU is very constrained in terms of program and memory size, so the library will end up taking most of the space available.
* [__mbed__](https://github.com/arduino/ArduinoCore-mbed) - Arduino Nano 33 BLE and Arduino Portenta H7
* [__megaAVR__](https://github.com/arduino/ArduinoCore-megaavr) - Arduino Uno WiFi Rev.2 and Nano Every
* [__SAM__](https://github.com/arduino/ArduinoCore-sam) - Arduino Due
* [__SAMD__](https://github.com/arduino/ArduinoCore-samd) - Arduino Zero, MKR boards, M0 Pro etc.
+ * [__Renesas__](https://github.com/arduino/ArduinoCore-renesas) - Arduino Uno R4
* __Adafruit__
* [__SAMD__](https://github.com/adafruit/ArduinoCore-samd) - Adafruit Feather M0 and M4 boards (Feather, Metro, Gemma, Trinket etc.)
@@ -72,25 +86,20 @@ SX127x, RFM9x, SX126x, RF69, SX1231, CC1101, nRF24L01, RFM2x, Si443x and SX128x
* __MCUdude__
* [__MegaCoreX__](https://github.com/MCUdude/MegaCoreX) - megaAVR-0 series (ATmega4809, ATmega3209 etc.)
+ * [__MegaCore__](https://github.com/MCUdude/MegaCore) - AVR (ATmega1281, ATmega640 etc.)
* __Raspberry Pi__
- * [__RP2040__](https://github.com/arduino/ArduinoCore-mbed) - Raspberry Pi Pico and Arduino Nano RP2040 Connect
-
-The list above is by no means exhaustive. Most of RadioLib code is independent of the used platform, so as long as your board is running some Arduino-compatible core, RadioLib should work. Compilation of all examples is tested for all platforms prior to releasing new version.
-
-### In development:
-* __SIM800C__ GSM module
-* __LoRaWAN__ protocol for SX127x, RFM9x and SX126x modules
-* __APRS__ protocol for all the modules that can transmit AX.25
-* ___and more!___
+ * [__RP2040__ (official core)](https://github.com/arduino/ArduinoCore-mbed) - Raspberry Pi Pico and Arduino Nano RP2040 Connect
+ * [__RP2040__ (unofficial core)](https://github.com/earlephilhower/arduino-pico) - Raspberry Pi Pico/RP2040-based boards
+ * [__Raspberry Pi__](https://github.com/me-no-dev/RasPiArduino) - Arduino framework for RaspberryPI
-## Frequently Asked Questions
+* __Heltec__
+ * [__CubeCell__](https://github.com/HelTecAutomation/CubeCell-Arduino) - ASR650X series (CubeCell-Board, CubeCell-Capsule, CubeCell-Module etc.)
-### Where should I start?
-First of all, take a look at the [examples](https://github.com/jgromes/RadioLib/tree/master/examples) and the [Wiki](https://github.com/jgromes/RadioLib/wiki) - especially the [Basics](https://github.com/jgromes/RadioLib/wiki/Basics) page. There's a lot of useful information over there. If something isn't working as expected, try searching the [issues](https://github.com/jgromes/RadioLib/issues/).
+* __PJRC__
+ * [__Teensy__](https://github.com/PaulStoffregen/cores) - Teensy 2.x, 3.x and 4.x boards
-### Help, my module isn't working!
-The fastest way to get help is by creating an [issue](https://github.com/jgromes/RadioLib/issues/new/choose) using the appropriate template. It is also highly recommended to try running the examples first - their functionality is tested from time to time and they should work. Finally, RadioLib is still under development, which means that sometimes, backwards-incompatible changes might be introduced. Though these are kept at minimum, sometimes it is unavoidable. You can check the [release changelog](https://github.com/jgromes/RadioLib/releases) to find out if there's been such a major change recently.
+* __Silicon Labs__
+ * [__EFR32__](https://github.com/SiliconLabs/arduino) - Silicon Labs xG24, xG27 and other boards
-### RadioLib doesn't support my module! What should I do?
-Start by creating new issue (if it doesn't exist yet). If you have some experience with Arduino and C/C++ in general, you can try to add the support yourself! Use the template files in `/extras/` folder to get started. This is by far the fastest way to implement new modules into RadioLib, since I can't be working on everything all the time. If you don't trust your programming skills enough to have a go at it yourself, don't worry. I will try to implement all requested modules, but it will take me a while.
+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.
diff --git a/examples/ADSB/ADSB_Monitor/ADSB_Monitor.ino b/examples/ADSB/ADSB_Monitor/ADSB_Monitor.ino
new file mode 100644
index 0000000000..5e9508e745
--- /dev/null
+++ b/examples/ADSB/ADSB_Monitor/ADSB_Monitor.ino
@@ -0,0 +1,166 @@
+/*
+ RadioLib ADS-B Monitor Example
+
+ This example shows how to receive ADS-B messages
+ using LR2021 OOK modem and forward them to be displayed
+ in a live dashboard.
+
+ To show the live dashboard in a terminal, run the Python script
+ RadioLib/extras/ADSB_Monitor/ADSBMonitorServer.py,
+ and then connect to from "modeslive" from the pyModeS package
+ (see the script helptext for installation instructions).
+
+ 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
+
+// LR2021 has the following connections:
+// NSS pin: 10
+// IRQ pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+LR2021 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
+Radio radio = new RadioModule();
+*/
+
+// create ADS-B client instance using the module
+ADSBClient adsb(&radio);
+
+// 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);
+
+ // LR2021 allows to use any DIO pin as the interrupt
+ // as an example, we set DIO10 to be the IRQ
+ // this has to be done prior to calling begin()!
+ radio.irqDioNum = 10;
+
+ // initialize LR2021 OOK modem at 1090 MHz,
+ // 2 Mbps bit rate and receiver bandwidth 3076 kHz
+ Serial.print(F("[LR2021] Initializing ... "));
+ int state = radio.beginOOK(1090, 2000, 3076);
+
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // initialize ADS-B client
+ Serial.print(F("[ADS-B] Initializing ... "));
+ state = adsb.begin();
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // apply LR2021-specific settings
+ Serial.print(F("[LR2021] Setting configuration ... "));
+ state = radio.setRxBoostedGainMode(7);
+ state += radio.setCRC(3, 0, 0x1FFF409UL, false);
+ state += radio.ookDetector();
+ state += radio.fixedPacketLengthMode(11);
+ state += radio.setGain(13);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // measure current noise floor and add some margin
+ // this values is later used to set the signal detection threshold
+ float threshold = radio.getRSSI(false) + 10;
+ Serial.print(F("[LR2021] Detection threshold: "));
+ Serial.print(threshold, 2);
+ Serial.println(F(" dBm"));
+
+ Serial.print(F("[LR2021] Setting threshold ... "));
+ state = radio.setOokDetectionThreshold(threshold);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // set the function that will be called
+ // when new packet is received
+ radio.setPacketReceivedAction(setFlag);
+
+ // start listening for LoRa packets
+ Serial.print(F("[LR2021] 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); }
+ }
+}
+
+void loop() {
+ // check if the flag is set
+ if(receivedFlag) {
+ // reset flag
+ receivedFlag = false;
+
+ // read the received binary data
+ // ADS-B frames have fixed length of 14 bytes,
+ // 3 of which are used as CRC which is handled automatically
+ uint8_t buff[11] = { 0 };
+ int state = radio.readData(buff, 11);
+
+ if (state == RADIOLIB_ERR_NONE) {
+ // packet was successfully received
+ // print it out, further processing is done by pyModeS
+ Serial.print(F("[ADS-B] "));
+ for(int i = 0; i < 11; i++) {
+ if(buff[i] < 0x10) { Serial.print('0'); }
+ Serial.print(buff[i], HEX);
+ }
+
+ // pyModeS expects the data to include the CRC
+ // but does not seem to be actually checking it
+ // since we handle CRC automatically, just append 3 null bytes
+ Serial.println(F("000000"));
+
+ }
+
+ }
+
+}
diff --git a/examples/ADSB/ADSB_Receive/ADSB_Receive.ino b/examples/ADSB/ADSB_Receive/ADSB_Receive.ino
new file mode 100644
index 0000000000..5bd25921eb
--- /dev/null
+++ b/examples/ADSB/ADSB_Receive/ADSB_Receive.ino
@@ -0,0 +1,223 @@
+/*
+ RadioLib ADS-B Reception Example
+
+ This example shows how to receive ADS-B messages
+ using LR2021 OOK modem.
+
+ 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
+
+// LR2021 has the following connections:
+// NSS pin: 10
+// IRQ pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+LR2021 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
+Radio radio = new RadioModule();
+*/
+
+// create ADS-B client instance using the module
+ADSBClient adsb(&radio);
+
+// 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);
+
+ // LR2021 allows to use any DIO pin as the interrupt
+ // as an example, we set DIO10 to be the IRQ
+ // this has to be done prior to calling begin()!
+ radio.irqDioNum = 10;
+
+ // initialize LR2021 OOK modem at 1090 MHz,
+ // 2 Mbps bit rate and receiver bandwidth 3076 kHz
+ Serial.print(F("[LR2021] Initializing ... "));
+ int state = radio.beginOOK(1090, 2000, 3076);
+
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // initialize ADS-B client
+ Serial.print(F("[ADS-B] Initializing ... "));
+ state = adsb.begin();
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // apply LR2021-specific settings
+ Serial.print(F("[LR2021] Setting configuration ... "));
+ state = radio.setRxBoostedGainMode(7);
+ state += radio.setCRC(3, 0, 0x1FFF409UL, false);
+ state += radio.ookDetector();
+ state += radio.fixedPacketLengthMode(11);
+ state += radio.setGain(13);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // measure current noise floor and add some margin
+ // this values is later used to set the signal detection threshold
+ float threshold = radio.getRSSI(false) + 10;
+ Serial.print(F("[LR2021] Detection threshold: "));
+ Serial.print(threshold, 2);
+ Serial.println(F(" dBm"));
+
+ Serial.print(F("[LR2021] Setting threshold ... "));
+ state = radio.setOokDetectionThreshold(threshold);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // set the reference position (position of the receiver)
+ // this will be used later to calculate the aircraft position
+ adsb.setReferencePosition(46.24722039359617f, 12.097993784412322f);
+
+ // set the function that will be called
+ // when new packet is received
+ radio.setPacketReceivedAction(setFlag);
+
+ // start listening for LoRa packets
+ Serial.print(F("[LR2021] 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); }
+ }
+}
+
+// these variables will be used later to save decoded information
+ADSBFrame frame;
+ADSBAircraftCategory category;
+char callsign[RADIOLIB_ADSB_CALLSIGN_LEN];
+char hexId[RADIOLIB_ADSB_HEX_ID_LEN];
+ADSBAircraftCategory cat;
+int alt;
+float lat, lon;
+bool altGnss;
+
+void loop() {
+ // check if the flag is set
+ if(receivedFlag) {
+ // reset flag
+ receivedFlag = false;
+
+ // read the received binary data
+ // ADS-B frames have fixed length of 14 bytes,
+ // 3 of which are used as CRC which is handled automatically
+ uint8_t buff[11] = { 0 };
+ int state = radio.readData(buff, 11);
+
+ if (state == RADIOLIB_ERR_NONE) {
+ // packet was successfully received
+ Serial.println(F("[LR2021] Received packet!"));
+
+ state = adsb.decode(buff, &frame);
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("[ADS-B] Decoded frame!"));
+ // print the decoded information
+ Serial.print(F("[ADS-B] DF = "));
+ Serial.println(frame.downlinkFormat);
+ Serial.print(F("[ADS-B] CA = "));
+ Serial.println(frame.capability);
+ Serial.print(F("[ADS-B] Message type = "));
+ Serial.println((int)frame.messageType);
+
+ // get the hexadecimal ID (ICAO address) of the transceiver
+ state = adsb.parseHexId(&frame, hexId);
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.print(F("[ADS-B] Hex ID = "));
+ Serial.println(hexId);
+ }
+
+ // further information depends on the message type
+ switch(frame.messageType) {
+ case(ADSBMessageType::AIRCRAFT_ID):
+ adsb.parseCallsign(&frame, callsign, &cat);
+ Serial.print(F("[ADS-B] Callsign = "));
+ Serial.println(callsign);
+ Serial.print(F("[ADS-B] Category = "));
+ Serial.println((int)category);
+ break;
+
+ case(ADSBMessageType::AIRBORNE_POS_ALT_BARO):
+ case(ADSBMessageType::AIRBORNE_POS_ALT_GNSS):
+ adsb.parseAirbornePosition(&frame, &alt, &lat, &lon, &altGnss);
+ Serial.print(F("[ADS-B] Altitude = "));
+ Serial.print(alt);
+ if(altGnss) { Serial.println(" meters\n"); } else { Serial.println(" feet\n"); }
+ Serial.print(F("[ADS-B] Latitude = "));
+ Serial.println(lat, 6);
+ Serial.print(F("[ADS-B] Longitude = "));
+ Serial.println(lon, 6);
+ break;
+
+ default:
+ break;
+
+ }
+
+ } else {
+ Serial.print(F("[ADS-B] Failed to decode, code "));
+ Serial.println(state);
+
+ }
+
+
+ } 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);
+
+ }
+ }
+}
diff --git a/examples/AFSK/AFSK_External_Radio/AFSK_External_Radio.ino b/examples/AFSK/AFSK_External_Radio/AFSK_External_Radio.ino
new file mode 100644
index 0000000000..012d1e20ff
--- /dev/null
+++ b/examples/AFSK/AFSK_External_Radio/AFSK_External_Radio.ino
@@ -0,0 +1,94 @@
+/*
+ RadioLib AFSK External Radio example
+
+ This example shows how to use your Arduino
+ as modulator for an external analogue FM radio.
+
+ The example sends APRS position reports with
+ audio modulated as AFSK at 1200 baud using
+ Bell 202 tones. However, any other AFSK
+ protocol (RTTY, SSTV, etc.) may be used as well.
+
+ DO NOT transmit in APRS bands unless
+ you have a ham radio license!
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// create a dummy radio module
+ExternalRadio radio;
+
+// create AFSK client instance using the external radio
+// pin 5 is connected to the radio sound input
+AFSKClient audio(&radio, 5);
+
+// create AX.25 client instance using the AFSK instance
+AX25Client ax25(&audio);
+
+// create APRS client instance using the AX.25 client
+APRSClient aprs(&ax25);
+
+void setup() {
+ Serial.begin(9600);
+
+ // initialize AX.25 client
+ Serial.print(F("[AX.25] Initializing ... "));
+ // source station callsign: "N7LEM"
+ // source station SSID: 0
+ // preamble length: 8 bytes
+ int16_t state = ax25.begin("N7LEM");
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // initialize APRS client
+ Serial.print(F("[APRS] Initializing ... "));
+ // symbol: '>' (car)
+ state = aprs.begin('>');
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+}
+
+void loop() {
+ Serial.print(F("[APRS] Sending position ... "));
+
+ // send a location without message or timestamp
+ char destination[] = "N0CALL";
+ char latitude[] = "4911.67N";
+ char longitude[] = "01635.96E";
+ int state = aprs.sendPosition(destination, 0, latitude, longitude);
+ delay(500);
+
+ // send a location with message and without timestamp
+ char message[] = "I'm here!";
+ state |= aprs.sendPosition(destination, 0, latitude, longitude, message);
+ delay(500);
+
+ // send a location with message and timestamp
+ char timestamp[] = "093045z";
+ state |= aprs.sendPosition(destination, 0, latitude, longitude, message, timestamp);
+ delay(500);
+
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ }
+
+ // wait one minute before transmitting again
+ delay(60000);
+}
diff --git a/examples/AFSK/AFSK_Imperial_March/AFSK_Imperial_March.ino b/examples/AFSK/AFSK_Imperial_March/AFSK_Imperial_March.ino
index ebe8b1a91f..c52dbe5f2a 100644
--- a/examples/AFSK/AFSK_Imperial_March/AFSK_Imperial_March.ino
+++ b/examples/AFSK/AFSK_Imperial_March/AFSK_Imperial_March.ino
@@ -1,20 +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:
- - SX127x/RFM9x
- - RF69
- - SX1231
- - CC1101
- - Si443x/RFM2x
+ Other modules that can be used for AFSK:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - Si443x/RFM2x
+ - SX126x/LLCC68
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration
+ For 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 full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -38,6 +39,7 @@ SX1278 radio = new Module(10, 2, 9, 3);
// SX1231: DIO2
// CC1101: GDO2
// Si443x/RFM2x: GPIO
+// SX126x/LLCC68: DIO2
AFSKClient audio(&radio, 5);
void setup() {
@@ -51,23 +53,23 @@ void setup() {
// (RF69, CC1101,, Si4432 etc.), use the basic begin() method
// int state = radio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// initialize AFSK client
Serial.print(F("[AFSK] Initializing ... "));
state = audio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
}
diff --git a/examples/AFSK/AFSK_Imperial_March/melody.h b/examples/AFSK/AFSK_Imperial_March/melody.h
index e4b151696b..64023de9d6 100644
--- a/examples/AFSK/AFSK_Imperial_March/melody.h
+++ b/examples/AFSK/AFSK_Imperial_March/melody.h
@@ -1,7 +1,7 @@
/*
- Note definitions, melody and melody-related functions
- adapted from https://github.com/robsoncouto/arduino-songs
- by Robson Couto, 2019
+ Note definitions, melody and melody-related functions
+ adapted from https://github.com/robsoncouto/arduino-songs
+ by Robson Couto, 2019
*/
#define NOTE_B0 31
@@ -95,16 +95,16 @@
#define NOTE_DS8 4978
#define REST 0
-// notes of the moledy followed by the duration.
+// notes of the melody followed by the duration.
// a 4 means a quarter note, 8 an eighteenth , 16 sixteenth, so on
// !!negative numbers are used to represent dotted notes,
// so -4 means a dotted quarter note, that is, a quarter plus an eighteenth!!
int melody[] = {
-
- // Darth Vader theme (Imperial March) - Star wars
+
+ // Darth Vader theme (Imperial March) - Star wars
// Score available at https://musescore.com/user/202909/scores/1141521
// The tenor saxophone part was used
-
+
NOTE_A4,-4, NOTE_A4,-4, NOTE_A4,16, NOTE_A4,16, NOTE_A4,16, NOTE_A4,16, NOTE_F4,8, REST,8,
NOTE_A4,-4, NOTE_A4,-4, NOTE_A4,16, NOTE_A4,16, NOTE_A4,16, NOTE_A4,16, NOTE_F4,8, REST,8,
NOTE_A4,4, NOTE_A4,4, NOTE_A4,4, NOTE_F4,-8, NOTE_C5,16,
@@ -112,17 +112,17 @@ int melody[] = {
NOTE_A4,4, NOTE_F4,-8, NOTE_C5,16, NOTE_A4,2,//4
NOTE_E5,4, NOTE_E5,4, NOTE_E5,4, NOTE_F5,-8, NOTE_C5,16,
NOTE_A4,4, NOTE_F4,-8, NOTE_C5,16, NOTE_A4,2,
-
- NOTE_A5,4, NOTE_A4,-8, NOTE_A4,16, NOTE_A5,4, NOTE_GS5,-8, NOTE_G5,16, //7
+
+ NOTE_A5,4, NOTE_A4,-8, NOTE_A4,16, NOTE_A5,4, NOTE_GS5,-8, NOTE_G5,16, //7
NOTE_DS5,16, NOTE_D5,16, NOTE_DS5,8, REST,8, NOTE_A4,8, NOTE_DS5,4, NOTE_D5,-8, NOTE_CS5,16,
NOTE_C5,16, NOTE_B4,16, NOTE_C5,16, REST,8, NOTE_F4,8, NOTE_GS4,4, NOTE_F4,-8, NOTE_A4,-16,//9
NOTE_C5,4, NOTE_A4,-8, NOTE_C5,16, NOTE_E5,2,
- NOTE_A5,4, NOTE_A4,-8, NOTE_A4,16, NOTE_A5,4, NOTE_GS5,-8, NOTE_G5,16, //7
+ NOTE_A5,4, NOTE_A4,-8, NOTE_A4,16, NOTE_A5,4, NOTE_GS5,-8, NOTE_G5,16, //7
NOTE_DS5,16, NOTE_D5,16, NOTE_DS5,8, REST,8, NOTE_A4,8, NOTE_DS5,4, NOTE_D5,-8, NOTE_CS5,16,
NOTE_C5,16, NOTE_B4,16, NOTE_C5,16, REST,8, NOTE_F4,8, NOTE_GS4,4, NOTE_F4,-8, NOTE_A4,-16,//9
NOTE_A4,4, NOTE_F4,-8, NOTE_C5,16, NOTE_A4,2,
-
+
};
diff --git a/examples/AFSK/AFSK_Tone/AFSK_Tone.ino b/examples/AFSK/AFSK_Tone/AFSK_Tone.ino
index 113576b3f6..ace105017a 100644
--- a/examples/AFSK/AFSK_Tone/AFSK_Tone.ino
+++ b/examples/AFSK/AFSK_Tone/AFSK_Tone.ino
@@ -1,21 +1,22 @@
/*
- RadioLib AFSK Example
+ RadioLib AFSK Example
- This example shows hot to send audio FSK tones
- using SX1278's FSK modem.
+ This example shows hot to send audio FSK tones
+ using SX1278's FSK modem.
- Other modules that can be used for AFSK:
- - SX127x/RFM9x
- - RF69
- - SX1231
- - CC1101
- - Si443x/RFM2x
+ Other modules that can be used for AFSK:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - Si443x/RFM2x
+ - SX126x/LLCC68
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration
+ For 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 full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -36,6 +37,7 @@ SX1278 radio = new Module(10, 2, 9, 3);
// SX1231: DIO2
// CC1101: GDO2
// Si443x/RFM2x: GPIO
+// SX126x/LLCC68: DIO2
AFSKClient audio(&radio, 5);
void setup() {
@@ -49,23 +51,23 @@ void setup() {
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
// int state = radio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// initialize AFSK client
Serial.print(F("[AFSK] Initializing ... "));
state = audio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
}
diff --git a/examples/AFSK/AFSK_Tone_AM/AFSK_Tone_AM.ino b/examples/AFSK/AFSK_Tone_AM/AFSK_Tone_AM.ino
index 7d780f42ca..3ae965baed 100644
--- a/examples/AFSK/AFSK_Tone_AM/AFSK_Tone_AM.ino
+++ b/examples/AFSK/AFSK_Tone_AM/AFSK_Tone_AM.ino
@@ -1,20 +1,20 @@
/*
- RadioLib AM-modulated AFSK Example
+ RadioLib AM-modulated AFSK Example
- This example shows hot to send AM-modulated
- audio FSK tones using SX1278's OOK modem.
+ This example shows hot to send AM-modulated
+ audio FSK tones using SX1278's OOK modem.
- Other modules that can be used for AFSK:
- - SX127x/RFM9x
- - RF69
- - SX1231
- - CC1101
+ Other modules that can be used for AFSK:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration
+ For 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 full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -46,34 +46,34 @@ void setup() {
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
// int state = radio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// initialize AFSK client
Serial.print(F("[AFSK] Initializing ... "));
state = audio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// after that, set mode to OOK
Serial.print(F("[SX1278] Switching to OOK ... "));
state = radio.setOOK(true);
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
}
diff --git a/examples/APRS/APRS_MicE/APRS_MicE.ino b/examples/APRS/APRS_MicE/APRS_MicE.ino
new file mode 100644
index 0000000000..414f5f3310
--- /dev/null
+++ b/examples/APRS/APRS_MicE/APRS_MicE.ino
@@ -0,0 +1,123 @@
+/*
+ RadioLib APRS Mic-E Example
+
+ This example sends APRS position reports
+ encoded in the Mic-E format using SX1278's
+ FSK modem. The data is modulated as AFSK
+ at 1200 baud using Bell 202 tones.
+
+ DO NOT transmit in APRS bands unless
+ you have a ham radio license!
+
+ Other modules that can be used for APRS:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - nRF24
+ - Si443x/RFM2x
+ - SX126x/LLCC68
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1278 has the following connections:
+// NSS pin: 10
+// DIO0 pin: 2
+// RESET pin: 9
+// DIO1 pin: 3
+SX1278 radio = new Module(10, 2, 9, 3);
+
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// create AFSK client instance using the FSK module
+// this requires connection to the module direct
+// input pin, here connected to Arduino pin 5
+// SX127x/RFM9x: DIO2
+// RF69: DIO2
+// SX1231: DIO2
+// CC1101: GDO2
+// Si443x/RFM2x: GPIO
+// SX126x/LLCC68: DIO2
+AFSKClient audio(&radio, 5);
+
+// create AX.25 client instance using the AFSK instance
+AX25Client ax25(&audio);
+
+// create APRS client instance using the AX.25 client
+APRSClient aprs(&ax25);
+
+void setup() {
+ Serial.begin(9600);
+
+ // initialize SX1278
+ // NOTE: moved to ISM band on purpose
+ // DO NOT transmit in APRS bands without ham radio license!
+ Serial.print(F("[SX1278] Initializing ... "));
+ int state = radio.beginFSK();
+
+ // when using one of the non-LoRa modules for AX.25
+ // (RF69, CC1101, Si4432 etc.), use the basic begin() method
+ // int state = radio.begin();
+
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // initialize AX.25 client
+ Serial.print(F("[AX.25] Initializing ... "));
+ // source station callsign: "N7LEM"
+ // source station SSID: 0
+ // preamble length: 8 bytes
+ state = ax25.begin("N7LEM");
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // initialize APRS client
+ Serial.print(F("[APRS] Initializing ... "));
+ // symbol: '>' (car)
+ state = aprs.begin('>');
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+}
+
+void loop() {
+ Serial.print(F("[APRS] Sending Mic-E position ... "));
+ int state = aprs.sendMicE(49.1945, 16.6000, 120, 10, RADIOLIB_APRS_MIC_E_TYPE_EN_ROUTE);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ }
+
+ // wait one minute before transmitting again
+ delay(60000);
+}
diff --git a/examples/APRS/APRS_Position/APRS_Position.ino b/examples/APRS/APRS_Position/APRS_Position.ino
new file mode 100644
index 0000000000..cf7f6977eb
--- /dev/null
+++ b/examples/APRS/APRS_Position/APRS_Position.ino
@@ -0,0 +1,157 @@
+/*
+ RadioLib APRS Position Example
+
+ This example sends APRS position reports
+ using SX1278's FSK modem. The data is
+ modulated as AFSK at 1200 baud using Bell
+ 202 tones.
+
+ DO NOT transmit in APRS bands unless
+ you have a ham radio license!
+
+ Other modules that can be used for APRS:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - nRF24
+ - Si443x/RFM2x
+ - SX126x/LLCC68
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1278 has the following connections:
+// NSS pin: 10
+// DIO0 pin: 2
+// RESET pin: 9
+// DIO1 pin: 3
+SX1278 radio = new Module(10, 2, 9, 3);
+
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// create AFSK client instance using the FSK module
+// this requires connection to the module direct
+// input pin, here connected to Arduino pin 5
+// SX127x/RFM9x: DIO2
+// RF69: DIO2
+// SX1231: DIO2
+// CC1101: GDO2
+// Si443x/RFM2x: GPIO
+// SX126x/LLCC68: DIO2
+AFSKClient audio(&radio, 5);
+
+// create AX.25 client instance using the AFSK instance
+AX25Client ax25(&audio);
+
+// create APRS client instance using the AX.25 client
+APRSClient aprs(&ax25);
+
+void setup() {
+ Serial.begin(9600);
+
+ // initialize SX1278
+ // NOTE: moved to ISM band on purpose
+ // DO NOT transmit in APRS bands without ham radio license!
+ Serial.print(F("[SX1278] Initializing ... "));
+ int state = radio.beginFSK(434.0);
+
+ // when using one of the non-LoRa modules for AX.25
+ // (RF69, CC1101, Si4432 etc.), use the basic begin() method
+ // int state = radio.begin();
+
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // initialize AX.25 client
+ Serial.print(F("[AX.25] Initializing ... "));
+ // source station callsign: "N7LEM"
+ // source station SSID: 0
+ // preamble length: 8 bytes
+ state = ax25.begin("N7LEM");
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // initialize APRS client
+ Serial.print(F("[APRS] Initializing ... "));
+ // symbol: '>' (car)
+ state = aprs.begin('>');
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+}
+
+void loop() {
+ Serial.println(F("[APRS] Sending location reports"));
+
+ // send a location without message or timestamp
+ char destination[] = "N0CALL";
+ char latitude[] = "4911.67N";
+ char longitude[] = "01635.96E";
+ int state = aprs.sendPosition(destination, 0, latitude, longitude);
+ if(state != RADIOLIB_ERR_NONE) {
+ Serial.print(F("[APRS] Failed to send location, code "));
+ Serial.println(state);
+ }
+ delay(500);
+
+ // send a location with message and without timestamp
+ char message[] = "I'm here!";
+ state = aprs.sendPosition(destination, 0, latitude, longitude, message);
+ if(state != RADIOLIB_ERR_NONE) {
+ Serial.print(F("[APRS] Failed to send location and message code "));
+ Serial.println(state);
+ }
+ delay(500);
+
+ // you can also set repeater callsigns and SSIDs
+ // up to 8 repeaters may be used
+ // sendPosition will be sent with "WIDE2-2" path
+ char* repeaterCallsigns[] = { "WIDE2" };
+ uint8_t repeaterSSIDs[] = { 2 };
+ aprs.useRepeaters(repeaterCallsigns, repeaterSSIDs, 1);
+
+ // send a location with message and timestamp
+ char timestamp[] = "093045z";
+ state = aprs.sendPosition(destination, 0, latitude, longitude, message, timestamp);
+ if(state != RADIOLIB_ERR_NONE) {
+ Serial.print(F("[APRS] Failed to send location, message and timestamp code "));
+ Serial.println(state);
+ }
+ delay(500);
+
+ // when repeaters are no longer needed, they can be dropped
+ aprs.dropRepeaters();
+
+ // wait one minute before transmitting again
+ Serial.println(F("[APRS] All done!"));
+ delay(60000);
+}
+
diff --git a/examples/APRS/APRS_Position_LoRa/APRS_Position_LoRa.ino b/examples/APRS/APRS_Position_LoRa/APRS_Position_LoRa.ino
new file mode 100644
index 0000000000..b1cf8ad779
--- /dev/null
+++ b/examples/APRS/APRS_Position_LoRa/APRS_Position_LoRa.ino
@@ -0,0 +1,106 @@
+/*
+ RadioLib APRS Position over LoRa Example
+
+ This example sends APRS position reports
+ using SX1278's LoRa modem.
+
+ Other modules that can be used for APRS:
+ - SX127x/RFM9x
+ - SX126x/LLCC68
+ - SX128x
+ - LR11x0
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1278 has the following connections:
+// NSS pin: 10
+// DIO0 pin: 2
+// RESET pin: 9
+// DIO1 pin: 3
+SX1278 radio = new Module(10, 2, 9, 3);
+
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// create APRS client instance using the LoRa radio
+APRSClient aprs(&radio);
+
+void setup() {
+ Serial.begin(9600);
+
+ // initialize SX1278 with the settings necessary for LoRa iGates
+ Serial.print(F("[SX1278] Initializing ... "));
+ // frequency: 433.775 MHz
+ // bandwidth: 125 kHz
+ // spreading factor: 12
+ // coding rate: 4/5
+ int state = radio.begin(433.775, 125, 12, 5);
+
+ // when using one of the non-LoRa modules for AX.25
+ // (RF69, CC1101, Si4432 etc.), use the basic begin() method
+ // int state = radio.begin();
+
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // initialize APRS client
+ Serial.print(F("[APRS] Initializing ... "));
+ // symbol: '>' (car)
+ // callsign "N7LEM"
+ // SSID 1
+ char source[] = "N7LEM";
+ state = aprs.begin('>', source, 1);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+}
+
+void loop() {
+ Serial.print(F("[APRS] Sending position ... "));
+
+ // send a location with message and timestamp
+ // SSID is set to 1, as APRS over LoRa uses WIDE1-1 path by default
+ char destination[] = "GPS";
+ char latitude[] = "4911.67N";
+ char longitude[] = "01635.96E";
+ char message[] = "I'm here!";
+ char timestamp[] = "093045z";
+ int state = aprs.sendPosition(destination, 1, latitude, longitude, message, timestamp);
+ delay(500);
+
+ // you can also send Mic-E encoded messages
+ state |= state = aprs.sendMicE(49.1945, 16.6000, 120, 10, RADIOLIB_APRS_MIC_E_TYPE_EN_ROUTE);
+ delay(500);
+
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ }
+
+ // wait one minute before transmitting again
+ delay(60000);
+}
diff --git a/examples/AX25/AX25_Frames/AX25_Frames.ino b/examples/AX25/AX25_Frames/AX25_Frames.ino
index 0167214c4a..256e587b4e 100644
--- a/examples/AX25/AX25_Frames/AX25_Frames.ino
+++ b/examples/AX25/AX25_Frames/AX25_Frames.ino
@@ -1,30 +1,31 @@
/*
- RadioLib AX.25 Frame Example
-
- This example shows how to send various
- AX.25 frames using SX1278's FSK modem.
-
- Other modules that can be used for AX.25:
- - SX127x/RFM9x
- - RF69
- - SX1231
- - CC1101
- - SX126x
- - nRF24
- - Si443x/RFM2x
-
- Using raw AX.25 frames requires some
- knowledge of the protocol, refer to
- AX25_Transmit for basic operation.
- Frames shown in this example are not
- exhaustive; all possible AX.25 frames
- should be supported.
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ RadioLib AX.25 Frame Example
+
+ This example shows how to send various
+ AX.25 frames using SX1278's FSK modem.
+
+ Other modules that can be used for AX.25:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - SX126x
+ - nRF24
+ - Si443x/RFM2x
+ - LR11x0
+
+ Using raw AX.25 frames requires some
+ knowledge of the protocol, refer to
+ AX25_Transmit for basic operation.
+ Frames shown in this example are not
+ exhaustive; all possible AX.25 frames
+ should be supported.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -37,9 +38,13 @@
// DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// create AX.25 client instance using the FSK module
AX25Client ax25(&radio);
@@ -58,12 +63,12 @@ void setup() {
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
// int state = radio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// initialize AX.25 client
@@ -72,12 +77,12 @@ void setup() {
// source station SSID: 0
// preamble length: 8 bytes
state = ax25.begin("N7LEM");
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
}
@@ -90,14 +95,14 @@ void loop() {
// control field: UI, P/F not used, unnumbered frame
// protocol identifier: no layer 3 protocol implemented
// information field: "Hello World!"
- AX25Frame frameUI("NJ7P", 0, "N7LEM", 0, AX25_CONTROL_U_UNNUMBERED_INFORMATION |
- AX25_CONTROL_POLL_FINAL_DISABLED | AX25_CONTROL_UNNUMBERED_FRAME,
- AX25_PID_NO_LAYER_3, "Hello World (unnumbered)!");
+ AX25Frame frameUI("NJ7P", 0, "N7LEM", 0, RADIOLIB_AX25_CONTROL_U_UNNUMBERED_INFORMATION |
+ RADIOLIB_AX25_CONTROL_POLL_FINAL_DISABLED | RADIOLIB_AX25_CONTROL_UNNUMBERED_FRAME,
+ RADIOLIB_AX25_PID_NO_LAYER_3, "Hello World (unnumbered)!");
// send the frame
Serial.print(F("[AX.25] Sending UI frame ... "));
int state = ax25.sendFrame(&frameUI);
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// the packet was successfully transmitted
Serial.println(F("success!"));
@@ -116,8 +121,8 @@ void loop() {
// source station callsign: "N7LEM"
// source station SSID: 0
// control field: RR, P/F not used, supervisory frame
- AX25Frame frameRR("NJ7P", 0, "N7LEM", 0, AX25_CONTROL_S_RECEIVE_READY |
- AX25_CONTROL_POLL_FINAL_DISABLED | AX25_CONTROL_SUPERVISORY_FRAME);
+ AX25Frame frameRR("NJ7P", 0, "N7LEM", 0, RADIOLIB_AX25_CONTROL_S_RECEIVE_READY |
+ RADIOLIB_AX25_CONTROL_POLL_FINAL_DISABLED | RADIOLIB_AX25_CONTROL_SUPERVISORY_FRAME);
// set receive sequence number (0 - 7)
frameRR.setRecvSequence(0);
@@ -125,7 +130,7 @@ void loop() {
// send the frame
Serial.print(F("[AX.25] Sending RR frame ... "));
state = ax25.sendFrame(&frameRR);
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// the packet was successfully transmitted
Serial.println(F("success!"));
@@ -146,8 +151,8 @@ void loop() {
// control field: P/F not used, information frame
// protocol identifier: no layer 3 protocol implemented
// information field: "Hello World (numbered)!"
- AX25Frame frameI("NJ7P", 0, "N7LEM", 0, AX25_CONTROL_POLL_FINAL_DISABLED |
- AX25_CONTROL_INFORMATION_FRAME, AX25_PID_NO_LAYER_3,
+ AX25Frame frameI("NJ7P", 0, "N7LEM", 0, RADIOLIB_AX25_CONTROL_POLL_FINAL_DISABLED |
+ RADIOLIB_AX25_CONTROL_INFORMATION_FRAME, RADIOLIB_AX25_PID_NO_LAYER_3,
"Hello World (numbered)!");
// set receive sequence number (0 - 7)
@@ -159,7 +164,7 @@ void loop() {
// send the frame
Serial.print(F("[AX.25] Sending I frame ... "));
state = ax25.sendFrame(&frameI);
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// the packet was successfully transmitted
Serial.println(F("success!"));
diff --git a/examples/AX25/AX25_Transmit/AX25_Transmit.ino b/examples/AX25/AX25_Transmit/AX25_Transmit.ino
index fa61383010..6d244ac260 100644
--- a/examples/AX25/AX25_Transmit/AX25_Transmit.ino
+++ b/examples/AX25/AX25_Transmit/AX25_Transmit.ino
@@ -1,23 +1,24 @@
/*
- RadioLib AX.25 Transmit Example
-
- This example sends AX.25 messages using
- SX1278's FSK modem.
-
- Other modules that can be used for AX.25:
- - SX127x/RFM9x
- - RF69
- - SX1231
- - CC1101
- - SX126x
- - nRF24
- - Si443x/RFM2x
-
- 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/
+ RadioLib AX.25 Transmit Example
+
+ This example sends AX.25 messages using
+ SX1278's FSK modem.
+
+ Other modules that can be used for AX.25:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - SX126x
+ - nRF24
+ - Si443x/RFM2x
+ - LR11x0
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -30,9 +31,13 @@
// DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// create AX.25 client instance using the FSK module
AX25Client ax25(&radio);
@@ -50,12 +55,12 @@ void setup() {
// (RF69, CC1101,, Si4432 etc.), use the basic begin() method
// int state = radio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// initialize AX.25 client
@@ -64,12 +69,12 @@ void setup() {
// source station SSID: 0
// preamble length: 8 bytes
state = ax25.begin("N7LEM");
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
}
@@ -79,7 +84,7 @@ void loop() {
// destination station callsign: "NJ7P"
// destination station SSID: 0
int state = ax25.transmit("Hello World!", "NJ7P");
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// the packet was successfully transmitted
Serial.println(F("success!"));
diff --git a/examples/AX25/AX25_Transmit_AFSK/AX25_Transmit_AFSK.ino b/examples/AX25/AX25_Transmit_AFSK/AX25_Transmit_AFSK.ino
index a44d1ed992..b2288e6964 100644
--- a/examples/AX25/AX25_Transmit_AFSK/AX25_Transmit_AFSK.ino
+++ b/examples/AX25/AX25_Transmit_AFSK/AX25_Transmit_AFSK.ino
@@ -1,24 +1,25 @@
/*
- RadioLib AX.25 Transmit AFSK Example
-
- This example sends AX.25 messages using
- SX1278's FSK modem. The data is modulated
- as AFSK at 1200 baud using Bell 202 tones.
-
- Other modules that can be used for AX.25
- with AFSK modulation:
- - SX127x/RFM9x
- - RF69
- - SX1231
- - CC1101
- - nRF24
- - Si443x/RFM2x
-
- 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/
+ RadioLib AX.25 Transmit AFSK Example
+
+ This example sends AX.25 messages using
+ SX1278's FSK modem. The data is modulated
+ as AFSK at 1200 baud using Bell 202 tones.
+
+ Other modules that can be used for AX.25
+ with AFSK modulation:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - nRF24
+ - Si443x/RFM2x
+ - SX126x/LLCC68
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -31,12 +32,23 @@
// DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// create AFSK client instance using the FSK module
-// pin 5 is connected to SX1278 DIO2
+// this requires connection to the module direct
+// input pin, here connected to Arduino pin 5
+// SX127x/RFM9x: DIO2
+// RF69: DIO2
+// SX1231: DIO2
+// CC1101: GDO2
+// Si443x/RFM2x: GPIO
+// SX126x/LLCC68: DIO2
AFSKClient audio(&radio, 5);
// create AX.25 client instance using the AFSK instance
@@ -53,12 +65,12 @@ void setup() {
// (RF69, CC1101,, Si4432 etc.), use the basic begin() method
// int state = radio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// initialize AX.25 client
@@ -67,12 +79,12 @@ void setup() {
// source station SSID: 0
// preamble length: 8 bytes
state = ax25.begin("N7LEM");
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// Sometimes, it may be required to adjust audio
@@ -82,12 +94,12 @@ void setup() {
/*
Serial.print(F("[AX.25] Setting correction ... "));
state = ax25.setCorrection(100, -100);
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
*/
}
@@ -98,7 +110,7 @@ void loop() {
// destination station callsign: "NJ7P"
// destination station SSID: 0
int state = ax25.transmit("Hello World!", "NJ7P");
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// the packet was successfully transmitted
Serial.println(F("success!"));
diff --git a/examples/BellModem/BellModem_Transmit/BellModem_Transmit.ino b/examples/BellModem/BellModem_Transmit/BellModem_Transmit.ino
new file mode 100644
index 0000000000..abd96d4d0f
--- /dev/null
+++ b/examples/BellModem/BellModem_Transmit/BellModem_Transmit.ino
@@ -0,0 +1,116 @@
+/*
+ RadioLib Bell Modem Transmit Example
+
+ This example shows how to transmit binary data
+ using audio Bell 202 tones.
+
+ Other implemented Bell modems
+ - Bell 101
+ - Bell 103
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1278 has the following connections:
+// NSS pin: 10
+// DIO0 pin: 2
+// RESET pin: 9
+// DIO1 pin: 3
+SX1278 radio = new Module(10, 2, 9, 3);
+
+// create Bell modem instance using the FSK module
+// this requires connection to the module direct
+// input pin, here connected to Arduino pin 5
+// SX127x/RFM9x: DIO2
+// RF69: DIO2
+// SX1231: DIO2
+// CC1101: GDO2
+// Si443x/RFM2x: GPIO
+// SX126x/LLCC68: DIO2
+BellClient bell(&radio, 5);
+
+void setup() {
+ Serial.begin(9600);
+
+ // initialize SX1278 with default settings
+ Serial.print(F("[SX1278] Initializing ... "));
+ int state = radio.beginFSK();
+
+ // when using one of the non-LoRa modules for AFSK
+ // (RF69, CC1101, Si4432 etc.), use the basic begin() method
+ // int state = radio.begin();
+
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // initialize Bell 202 modem
+ Serial.print(F("[Bell 202] Initializing ... "));
+ state = bell.begin(Bell202);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+}
+
+void loop() {
+ Serial.print(F("[Bell 202] Sending data ... "));
+
+ // send out idle condition for 500 ms
+ bell.idle();
+ delay(500);
+
+ // BellClient supports all methods of the Serial class
+
+ // Arduino String class
+ String aStr = "Arduino String";
+ bell.println(aStr);
+
+ // character array (C-String)
+ bell.println("C-String");
+
+ // string saved in flash
+ bell.println(F("Flash String"));
+
+ // character
+ bell.println('c');
+
+ // byte
+ // formatting DEC/HEX/OCT/BIN is supported for
+ // any integer type (byte/int/long)
+ bell.println(255, HEX);
+
+ // integer number
+ int i = 1000;
+ bell.println(i);
+
+ // floating point number
+ float f = -3.1415;
+ bell.println(f, 3);
+
+ // ITA2-encoded string
+ ITA2String str("HELLO WORLD!");
+ bell.print(str);
+
+ // turn the transmitter off
+ bell.standby();
+
+ Serial.println(F("done!"));
+
+ // wait for a second before transmitting again
+ delay(1000);
+}
diff --git a/examples/CC1101/CC1101_Receive_Address/CC1101_Receive_Address.ino b/examples/CC1101/CC1101_Receive_Address/CC1101_Receive_Address.ino
index 81eac67c8c..11a6988d3b 100644
--- a/examples/CC1101/CC1101_Receive_Address/CC1101_Receive_Address.ino
+++ b/examples/CC1101/CC1101_Receive_Address/CC1101_Receive_Address.ino
@@ -1,17 +1,17 @@
/*
- RadioLib CC1101 Receive with Address Example
+ RadioLib CC1101 Receive with Address Example
- This example receives packets using CC1101 FSK radio
- module. Packets can have 1-byte address of the
- destination node. After setting node address, this node
- will automatically filter out any packets that do not
- contain either node address or broadcast addresses.
+ This example receives packets using CC1101 FSK radio
+ module. Packets can have 1-byte address of the
+ destination node. After setting node address, this node
+ will automatically filter out any packets that do not
+ contain either node address or broadcast addresses.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -24,9 +24,13 @@
// GDO2 pin: 3 (optional)
CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//CC1101 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -34,12 +38,12 @@ void setup() {
// initialize CC1101 with default settings
Serial.print(F("[CC1101] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set node address
@@ -51,12 +55,12 @@ void setup() {
// 0xFF will be used.
Serial.print(F("[CC1101] Setting node address ... "));
state = radio.setNodeAddress(0x01, 1);
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// address filtering can also be disabled
@@ -65,12 +69,12 @@ void setup() {
/*
Serial.print(F("[CC1101] Disabling address filtering ... "));
state == radio.disableAddressFiltering();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
*/
}
@@ -88,7 +92,7 @@ void loop() {
int state = radio.receive(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("success!"));
@@ -107,7 +111,7 @@ void loop() {
Serial.print(F("[CC1101] LQI:\t\t"));
Serial.println(radio.getLQI());
- } else if (state == ERR_CRC_MISMATCH) {
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
// packet was received, but is malformed
Serial.println(F("CRC error!"));
diff --git a/examples/CC1101/CC1101_Receive/CC1101_Receive.ino b/examples/CC1101/CC1101_Receive_Blocking/CC1101_Receive_Blocking.ino
similarity index 60%
rename from examples/CC1101/CC1101_Receive/CC1101_Receive.ino
rename to examples/CC1101/CC1101_Receive_Blocking/CC1101_Receive_Blocking.ino
index 4ff6235915..e24189c314 100644
--- a/examples/CC1101/CC1101_Receive/CC1101_Receive.ino
+++ b/examples/CC1101/CC1101_Receive_Blocking/CC1101_Receive_Blocking.ino
@@ -1,19 +1,24 @@
/*
- RadioLib CC1101 Receive Example
-
- This example receives packets using CC1101 FSK radio module.
- To successfully receive data, the following settings have to be the same
- on both transmitter and receiver:
- - carrier frequency
- - bit rate
- - frequency deviation
- - sync word
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ RadioLib CC1101 Blocking Receive Example
+
+ This example receives packets using CC1101 FSK radio module.
+ To successfully receive data, the following settings have to be the same
+ on both transmitter and receiver:
+ - carrier frequency
+ - bit rate
+ - frequency deviation
+ - sync word
+
+ Using blocking receive is not recommended, as it will lead
+ to significant amount of timeouts, inefficient use of processor
+ time and can some miss packets!
+ Instead, interrupt receive is recommended.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -26,9 +31,13 @@
// GDO2 pin: 3 (optional)
CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//CC1101 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -36,12 +45,12 @@ void setup() {
// initialize CC1101 with default settings
Serial.print(F("[CC1101] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
}
@@ -58,7 +67,7 @@ void loop() {
int state = radio.receive(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("success!"));
@@ -77,11 +86,11 @@ void loop() {
Serial.print(F("[CC1101] LQI:\t\t"));
Serial.println(radio.getLQI());
- } else if (state == ERR_RX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
// timeout occurred while waiting for a packet
Serial.println(F("timeout!"));
- } else if (state == ERR_CRC_MISMATCH) {
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
// packet was received, but is malformed
Serial.println(F("CRC error!"));
diff --git a/examples/CC1101/CC1101_Receive_Interrupt/CC1101_Receive_Interrupt.ino b/examples/CC1101/CC1101_Receive_Interrupt/CC1101_Receive_Interrupt.ino
index a7228de4af..9f9a18873c 100644
--- a/examples/CC1101/CC1101_Receive_Interrupt/CC1101_Receive_Interrupt.ino
+++ b/examples/CC1101/CC1101_Receive_Interrupt/CC1101_Receive_Interrupt.ino
@@ -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
- receive them. Once a packet is received, an interrupt is
- triggered.
+ This example listens for FSK transmissions and tries to
+ receive them. Once a packet is received, an interrupt is
+ triggered.
- To successfully receive data, the following settings have to be the same
- on both transmitter and receiver:
- - carrier frequency
- - bit rate
- - frequency deviation
- - sync word
+ To successfully receive data, the following settings have to be the same
+ on both transmitter and receiver:
+ - carrier frequency
+ - bit rate
+ - frequency deviation
+ - sync word
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -29,9 +29,28 @@
// GDO2 pin: 3 (optional)
CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//CC1101 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// flag to indicate that a packet was received
+volatile bool receivedFlag = false;
+
+// this function is called when a complete packet
+// is received by the module
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+#if defined(ESP8266) || defined(ESP32)
+ ICACHE_RAM_ATTR
+#endif
+void setFlag(void) {
+ // we got a packet, set the flag
+ receivedFlag = true;
+}
void setup() {
Serial.begin(9600);
@@ -39,27 +58,27 @@ void setup() {
// initialize CC1101 with default settings
Serial.print(F("[CC1101] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set the function that will be called
// when new packet is received
- radio.setGdo0Action(setFlag);
+ radio.setPacketReceivedAction(setFlag);
// start listening for packets
Serial.print(F("[CC1101] Starting to listen ... "));
state = radio.startReceive();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// if needed, 'listen' mode can be disabled by calling
@@ -72,33 +91,9 @@ void setup() {
// radio.readData();
}
-// flag to indicate that a packet was received
-volatile bool receivedFlag = false;
-
-// disable interrupt when it's not needed
-volatile bool enableInterrupt = true;
-
-// this function is called when a complete packet
-// is received by the module
-// IMPORTANT: this function MUST be 'void' type
-// and MUST NOT have any arguments!
-void setFlag(void) {
- // check if the interrupt is enabled
- if(!enableInterrupt) {
- return;
- }
-
- // we got a packet, set the flag
- receivedFlag = true;
-}
-
void loop() {
// check if the flag is set
if(receivedFlag) {
- // disable the interrupt service routine while
- // processing the data
- enableInterrupt = false;
-
// reset flag
receivedFlag = false;
@@ -109,10 +104,11 @@ void loop() {
// you can also read received data as byte array
/*
byte byteArr[8];
- int state = radio.readData(byteArr, 8);
+ int numBytes = radio.getPacketLength();
+ int state = radio.readData(byteArr, numBytes);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("[CC1101] Received packet!"));
@@ -131,7 +127,7 @@ void loop() {
Serial.print(F("[CC1101] LQI:\t\t"));
Serial.println(radio.getLQI());
- } else if (state == ERR_CRC_MISMATCH) {
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
// packet was received, but is malformed
Serial.println(F("CRC error!"));
@@ -144,10 +140,6 @@ void loop() {
// put module back to listen mode
radio.startReceive();
-
- // we're ready to receive more packets,
- // enable interrupt service routine
- enableInterrupt = true;
}
}
diff --git a/examples/CC1101/CC1101_Settings/CC1101_Settings.ino b/examples/CC1101/CC1101_Settings/CC1101_Settings.ino
index e724f7b625..c3423e4bcd 100644
--- a/examples/CC1101/CC1101_Settings/CC1101_Settings.ino
+++ b/examples/CC1101/CC1101_Settings/CC1101_Settings.ino
@@ -1,21 +1,21 @@
/*
- RadioLib CC1101 Settings Example
-
- This example shows how to change all the properties of RF69 radio.
- RadioLib currently supports the following settings:
- - pins (SPI slave select, digital IO 0, digital IO 1)
- - carrier frequency
- - bit rate
- - receiver bandwidth
- - allowed frequency deviation
- - output power during transmission
- - sync word
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ RadioLib CC1101 Settings Example
+
+ This example shows how to change all the properties of RF69 radio.
+ RadioLib currently supports the following settings:
+ - pins (SPI slave select, digital IO 0, digital IO 1)
+ - carrier frequency
+ - bit rate
+ - receiver bandwidth
+ - allowed frequency deviation
+ - output power during transmission
+ - sync word
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -33,11 +33,15 @@ CC1101 radio1 = new Module(10, 2, RADIOLIB_NC, 3);
// GDO0 pin: 4
// RST pin: unused
// GDO2 pin: 5 (optional)
-CC1101 radio2 = new Module(9, 4, RADIOLIB_NC, 53);
+CC1101 radio2 = new Module(9, 4, RADIOLIB_NC, 5);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//CC1101 radio3 = RadioShield.ModuleB;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio3 = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -45,12 +49,12 @@ void setup() {
// initialize CC1101 with default settings
Serial.print(F("[CC1101] Initializing ... "));
int state = radio1.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// initialize CC1101 with non-default settings
@@ -62,56 +66,56 @@ void setup() {
// output power: 7 dBm
// preamble length: 32 bits
state = radio2.begin(434.0, 32.0, 60.0, 250.0, 7, 32);
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// you can also change the settings at runtime
// and check if the configuration was changed successfully
// set carrier frequency to 433.5 MHz
- if (radio1.setFrequency(433.5) == ERR_INVALID_FREQUENCY) {
+ if (radio1.setFrequency(433.5) == RADIOLIB_ERR_INVALID_FREQUENCY) {
Serial.println(F("[CC1101] Selected frequency is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set bit rate to 100.0 kbps
state = radio1.setBitRate(100.0);
- if (state == ERR_INVALID_BIT_RATE) {
+ if (state == RADIOLIB_ERR_INVALID_BIT_RATE) {
Serial.println(F("[CC1101] Selected bit rate is invalid for this module!"));
- while (true);
- } else if (state == ERR_INVALID_BIT_RATE_BW_RATIO) {
+ while (true) { delay(10); }
+ } else if (state == RADIOLIB_ERR_INVALID_BIT_RATE_BW_RATIO) {
Serial.println(F("[CC1101] Selected bit rate to bandwidth ratio is invalid!"));
Serial.println(F("[CC1101] Increase receiver bandwidth to set this bit rate."));
- while (true);
+ while (true) { delay(10); }
}
// set receiver bandwidth to 250.0 kHz
- if (radio1.setRxBandwidth(250.0) == 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!"));
- while (true);
+ while (true) { delay(10); }
}
// set allowed frequency deviation to 10.0 kHz
- if (radio1.setFrequencyDeviation(10.0) == 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!"));
- while (true);
+ while (true) { delay(10); }
}
// set output power to 5 dBm
- if (radio1.setOutputPower(5) == 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!"));
- while (true);
+ while (true) { delay(10); }
}
// 2 bytes can be set as sync word
- if (radio1.setSyncWord(0x01, 0x23) == 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!"));
- while (true);
+ while (true) { delay(10); }
}
}
diff --git a/examples/CC1101/CC1101_Transmit/CC1101_Transmit.ino b/examples/CC1101/CC1101_Transmit/CC1101_Transmit.ino
deleted file mode 100644
index 3463c6f14f..0000000000
--- a/examples/CC1101/CC1101_Transmit/CC1101_Transmit.ino
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- RadioLib CC1101 Transmit Example
-
- This example transmits packets using CC1101 FSK radio module.
- Each packet contains up to 64 bytes of data, in the form of:
- - Arduino String
- - null-terminated char array (C-string)
- - arbitrary binary data (byte array)
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
-*/
-
-// include the library
-#include
-
-// CC1101 has the following connections:
-// CS pin: 10
-// GDO0 pin: 2
-// RST pin: unused
-// GDO2 pin: 3 (optional)
-CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
-
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//CC1101 radio = RadioShield.ModuleA;
-
-void setup() {
- Serial.begin(9600);
-
- // initialize CC1101 with default settings
- Serial.print(F("[CC1101] Initializing ... "));
- int state = radio.begin();
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-}
-
-void loop() {
- Serial.print(F("[CC1101] Transmitting packet ... "));
-
- // you can transmit C-string or Arduino string up to 63 characters long
- int state = radio.transmit("Hello World!");
-
- // you can also transmit byte array up to 63 bytes long
- /*
- byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
- int state = radio.transmit(byteArr, 8);
- */
-
- if (state == ERR_NONE) {
- // the packet was successfully transmitted
- Serial.println(F("success!"));
-
- } else if (state == ERR_PACKET_TOO_LONG) {
- // the supplied packet was longer than 64 bytes
- Serial.println(F("too long!"));
-
- } else {
- // some other error occurred
- Serial.print(F("failed, code "));
- Serial.println(state);
-
- }
-
- // wait for a second before transmitting again
- delay(1000);
-}
diff --git a/examples/CC1101/CC1101_Transmit_Address/CC1101_Transmit_Address.ino b/examples/CC1101/CC1101_Transmit_Address/CC1101_Transmit_Address.ino
index 430eafd864..7042015623 100644
--- a/examples/CC1101/CC1101_Transmit_Address/CC1101_Transmit_Address.ino
+++ b/examples/CC1101/CC1101_Transmit_Address/CC1101_Transmit_Address.ino
@@ -1,17 +1,17 @@
/*
- RadioLib CC1101 Transmit to Address Example
+ RadioLib CC1101 Transmit to Address Example
- This example transmits packets using CC1101 FSK radio
- module. Packets can have 1-byte address of the
- destination node. After setting node address, this node
- will automatically filter out any packets that do not
- contain either node address or broadcast addresses.
+ This example transmits packets using CC1101 FSK radio
+ module. Packets can have 1-byte address of the
+ destination node. After setting node address, this node
+ will automatically filter out any packets that do not
+ contain either node address or broadcast addresses.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -24,9 +24,13 @@
// GDO2 pin: 3 (optional)
CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//CC1101 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -34,12 +38,12 @@ void setup() {
// initialize CC1101 with default settings
Serial.print(F("[CC1101] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set node address
@@ -51,12 +55,12 @@ void setup() {
// 0xFF will be used.
Serial.print(F("[CC1101] Setting node address ... "));
state = radio.setNodeAddress(0x01, 1);
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// address filtering can also be disabled
@@ -65,12 +69,12 @@ void setup() {
/*
Serial.print(F("[CC1101] Disabling address filtering ... "));
state == radio.disableAddressFiltering();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
*/
}
@@ -78,20 +82,21 @@ void setup() {
void loop() {
Serial.print(F("[CC1101] Transmitting packet ... "));
- // you can transmit C-string or Arduino string up to 63 characters long
+ // you can transmit C-string or Arduino string up to 255 characters long
int state = radio.transmit("Hello World!");
- // you can also transmit byte array up to 63 bytes long
+ // you can also transmit byte array up to 255 bytes long
+ // With some limitations see here: https://github.com/jgromes/RadioLib/discussions/1138
/*
byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
int state = radio.transmit(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// the packet was successfully transmitted
Serial.println(F("success!"));
- } else if (state == ERR_PACKET_TOO_LONG) {
+ } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
// the supplied packet was longer than 255 bytes
Serial.println(F("too long!"));
diff --git a/examples/CC1101/CC1101_Transmit_Blocking/CC1101_Transmit_Blocking.ino b/examples/CC1101/CC1101_Transmit_Blocking/CC1101_Transmit_Blocking.ino
new file mode 100644
index 0000000000..809cfa60bf
--- /dev/null
+++ b/examples/CC1101/CC1101_Transmit_Blocking/CC1101_Transmit_Blocking.ino
@@ -0,0 +1,87 @@
+/*
+ RadioLib CC1101 Blocking Transmit Example
+
+ 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:
+ - Arduino String
+ - null-terminated char array (C-string)
+ - arbitrary binary data (byte array)
+
+ Using blocking transmit is not recommended, as it will lead
+ to inefficient use of processor time!
+ Instead, interrupt transmit is recommended.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// CC1101 has the following connections:
+// CS pin: 10
+// GDO0 pin: 2
+// RST pin: unused
+// GDO2 pin: 3
+CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
+
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+void setup() {
+ Serial.begin(9600);
+
+ // initialize CC1101 with default settings
+ Serial.print(F("[CC1101] Initializing ... "));
+ int state = radio.begin();
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+}
+
+// counter to keep track of transmitted packets
+int count = 0;
+
+void loop() {
+ Serial.print(F("[CC1101] Transmitting packet ... "));
+
+ // you can transmit C-string or Arduino string up to 255 characters long
+ String str = "Hello World! #" + String(count++);
+ 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
+ /*
+ byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
+ int state = radio.transmit(byteArr, 8);
+ */
+
+ if (state == RADIOLIB_ERR_NONE) {
+ // the packet was successfully transmitted
+ Serial.println(F("success!"));
+
+ } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
+ // the supplied packet was longer than 255 bytes
+ Serial.println(F("too long!"));
+
+ } else {
+ // some other error occurred
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+
+ }
+
+ // wait for a second before transmitting again
+ delay(1000);
+}
diff --git a/examples/CC1101/CC1101_Transmit_Interrupt/CC1101_Transmit_Interrupt.ino b/examples/CC1101/CC1101_Transmit_Interrupt/CC1101_Transmit_Interrupt.ino
index c15652b670..0a87645dbc 100644
--- a/examples/CC1101/CC1101_Transmit_Interrupt/CC1101_Transmit_Interrupt.ino
+++ b/examples/CC1101/CC1101_Transmit_Interrupt/CC1101_Transmit_Interrupt.ino
@@ -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.
- Once a packet is transmitted, an interrupt is triggered.
- Each packet contains up to 64 bytes of data, in the form of:
- - Arduino String
- - null-terminated char array (C-string)
- - arbitrary binary data (byte array)
+ This example transmits packets using CC1101 FSK radio module.
+ 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:
+ - Arduino String
+ - null-terminated char array (C-string)
+ - arbitrary binary data (byte array)
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -22,15 +22,34 @@
// CS pin: 10
// GDO0 pin: 2
// RST pin: unused
-// GDO2 pin: 3 (optional)
+// GDO2 pin: 3
CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//CC1101 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// save transmission state between loops
-int transmissionState = ERR_NONE;
+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);
@@ -38,26 +57,28 @@ void setup() {
// initialize CC1101 with default settings
Serial.print(F("[CC1101] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set the function that will be called
// when packet transmission is finished
- radio.setGdo0Action(setFlag);
+ 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
+ // 255 characters long
transmissionState = radio.startTransmit("Hello World!");
- // you can also transmit byte array up to 64 bytes long
+ // 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};
@@ -65,50 +86,30 @@ void setup() {
*/
}
-// flag to indicate that a packet was sent
-volatile bool transmittedFlag = false;
-
-// disable interrupt when it's not needed
-volatile bool enableInterrupt = true;
-
-// this function is called when a complete packet
-// is transmitted by the module
-// IMPORTANT: this function MUST be 'void' type
-// and MUST NOT have any arguments!
-void setFlag(void) {
- // check if the interrupt is enabled
- if(!enableInterrupt) {
- return;
- }
-
- // we sent a packet, set the flag
- transmittedFlag = true;
-}
+// counter to keep track of transmitted packets
+int count = 0;
void loop() {
// check if the previous transmission finished
if(transmittedFlag) {
- // disable the interrupt service routine while
- // processing the data
- enableInterrupt = false;
-
// reset flag
transmittedFlag = false;
- if (transmissionState == ERR_NONE) {
+ 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);
@@ -116,18 +117,15 @@ void loop() {
Serial.print(F("[CC1101] Sending another packet ... "));
// you can transmit C-string or Arduino string up to
- // 256 characters long
- transmissionState = radio.startTransmit("Hello World!");
+ // 255 characters long
+ String str = "Hello World! #" + String(count++);
+ transmissionState = radio.startTransmit(str);
- // you can also transmit byte array up to 256 bytes long
+ // you can also transmit byte array up to 255 bytes long with limitations https://github.com/jgromes/RadioLib/discussions/1138
/*
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
0x89, 0xAB, 0xCD, 0xEF};
int state = radio.startTransmit(byteArr, 8);
*/
-
- // we're ready to send more packets,
- // enable interrupt service routine
- enableInterrupt = true;
}
}
diff --git a/examples/FSK4/FSK4_Transmit/FSK4_Transmit.ino b/examples/FSK4/FSK4_Transmit/FSK4_Transmit.ino
index 4f7319bcad..d521b8a568 100644
--- a/examples/FSK4/FSK4_Transmit/FSK4_Transmit.ino
+++ b/examples/FSK4/FSK4_Transmit/FSK4_Transmit.ino
@@ -1,27 +1,27 @@
/*
- RadioLib FSK4 Transmit Example
+ RadioLib FSK4 Transmit Example
- This example sends an example FSK-4 'Horus Binary' message
- using SX1278's FSK modem.
+ This example sends an example FSK-4 'Horus Binary' message
+ using SX1278's FSK modem.
- This signal can be demodulated using a SSB demodulator (SDR or otherwise),
- and horusdemodlib: https://github.com/projecthorus/horusdemodlib/wiki
+ This signal can be demodulated using a SSB demodulator (SDR or otherwise),
+ and horusdemodlib: https://github.com/projecthorus/horusdemodlib/wiki
- Other modules that can be used for FSK4:
- - SX127x/RFM9x
- - RF69
- - SX1231
- - CC1101
- - SX126x
- - nRF24
- - Si443x/RFM2x
- - SX128x
+ Other modules that can be used for FSK4:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - SX126x
+ - nRF24
+ - Si443x/RFM2x
+ - SX128x
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration
+ For 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 full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -34,9 +34,13 @@
// DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// create FSK4 client instance using the FSK module
FSK4Client fsk4(&radio);
@@ -68,12 +72,12 @@ void setup() {
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
// int state = radio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// initialize FSK4 client
@@ -92,13 +96,30 @@ void setup() {
// frequency shift: 270 Hz
// baud rate: 100 baud
state = fsk4.begin(434.0, 270, 100);
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
+
+ // sometimes, it may be needed to set some manual corrections
+ // this can be done for tone frequencies,
+ // as well as tone lengths
+ /*
+ // set frequency shift offsets to -120, 60, 0 and 60 Hz and decrease tone length to 95%
+ int offsets[4] = { -120, -60, 0, 60 };
+ Serial.print(F("[FSK4] Setting corrections ... "));
+ state = fsk4.setCorrection(offsets, 0.95);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+ */
}
void loop() {
diff --git a/examples/FSK4/FSK4_Transmit_AFSK/FSK4_Transmit_AFSK.ino b/examples/FSK4/FSK4_Transmit_AFSK/FSK4_Transmit_AFSK.ino
index d3e4007472..58cc7aa9d3 100644
--- a/examples/FSK4/FSK4_Transmit_AFSK/FSK4_Transmit_AFSK.ino
+++ b/examples/FSK4/FSK4_Transmit_AFSK/FSK4_Transmit_AFSK.ino
@@ -1,24 +1,25 @@
/*
- RadioLib FSK4 Transmit AFSK Example
+ RadioLib FSK4 Transmit AFSK Example
- This example sends an example FSK-4 'Horus Binary' message
- using SX1278's FSK modem. The data is modulated as AFSK.
+ This example sends an example FSK-4 'Horus Binary' message
+ using SX1278's FSK modem. The data is modulated as AFSK.
- This signal can be demodulated using an FM demodulator (SDR or otherwise),
- and horusdemodlib: https://github.com/projecthorus/horusdemodlib/wiki
+ This signal can be demodulated using an FM demodulator (SDR or otherwise),
+ and horusdemodlib: https://github.com/projecthorus/horusdemodlib/wiki
- Other modules that can be used for FSK4:
- - SX127x/RFM9x
- - RF69
- - SX1231
- - CC1101
- - Si443x/RFM2x
+ Other modules that can be used for FSK4:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - Si443x/RFM2x
+ - SX126x/LLCC68
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration
+ For 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 full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -31,12 +32,23 @@
// DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// create AFSK client instance using the FSK module
-// pin 5 is connected to SX1278 DIO2
+// this requires connection to the module direct
+// input pin, here connected to Arduino pin 5
+// SX127x/RFM9x: DIO2
+// RF69: DIO2
+// SX1231: DIO2
+// CC1101: GDO2
+// Si443x/RFM2x: GPIO
+// SX126x/LLCC68: DIO2
AFSKClient audio(&radio, 5);
// create FSK4 client instance using the AFSK instance
@@ -69,29 +81,46 @@ void setup() {
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
// int state = radio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// initialize FSK4 client
// NOTE: Unlike FSK FSK4, AFSK requires no rounding of
// the frequency shift.
Serial.print(F("[FSK4] Initializing ... "));
- // low ("space") frequency: 434.0 MHz
+ // lowest ("space") frequency: 400 Hz
// frequency shift: 270 Hz
// baud rate: 100 baud
state = fsk4.begin(400, 270, 100);
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
+
+ // sometimes, it may be needed to set some manual corrections
+ // this can be done for tone frequencies,
+ // as well as tone lengths
+ /*
+ // set audio tone offsets to -10, 20, 0 and 5 Hz and decrease tone length to 95%
+ int offsets[4] = { -10, 20, 0, 5 };
+ Serial.print(F("[FSK4] Setting corrections ... "));
+ state = fsk4.setCorrection(offsets, 0.95);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+ */
}
void loop() {
diff --git a/examples/HC05/HC05_Basic/HC05_Basic.ino b/examples/HC05/HC05_Basic/HC05_Basic.ino
deleted file mode 100644
index fc7ad4c7f5..0000000000
--- a/examples/HC05/HC05_Basic/HC05_Basic.ino
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- RadioLib HC05 Example
-
- This example sends data using HC05 Bluetooth module.
- HC05 works exactly like a Serial line, data are sent to the paired device.
- The default pairing code for HC05 is 1234 or 1111.
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
-*/
-
-// include the library
-#include
-
-// HC05 has the following connections:
-// TX pin: 9
-// RX pin: 8
-HC05 bluetooth = new SerialModule(9, 8);
-
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//HC05 bluetooth = RadioShield.ModuleA;
-
-void setup() {
- Serial.begin(9600);
-
- // initialize HC05
- // baudrate: 9600 baud
- bluetooth.begin(9600);
-}
-
-void loop() {
- // HC05 supports all methods of the Serial class
- // read data incoming from Serial port and write them to Bluetooth
- while (Serial.available() > 0) {
- bluetooth.write(Serial.read());
- }
-
- // read data incoming from Bluetooth and write them to Serial port
- while (bluetooth.available() > 0) {
- Serial.write(bluetooth.read());
- }
-}
diff --git a/examples/HTTP/HTTP_Get/HTTP_Get.ino b/examples/HTTP/HTTP_Get/HTTP_Get.ino
deleted file mode 100644
index cea5ead263..0000000000
--- a/examples/HTTP/HTTP_Get/HTTP_Get.ino
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- RadioLib HTTP GET Example
-
- This example sends HTTP GET request using ESP8266 WiFi module.
-
- Please note that the response will be saved including header. HTTP header size
- can easily exceed Arduino resources and cause the program to behave erratically.
-
- IMPORTANT: Before uploading this example, make sure that the ESP8266 module is running
- AT firmware (can be found in the /extras folder of the library)!
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
-*/
-
-// include the library
-#include
-
-// ESP8266 has the following connections:
-// TX pin: 9
-// RX pin: 8
-ESP8266 wifi = new SerialModule(9, 8);
-
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//ESP8266 wifi = RadioShield.ModuleA;
-
-// create HTTP client instance using the wifi module
-// the default port used for HTTP is 80
-HTTPClient http(&wifi, 80);
-
-void setup() {
- Serial.begin(9600);
-
- // initialize ESP8266
- Serial.print(F("[ESP8266] Initializing ... "));
- // baudrate: 9600 baud
- int state = wifi.begin(9600);
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-
- // join access point
- Serial.print(F("[ESP8266] Joining AP ... "));
- // name: SSID
- // password: password
- state = wifi.join("SSID", "password");
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-
-}
-
-void loop() {
- // send HTTP GET request to www.httpbin.org/ip
- // the response will contain origin IP address of the request
- String response;
- Serial.print(F("[ESP8266] Sending HTTP GET request ... "));
- // URL: www.httpbin.org/ip
- int http_code = http.get("www.httpbin.org/ip", response);
- if (http_code > 0) {
- Serial.print(F("HTTP code "));
- Serial.println(http_code);
- Serial.print(F("[ESP8266] Response is "));
- Serial.print(response.length());
- Serial.println(F(" bytes long."));
- Serial.println(response);
- } else {
- Serial.print(F("failed, code "));
- Serial.println(http_code);
- }
-
- // wait for a second before sending new request
- delay(1000);
-}
diff --git a/examples/HTTP/HTTP_Post/HTTP_Post.ino b/examples/HTTP/HTTP_Post/HTTP_Post.ino
deleted file mode 100644
index 0484e2ffb5..0000000000
--- a/examples/HTTP/HTTP_Post/HTTP_Post.ino
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- RadioLib HTTP POST Example
-
- This example sends HTTP POST request using ESP8266 WiFi module.
-
- Please note that the response will be saved including header. HTTP header size
- can easily exceed Arduino resources and cause the program to behave erratically.
-
- IMPORTANT: Before uploading this example, make sure that the ESP8266 module is running
- AT firmware (can be found in the /extras folder of the library)!
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
- */
-
-// include the library
-#include
-
-// ESP8266 has the following connections:
-// TX pin: 9
-// RX pin: 8
-ESP8266 wifi = new SerialModule(9, 8);
-
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//ESP8266 wifi = RadioShield.ModuleA;
-
-// create HTTP client instance using the wifi module
-// the default port used for HTTP is 80
-HTTPClient http(&wifi, 80);
-
-void setup() {
- Serial.begin(9600);
-
- // initialize ESP8266
- Serial.print(F("[ESP8266] Initializing ... "));
- // baudrate: 9600 baud
- int state = wifi.begin(9600);
- if(state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while(true);
- }
-
- // join access point
- Serial.print(F("[ESP8266] Joining AP ... "));
- // name: SSID
- // password: password
- state = wifi.join("SSID", "password");
- if(state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while(true);
- }
-
-}
-
-void loop() {
- // send HTTP POST request to www.httpbin.org/status/404
- // the server doesn't process the posted data, it just returns
- // response with the status code 404
- String response;
- Serial.print(F("[ESP8266] Sending HTTP POST request ... "));
- // URL: www.httpbin.org/status/404
- // content: str
- // content type: text/plain
- int http_code = http.post("www.httpbin.org/status/404", "str", response);
- if(http_code > 0) {
- Serial.print(F("HTTP code "));
- Serial.println(http_code);
- Serial.print(F("[ESP8266] Response is "));
- Serial.print(response.length());
- Serial.println(F(" bytes long."));
- Serial.println(response);
- } else {
- Serial.print(F("failed, code "));
- Serial.println(http_code);
- }
-
- // wait for a second before sending new request
- delay(1000);
-}
diff --git a/examples/Hellschreiber/Hellschreiber_Transmit/Hellschreiber_Transmit.ino b/examples/Hellschreiber/Hellschreiber_Transmit/Hellschreiber_Transmit.ino
index edadc5d684..ceebc924f2 100644
--- a/examples/Hellschreiber/Hellschreiber_Transmit/Hellschreiber_Transmit.ino
+++ b/examples/Hellschreiber/Hellschreiber_Transmit/Hellschreiber_Transmit.ino
@@ -1,24 +1,25 @@
/*
- RadioLib Hellschreiber Transmit Example
-
- This example sends Hellschreiber message using
- SX1278's FSK modem.
-
- Other modules that can be used for Hellschreiber:
- - SX127x/RFM9x
- - RF69
- - SX1231
- - CC1101
- - SX126x
- - nRF24
- - Si443x/RFM2x
- - SX128x
-
- 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/
+ RadioLib Hellschreiber Transmit Example
+
+ This example sends Hellschreiber message using
+ SX1278's FSK modem.
+
+ Other modules that can be used for Hellschreiber:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - SX126x
+ - nRF24
+ - Si443x/RFM2x
+ - SX128x
+ - LR11x0
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -31,9 +32,13 @@
// DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// create Hellschreiber client instance using the FSK module
HellClient hell(&radio);
@@ -49,12 +54,12 @@ void setup() {
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
// int state = radio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// initialize Hellschreiber client
@@ -62,12 +67,12 @@ void setup() {
// base frequency: 434.0 MHz
// speed: 122.5 Baud ("Feld Hell")
state = hell.begin(434.0);
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
}
diff --git a/examples/Hellschreiber/Hellschreiber_Transmit_AFSK/Hellschreiber_Transmit_AFSK.ino b/examples/Hellschreiber/Hellschreiber_Transmit_AFSK/Hellschreiber_Transmit_AFSK.ino
index 1938f34ccb..14fb049a66 100644
--- a/examples/Hellschreiber/Hellschreiber_Transmit_AFSK/Hellschreiber_Transmit_AFSK.ino
+++ b/examples/Hellschreiber/Hellschreiber_Transmit_AFSK/Hellschreiber_Transmit_AFSK.ino
@@ -1,23 +1,24 @@
/*
- RadioLib Hellschreiber Transmit AFSK Example
-
- This example sends Hellschreiber message using
- SX1278's FSK modem. The data is modulated
- as AFSK.
-
- Other modules that can be used for Hellschreiber
- with AFSK modulation:
- - SX127x/RFM9x
- - RF69
- - SX1231
- - CC1101
- - Si443x/RFM2x
-
- 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/
+ RadioLib Hellschreiber Transmit AFSK Example
+
+ This example sends Hellschreiber message using
+ SX1278's FSK modem. The data is modulated
+ as AFSK.
+
+ Other modules that can be used for Hellschreiber
+ with AFSK modulation:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - Si443x/RFM2x
+ - SX126x/LLCC68
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -30,12 +31,23 @@
// DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// create AFSK client instance using the FSK module
-// pin 5 is connected to SX1278 DIO2
+// this requires connection to the module direct
+// input pin, here connected to Arduino pin 5
+// SX127x/RFM9x: DIO2
+// RF69: DIO2
+// SX1231: DIO2
+// CC1101: GDO2
+// Si443x/RFM2x: GPIO
+// SX126x/LLCC68: DIO2
AFSKClient audio(&radio, 5);
// create Hellschreiber client instance using the AFSK instance
@@ -52,12 +64,12 @@ void setup() {
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
// int state = radio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// initialize Hellschreiber client
@@ -65,12 +77,12 @@ void setup() {
// AFSK tone frequency: 400 Hz
// speed: 122.5 Baud ("Feld Hell")
state = hell.begin(400);
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
}
@@ -90,6 +102,12 @@ void loop() {
// string saved in flash
hell.print(F("Flash String"));
+ // in AFSK mode, it is possible to invert the text colors
+ // use white text on black background
+ hell.setInversion(true);
+ hell.print("Inverted String");
+ hell.setInversion(false);
+
// character
hell.print('c');
diff --git a/examples/JDY08/JDY08_Basic/JDY08_Basic.ino b/examples/JDY08/JDY08_Basic/JDY08_Basic.ino
deleted file mode 100644
index c249e37f2e..0000000000
--- a/examples/JDY08/JDY08_Basic/JDY08_Basic.ino
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- RadioLib JDY08 Example
-
- This example sends data using JDY08 Bluetooth module.
- JDY08 works exactly like a Serial line, data are sent to the paired device.
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
-*/
-
-// include the library
-#include
-
-// JDY08 has the following connections:
-// TX pin: 9
-// RX pin: 8
-JDY08 ble = new SerialModule(9, 8);
-
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//JDY08 ble = RadioShield.ModuleA;
-
-void setup() {
- Serial.begin(9600);
-
- // initialize JDY08
- // baudrate: 9600 baud
- ble.begin(9600);
-}
-
-void loop() {
- // JDY08 supports all methods of the Serial class
- // read data incoming from Serial port and write them to Bluetooth
- while (Serial.available() > 0) {
- ble.write(Serial.read());
- }
-
- // read data incoming from Bluetooth and write them to Serial port
- while (ble.available() > 0) {
- Serial.write(ble.read());
- }
-}
diff --git a/examples/LR11x0/LR11x0_Channel_Activity_Detection_Blocking/LR11x0_Channel_Activity_Detection_Blocking.ino b/examples/LR11x0/LR11x0_Channel_Activity_Detection_Blocking/LR11x0_Channel_Activity_Detection_Blocking.ino
new file mode 100644
index 0000000000..0a6c13ca08
--- /dev/null
+++ b/examples/LR11x0/LR11x0_Channel_Activity_Detection_Blocking/LR11x0_Channel_Activity_Detection_Blocking.ino
@@ -0,0 +1,106 @@
+/*
+ RadioLib LR11x0 Blocking Channel Activity Detection Example
+
+ This example uses LR1110 to scan the current LoRa
+ channel and detect ongoing LoRa transmissions.
+ Unlike SX127x CAD, LR11x0 can detect any part
+ of LoRa transmission, not just the preamble.
+
+ Other modules from LR11x0 family can also be used.
+
+ This example assumes Seeed Studio Wio WM1110 is used.
+ For other LR11x0 modules, some configuration such as
+ RF switch control may have to be adjusted.
+
+ Using blocking CAD is not recommended, as it will lead
+ to significant amount of timeouts, inefficient use of processor
+ time and can some miss packets!
+ Instead, interrupt CAD is recommended.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// 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
+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);
+}
diff --git a/examples/LR11x0/LR11x0_Channel_Activity_Detection_Interrupt/LR11x0_Channel_Activity_Detection_Interrupt.ino b/examples/LR11x0/LR11x0_Channel_Activity_Detection_Interrupt/LR11x0_Channel_Activity_Detection_Interrupt.ino
new file mode 100644
index 0000000000..7de03b216e
--- /dev/null
+++ b/examples/LR11x0/LR11x0_Channel_Activity_Detection_Interrupt/LR11x0_Channel_Activity_Detection_Interrupt.ino
@@ -0,0 +1,141 @@
+/*
+ RadioLib LR11x0 Channel Activity Detection Example
+
+ This example uses LR1110 to scan the current LoRa
+ channel and detect ongoing LoRa transmissions.
+ Unlike SX127x CAD, LR11x0 can detect any part
+ of LoRa transmission, not just the preamble.
+
+ Other modules from LR11x0 family can also be used.
+
+ This example assumes Seeed Studio Wio WM1110 is used.
+ For other LR11x0 modules, some configuration such as
+ RF switch control may have to be adjusted.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// 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
+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);
+ }
+ }
+}
diff --git a/examples/LR11x0/LR11x0_Firmware_Update/LR11x0_Firmware_Update.ino b/examples/LR11x0/LR11x0_Firmware_Update/LR11x0_Firmware_Update.ino
new file mode 100644
index 0000000000..03296fb480
--- /dev/null
+++ b/examples/LR11x0/LR11x0_Firmware_Update/LR11x0_Firmware_Update.ino
@@ -0,0 +1,136 @@
+/*
+ RadioLib LR11x0 Firmware Update Example
+
+ This example updates the internal LR1110 firmware.
+ Newer versions of the firmware introduce fixes
+ and possibly even new features, so it is recommended
+ to use the latest available firmware version
+ when possible.
+
+ Other modules from LR11x0 family can also be used.
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// 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
+
+// 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
+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() {
+
+}
diff --git a/examples/LR11x0/LR11x0_GFSK_Modem/LR11x0_GFSK_Modem.ino b/examples/LR11x0/LR11x0_GFSK_Modem/LR11x0_GFSK_Modem.ino
new file mode 100644
index 0000000000..c3a80037ee
--- /dev/null
+++ b/examples/LR11x0/LR11x0_GFSK_Modem/LR11x0_GFSK_Modem.ino
@@ -0,0 +1,150 @@
+/*
+ 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
+
+// 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
+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 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 "));
+ }
+ */
+}
diff --git a/examples/LR11x0/LR11x0_GNSS_Almanac_Update/LR11x0_GNSS_Almanac_Update.ino b/examples/LR11x0/LR11x0_GNSS_Almanac_Update/LR11x0_GNSS_Almanac_Update.ino
new file mode 100644
index 0000000000..0f02a25367
--- /dev/null
+++ b/examples/LR11x0/LR11x0_GNSS_Almanac_Update/LR11x0_GNSS_Almanac_Update.ino
@@ -0,0 +1,182 @@
+/*
+ RadioLib LR11x0 GNSS Almanac Update Example
+
+ This example updates the LR11x0 GNSS almanac.
+ Almanac is a database of orbital predictions of
+ GNSS satellites, which allows the module to predict
+ when different satellites will appear in the sky,
+ and frequency of their signal.
+
+ Up-to-date almanac is necessary for operation!
+ After an update, data will remain valid for 30 days.
+ All GNSS examples require at least limited
+ visibility of the sky!
+
+ NOTE: This example will only work for LR11x0 devices
+ with sufficiently recent firmware!
+ LR1110: 4.1
+ LR1120: 2.1
+ If your device firmware reports older firmware,
+ update it using the LR11x0_Firmware_Update example.
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// 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
+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);
+
+}
diff --git a/examples/LR11x0/LR11x0_GNSS_Autonomous_Position/LR11x0_GNSS_Autonomous_Position.ino b/examples/LR11x0/LR11x0_GNSS_Autonomous_Position/LR11x0_GNSS_Autonomous_Position.ino
new file mode 100644
index 0000000000..994b749da5
--- /dev/null
+++ b/examples/LR11x0/LR11x0_GNSS_Autonomous_Position/LR11x0_GNSS_Autonomous_Position.ino
@@ -0,0 +1,134 @@
+/*
+ RadioLib LR11x0 GNSS Autonomous Position Example
+
+ This example performs GNSS scans and calculates
+ position of the device using autonomous mode.
+ In this mode, scan data does not need to be uploaded
+ to LoRaCloud, however, it requires up-to-date almanac
+ data. Run the LR11x0_Almanac_Update example to update
+ the device almanac.
+
+ NOTE: This example will only work for LR11x0 devices
+ with sufficiently recent firmware!
+ LR1110: 4.1
+ LR1120: 2.1
+ If your device firmware reports older firmware,
+ update it using the LR11x0_Firmware_Update example.
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// 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
+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);
+}
diff --git a/examples/LR11x0/LR11x0_GNSS_Satellites/LR11x0_GNSS_Satellites.ino b/examples/LR11x0/LR11x0_GNSS_Satellites/LR11x0_GNSS_Satellites.ino
new file mode 100644
index 0000000000..ad0457c927
--- /dev/null
+++ b/examples/LR11x0/LR11x0_GNSS_Satellites/LR11x0_GNSS_Satellites.ino
@@ -0,0 +1,133 @@
+/*
+ RadioLib LR11x0 GNSS Satellites Example
+
+ This example performs GNSS scans and shows the satellites
+ currently in view. It is mostly useful to verify
+ visibility and antenna setup.
+
+ NOTE: This example will only work for LR11x0 devices
+ with sufficiently recent firmware!
+ LR1110: 4.1
+ LR1120: 2.1
+ If your device firmware reports older firmware,
+ update it using the LR11x0_Firmware_Update example.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---wifi-scan
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// 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
+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);
+}
diff --git a/examples/LR11x0/LR11x0_LR_FHSS_Modem/LR11x0_LR_FHSS_Modem.ino b/examples/LR11x0/LR11x0_LR_FHSS_Modem/LR11x0_LR_FHSS_Modem.ino
new file mode 100644
index 0000000000..a0dc436d9b
--- /dev/null
+++ b/examples/LR11x0/LR11x0_LR_FHSS_Modem/LR11x0_LR_FHSS_Modem.ino
@@ -0,0 +1,96 @@
+/*
+ RadioLib LR11x0 LR-FHSS Modem Example
+
+ This example shows how to use LR-FHSS modem in LR11x0 chips.
+ This modem can only transmit data, and is not able to receive.
+
+ NOTE: The sketch below is just a guide on how to use
+ LR-FHSS modem, so this code should not be run directly!
+ Instead, modify the other examples to use LR-FHSS
+ modem and use the appropriate configuration
+ methods.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---lr-fhss-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// 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
+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_LRXXXX_LR_FHSS_BW_1523_4, // bandwidth
+ RADIOLIB_LRXXXX_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);
+ }
+
+}
diff --git a/examples/LR11x0/LR11x0_PingPong/LR11x0_PingPong.ino b/examples/LR11x0/LR11x0_PingPong/LR11x0_PingPong.ino
new file mode 100644
index 0000000000..a2a62f9611
--- /dev/null
+++ b/examples/LR11x0/LR11x0_PingPong/LR11x0_PingPong.ino
@@ -0,0 +1,173 @@
+/*
+ RadioLib LR11x0 Ping-Pong Example
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// 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
+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;
+ }
+
+ }
+}
diff --git a/examples/LR11x0/LR11x0_Receive_Blocking/LR11x0_Receive_Blocking.ino b/examples/LR11x0/LR11x0_Receive_Blocking/LR11x0_Receive_Blocking.ino
new file mode 100644
index 0000000000..341b1a74d2
--- /dev/null
+++ b/examples/LR11x0/LR11x0_Receive_Blocking/LR11x0_Receive_Blocking.ino
@@ -0,0 +1,135 @@
+/*
+ RadioLib LR11x0 Blocking Receive Example
+
+ This example listens for LoRa transmissions using LR11x0 Lora modules.
+ To successfully receive data, the following settings have to be the same
+ on both transmitter and receiver:
+ - carrier frequency
+ - bandwidth
+ - spreading factor
+ - coding rate
+ - sync word
+ - preamble length
+
+ Other modules from LR11x0 family can also be used.
+
+ This example assumes Seeed Studio Wio WM1110 is used.
+ For other LR11x0 modules, some configuration such as
+ RF switch control may have to be adjusted.
+
+ Using blocking receive is not recommended, as it will lead
+ to significant amount of timeouts, inefficient use of processor
+ time and can some miss packets!
+ Instead, interrupt receive is recommended.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// 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
+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);
+
+ }
+}
diff --git a/examples/LR11x0/LR11x0_Receive_Interrupt/LR11x0_Receive_Interrupt.ino b/examples/LR11x0/LR11x0_Receive_Interrupt/LR11x0_Receive_Interrupt.ino
new file mode 100644
index 0000000000..3b1d60743c
--- /dev/null
+++ b/examples/LR11x0/LR11x0_Receive_Interrupt/LR11x0_Receive_Interrupt.ino
@@ -0,0 +1,169 @@
+/*
+ RadioLib LR11x0 Receive with Interrupts Example
+
+ This example listens for LoRa transmissions and tries to
+ receive them. Once a packet is received, an interrupt is
+ triggered. To successfully receive data, the following
+ settings have to be the same on both transmitter
+ and receiver:
+ - carrier frequency
+ - bandwidth
+ - spreading factor
+ - coding rate
+ - sync word
+
+ Other modules from LR11x0 family can also be used.
+
+ This example assumes Seeed Studio Wio WM1110 is used.
+ For other LR11x0 modules, some configuration such as
+ RF switch control may have to be adjusted.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// 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
+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);
+
+ }
+ }
+}
diff --git a/examples/LR11x0/LR11x0_Transmit_Blocking/LR11x0_Transmit_Blocking.ino b/examples/LR11x0/LR11x0_Transmit_Blocking/LR11x0_Transmit_Blocking.ino
new file mode 100644
index 0000000000..982401164d
--- /dev/null
+++ b/examples/LR11x0/LR11x0_Transmit_Blocking/LR11x0_Transmit_Blocking.ino
@@ -0,0 +1,121 @@
+/*
+ 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
+
+// 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
+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!"));
+
+ } 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);
+}
diff --git a/examples/LR11x0/LR11x0_Transmit_Interrupt/LR11x0_Transmit_Interrupt.ino b/examples/LR11x0/LR11x0_Transmit_Interrupt/LR11x0_Transmit_Interrupt.ino
new file mode 100644
index 0000000000..14942deb45
--- /dev/null
+++ b/examples/LR11x0/LR11x0_Transmit_Interrupt/LR11x0_Transmit_Interrupt.ino
@@ -0,0 +1,158 @@
+/*
+ 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
+
+// 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
+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!"));
+
+ } 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);
+ */
+ }
+}
diff --git a/examples/LR11x0/LR11x0_WiFi_Scan_Blocking/LR11x0_WiFi_Scan_Blocking.ino b/examples/LR11x0/LR11x0_WiFi_Scan_Blocking/LR11x0_WiFi_Scan_Blocking.ino
new file mode 100644
index 0000000000..6da1b356e5
--- /dev/null
+++ b/examples/LR11x0/LR11x0_WiFi_Scan_Blocking/LR11x0_WiFi_Scan_Blocking.ino
@@ -0,0 +1,143 @@
+/*
+ RadioLib LR11x0 WiFi scan Blocking Example
+
+ This example performs a passive scan of WiFi networks.
+ The scan shows basic information about the networks,
+ such as the frequency, country code and SSID.
+
+ Other modules from LR11x0 family can also be used.
+
+ This example assumes Seeed Studio Wio WM1110 is used.
+ For other LR11x0 modules, some configuration such as
+ RF switch control may have to be adjusted.
+
+ Using blocking scan is not recommended, as depending
+ on the scan settings, the program may be blocked
+ for several seconds! Instead, interrupt scan is recommended.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---wifi-scan
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// 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
+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);
+}
diff --git a/examples/LR11x0/LR11x0_WiFi_Scan_Interrupt/LR11x0_WiFi_Scan_Interrupt.ino b/examples/LR11x0/LR11x0_WiFi_Scan_Interrupt/LR11x0_WiFi_Scan_Interrupt.ino
new file mode 100644
index 0000000000..21d90f2c35
--- /dev/null
+++ b/examples/LR11x0/LR11x0_WiFi_Scan_Interrupt/LR11x0_WiFi_Scan_Interrupt.ino
@@ -0,0 +1,181 @@
+/*
+ RadioLib LR11x0 WiFi scan Interrupt Example
+
+ This example performs a passive scan of WiFi networks.
+ The scan shows basic information about the networks,
+ such as the frequency, country code and SSID.
+
+ Other modules from LR11x0 family can also be used.
+
+ This example assumes Seeed Studio Wio WM1110 is used.
+ For other LR11x0 modules, some configuration such as
+ RF switch control may have to be adjusted.
+
+ Using blocking scan is not recommended, as depending
+ on the scan settings, the program may be blocked
+ for several seconds! Instead, interrupt scan is recommended.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr11x0---wifi-scan
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// 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
+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);
+ }
+ }
+}
diff --git a/examples/LR2021/LR2021_Channel_Activity_Detection_Blocking/LR2021_Channel_Activity_Detection_Blocking.ino b/examples/LR2021/LR2021_Channel_Activity_Detection_Blocking/LR2021_Channel_Activity_Detection_Blocking.ino
new file mode 100644
index 0000000000..31fe6be1cc
--- /dev/null
+++ b/examples/LR2021/LR2021_Channel_Activity_Detection_Blocking/LR2021_Channel_Activity_Detection_Blocking.ino
@@ -0,0 +1,82 @@
+/*
+ RadioLib LR2021 Blocking Channel Activity Detection Example
+
+ This example uses LR2021 to scan the current LoRa
+ channel and detect ongoing LoRa transmissions.
+ Unlike SX127x CAD, LR2021 can detect any part
+ of LoRa transmission, not just the preamble.
+
+ 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#lr2021---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// LR2021 has the following connections:
+// NSS pin: 10
+// IRQ pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+LR2021 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
+Radio radio = new RadioModule();
+*/
+
+void setup() {
+ Serial.begin(9600);
+
+ // LR2021 allows to use any DIO pin as the interrupt
+ // as an example, we set DIO10 to be the IRQ
+ // this has to be done prior to calling begin()!
+ radio.irqDioNum = 10;
+
+ // initialize LR2021 with default settings
+ Serial.print(F("[LR2021] Initializing ... "));
+ int state = radio.begin();
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+}
+
+void loop() {
+ Serial.print(F("[LR2021] 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);
+}
diff --git a/examples/LR2021/LR2021_Channel_Activity_Detection_Interrupt/LR2021_Channel_Activity_Detection_Interrupt.ino b/examples/LR2021/LR2021_Channel_Activity_Detection_Interrupt/LR2021_Channel_Activity_Detection_Interrupt.ino
new file mode 100644
index 0000000000..e3ff8029a3
--- /dev/null
+++ b/examples/LR2021/LR2021_Channel_Activity_Detection_Interrupt/LR2021_Channel_Activity_Detection_Interrupt.ino
@@ -0,0 +1,117 @@
+/*
+ RadioLib LR2021 Channel Activity Detection Example
+
+ This example uses LR2021 to scan the current LoRa
+ channel and detect ongoing LoRa transmissions.
+ Unlike SX127x CAD, LR2021 can detect any part
+ of LoRa transmission, not just the preamble.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr2021---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// LR2021 has the following connections:
+// NSS pin: 10
+// IRQ pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+LR2021 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
+Radio radio = new RadioModule();
+*/
+
+// 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);
+
+ // LR2021 allows to use any DIO pin as the interrupt
+ // as an example, we set DIO10 to be the IRQ
+ // this has to be done prior to calling begin()!
+ radio.irqDioNum = 10;
+
+ // initialize LR2021 with default settings
+ Serial.print(F("[LR2021] 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 LoRa packet or timeout is detected
+ radio.setIrqAction(setFlag);
+
+ // start scanning the channel
+ Serial.print(F("[LR2021] 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("[LR2021] Packet detected!"));
+
+ } else if (state == RADIOLIB_CHANNEL_FREE) {
+ // channel is free
+ Serial.println(F("[LR2021] Channel is free!"));
+
+ } else {
+ // some other error occurred
+ Serial.print(F("[LR2021] Failed, code "));
+ Serial.println(state);
+
+ }
+
+ // start scanning the channel again
+ Serial.print(F("[LR2021] 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);
+ }
+ }
+}
diff --git a/examples/LR2021/LR2021_GFSK_Modem/LR2021_GFSK_Modem.ino b/examples/LR2021/LR2021_GFSK_Modem/LR2021_GFSK_Modem.ino
new file mode 100644
index 0000000000..ad8997a6ca
--- /dev/null
+++ b/examples/LR2021/LR2021_GFSK_Modem/LR2021_GFSK_Modem.ino
@@ -0,0 +1,155 @@
+/*
+ RadioLib LR2021 GFSK Modem Example
+
+ This example shows how to use GFSK modem in LR2021 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#lr2021---gfsk-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// LR2021 has the following connections:
+// NSS pin: 10
+// IRQ pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+LR2021 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
+Radio radio = new RadioModule();
+*/
+
+void setup() {
+ Serial.begin(9600);
+
+ // LR2021 allows to use any DIO pin as the interrupt
+ // as an example, we set DIO10 to be the IRQ
+ // this has to be done prior to calling begin()!
+ radio.irqDioNum = 10;
+
+ // initialize LR2021 with default settings
+ Serial.print(F("[LR2021] 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 allows advanced CRC configuration
+ // Default is CCITT 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("[LR2021] Packet transmitted successfully!"));
+ } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
+ Serial.println(F("[LR2021] Packet too long!"));
+ } else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
+ Serial.println(F("[LR2021] Timed out while transmitting!"));
+ } else {
+ Serial.println(F("[LR2021] 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("[LR2021] Received packet!"));
+ Serial.print(F("[LR2021] Data:\t"));
+ Serial.println(str);
+ } else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
+ Serial.println(F("[LR2021] Timed out while waiting for packet!"));
+ } else {
+ Serial.print(F("[LR2021] 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("[LR2021] 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 "));
+ }
+ */
+}
diff --git a/examples/LR2021/LR2021_LR_FHSS_Modem/LR2021_LR_FHSS_Modem.ino b/examples/LR2021/LR2021_LR_FHSS_Modem/LR2021_LR_FHSS_Modem.ino
new file mode 100644
index 0000000000..097c1f34ee
--- /dev/null
+++ b/examples/LR2021/LR2021_LR_FHSS_Modem/LR2021_LR_FHSS_Modem.ino
@@ -0,0 +1,101 @@
+/*
+ RadioLib LR2021 LR-FHSS Modem Example
+
+ This example shows how to use LR-FHSS modem in LR2021 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#lr2021---lr-fhss-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// LR2021 has the following connections:
+// NSS pin: 10
+// IRQ pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+LR2021 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
+Radio radio = new RadioModule();
+*/
+
+void setup() {
+ Serial.begin(9600);
+
+ // LR2021 allows to use any DIO pin as the interrupt
+ // as an example, we set DIO10 to be the IRQ
+ // this has to be done prior to calling begin()!
+ radio.irqDioNum = 10;
+
+ // initialize LR2021 with default settings
+ Serial.print(F("[LR2021] 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_LRXXXX_LR_FHSS_BW_1523_4, // bandwidth
+ RADIOLIB_LRXXXX_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("[LR2021] Packet transmitted successfully!"));
+ } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
+ Serial.println(F("[LR2021] Packet too long!"));
+ } else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
+ Serial.println(F("[LR2021] Timed out while transmitting!"));
+ } else {
+ Serial.println(F("[LR2021] Failed to transmit packet, code "));
+ Serial.println(state);
+ }
+
+}
diff --git a/examples/LR2021/LR2021_PingPong/LR2021_PingPong.ino b/examples/LR2021/LR2021_PingPong/LR2021_PingPong.ino
new file mode 100644
index 0000000000..4a399d88e1
--- /dev/null
+++ b/examples/LR2021/LR2021_PingPong/LR2021_PingPong.ino
@@ -0,0 +1,155 @@
+/*
+ RadioLib LR2021 Ping-Pong Example
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr2021---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// uncomment the following only on one
+// of the nodes to initiate the pings
+//#define INITIATING_NODE
+
+// LR2021 has the following connections:
+// NSS pin: 10
+// IRQ pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+LR2021 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
+Radio radio = new RadioModule();
+*/
+
+// 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);
+
+ // LR2021 allows to use any DIO pin as the interrupt
+ // as an example, we set DIO10 to be the IRQ
+ // this has to be done prior to calling begin()!
+ radio.irqDioNum = 10;
+
+ // initialize LR2021 with default settings
+ Serial.print(F("[LR2021] Initializing ... "));
+ int state = radio.begin();
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // set the function that will be called
+ // when new packet is received
+ radio.setIrqAction(setFlag);
+
+ #if defined(INITIATING_NODE)
+ // send the first packet on this node
+ Serial.print(F("[LR2021] Sending first packet ... "));
+ transmissionState = radio.startTransmit("Hello World!");
+ transmitFlag = true;
+ #else
+ // start listening for LoRa packets on this node
+ Serial.print(F("[LR2021] 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("[LR2021] Received packet!"));
+
+ // print data of the packet
+ Serial.print(F("[LR2021] Data:\t\t"));
+ Serial.println(str);
+
+ // print RSSI (Received Signal Strength Indicator)
+ Serial.print(F("[LR2021] RSSI:\t\t"));
+ Serial.print(radio.getRSSI());
+ Serial.println(F(" dBm"));
+
+ // print SNR (Signal-to-Noise Ratio)
+ Serial.print(F("[LR2021] 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("[LR2021] Sending another packet ... "));
+ transmissionState = radio.startTransmit("Hello World!");
+ transmitFlag = true;
+ }
+
+ }
+}
diff --git a/examples/LR2021/LR2021_Receive_Blocking/LR2021_Receive_Blocking.ino b/examples/LR2021/LR2021_Receive_Blocking/LR2021_Receive_Blocking.ino
new file mode 100644
index 0000000000..709d61d3e4
--- /dev/null
+++ b/examples/LR2021/LR2021_Receive_Blocking/LR2021_Receive_Blocking.ino
@@ -0,0 +1,111 @@
+/*
+ RadioLib LR2021 Blocking Receive Example
+
+ This example listens for LoRa transmissions using LR2021 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
+
+ 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#lr2021---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// LR2021 has the following connections:
+// NSS pin: 10
+// IRQ pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+LR2021 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
+Radio radio = new RadioModule();
+*/
+
+void setup() {
+ Serial.begin(9600);
+
+ // LR2021 allows to use any DIO pin as the interrupt
+ // as an example, we set DIO10 to be the IRQ
+ // this has to be done prior to calling begin()!
+ radio.irqDioNum = 10;
+
+ // initialize LR2021 with default settings
+ Serial.print(F("[LR2021] Initializing ... "));
+ int state = radio.begin();
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+}
+
+void loop() {
+ Serial.print(F("[LR2021] 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("[LR2021] Data:\t\t"));
+ Serial.println(str);
+
+ // print the RSSI (Received Signal Strength Indicator)
+ // of the last received packet
+ Serial.print(F("[LR2021] 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("[LR2021] 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);
+
+ }
+}
diff --git a/examples/LR2021/LR2021_Receive_Interrupt/LR2021_Receive_Interrupt.ino b/examples/LR2021/LR2021_Receive_Interrupt/LR2021_Receive_Interrupt.ino
new file mode 100644
index 0000000000..bcc63abb69
--- /dev/null
+++ b/examples/LR2021/LR2021_Receive_Interrupt/LR2021_Receive_Interrupt.ino
@@ -0,0 +1,145 @@
+/*
+ RadioLib LR2021 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
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr2021---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// LR2021 has the following connections:
+// NSS pin: 10
+// IRQ pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+LR2021 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
+Radio radio = new RadioModule();
+*/
+
+// flag to indicate that a packet was received
+volatile bool receivedFlag = false;
+
+// this function is called when a complete packet
+// is received by the module
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+#if defined(ESP8266) || defined(ESP32)
+ ICACHE_RAM_ATTR
+#endif
+void setFlag(void) {
+ // we got a packet, set the flag
+ receivedFlag = true;
+}
+
+void setup() {
+ Serial.begin(9600);
+
+ // LR2021 allows to use any DIO pin as the interrupt
+ // as an example, we set DIO10 to be the IRQ
+ // this has to be done prior to calling begin()!
+ radio.irqDioNum = 10;
+
+ // initialize LR2021 with default settings
+ Serial.print(F("[LR2021] Initializing ... "));
+ int state = radio.begin();
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // set the function that will be called
+ // when new packet is received
+ radio.setPacketReceivedAction(setFlag);
+
+ // start listening for LoRa packets
+ Serial.print(F("[LR2021] 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("[LR2021] Received packet!"));
+
+ // print data of the packet
+ Serial.print(F("[LR2021] Data:\t\t"));
+ Serial.println(str);
+
+ // print RSSI (Received Signal Strength Indicator)
+ Serial.print(F("[LR2021] RSSI:\t\t"));
+ Serial.print(radio.getRSSI());
+ Serial.println(F(" dBm"));
+
+ // print SNR (Signal-to-Noise Ratio)
+ Serial.print(F("[LR2021] 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);
+
+ }
+ }
+}
diff --git a/examples/LR2021/LR2021_Receive_MultiSF/LR2021_Receive_MultiSF.ino b/examples/LR2021/LR2021_Receive_MultiSF/LR2021_Receive_MultiSF.ino
new file mode 100644
index 0000000000..d516a7c0ae
--- /dev/null
+++ b/examples/LR2021/LR2021_Receive_MultiSF/LR2021_Receive_MultiSF.ino
@@ -0,0 +1,179 @@
+/*
+ RadioLib LR2021 Receive Multi-SF Example
+
+ This example listens for LoRa transmissions with different
+ spreading factors and tries to receive them.
+ Once a packet is received, an interrupt is triggered.
+
+ There are the following limits on configuration of multi-SF
+ (or side-detect) reception:
+ * In Rx mode, all side-detector spreading factors must be higher
+ than the primary one (configured via begin or setSpreadingFactor).
+ * For CAD mode, the above condition is inverted,
+ all side-detector spreading factors must be smaller.
+ * All packets to be detected/received must have the same header type
+ (implicit or explicit).
+ * If bandwidth is higher than 500 kHz,
+ at most 2 side detectors are allowed.
+ * If the primary spreading factor is 10, 11 or 12,
+ at most 2 side detectors are allowed.
+ * All spreading factors must be different.
+ * The difference between maximum and minimum spreading factor used
+ must be less than or equal to 4.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr2021---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// LR2021 has the following connections:
+// NSS pin: 10
+// IRQ pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+LR2021 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
+Radio radio = new RadioModule();
+*/
+
+// flag to indicate that a packet was received
+volatile bool receivedFlag = false;
+
+// this function is called when a complete packet
+// is received by the module
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+#if defined(ESP8266) || defined(ESP32)
+ ICACHE_RAM_ATTR
+#endif
+void setFlag(void) {
+ // we got a packet, set the flag
+ receivedFlag = true;
+}
+
+void setup() {
+ Serial.begin(9600);
+
+ // LR2021 allows to use any DIO pin as the interrupt
+ // as an example, we set DIO10 to be the IRQ
+ // this has to be done prior to calling begin()!
+ radio.irqDioNum = 10;
+
+ // initialize LR2021 with default settings
+ Serial.print(F("[LR2021] 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); }
+ }
+
+ // prepare array of side detector configuration structures
+ // for spreading factors 10 - 12
+ // as the default spreading factor is 9, this satisfies
+ // the conditions listed at the top of this example
+ // this is just an example; you can also set different
+ // sync words, IQ inversions and low data-rate optimization
+ // depending on the types of transmitters you expect
+ const struct LR2021LoRaSideDetector_t sideDet[3] = {
+ { .sf = 10, .ldro = false, .invertIQ = false,
+ .syncWord = RADIOLIB_LR2021_LORA_SYNC_WORD_PRIVATE },
+ { .sf = 11, .ldro = true, .invertIQ = false,
+ .syncWord = RADIOLIB_LR2021_LORA_SYNC_WORD_PRIVATE },
+ { .sf = 12, .ldro = true, .invertIQ = false,
+ .syncWord = RADIOLIB_LR2021_LORA_SYNC_WORD_PRIVATE },
+ };
+ Serial.print(F("[LR2021] Setting side detector configuration ... "));
+ state = radio.setSideDetector(sideDet, 3);
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // set the function that will be called
+ // when new packet is received
+ radio.setPacketReceivedAction(setFlag);
+
+ // start listening for LoRa packets
+ Serial.print(F("[LR2021] 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("[LR2021] Received packet!"));
+
+ // print data of the packet
+ Serial.print(F("[LR2021] Data:\t\t"));
+ Serial.println(str);
+
+ // print RSSI (Received Signal Strength Indicator)
+ Serial.print(F("[LR2021] RSSI:\t\t"));
+ Serial.print(radio.getRSSI());
+ Serial.println(F(" dBm"));
+
+ // print SNR (Signal-to-Noise Ratio)
+ Serial.print(F("[LR2021] 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);
+
+ }
+ }
+}
diff --git a/examples/LR2021/LR2021_Transmit_Blocking/LR2021_Transmit_Blocking.ino b/examples/LR2021/LR2021_Transmit_Blocking/LR2021_Transmit_Blocking.ino
new file mode 100644
index 0000000000..7b6518b417
--- /dev/null
+++ b/examples/LR2021/LR2021_Transmit_Blocking/LR2021_Transmit_Blocking.ino
@@ -0,0 +1,97 @@
+/*
+ RadioLib LR2021 Blocking Transmit Example
+
+ This example transmits packets using LR2021 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)
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr2021---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// LR2021 has the following connections:
+// NSS pin: 10
+// IRQ pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+LR2021 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
+Radio radio = new RadioModule();
+*/
+
+void setup() {
+ Serial.begin(9600);
+
+ // LR2021 allows to use any DIO pin as the interrupt
+ // as an example, we set DIO10 to be the IRQ
+ // this has to be done prior to calling begin()!
+ radio.irqDioNum = 10;
+
+ // initialize LR2021 with default settings
+ Serial.print(F("[LR2021] 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); }
+ }
+}
+
+// counter to keep track of transmitted packets
+int count = 0;
+
+void loop() {
+ Serial.print(F("[LR2021] 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!"));
+
+ } 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 occurred 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);
+}
diff --git a/examples/LR2021/LR2021_Transmit_Interrupt/LR2021_Transmit_Interrupt.ino b/examples/LR2021/LR2021_Transmit_Interrupt/LR2021_Transmit_Interrupt.ino
new file mode 100644
index 0000000000..8265ed2d5b
--- /dev/null
+++ b/examples/LR2021/LR2021_Transmit_Interrupt/LR2021_Transmit_Interrupt.ino
@@ -0,0 +1,134 @@
+/*
+ RadioLib LR2021 Transmit with Interrupts Example
+
+ This example transmits LoRa packets with one second delays
+ between them. Each packet contains up to 256 bytes
+ of data, in the form of:
+ - Arduino String
+ - null-terminated char array (C-string)
+ - arbitrary binary data (byte array)
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#lr2021---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// LR2021 has the following connections:
+// NSS pin: 10
+// IRQ pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+LR2021 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
+Radio radio = new RadioModule();
+*/
+
+// save transmission state between loops
+int transmissionState = RADIOLIB_ERR_NONE;
+
+// flag to indicate that a packet was sent
+volatile bool transmittedFlag = false;
+
+// this function is called when a complete packet
+// is transmitted by the module
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+#if defined(ESP8266) || defined(ESP32)
+ ICACHE_RAM_ATTR
+#endif
+void setFlag(void) {
+ // we sent a packet, set the flag
+ transmittedFlag = true;
+}
+
+void setup() {
+ Serial.begin(9600);
+
+ // LR2021 allows to use any DIO pin as the interrupt
+ // as an example, we set DIO10 to be the IRQ
+ // this has to be done prior to calling begin()!
+ radio.irqDioNum = 10;
+
+ // initialize LR2021 with default settings
+ Serial.print(F("[LR2021] 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("[LR2021] 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!"));
+
+ } 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("[LR2021] 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);
+ */
+ }
+}
diff --git a/examples/LoRaWAN/LoRaWAN_ABP/LoRaWAN_ABP.ino b/examples/LoRaWAN/LoRaWAN_ABP/LoRaWAN_ABP.ino
new file mode 100644
index 0000000000..1442e0d4b3
--- /dev/null
+++ b/examples/LoRaWAN/LoRaWAN_ABP/LoRaWAN_ABP.ino
@@ -0,0 +1,85 @@
+/*
+ RadioLib LoRaWAN ABP Example
+
+ ABP = Activation by Personalisation, an alternative
+ to OTAA (Over the Air Activation). OTAA is preferable.
+
+ This example will send uplink packets to a LoRaWAN network.
+ Before you start, you will have to register your device at
+ https://www.thethingsnetwork.org/
+ After your device is registered, you can run this example.
+ The device will join the network and start uploading data.
+
+ LoRaWAN v1.0.4/v1.1 requires the use of persistent storage.
+ As this example does not use persistent storage, running this
+ examples REQUIRES you to check "Resets frame counters"
+ on your LoRaWAN dashboard. Refer to the notes or the
+ network's documentation on how to do this.
+ To comply with LoRaWAN's persistent storage, refer to
+ https://github.com/radiolib-org/radiolib-persistence
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+
+ For LoRaWAN details, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/LoRaWAN
+
+*/
+
+#include "configABP.h"
+
+void setup() {
+ Serial.begin(115200);
+ while(!Serial);
+ delay(5000); // Give time to switch to the serial monitor
+ Serial.println(F("\nSetup ... "));
+
+ Serial.println(F("Initialise the radio"));
+ int state = radio.begin();
+ debug(state != RADIOLIB_ERR_NONE, F("Initialise radio failed"), state, true);
+
+ Serial.println(F("Initialise LoRaWAN Network credentials"));
+ node.beginABP(devAddr, fNwkSIntKey, sNwkSIntKey, nwkSEncKey, appSKey);
+
+ node.activateABP();
+ debug(state != RADIOLIB_ERR_NONE, F("Activate ABP failed"), state, true);
+
+ Serial.println(F("Ready!\n"));
+}
+
+void loop() {
+ Serial.println(F("Sending uplink"));
+
+ // This is the place to gather the sensor inputs
+ // Instead of reading any real sensor, we just generate some random numbers as example
+ uint8_t value1 = radio.random(100);
+ uint16_t value2 = radio.random(2000);
+
+ // Build payload byte array
+ uint8_t uplinkPayload[3];
+ uplinkPayload[0] = value1;
+ uplinkPayload[1] = highByte(value2); // See notes for high/lowByte functions
+ uplinkPayload[2] = lowByte(value2);
+
+ // Perform an uplink
+ int state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload));
+ debug(state < RADIOLIB_ERR_NONE, F("Error in sendReceive"), state, false);
+
+ // Check if a downlink was received
+ // (state 0 = no downlink, state 1/2 = downlink in window Rx1/Rx2)
+ if(state > 0) {
+ Serial.println(F("Received a downlink"));
+ } else {
+ Serial.println(F("No downlink received"));
+ }
+
+ Serial.print(F("Next uplink in "));
+ Serial.print(uplinkIntervalSeconds);
+ Serial.println(F(" seconds\n"));
+
+ // Wait until next uplink - observing legal & TTN FUP constraints
+ delay(uplinkIntervalSeconds * 1000UL); // delay needs milli-seconds
+}
diff --git a/examples/LoRaWAN/LoRaWAN_ABP/configABP.h b/examples/LoRaWAN/LoRaWAN_ABP/configABP.h
new file mode 100644
index 0000000000..a19a1dc62d
--- /dev/null
+++ b/examples/LoRaWAN/LoRaWAN_ABP/configABP.h
@@ -0,0 +1,148 @@
+#ifndef _RADIOLIB_EX_LORAWAN_CONFIG_H
+#define _RADIOLIB_EX_LORAWAN_CONFIG_H
+
+#include
+
+// 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
+
+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_MIC_MISMATCH:
+ return "ERR_MIC_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_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
diff --git a/examples/LoRaWAN/LoRaWAN_Class_C/LoRaWAN_Class_C.ino b/examples/LoRaWAN/LoRaWAN_Class_C/LoRaWAN_Class_C.ino
new file mode 100644
index 0000000000..db2a5e791c
--- /dev/null
+++ b/examples/LoRaWAN/LoRaWAN_Class_C/LoRaWAN_Class_C.ino
@@ -0,0 +1,136 @@
+/*
+ RadioLib LoRaWAN Class C Example
+
+ This example joins a LoRaWAN network and switches to Class C.
+ Note that a confirmed uplink with a confirming downlink is
+ required for the switch to Class C to complete. This example
+ assumes that coverage is good enough to receive the downlink
+ at once. It is up to you to handle the situation if coverage
+ is worse.
+
+ 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);
+
+ // switch class
+ node.setClass(RADIOLIB_LORAWAN_CLASS_C);
+
+ // read the note at the top about this first confirmed uplink
+ const char* payload = "C";
+ Serial.println(F("Sending a confirmed uplink"));
+ state = node.sendReceive(payload, 1, true);
+ debug(state <= 0, F("No downlink received"), state, true);
+
+ Serial.println(F("Ready!\n"));
+}
+
+uint32_t lastUplink = 0;
+
+void loop() {
+ uint8_t downlinkPayload[255];
+ size_t downlinkLen = 0;
+ LoRaWANEvent_t downlinkEvent;
+
+ // check if a Class C downlink is ready for processing
+ // tip: internally, this just checks a boolean;
+ // it does not poll the radio over SPI.
+ // tip: you are not required to continuously call
+ // this function; you can do other stuff in between.
+ // however, a downlink may be overwritten if you
+ // don't call this function in time for the previous one.
+ int16_t state = node.getDownlinkClassC(downlinkPayload, &downlinkLen, &downlinkEvent);
+ if(state > 0) {
+ Serial.println(F("Received a Class C downlink!"));
+ // Did we get a downlink with data for us
+ if(downlinkLen > 0) {
+ Serial.println(F("Downlink data: "));
+ arrayDump(downlinkPayload, downlinkLen);
+ }
+
+ // print extra information about the event
+ Serial.println(F("[LoRaWAN] Event information:"));
+ Serial.print(F("[LoRaWAN] Datarate:\t"));
+ Serial.println(downlinkEvent.datarate);
+ Serial.print(F("[LoRaWAN] Frequency:\t"));
+ Serial.print(downlinkEvent.freq, 3);
+ Serial.println(F(" MHz"));
+ Serial.print(F("[LoRaWAN] Frame count:\t"));
+ Serial.println(downlinkEvent.fCnt);
+ Serial.print(F("[LoRaWAN] Port:\t\t"));
+ Serial.println(downlinkEvent.fPort);
+ Serial.println(F(" ms"));
+ Serial.print(F("[LoRaWAN] Rx window: \t"));
+ Serial.println(state);
+ Serial.print(F("[LoRaWAN] Cast:\t\t"));
+ Serial.println(downlinkEvent.multicast ? "Multi" : "Uni");
+ }
+
+ // if less than uplinkIntervalSeconds have elapsed since previous uplink,
+ // stop and go back to the top of the loop()
+ if(millis() - lastUplink < uplinkIntervalSeconds * 1000) {
+ return;
+ }
+
+ 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
+ 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/3 = downlink in window Rx1/Rx2/RxC)
+ 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"));
+
+ // set timestamp of last uplink
+ lastUplink = millis();
+}
diff --git a/examples/LoRaWAN/LoRaWAN_Class_C/config.h b/examples/LoRaWAN/LoRaWAN_Class_C/config.h
new file mode 100644
index 0000000000..dd853274f3
--- /dev/null
+++ b/examples/LoRaWAN/LoRaWAN_Class_C/config.h
@@ -0,0 +1,141 @@
+#ifndef _RADIOLIB_EX_LORAWAN_CONFIG_H
+#define _RADIOLIB_EX_LORAWAN_CONFIG_H
+
+#include
+
+// first you have to set your radio model and pin configuration
+// this is provided just as a default example
+SX1262 radio = new Module(8, 14, 12, 13);
+
+// 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
+
+Radio radio = new RadioModule();
+*/
+
+// how often to send an uplink - consider legal & FUP constraints - see notes
+const uint32_t uplinkIntervalSeconds = 1UL * 60UL; // minutes x seconds
+
+// joinEUI - previous versions of LoRaWAN called this AppEUI
+// for development purposes you can use all zeros - see wiki for details
+#define RADIOLIB_LORAWAN_JOIN_EUI 0x0000000000000000
+
+// the Device EUI & two keys can be generated on the TTN console
+#ifndef RADIOLIB_LORAWAN_DEV_EUI // Replace with your Device EUI
+#define RADIOLIB_LORAWAN_DEV_EUI 0x---------------
+#endif
+#ifndef RADIOLIB_LORAWAN_APP_KEY // Replace with your App Key
+#define RADIOLIB_LORAWAN_APP_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
+#endif
+#ifndef RADIOLIB_LORAWAN_NWK_KEY // Put your Nwk Key here
+#define RADIOLIB_LORAWAN_NWK_KEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
+#endif
+
+// for the curious, the #ifndef blocks allow for automated testing &/or you can
+// put your EUI & keys in to your platformio.ini - see wiki for more tips
+
+// regional choices: EU868, US915, AU915, AS923, AS923_2, AS923_3, AS923_4, IN865, KR920, CN500
+const LoRaWANBand_t Region = EU868;
+const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
+
+// ============================================================================
+// Below is to support the sketch - only make changes if the notes say so ...
+
+// copy over the EUI's & keys in to the something that will not compile if incorrectly formatted
+uint64_t joinEUI = RADIOLIB_LORAWAN_JOIN_EUI;
+uint64_t devEUI = RADIOLIB_LORAWAN_DEV_EUI;
+uint8_t appKey[] = { RADIOLIB_LORAWAN_APP_KEY };
+uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY };
+
+// create the LoRaWAN node
+LoRaWANNode node(&radio, &Region, subBand);
+
+// result code to text - these are error codes that can be raised when using LoRaWAN
+// however, RadioLib has many more - see https://jgromes.github.io/RadioLib/group__status__codes.html for a complete list
+String stateDecode(const int16_t result) {
+ switch (result) {
+ case RADIOLIB_ERR_NONE:
+ return "ERR_NONE";
+ case RADIOLIB_ERR_CHIP_NOT_FOUND:
+ return "ERR_CHIP_NOT_FOUND";
+ case RADIOLIB_ERR_PACKET_TOO_LONG:
+ return "ERR_PACKET_TOO_LONG";
+ case RADIOLIB_ERR_RX_TIMEOUT:
+ return "ERR_RX_TIMEOUT";
+ case RADIOLIB_ERR_MIC_MISMATCH:
+ return "ERR_MIC_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_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
diff --git a/examples/LoRaWAN/LoRaWAN_Multicast/LoRaWAN_Multicast.ino b/examples/LoRaWAN/LoRaWAN_Multicast/LoRaWAN_Multicast.ino
new file mode 100644
index 0000000000..7e5be0b0f4
--- /dev/null
+++ b/examples/LoRaWAN/LoRaWAN_Multicast/LoRaWAN_Multicast.ino
@@ -0,0 +1,133 @@
+/*
+ RadioLib LoRaWAN Multicast Example
+
+ This example joins a LoRaWAN network and starts a
+ Multicast session (only Multicast over Class C is implemented).
+ You should refer to the network's documentation on how
+ to create a Multicast group (or device).
+ Note that you can switch the device to Class C as well
+ to receive Unicast downlinks. In this case, you must
+ use the downlink event details to discern whether a
+ downlink belongs to the Unicast or Multicast session.
+
+ 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);
+
+ // Start a Multicast session over Class C
+ // (this will automatically perform a switch to Class C for Multicast)
+ node.startMulticastSession(RADIOLIB_LORAWAN_CLASS_C, mcDevAddr, mcAppSKey, mcNwkSKey);
+
+ Serial.println(F("Ready!\n"));
+}
+
+uint32_t lastUplink = 0;
+
+void loop() {
+ uint8_t downlinkPayload[255];
+ size_t downlinkLen = 0;
+ LoRaWANEvent_t downlinkEvent;
+
+ // check if a Class C downlink is ready for processing
+ // tip: internally, this just checks a boolean;
+ // it does not poll the radio over SPI.
+ // tip: you are not required to continuously call
+ // this function; you can do other stuff in between.
+ // however, a downlink may be overwritten if you
+ // don't call this function in time for the previous one.
+ int16_t state = node.getDownlinkClassC(downlinkPayload, &downlinkLen, &downlinkEvent);
+ if(state > 0) {
+ Serial.println(F("Received a Class C downlink!"));
+ // Did we get a downlink with data for us
+ if(downlinkLen > 0) {
+ Serial.println(F("Downlink data: "));
+ arrayDump(downlinkPayload, downlinkLen);
+ }
+
+ // print extra information about the event
+ Serial.println(F("[LoRaWAN] Event information:"));
+ Serial.print(F("[LoRaWAN] Datarate:\t"));
+ Serial.println(downlinkEvent.datarate);
+ Serial.print(F("[LoRaWAN] Frequency:\t"));
+ Serial.print(downlinkEvent.freq, 3);
+ Serial.println(F(" MHz"));
+ Serial.print(F("[LoRaWAN] Frame count:\t"));
+ Serial.println(downlinkEvent.fCnt);
+ Serial.print(F("[LoRaWAN] Port:\t\t"));
+ Serial.println(downlinkEvent.fPort);
+ Serial.println(F(" ms"));
+ Serial.print(F("[LoRaWAN] Rx window: \t"));
+ Serial.println(state);
+ Serial.print(F("[LoRaWAN] Cast:\t\t"));
+ Serial.println(downlinkEvent.multicast ? "Multi" : "Uni");
+ }
+
+ // if less than uplinkIntervalSeconds have elapsed since previous uplink,
+ // stop and go back to the top of the loop()
+ if(millis() - lastUplink < uplinkIntervalSeconds * 1000) {
+ return;
+ }
+
+ 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
+ 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/3 = downlink in window Rx1/Rx2/RxC)
+ 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"));
+
+ // set timestamp of last uplink
+ lastUplink = millis();
+}
diff --git a/examples/LoRaWAN/LoRaWAN_Multicast/config.h b/examples/LoRaWAN/LoRaWAN_Multicast/config.h
new file mode 100644
index 0000000000..bbe12e715d
--- /dev/null
+++ b/examples/LoRaWAN/LoRaWAN_Multicast/config.h
@@ -0,0 +1,154 @@
+#ifndef _RADIOLIB_EX_LORAWAN_CONFIG_H
+#define _RADIOLIB_EX_LORAWAN_CONFIG_H
+
+#include
+
+// first you have to set your radio model and pin configuration
+// this is provided just as a default example
+SX1262 radio = new Module(8, 14, 12, 13);
+
+// 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
+
+Radio radio = new RadioModule();
+*/
+
+// how often to send an uplink - consider legal & FUP constraints - see notes
+const uint32_t uplinkIntervalSeconds = 1UL * 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
+
+#ifndef RADIOLIB_LORAWAN_MC_DEV_ADDR // Replace with your Multicast Device Address
+#define RADIOLIB_LORAWAN_MC_DEV_ADDR 0x---------------
+#endif
+#ifndef RADIOLIB_LORAWAN_MC_APP_SKEY // Replace with your Multicast App SKey
+#define RADIOLIB_LORAWAN_MC_APP_SKEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
+#endif
+#ifndef RADIOLIB_LORAWAN_MC_NWK_SKEY // Put your Multicast Nwk SKey here
+#define RADIOLIB_LORAWAN_MC_NWK_SKEY 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--, 0x--
+#endif
+
+// for the curious, the #ifndef blocks allow for automated testing &/or you can
+// put your EUI & keys in to your platformio.ini - see wiki for more tips
+
+// regional choices: EU868, US915, AU915, AS923, AS923_2, AS923_3, AS923_4, IN865, KR920, CN500
+const LoRaWANBand_t Region = EU868;
+const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
+
+// ============================================================================
+// Below is to support the sketch - only make changes if the notes say so ...
+
+// copy over the EUI's & keys in to the something that will not compile if incorrectly formatted
+uint64_t joinEUI = RADIOLIB_LORAWAN_JOIN_EUI;
+uint64_t devEUI = RADIOLIB_LORAWAN_DEV_EUI;
+uint8_t appKey[] = { RADIOLIB_LORAWAN_APP_KEY };
+uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY };
+uint32_t mcDevAddr = RADIOLIB_LORAWAN_MC_DEV_ADDR;
+uint8_t mcAppSKey[] = { RADIOLIB_LORAWAN_MC_APP_SKEY };
+uint8_t mcNwkSKey[] = { RADIOLIB_LORAWAN_MC_NWK_SKEY };
+
+// 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_MIC_MISMATCH:
+ return "ERR_MIC_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_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
diff --git a/examples/LoRaWAN/LoRaWAN_Reference/LoRaWAN_Reference.ino b/examples/LoRaWAN/LoRaWAN_Reference/LoRaWAN_Reference.ino
new file mode 100644
index 0000000000..f39d08babd
--- /dev/null
+++ b/examples/LoRaWAN/LoRaWAN_Reference/LoRaWAN_Reference.ino
@@ -0,0 +1,205 @@
+/*
+ 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
+
+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);
+
+ // Optionally provide a custom sleep function - see config.h
+ //node.setSleepFunction(customDelay);
+
+ // Setup the OTAA session information
+ node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
+
+ // Override the default join rate
+ node.setDatarate(4);
+
+ Serial.println(F("Join ('login') the LoRaWAN Network"));
+ state = node.activateOTAA();
+ 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(""));
+ }
+
+ // 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 timestamp = 0;
+ uint16_t milliseconds = 0;
+ if(node.getMacDeviceTimeAns(×tamp, &milliseconds, true) == RADIOLIB_ERR_NONE) {
+ Serial.print(F("[LoRaWAN] DeviceTime Unix:\t"));
+ Serial.println(timestamp);
+ Serial.print(F("[LoRaWAN] DeviceTime frac:\t"));
+ Serial.print(milliseconds);
+ Serial.println(F(" ms"));
+ }
+
+ } 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);
+}
diff --git a/examples/LoRaWAN/LoRaWAN_Reference/config.h b/examples/LoRaWAN/LoRaWAN_Reference/config.h
new file mode 100644
index 0000000000..5de9cc98a1
--- /dev/null
+++ b/examples/LoRaWAN/LoRaWAN_Reference/config.h
@@ -0,0 +1,158 @@
+#ifndef _RADIOLIB_EX_LORAWAN_CONFIG_H
+#define _RADIOLIB_EX_LORAWAN_CONFIG_H
+
+#include
+
+// 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
+
+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_MIC_MISMATCH:
+ return "ERR_MIC_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_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
diff --git a/examples/LoRaWAN/LoRaWAN_Starter/LoRaWAN_Starter.ino b/examples/LoRaWAN/LoRaWAN_Starter/LoRaWAN_Starter.ino
new file mode 100644
index 0000000000..30b1e217c1
--- /dev/null
+++ b/examples/LoRaWAN/LoRaWAN_Starter/LoRaWAN_Starter.ino
@@ -0,0 +1,82 @@
+/*
+ RadioLib LoRaWAN Starter Example
+
+ ! Please refer to the included notes to get started !
+
+ This example joins a LoRaWAN network and will send
+ uplink packets. Before you start, you will have to
+ register your device at https://www.thethingsnetwork.org/
+ After your device is registered, you can run this example.
+ The device will join the network and start uploading data.
+
+ Running this examples REQUIRES you to check "Resets DevNonces"
+ on your LoRaWAN dashboard. Refer to the network's
+ documentation on how to do this.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+
+ For LoRaWAN details, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/LoRaWAN
+
+*/
+
+#include "config.h"
+
+void setup() {
+ Serial.begin(115200);
+ while(!Serial);
+ delay(5000); // Give time to switch to the serial monitor
+ Serial.println(F("\nSetup ... "));
+
+ Serial.println(F("Initialise the radio"));
+ int16_t state = radio.begin();
+ debug(state != RADIOLIB_ERR_NONE, F("Initialise radio failed"), state, true);
+
+ // Setup the OTAA session information
+ state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
+ debug(state != RADIOLIB_ERR_NONE, F("Initialise node failed"), state, true);
+
+ Serial.println(F("Join ('login') the LoRaWAN Network"));
+ state = node.activateOTAA();
+ debug(state != RADIOLIB_LORAWAN_NEW_SESSION, F("Join failed"), state, true);
+
+ Serial.println(F("Ready!\n"));
+}
+
+void loop() {
+ Serial.println(F("Sending uplink"));
+
+ // This is the place to gather the sensor inputs
+ // Instead of reading any real sensor, we just generate some random numbers as example
+ uint8_t value1 = radio.random(100);
+ uint16_t value2 = radio.random(2000);
+
+ // Build payload byte array
+ uint8_t uplinkPayload[3];
+ uplinkPayload[0] = value1;
+ uplinkPayload[1] = highByte(value2); // See notes for high/lowByte functions
+ uplinkPayload[2] = lowByte(value2);
+
+ // Perform an uplink
+ int16_t state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload));
+ debug(state < RADIOLIB_ERR_NONE, F("Error in sendReceive"), state, false);
+
+ // Check if a downlink was received
+ // (state 0 = no downlink, state 1/2 = downlink in window Rx1/Rx2)
+ if(state > 0) {
+ Serial.println(F("Received a downlink"));
+ } else {
+ Serial.println(F("No downlink received"));
+ }
+
+ Serial.print(F("Next uplink in "));
+ Serial.print(uplinkIntervalSeconds);
+ Serial.println(F(" seconds\n"));
+
+ // Wait until next uplink - observing legal & TTN FUP constraints
+ delay(uplinkIntervalSeconds * 1000UL); // delay needs milli-seconds
+}
diff --git a/examples/LoRaWAN/LoRaWAN_Starter/config.h b/examples/LoRaWAN/LoRaWAN_Starter/config.h
new file mode 100644
index 0000000000..7d025abc21
--- /dev/null
+++ b/examples/LoRaWAN/LoRaWAN_Starter/config.h
@@ -0,0 +1,143 @@
+#ifndef _RADIOLIB_EX_LORAWAN_CONFIG_H
+#define _RADIOLIB_EX_LORAWAN_CONFIG_H
+
+#include
+
+// 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
+
+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_MIC_MISMATCH:
+ return "ERR_MIC_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_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
diff --git a/examples/LoRaWAN/LoRaWAN_Starter/notes.md b/examples/LoRaWAN/LoRaWAN_Starter/notes.md
new file mode 100644
index 0000000000..9305968ef1
--- /dev/null
+++ b/examples/LoRaWAN/LoRaWAN_Starter/notes.md
@@ -0,0 +1,178 @@
+# 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. Chirpstack works just as well, but the buttons and labels may have different names. We discourage the use of Helium as it does not support LoRaWAN v1.1 and has some other odd limitations. Other LoRaWAN Network Servers (LNS) have not been tested by the developers, 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 RP002 Regional Parameters 1.0.4.
+
+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 retail sensors are being deployed, a device is registered, batteries put in, it joins and gets on with sending data for the next few years. For development purposes however 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.
diff --git a/examples/LoRaWAN/LoRaWAN_TS_Packages/LoRaWAN_TS009.h b/examples/LoRaWAN/LoRaWAN_TS_Packages/LoRaWAN_TS009.h
new file mode 100644
index 0000000000..63704d8ed1
--- /dev/null
+++ b/examples/LoRaWAN/LoRaWAN_TS_Packages/LoRaWAN_TS009.h
@@ -0,0 +1,238 @@
+#include
+#include
+// #include
+
+#warning "The variables below must match your main code. Please check your radio type!"
+extern SX1278 radio; // this can be any LoRaWAN-compatible type (e.g. SX1262)
+extern LoRaWANNode node;
+extern uint32_t periodicity;
+extern bool isConfirmed;
+extern bool reply;
+extern uint8_t dataUp[255];
+extern size_t lenUp;
+extern uint8_t fPort;
+
+#define RADIOLIB_LORAWAN_TS009_PACKAGE_VERSION (0x00)
+#define RADIOLIB_LORAWAN_TS009_DUT_RESET (0x01)
+#define RADIOLIB_LORAWAN_TS009_DUT_JOIN (0x02)
+#define RADIOLIB_LORAWAN_TS009_SWITCH_CLASS (0x03)
+#define RADIOLIB_LORAWAN_TS009_ADR_BIT_CHANGE (0x04)
+#define RADIOLIB_LORAWAN_TS009_REGIONAL_DUTY_CYCLE (0x05)
+#define RADIOLIB_LORAWAN_TS009_TX_PERIODICITY_CHANGE (0x06)
+#define RADIOLIB_LORAWAN_TS009_TX_FRAMES_CTRL (0x07)
+#define RADIOLIB_LORAWAN_TS009_ECHO_PAYLOAD (0x08)
+#define RADIOLIB_LORAWAN_TS009_RX_APP_CNT (0x09)
+#define RADIOLIB_LORAWAN_TS009_RX_APP_CNT_RESET (0x0A)
+#define RADIOLIB_LORAWAN_TS009_LINK_CHECK (0x20)
+#define RADIOLIB_LORAWAN_TS009_DEVICE_TIME (0x21)
+#define RADIOLIB_LORAWAN_TS009_PING_SLOT_INFO (0x22)
+#define RADIOLIB_LORAWAN_TS009_TX_CW (0x7D)
+#define RADIOLIB_LORAWAN_TS009_DUT_FPORT224_DISABLE (0x7E)
+#define RADIOLIB_LORAWAN_TS009_DUT_VERSIONS (0x7F)
+
+/*!
+ \brief This function implements the TS009 specification.
+ To enable this package, add this to your setup:
+ `node.addAppPackage(RADIOLIB_LORAWAN_PACKAGE_TS009, handleTS009)`
+ Make sure that all `extern` variables are handled in your user code!
+*/
+void handleTS009(uint8_t* dataDown, size_t lenDown) {
+ if(lenDown == 0 || dataDown == NULL) {
+ return;
+ }
+ RADIOLIB_DEBUG_PRINTLN("CID = %02x, len = %d", dataDown[0], lenDown - 1);
+
+ switch(dataDown[0]) {
+ case(RADIOLIB_LORAWAN_TS009_PACKAGE_VERSION): {
+ lenUp = 3;
+ dataUp[1] = 5; // PackageIdentifier
+ dataUp[2] = 1; // PackageVersion
+ fPort = RADIOLIB_LORAWAN_FPORT_TS009;
+ RADIOLIB_DEBUG_PRINTLN("PackageIdentifier: %d, PackageVersion: %d", dataUp[1], dataUp[2]);
+
+ reply = true;
+ } break;
+
+ case(RADIOLIB_LORAWAN_TS009_DUT_RESET): {
+ RADIOLIB_DEBUG_PRINTLN("Restarting...");
+
+ #warning "Please implement this reset function yourself!"
+
+ // the function to reset the MCU is platform-dependent
+ // for ESP32 for example, this would be:
+ // ESP.restart();
+
+ reply = false;
+ } break;
+
+ case(RADIOLIB_LORAWAN_TS009_DUT_JOIN): {
+ RADIOLIB_DEBUG_PRINTLN("Reverting to Join state");
+ node.clearSession();
+
+ reply = false;
+ } break;
+
+ case(RADIOLIB_LORAWAN_TS009_SWITCH_CLASS): {
+ uint8_t classType = dataDown[1];
+ node.setClass(classType);
+ RADIOLIB_DEBUG_PRINTLN("Switching to class: %s", classType == 0 ? "A" : (classType == 1 ? "B" : "C"));
+
+ reply = false;
+ } break;
+
+ case(RADIOLIB_LORAWAN_TS009_ADR_BIT_CHANGE): {
+ bool adr = (bool)dataDown[1];
+ node.setADR(adr);
+ RADIOLIB_DEBUG_PRINTLN("ADR: %d", adr);
+
+ reply = false;
+ } break;
+
+ case(RADIOLIB_LORAWAN_TS009_REGIONAL_DUTY_CYCLE): {
+ bool dutycycle = (bool)dataDown[1];
+ node.setDutyCycle(dutycycle, 36000);
+ RADIOLIB_DEBUG_PRINTLN("Dutycycle: %d", dutycycle);
+
+ reply = false;
+ } break;
+
+ case(RADIOLIB_LORAWAN_TS009_TX_PERIODICITY_CHANGE): {
+ uint32_t defaultIntervalSecs = 30;
+ uint32_t intervals[11] = {defaultIntervalSecs, 5, 10, 20, 30, 40, 50, 60, 120, 240, 480};
+ periodicity = intervals[dataDown[1]];
+
+ RADIOLIB_DEBUG_PRINTLN("Tx Periodicity: %d", periodicity);
+
+ reply = false;
+ } break;
+
+ case(RADIOLIB_LORAWAN_TS009_TX_FRAMES_CTRL): {
+ switch(dataDown[1]) {
+ case(0):
+ // no change
+ // isConfirmed = isConfirmed;
+ break;
+ case(1):
+ isConfirmed = false;
+ break;
+ case(2):
+ isConfirmed = true;
+ break;
+ }
+ RADIOLIB_DEBUG_PRINTLN("Confirmed: %d", isConfirmed);
+
+ reply = false;
+ } break;
+
+ case(RADIOLIB_LORAWAN_TS009_ECHO_PAYLOAD): {
+ lenUp = lenDown;
+ for (size_t i = 1; i < lenDown; i++) {
+ dataUp[i] = dataDown[i] + 1;
+ }
+ fPort = RADIOLIB_LORAWAN_FPORT_TS009;
+ RADIOLIB_DEBUG_PRINTLN("Echoing payload");
+
+ reply = true;
+ } break;
+
+ case(RADIOLIB_LORAWAN_TS009_RX_APP_CNT): {
+ lenUp = 3;
+ uint16_t aFcntDown16 = (uint16_t)node.getAFCntDown();
+ dataUp[1] = aFcntDown16 & 0xFF;
+ dataUp[2] = aFcntDown16 >> 8;
+ fPort = RADIOLIB_LORAWAN_FPORT_TS009;
+ RADIOLIB_DEBUG_PRINTLN("aFCntDown16: %d", aFcntDown16);
+
+ reply = true;
+ } break;
+
+ case(RADIOLIB_LORAWAN_TS009_RX_APP_CNT_RESET): {
+ RADIOLIB_DEBUG_PRINTLN("Resetting Application Frame count");
+ RADIOLIB_DEBUG_PRINTLN("WARNING: not implemented - never used in tests!");
+
+ reply = false;
+ } break;
+
+ case(RADIOLIB_LORAWAN_TS009_LINK_CHECK): {
+ lenUp = 0;
+ fPort = RADIOLIB_LORAWAN_FPORT_MAC_COMMAND;
+ node.sendMacCommandReq(RADIOLIB_LORAWAN_MAC_LINK_CHECK);
+ RADIOLIB_DEBUG_PRINTLN("Requesting LinkCheck");
+
+ reply = true;
+ } break;
+
+ case(RADIOLIB_LORAWAN_TS009_DEVICE_TIME): {
+ lenUp = 0;
+ fPort = RADIOLIB_LORAWAN_FPORT_MAC_COMMAND;
+ node.sendMacCommandReq(RADIOLIB_LORAWAN_MAC_DEVICE_TIME);
+ RADIOLIB_DEBUG_PRINTLN("Requesting DeviceTime");
+
+ reply = true;
+ } break;
+
+ case(RADIOLIB_LORAWAN_TS009_PING_SLOT_INFO): {
+ lenUp = 0;
+ RADIOLIB_DEBUG_PRINTLN("Requesting PingSlotInfo not implemented");
+ // send PingSlotInfo MAC command which is not implemented
+ reply = false;
+ } break;
+
+ case(RADIOLIB_LORAWAN_TS009_TX_CW): {
+ uint16_t timeout = ((uint16_t)dataDown[2] << 8) | (uint16_t)dataDown[1];
+ uint32_t freqRaw = ((uint32_t)dataDown[5] << 16) | ((uint32_t)dataDown[4] << 8) | ((uint32_t)dataDown[3]);
+ float freq = (float)freqRaw/10000.0;
+ uint8_t txPower = dataDown[6];
+ RADIOLIB_DEBUG_PRINTLN("Continuous wave: %7.3f MHz, %d dBm, %d s", freq, txPower, timeout);
+ radio.setFrequency(freq);
+ radio.setOutputPower(txPower);
+ radio.transmitDirect();
+ delay(timeout * 1000);
+ radio.standby();
+
+ reply = false;
+ } break;
+
+ case(RADIOLIB_LORAWAN_TS009_DUT_FPORT224_DISABLE): {
+ RADIOLIB_DEBUG_PRINTLN("Disabling FPort 224");
+ node.removePackage(RADIOLIB_LORAWAN_PACKAGE_TS009);
+
+ reply = false;
+ } break;
+
+ case(RADIOLIB_LORAWAN_TS009_DUT_VERSIONS): {
+ lenUp = 13;
+ // firmware version - this is RadioLib's version as an example
+ dataUp[1] = RADIOLIB_VERSION_MAJOR;
+ dataUp[2] = RADIOLIB_VERSION_MINOR;
+ dataUp[3] = RADIOLIB_VERSION_PATCH;
+ dataUp[4] = RADIOLIB_VERSION_EXTRA;
+
+ // lorawan version
+ dataUp[5] = 1;
+#if (LORAWAN_VERSION == 1)
+ dataUp[6] = 1;
+ dataUp[7] = 0;
+#else
+ dataUp[6] = 0;
+ dataUp[7] = 4;
+#endif
+ dataUp[8] = 0;
+
+ // regional parameters version
+ dataUp[9] = 1;
+ dataUp[10] = 0;
+ dataUp[11] = 4;
+ dataUp[12] = 0;
+ fPort = RADIOLIB_LORAWAN_FPORT_TS009;
+ RADIOLIB_DEBUG_PRINTLN("Requested DUT versions");
+
+ reply = true;
+ } break;
+ }
+
+ // if we must reply, copy the command ID into the uplink buffer
+ if(reply) {
+ dataUp[0] = dataDown[0];
+ }
+}
\ No newline at end of file
diff --git a/examples/LoRaWAN/LoRaWAN_TS_Packages/LoRaWAN_TS_Packages.ino b/examples/LoRaWAN/LoRaWAN_TS_Packages/LoRaWAN_TS_Packages.ino
new file mode 100644
index 0000000000..df1cf5f308
--- /dev/null
+++ b/examples/LoRaWAN/LoRaWAN_TS_Packages/LoRaWAN_TS_Packages.ino
@@ -0,0 +1,171 @@
+/*
+ RadioLib LoRaWAN Packages Example
+
+ This example shows how the TS009 package can be used
+ and is the sketch used for passing pre-certification testing.
+ This scheme can also be used for other future packages
+ such as TS003/004/005/006/007 which, combined, build FUOTA.
+
+ PLEASE NOTE that this is a highly customized sketch with
+ settings that likely violate laws & regulations, and it is
+ intended to be used with RF blocking materials and attenuators.
+
+ 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
+#include
+
+#include "LoRaWAN_TS009.h"
+#include "config.h"
+#include "lorawan.h"
+
+uint32_t periodicity = uplinkIntervalSeconds;
+bool isConfirmed = false;
+bool reply = false;
+
+uint8_t fPort = 1;
+uint8_t dataUp[255];
+uint8_t dataDown[255];
+size_t lenUp = 0;
+size_t lenDown = 0;
+
+void setup() {
+ Serial.begin(115200);
+ delay(3000);
+
+ Serial.print(F("Initialise the radio ... "));
+ int state = radio.begin();
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while(true);
+ }
+
+ // setup, restore and join the network
+ lwBegin();
+ lwRestore();
+ lwActivate();
+
+ // add TS009 package
+ node.addAppPackage(RADIOLIB_LORAWAN_PACKAGE_TS009, handleTS009);
+
+ // LCTT (TS009 testing) has a huge timing problem on the JoinAccept Rx2 window...
+ node.scanGuard = 100;
+
+ // these settings are totally not recommended
+ // but unfortunately they are the default settings for TS009 testing
+ node.setDutyCycle(false);
+ node.setADR(false);
+}
+
+void loop() {
+ while(!node.isActivated()) {
+ lwActivate();
+ // this 5s interval is way too short for normal use!
+ // but you'd be waiting around for long minutes during TS009 testing otherwise
+ if(!node.isActivated()) {
+ delay(5000);
+ }
+ node.setDutyCycle(false);
+ }
+
+ int state = RADIOLIB_ERR_NONE;
+ LoRaWANEvent_t eventUp;
+ LoRaWANEvent_t eventDown;
+
+ uint32_t start = millis();
+
+ Serial.println("--------------------");
+ Serial.println("[LoRaWAN] Sending uplink packet ... ");
+ if (!reply) {
+ memset(dataUp, 0, 255);
+ lenUp = 4;
+ fPort = 1;
+ sprintf((char*)dataUp, "%04lu", node.getFCntUp());
+ state = node.sendReceive(dataUp, lenUp, fPort, dataDown, &lenDown, isConfirmed, &eventUp, &eventDown);
+ } else {
+ reply = false;
+ state = node.sendReceive(dataUp, lenUp, fPort, dataDown, &lenDown, isConfirmed, &eventUp, &eventDown);
+ }
+
+ if(state >= RADIOLIB_ERR_NONE) {
+ Serial.println(F("[LoRaWAN] success!"));
+ }
+
+ if(state > 0) {
+ // print data of the packet (if there are any)
+ Serial.print(F("[LoRaWAN] Data:\t\t"));
+ if(lenDown > 0) {
+ arrayDump(dataDown, lenDown);
+ } else {
+ Serial.println(F(""));
+ }
+
+ Serial.print(F("[LoRaWAN] FPort:\t"));
+ Serial.print(eventDown.fPort);
+
+ // 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"));
+
+ 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 timestamp = 0;
+ uint16_t milliseconds = 0;
+ if(node.getMacDeviceTimeAns(×tamp, &milliseconds, true) == RADIOLIB_ERR_NONE) {
+ Serial.print(F("[LoRaWAN] DeviceTime Unix:\t"));
+ Serial.println(timestamp);
+ Serial.print(F("[LoRaWAN] DeviceTime frac:\t"));
+ Serial.print(milliseconds);
+ Serial.println(F(" ms"));
+ }
+
+ } else if(state == 0) {
+ Serial.println(F("No downlink!"));
+
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ }
+
+ uint32_t end = millis();
+
+ uint32_t delayDc = node.timeUntilUplink();
+ uint32_t delayMs = periodicity*1000;
+ if(delayMs > end - start) {
+ delayMs -= (end - start);
+ } else {
+ delayMs = 1;
+ }
+ delayMs += 50;
+ Serial.print(F("Delay: "));
+ Serial.print(max(delayDc, delayMs));
+ Serial.println(F(" ms"));
+
+ // wait before sending another packet
+ delay(max(delayDc, delayMs));
+}
\ No newline at end of file
diff --git a/examples/LoRaWAN/LoRaWAN_TS_Packages/config.h b/examples/LoRaWAN/LoRaWAN_TS_Packages/config.h
new file mode 100644
index 0000000000..9c64a4da04
--- /dev/null
+++ b/examples/LoRaWAN/LoRaWAN_TS_Packages/config.h
@@ -0,0 +1,115 @@
+#ifndef _CONFIG_H
+#define _CONFIG_H
+
+#include
+
+// 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
+
+Radio radio = new RadioModule();
+*/
+
+// how often to send an uplink - consider legal & FUP constraints
+const uint32_t uplinkIntervalSeconds = 1UL * 60UL; // minutes x seconds
+
+#define LORAWAN_VERSION (0) // use version 1.LORAWAN_VERSION when joining
+#define LORAWAN_OTAA (1) // use OTAA (1) or ABP (0)
+
+#if (LORAWAN_OTAA == 1)
+// 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
+
+// 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 };
+
+#if (LORAWAN_VERSION == 1)
+#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
+uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY }; // LW v1.1 only
+#endif
+
+#else // ABP
+
+#ifndef RADIOLIB_LORAWAN_DEV_ADDR // Replace with your DevAddr
+#define RADIOLIB_LORAWAN_DEV_ADDR 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
+
+// copy over the keys in to the something that will not compile if incorrectly formatted
+uint32_t devAddr = RADIOLIB_LORAWAN_DEV_ADDR;
+uint8_t sNwkSEncKey[] = { RADIOLIB_LORAWAN_NWKSENC_KEY };
+uint8_t appSKey[] = { RADIOLIB_LORAWAN_APPS_KEY };
+
+#if (LORAWAN_VERSION == 1)
+#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
+uint8_t fNwkSIntKey[] = { RADIOLIB_LORAWAN_FNWKSINT_KEY }; // LW v1.1 only
+uint8_t sNwkSIntKey[] = { RADIOLIB_LORAWAN_SNWKSINT_KEY }; // LW v1.1 only
+#endif
+
+#endif // OTAA/ABP
+
+// 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, IN865, KR920, CN780, CN500
+const LoRaWANBand_t Region = EU868;
+const uint8_t subBand = 0; // For US915, change this to 2, otherwise leave on 0
+
+// ============================================================================
+// Below is to support the sketch - only make changes if the notes say so ...
+
+// create the LoRaWAN node
+LoRaWANNode node(&radio, &Region, subBand);
+
+// helper function to display any issues
+void debug(bool isFail, const __FlashStringHelper* message, int state, bool Freeze) {
+ if (isFail) {
+ Serial.print(message);
+ Serial.print("(");
+ Serial.print(state);
+ Serial.println(")");
+ while (Freeze);
+ }
+}
+
+// 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
\ No newline at end of file
diff --git a/examples/LoRaWAN/LoRaWAN_TS_Packages/lorawan.h b/examples/LoRaWAN/LoRaWAN_TS_Packages/lorawan.h
new file mode 100644
index 0000000000..95220fcbc6
--- /dev/null
+++ b/examples/LoRaWAN/LoRaWAN_TS_Packages/lorawan.h
@@ -0,0 +1,76 @@
+#ifndef _LORAWAN_H
+#define _LORAWAN_H
+
+#include
+#include "config.h"
+
+#warning "You are required to implement persistence here! (ESP32 example provided in comments)"
+
+// #include
+// Preferences store;
+// uint8_t LWnonces[RADIOLIB_LORAWAN_NONCES_BUF_SIZE];
+
+bool lwBegin() {
+#if (LORAWAN_OTAA == 1)
+ #if (LORAWAN_VERSION == 1)
+ node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
+ #else
+ node.beginOTAA(joinEUI, devEUI, NULL, appKey);
+ #endif
+#else
+ #if (LORAWAN_VERSION == 1)
+ node.beginABP(devAddr, fNwkSIntKey, sNwkSIntKey, sNwkSEncKey, appSKey);
+ #else
+ node.beginABP(devAddr, NULL, NULL, sNwkSEncKey, appSKey);
+ #endif
+#endif
+ return(true);
+}
+
+int16_t lwRestore() {
+ int16_t state = RADIOLIB_ERR_UNKNOWN;
+
+ // store.begin("radiolib");
+ // if (store.isKey("nonces")) {
+ // radio.standby();
+
+ // store.getBytes("nonces", LWnonces, RADIOLIB_LORAWAN_NONCES_BUF_SIZE);
+ // state = node.setBufferNonces(LWnonces);
+ // }
+ // store.end();
+
+ return(state);
+}
+
+void lwActivate() {
+ int16_t state = RADIOLIB_ERR_NETWORK_NOT_JOINED;
+ Serial.println(F("[LoRaWAN] Attempting network join ... "));
+
+ radio.standby();
+
+#if (LORAWAN_OTAA == 1)
+ state = node.activateOTAA();
+#else
+ state = node.activateABP();
+#endif
+
+ if(state == RADIOLIB_LORAWAN_SESSION_RESTORED) {
+ Serial.println(F("[LoRaWAN] Session restored!"));
+ return;
+ }
+
+ // store.begin("radiolib");
+ // uint8_t *persist = node.getBufferNonces();
+ // store.putBytes("nonces", persist, RADIOLIB_LORAWAN_NONCES_BUF_SIZE);
+ // store.end();
+
+ if(state == RADIOLIB_LORAWAN_NEW_SESSION) {
+ Serial.println(F("[LoRaWAN] Successfully started new session!"));
+ return;
+ }
+
+ Serial.print(F("[LoRaWAN] Failed, code "));
+ Serial.println(state);
+}
+
+#endif
\ No newline at end of file
diff --git a/examples/LoRaWAN/README.md b/examples/LoRaWAN/README.md
new file mode 100644
index 0000000000..2ad96c20a8
--- /dev/null
+++ b/examples/LoRaWAN/README.md
@@ -0,0 +1,14 @@
+# 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, this example shows how you can do this using RadioLib. However, to comply with the specification, the full session must persist through resets and power loss - you would need proper NVM for this. Really, we recommend using OTAA.
+* [LoRaWAN_Class_C](https://github.com/jgromes/RadioLib/tree/master/examples/LoRaWAN/LoRaWAN_Class_C): this shows how to use Class C on top of Class A. This is useful for continuously-powered devices (no batteries) such as lights. If you deploy multiple similar devices, please use Multicast instead.
+* [LoRaWAN_Multicast](https://github.com/jgromes/RadioLib/tree/master/examples/LoRaWAN/LoRaWAN_Multicast): a showcase of Multicast over Class C. This is particularly useful for groups of devices such as a series of street lights.
+
+> [!CAUTION]
+> These examples are quick wins during development. However, for production devices, you will need to add persistence to your device. See the wiki for more details, or head straight to some [persistence examples](https://github.com/radiolib-org/radiolib-persistence).
+
+> [!TIP]
+> Refer to the [Wiki](https://github.com/jgromes/RadioLib/wiki/LoRaWAN) for guides and information, for example on LoRaWAN versions, registering your device and more.
diff --git a/examples/MQTT/MQTT_Publish/MQTT_Publish.ino b/examples/MQTT/MQTT_Publish/MQTT_Publish.ino
deleted file mode 100644
index faf8817d07..0000000000
--- a/examples/MQTT/MQTT_Publish/MQTT_Publish.ino
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- RadioLib MQTT Publish Example
-
- This example publishes MQTT messages using ESP8266 WiFi module.
-
- The messages are published to https://shiftr.io/try. You can use this namespace
- for testing purposes, but remember that it is publicly accessible!
-
- IMPORTANT: Before uploading this example, make sure that the ESP8266 module is running
- AT firmware (can be found in the /extras folder of the library)!
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
-*/
-
-// include the library
-#include
-
-// ESP8266 has the following connections:
-// TX pin: 9
-// RX pin: 8
-ESP8266 wifi = new SerialModule(9, 8);
-
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//ESP8266 wifi = RadioShield.ModuleA;
-
-// create MQTT client instance using the wifi module
-// the default port used for MQTT is 1883
-MQTTClient mqtt(&wifi, 1883);
-
-void setup() {
- Serial.begin(9600);
-
- // initialize ESP8266
- Serial.print(F("[ESP8266] Initializing ... "));
- // baudrate: 9600 baud
- int state = wifi.begin(9600);
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-
- // join access point
- Serial.print(F("[ESP8266] Joining AP ... "));
- // name: SSID
- // password: password
- state = wifi.join("SSID", "password");
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-
- // connect to MQTT server
- Serial.print(F("[ESP8266] Connecting to MQTT server ... "));
- // server URL: broker.shiftr.io
- // client ID: arduino
- // username: try
- // password: try
- state = mqtt.connect("broker.shiftr.io", "arduino", "try", "try");
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-}
-
-void loop() {
- // publish MQTT message
- Serial.print(F("[ESP8266] Publishing MQTT message ... "));
- // topic name: hello
- // application message: world
- int state = mqtt.publish("hello", "world");
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- }
-
- // wait for a second before publishing again
- delay(1000);
-}
diff --git a/examples/MQTT/MQTT_Subscribe/MQTT_Subscribe.ino b/examples/MQTT/MQTT_Subscribe/MQTT_Subscribe.ino
deleted file mode 100644
index 093eb02eb2..0000000000
--- a/examples/MQTT/MQTT_Subscribe/MQTT_Subscribe.ino
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- RadioLib MQTT Subscribe Example
-
- This example subscribes to MQTT topic using ESP8266 WiFi module.
-
- The messages are pulled from https://shiftr.io/try. You can use this namespace
- for testing purposes, but remember that it is publicly accessible!
-
- IMPORTANT: Before uploading this example, make sure that the ESP8266 module is running
- AT firmware (can be found in the /extras folder of the library)!
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
-*/
-
-// include the library
-#include
-
-// ESP8266 has the following connections:
-// TX pin: 9
-// RX pin: 8
-ESP8266 wifi = new SerialModule(9, 8);
-
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//ESP8266 wifi = RadioShield.ModuleA;
-
-// create MQTT client instance using the wifi module
-// the default port used for MQTT is 1883
-MQTTClient mqtt(&wifi, 1883);
-
-void setup() {
- Serial.begin(9600);
-
- // initialize ESP8266
- Serial.print(F("[ESP8266] Initializing ... "));
- // baudrate: 9600 baud
- int state = wifi.begin(9600);
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-
- // join access point
- Serial.print(F("[ESP8266] Joining AP ... "));
- // name: SSID
- // password: password
- state = wifi.join("SSID", "password");
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-
- // connect to MQTT server
- Serial.print(F("[ESP8266] Connecting to MQTT server ... "));
- // server URL: broker.shiftr.io
- // client ID: arduino
- // username: try
- // password: try
- state = mqtt.connect("broker.shiftr.io", "arduino", "try", "try");
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-
- // subscribe to MQTT topic
- // after calling this method, server will send PUBLISH packets
- // to this client each time a new message was published at the topic
- Serial.print(F("[ESP8266] Subscribing to MQTT topic ... "));
- // topic name: hello
- state = mqtt.subscribe("hello");
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- }
-
- // unsubscribe from MQTT topic
- // after calling this method, server will stop sending PUBLISH packets
- Serial.print(F("[ESP8266] Unsubscribing from MQTT topic ... "));
- // topic filter: hello
- state = mqtt.unsubscribe("hello");
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- }
-}
-
-// create a function that will be called when a new PUBLISH packet
-// arrives from the server
-//
-// IMPORTANT: This function MUST have two C-strings as arguments!
-void onPublish(const char* topic, const char* message) {
- Serial.println(F("[ESP8266] Received packet from MQTT server: "));
- Serial.print(F("[ESP8266] Topic:\t"));
- Serial.println(topic);
- Serial.print(F("[ESP8266] Message:\t"));
- Serial.println(message);
-}
-
-void loop() {
- // check for new MQTT packets from server each time the loop() runs
- // this will also send a PING packet, restarting the keep alive timer
- int state = mqtt.check(onPublish);
- Serial.print(F("[ESP8266] MQTT check "));
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- }
-
- // the rest of your loop() code goes here
- // make sure that the maximum time the loop() runs is less than 1.5x keep alive,
- // otherwise the server will close the network connection
-}
diff --git a/examples/Morse/Morse_Receive_AM/Morse_Receive_AM.ino b/examples/Morse/Morse_Receive_AM/Morse_Receive_AM.ino
new file mode 100644
index 0000000000..e4fb4037a6
--- /dev/null
+++ b/examples/Morse/Morse_Receive_AM/Morse_Receive_AM.ino
@@ -0,0 +1,119 @@
+/*
+ RadioLib SX127x Morse Receive AM Example
+
+ This example receives Morse code message using
+ SX1278's FSK modem. The signal is expected to be
+ modulated as OOK, to be demodulated in AM mode.
+
+ Other modules that can be used for Morse Code
+ with AFSK modulation:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - Si443x/RFM2x
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1278 has the following connections:
+// NSS pin: 10
+// DIO0 pin: 2
+// RESET pin: 9
+// DIO1 pin: 3
+SX1278 radio = new Module(10, 2, 9, 3);
+
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// create AFSK client instance using the FSK module
+// pin 5 is connected to SX1278 DIO2
+AFSKClient audio(&radio, 5);
+
+// create Morse client instance using the AFSK instance
+MorseClient morse(&audio);
+
+void setup() {
+ Serial.begin(9600);
+
+ // initialize SX1278 with default settings
+ Serial.print(F("[SX1278] Initializing ... "));
+ int state = radio.beginFSK();
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // when using one of the non-LoRa modules for Morse code
+ // (RF69, CC1101, Si4432 etc.), use the basic begin() method
+ // int state = radio.begin();
+
+ // initialize Morse client
+ Serial.print(F("[Morse] Initializing ... "));
+ // AFSK tone frequency: 400 Hz
+ // speed: 20 words per minute
+ state = morse.begin(400);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // after that, set mode to OOK to emulate AM modulation
+ Serial.print(F("[SX1278] Switching to OOK ... "));
+ state = radio.setOOK(true);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // start direct mode reception
+ radio.receiveDirect();
+}
+
+// save symbol and length between loops
+byte symbol = 0;
+byte len = 0;
+
+void loop() {
+ // try to read a new symbol
+ int state = morse.read(&symbol, &len);
+
+ // check if we have something to decode
+ if(state != RADIOLIB_MORSE_INTER_SYMBOL) {
+ // decode and print
+ Serial.print(MorseClient::decode(symbol, len));
+
+ // reset the symbol buffer
+ symbol = 0;
+ len = 0;
+
+ // check if we have a complete word
+ if(state == RADIOLIB_MORSE_WORD_COMPLETE) {
+ // inter-word space, interpret that as a new line
+ Serial.println();
+ }
+
+ }
+
+}
diff --git a/examples/Morse/Morse_Transmit_AM/Morse_Transmit_AM.ino b/examples/Morse/Morse_Transmit_AM/Morse_Transmit_AM.ino
new file mode 100644
index 0000000000..b81ba86176
--- /dev/null
+++ b/examples/Morse/Morse_Transmit_AM/Morse_Transmit_AM.ino
@@ -0,0 +1,135 @@
+/*
+ RadioLib Morse Transmit AM Example
+
+ This example sends Morse code message using
+ SX1278's FSK modem. The signal is modulated
+ as OOK, and may be demodulated in AM mode.
+
+ Other modules that can be used for Morse Code
+ with AM modulation:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - Si443x/RFM2x
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1278 has the following connections:
+// NSS pin: 10
+// DIO0 pin: 2
+// RESET pin: 9
+// DIO1 pin: 3
+SX1278 radio = new Module(10, 2, 9, 3);
+
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// create AFSK client instance using the FSK module
+// pin 5 is connected to SX1278 DIO2
+AFSKClient audio(&radio, 5);
+
+// create Morse client instance using the AFSK instance
+MorseClient morse(&audio);
+
+void setup() {
+ Serial.begin(9600);
+
+ // initialize SX1278 with default settings
+ Serial.print(F("[SX1278] Initializing ... "));
+ int state = radio.beginFSK();
+
+ // when using one of the non-LoRa modules for Morse code
+ // (RF69, CC1101, Si4432 etc.), use the basic begin() method
+ // int state = radio.begin();
+
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // initialize Morse client
+ Serial.print(F("[Morse] Initializing ... "));
+ // tone frequency: 400 Hz
+ // speed: 20 words per minute
+ state = morse.begin(400);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // after that, set mode to OOK to emulate AM modulation
+ Serial.print(F("[SX1278] Switching to OOK ... "));
+ state = radio.setOOK(true);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+}
+
+void loop() {
+ Serial.print(F("[Morse] Sending Morse data ... "));
+
+ // MorseClient supports all methods of the Serial class
+ // NOTE: Characters that do not have ITU-R M.1677-1
+ // representation will not be sent! Lower case
+ // letters will be capitalized.
+
+ // send start signal first
+ morse.startSignal();
+
+ // Arduino String class
+ String aStr = "Arduino String";
+ morse.print(aStr);
+
+ // character array (C-String)
+ morse.print("C-String");
+
+ // string saved in flash
+ morse.print(F("Flash String"));
+
+ // character
+ morse.print('c');
+
+ // byte
+ // formatting DEC/HEX/OCT/BIN is supported for
+ // any integer type (byte/int/long)
+ morse.print(255, HEX);
+
+ // integer number
+ int i = 1000;
+ morse.print(i);
+
+ // floating point number
+ // NOTE: When using println(), the transmission will be
+ // terminated with end-of-work signal (...-.-).
+ float f = -3.1415;
+ morse.println(f, 3);
+
+ Serial.println(F("done!"));
+
+ // wait for a second before transmitting again
+ delay(1000);
+}
diff --git a/examples/Morse/Morse_Transmit_AFSK/Morse_Transmit_AFSK.ino b/examples/Morse/Morse_Transmit_FM/Morse_Transmit_FM.ino
similarity index 65%
rename from examples/Morse/Morse_Transmit_AFSK/Morse_Transmit_AFSK.ino
rename to examples/Morse/Morse_Transmit_FM/Morse_Transmit_FM.ino
index ad89cb49a5..b4ba7865f0 100644
--- a/examples/Morse/Morse_Transmit_AFSK/Morse_Transmit_AFSK.ino
+++ b/examples/Morse/Morse_Transmit_FM/Morse_Transmit_FM.ino
@@ -1,23 +1,24 @@
/*
- RadioLib Morse Transmit AFSK Example
-
- This example sends Morse code message using
- SX1278's FSK modem. The data is modulated
- as AFSK.
-
- Other modules that can be used for Morse Code
- with AFSK modulation:
- - SX127x/RFM9x
- - RF69
- - SX1231
- - CC1101
- - Si443x/RFM2x
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ RadioLib Morse Transmit AFSK Example
+
+ This example sends Morse code message using
+ SX1278's FSK modem. The signal is modulated
+ as AFSK, and may be demodulated in FM mode.
+
+ Other modules that can be used for Morse Code
+ with AFSK modulation:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - Si443x/RFM2x
+ - SX126x/LLCC68
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -30,12 +31,23 @@
// DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// create AFSK client instance using the FSK module
-// pin 5 is connected to SX1278 DIO2
+// this requires connection to the module direct
+// input pin, here connected to Arduino pin 5
+// SX127x/RFM9x: DIO2
+// RF69: DIO2
+// SX1231: DIO2
+// CC1101: GDO2
+// Si443x/RFM2x: GPIO
+// SX126x/LLCC68: DIO2
AFSKClient audio(&radio, 5);
// create Morse client instance using the AFSK instance
@@ -52,25 +64,25 @@ void setup() {
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
// int state = radio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// initialize Morse client
Serial.print(F("[Morse] Initializing ... "));
- // AFSK tone frequency: 400 MHz
+ // tone frequency: 400 Hz
// speed: 20 words per minute
state = morse.begin(400);
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
}
diff --git a/examples/Morse/Morse_Transmit/Morse_Transmit.ino b/examples/Morse/Morse_Transmit_SSB/Morse_Transmit_SSB.ino
similarity index 68%
rename from examples/Morse/Morse_Transmit/Morse_Transmit.ino
rename to examples/Morse/Morse_Transmit_SSB/Morse_Transmit_SSB.ino
index 9c39a3b7dd..f7615e2006 100644
--- a/examples/Morse/Morse_Transmit/Morse_Transmit.ino
+++ b/examples/Morse/Morse_Transmit_SSB/Morse_Transmit_SSB.ino
@@ -1,24 +1,26 @@
/*
- RadioLib Morse Transmit Example
-
- This example sends Morse code message using
- SX1278's FSK modem.
-
- Other modules that can be used for Morse Code:
- - SX127x/RFM9x
- - RF69
- - SX1231
- - CC1101
- - SX126x
- - nRF24
- - Si443x/RFM2x
- - SX128x
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ RadioLib Morse Transmit SSB Example
+
+ This example sends Morse code message using
+ SX1278's FSK modem. The signal is an unmodulated
+ carrier wave, and may be demodulated in SSB mode.
+
+ Other modules that can be used for Morse Code:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - SX126x
+ - nRF24
+ - Si443x/RFM2x
+ - SX128x
+ - LR11x0
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -31,9 +33,13 @@
// DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// create Morse client instance using the FSK module
MorseClient morse(&radio);
@@ -49,25 +55,25 @@ void setup() {
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
// int state = radio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// initialize Morse client
Serial.print(F("[Morse] Initializing ... "));
- // base frequency: 434.0 MHz
+ // carrier wave frequency: 434.0 MHz
// speed: 20 words per minute
state = morse.begin(434.0);
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
}
diff --git a/examples/NonArduino/ESP-IDF/.gitignore b/examples/NonArduino/ESP-IDF/.gitignore
new file mode 100644
index 0000000000..a6007c83eb
--- /dev/null
+++ b/examples/NonArduino/ESP-IDF/.gitignore
@@ -0,0 +1,4 @@
+# generated by ESP-IDF
+managed_components/
+dependencies.lock
+sdkconfig
diff --git a/examples/NonArduino/ESP-IDF/CMakeLists.txt b/examples/NonArduino/ESP-IDF/CMakeLists.txt
new file mode 100644
index 0000000000..a726278da6
--- /dev/null
+++ b/examples/NonArduino/ESP-IDF/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.16)
+
+# include the top-level cmake
+include($ENV{IDF_PATH}/tools/cmake/project.cmake)
+
+# name the project something nice
+project(esp-sx1261)
diff --git a/examples/NonArduino/ESP-IDF/README.md b/examples/NonArduino/ESP-IDF/README.md
new file mode 100644
index 0000000000..df1d0b728b
--- /dev/null
+++ b/examples/NonArduino/ESP-IDF/README.md
@@ -0,0 +1,11 @@
+# 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
+* `sdkconfig.defaults` - List of preset configuration option values for ESP-IDF. All other options use default values provided by ESP-IDF.
diff --git a/examples/NonArduino/ESP-IDF/main/CMakeLists.txt b/examples/NonArduino/ESP-IDF/main/CMakeLists.txt
new file mode 100644
index 0000000000..1f57116422
--- /dev/null
+++ b/examples/NonArduino/ESP-IDF/main/CMakeLists.txt
@@ -0,0 +1,4 @@
+# register the component and set "RadioLib", "esp_timer" and "driver" as required
+idf_component_register(SRCS "main.cpp"
+ INCLUDE_DIRS "."
+ REQUIRES RadioLib esp_timer driver)
diff --git a/examples/NonArduino/ESP-IDF/main/EspHal.h b/examples/NonArduino/ESP-IDF/main/EspHal.h
new file mode 100644
index 0000000000..3f7cd12557
--- /dev/null
+++ b/examples/NonArduino/ESP-IDF/main/EspHal.h
@@ -0,0 +1,322 @@
+#ifndef ESP_HAL_H
+#define ESP_HAL_H
+
+// include RadioLib
+#include
+
+// this example only works on ESP32 and is unlikely to work on ESP32S2/S3 etc.
+// if you need high portability, you should probably use Arduino anyway ...
+#if CONFIG_IDF_TARGET_ESP32 == 0
+ #error This example HAL only supports ESP32 targets. Support for ESP32S2/S3 etc. can be added by adjusting this file to user needs.
+#endif
+
+// include all the dependencies
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "esp32/rom/gpio.h"
+#include "soc/rtc.h"
+#include "soc/dport_reg.h"
+#include "soc/spi_reg.h"
+#include "soc/spi_struct.h"
+#include "driver/gpio.h"
+#include "hal/gpio_hal.h"
+#include "esp_timer.h"
+#include "esp_log.h"
+
+// define Arduino-style macros
+#define LOW (0x0)
+#define HIGH (0x1)
+#define INPUT (0x01)
+#define OUTPUT (0x03)
+#define RISING (0x01)
+#define FALLING (0x02)
+#define NOP() asm volatile ("nop")
+
+#define MATRIX_DETACH_OUT_SIG (0x100)
+#define MATRIX_DETACH_IN_LOW_PIN (0x30)
+
+// all of the following is needed to calculate SPI clock divider
+#define ClkRegToFreq(reg) (apb_freq / (((reg)->clkdiv_pre + 1) * ((reg)->clkcnt_n + 1)))
+
+typedef union {
+ uint32_t value;
+ struct {
+ uint32_t clkcnt_l: 6;
+ uint32_t clkcnt_h: 6;
+ uint32_t clkcnt_n: 6;
+ uint32_t clkdiv_pre: 13;
+ uint32_t clk_equ_sysclk: 1;
+ };
+} spiClk_t;
+
+uint32_t getApbFrequency() {
+ rtc_cpu_freq_config_t conf;
+ rtc_clk_cpu_freq_get_config(&conf);
+
+ if(conf.freq_mhz >= 80) {
+ return(80 * MHZ);
+ }
+
+ return((conf.source_freq_mhz * MHZ) / conf.div);
+}
+
+uint32_t spiFrequencyToClockDiv(uint32_t freq) {
+ uint32_t apb_freq = getApbFrequency();
+ if(freq >= apb_freq) {
+ return SPI_CLK_EQU_SYSCLK;
+ }
+
+ const spiClk_t minFreqReg = { 0x7FFFF000 };
+ uint32_t minFreq = ClkRegToFreq((spiClk_t*) &minFreqReg);
+ if(freq < minFreq) {
+ return minFreqReg.value;
+ }
+
+ uint8_t calN = 1;
+ spiClk_t bestReg = { 0 };
+ int32_t bestFreq = 0;
+ while(calN <= 0x3F) {
+ spiClk_t reg = { 0 };
+ int32_t calFreq;
+ int32_t calPre;
+ int8_t calPreVari = -2;
+
+ reg.clkcnt_n = calN;
+
+ while(calPreVari++ <= 1) {
+ calPre = (((apb_freq / (reg.clkcnt_n + 1)) / freq) - 1) + calPreVari;
+ if(calPre > 0x1FFF) {
+ reg.clkdiv_pre = 0x1FFF;
+ } else if(calPre <= 0) {
+ reg.clkdiv_pre = 0;
+ } else {
+ reg.clkdiv_pre = calPre;
+ }
+ reg.clkcnt_l = ((reg.clkcnt_n + 1) / 2);
+ calFreq = ClkRegToFreq(®);
+ if(calFreq == (int32_t) freq) {
+ memcpy(&bestReg, ®, sizeof(bestReg));
+ break;
+ } else if(calFreq < (int32_t) freq) {
+ if(RADIOLIB_ABS(freq - calFreq) < RADIOLIB_ABS(freq - bestFreq)) {
+ bestFreq = calFreq;
+ memcpy(&bestReg, ®, sizeof(bestReg));
+ }
+ }
+ }
+ if(calFreq == (int32_t) freq) {
+ break;
+ }
+ calN++;
+ }
+ return(bestReg.value);
+}
+
+// create a new ESP-IDF hardware abstraction layer
+// the HAL must inherit from the base RadioLibHal class
+// and implement all of its virtual methods
+// this is pretty much just copied from Arduino ESP32 core
+class EspHal : public RadioLibHal {
+ public:
+ // default constructor - initializes the base HAL and any needed private members
+ EspHal(int8_t sck, int8_t miso, int8_t mosi)
+ : RadioLibHal(INPUT, OUTPUT, LOW, HIGH, RISING, FALLING),
+ spiSCK(sck), spiMISO(miso), spiMOSI(mosi) {
+ }
+
+ void init() override {
+ // we only need to init the SPI here
+ spiBegin();
+ }
+
+ void term() override {
+ // we only need to stop the SPI here
+ spiEnd();
+ }
+
+ // GPIO-related methods (pinMode, digitalWrite etc.) should check
+ // RADIOLIB_NC as an alias for non-connected pins
+ void pinMode(uint32_t pin, uint32_t mode) override {
+ if(pin == RADIOLIB_NC) {
+ return;
+ }
+
+ gpio_hal_context_t gpiohal;
+ gpiohal.dev = GPIO_LL_GET_HW(GPIO_PORT_0);
+
+ gpio_config_t conf = {
+ .pin_bit_mask = (1ULL<pin[pin].int_type,
+ };
+ gpio_config(&conf);
+ }
+
+ void digitalWrite(uint32_t pin, uint32_t value) override {
+ if(pin == RADIOLIB_NC) {
+ return;
+ }
+
+ gpio_set_level((gpio_num_t)pin, value);
+ }
+
+ uint32_t digitalRead(uint32_t pin) override {
+ if(pin == RADIOLIB_NC) {
+ return(0);
+ }
+
+ return(gpio_get_level((gpio_num_t)pin));
+ }
+
+ void attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) override {
+ if(interruptNum == RADIOLIB_NC) {
+ return;
+ }
+
+ gpio_install_isr_service((int)ESP_INTR_FLAG_IRAM);
+ gpio_set_intr_type((gpio_num_t)interruptNum, (gpio_int_type_t)(mode & 0x7));
+
+ // this uses function typecasting, which is not defined when the functions have different signatures
+ // untested and might not work
+ gpio_isr_handler_add((gpio_num_t)interruptNum, (void (*)(void*))interruptCb, NULL);
+ }
+
+ void detachInterrupt(uint32_t interruptNum) override {
+ if(interruptNum == RADIOLIB_NC) {
+ return;
+ }
+
+ gpio_isr_handler_remove((gpio_num_t)interruptNum);
+ gpio_wakeup_disable((gpio_num_t)interruptNum);
+ gpio_set_intr_type((gpio_num_t)interruptNum, GPIO_INTR_DISABLE);
+ }
+
+ void delay(unsigned long ms) override {
+ vTaskDelay(ms / portTICK_PERIOD_MS);
+ }
+
+ void delayMicroseconds(unsigned long us) override {
+ uint64_t m = (uint64_t)esp_timer_get_time();
+ if(us) {
+ uint64_t e = (m + us);
+ if(m > e) { // overflow
+ while((uint64_t)esp_timer_get_time() > e) {
+ NOP();
+ }
+ }
+ while((uint64_t)esp_timer_get_time() < e) {
+ NOP();
+ }
+ }
+ }
+
+ unsigned long millis() override {
+ return((unsigned long)(esp_timer_get_time() / 1000ULL));
+ }
+
+ unsigned long micros() override {
+ return((unsigned long)(esp_timer_get_time()));
+ }
+
+ long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override {
+ if(pin == RADIOLIB_NC) {
+ return(0);
+ }
+
+ this->pinMode(pin, INPUT);
+ uint32_t start = this->micros();
+ uint32_t curtick = this->micros();
+
+ while(this->digitalRead(pin) == state) {
+ if((this->micros() - curtick) > timeout) {
+ return(0);
+ }
+ }
+
+ return(this->micros() - start);
+ }
+
+ void spiBegin() {
+ // enable peripheral
+ DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI2_CLK_EN);
+ DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI2_RST);
+
+ // reset the control struct
+ this->spi->slave.trans_done = 0;
+ this->spi->slave.val = 0;
+ this->spi->pin.val = 0;
+ this->spi->user.val = 0;
+ this->spi->user1.val = 0;
+ this->spi->ctrl.val = 0;
+ this->spi->ctrl1.val = 0;
+ this->spi->ctrl2.val = 0;
+ this->spi->clock.val = 0;
+ this->spi->user.usr_mosi = 1;
+ this->spi->user.usr_miso = 1;
+ this->spi->user.doutdin = 1;
+ for(uint8_t i = 0; i < 16; i++) {
+ this->spi->data_buf[i] = 0x00000000;
+ }
+
+ // set SPI mode 0
+ this->spi->pin.ck_idle_edge = 0;
+ this->spi->user.ck_out_edge = 0;
+
+ // set bit order to MSB first
+ this->spi->ctrl.wr_bit_order = 0;
+ this->spi->ctrl.rd_bit_order = 0;
+
+ // set the clock
+ this->spi->clock.val = spiFrequencyToClockDiv(2000000);
+
+ // initialize pins
+ this->pinMode(this->spiSCK, OUTPUT);
+ this->pinMode(this->spiMISO, INPUT);
+ this->pinMode(this->spiMOSI, OUTPUT);
+ gpio_matrix_out(this->spiSCK, HSPICLK_OUT_IDX, false, false);
+ gpio_matrix_in(this->spiMISO, HSPIQ_OUT_IDX, false);
+ gpio_matrix_out(this->spiMOSI, HSPID_IN_IDX, false, false);
+ }
+
+ void spiBeginTransaction() {
+ // not needed - in ESP32 Arduino core, this function
+ // repeats clock div, mode and bit order configuration
+ }
+
+ uint8_t spiTransferByte(uint8_t b) {
+ this->spi->mosi_dlen.usr_mosi_dbitlen = 7;
+ this->spi->miso_dlen.usr_miso_dbitlen = 7;
+ this->spi->data_buf[0] = b;
+ this->spi->cmd.usr = 1;
+ while(this->spi->cmd.usr);
+ return(this->spi->data_buf[0] & 0xFF);
+ }
+
+ void spiTransfer(uint8_t* out, size_t len, uint8_t* in) {
+ for(size_t i = 0; i < len; i++) {
+ in[i] = this->spiTransferByte(out[i]);
+ }
+ }
+
+ void spiEndTransaction() {
+ // nothing needs to be done here
+ }
+
+ void spiEnd() {
+ // detach pins
+ gpio_matrix_out(this->spiSCK, MATRIX_DETACH_OUT_SIG, false, false);
+ gpio_matrix_in(this->spiMISO, MATRIX_DETACH_IN_LOW_PIN, false);
+ gpio_matrix_out(this->spiMOSI, MATRIX_DETACH_OUT_SIG, false, false);
+ }
+
+ private:
+ // the HAL can contain any additional private members
+ int8_t spiSCK;
+ int8_t spiMISO;
+ int8_t spiMOSI;
+ spi_dev_t * spi = (volatile spi_dev_t *)(DR_REG_SPI2_BASE);
+};
+
+#endif
diff --git a/examples/NonArduino/ESP-IDF/main/idf_component.yml b/examples/NonArduino/ESP-IDF/main/idf_component.yml
new file mode 100644
index 0000000000..ce1ccc2cb2
--- /dev/null
+++ b/examples/NonArduino/ESP-IDF/main/idf_component.yml
@@ -0,0 +1,7 @@
+dependencies:
+ RadioLib:
+ # referenced locally because the example is a part of the repository itself
+ # under normal circumstances, it's preferable to reference the repository instead
+ # for other options, see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html
+ path: ../../../../../RadioLib
+ #git: https://github.com/jgromes/RadioLib.git
diff --git a/examples/NonArduino/ESP-IDF/main/main.cpp b/examples/NonArduino/ESP-IDF/main/main.cpp
new file mode 100644
index 0000000000..9a2272b6ed
--- /dev/null
+++ b/examples/NonArduino/ESP-IDF/main/main.cpp
@@ -0,0 +1,67 @@
+/*
+ RadioLib Non-Arduino ESP-IDF Example
+
+ This example shows how to use RadioLib without Arduino.
+ In this case, a Liligo T-BEAM (ESP32 and SX1276)
+ is used.
+
+ Can be used as a starting point to port RadioLib to any platform!
+ See this API reference page for details on the RadioLib hardware abstraction
+ https://jgromes.github.io/RadioLib/class_hal.html
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// include the hardware abstraction layer
+#include "EspHal.h"
+
+// create a new instance of the HAL class
+EspHal* hal = new EspHal(5, 19, 27);
+
+// now we can create the radio module
+// NSS pin: 18
+// DIO0 pin: 26
+// NRST pin: 14
+// DIO1 pin: 33
+SX1276 radio = new Module(hal, 18, 26, 14, 33);
+
+static const char *TAG = "main";
+
+// the entry point for the program
+// it must be declared as "extern C" because the compiler assumes this will be a C function
+extern "C" void app_main(void) {
+ // initialize just like with Arduino
+ ESP_LOGI(TAG, "[SX1276] Initializing ... ");
+ int state = radio.begin();
+ if (state != RADIOLIB_ERR_NONE) {
+ ESP_LOGI(TAG, "failed, code %d\n", state);
+ while(true) {
+ hal->delay(1000);
+ }
+ }
+ ESP_LOGI(TAG, "success!\n");
+
+ // loop forever
+ for(;;) {
+ // send a packet
+ ESP_LOGI(TAG, "[SX1276] Transmitting packet ... ");
+ state = radio.transmit("Hello World!");
+ if(state == RADIOLIB_ERR_NONE) {
+ // the packet was successfully transmitted
+ ESP_LOGI(TAG, "success!");
+
+ } else {
+ ESP_LOGI(TAG, "failed, code %d\n", state);
+
+ }
+
+ // wait for a second before transmitting again
+ hal->delay(1000);
+
+ }
+
+}
diff --git a/examples/NonArduino/ESP-IDF/sdkconfig.defaults b/examples/NonArduino/ESP-IDF/sdkconfig.defaults
new file mode 100644
index 0000000000..c95181cf1f
--- /dev/null
+++ b/examples/NonArduino/ESP-IDF/sdkconfig.defaults
@@ -0,0 +1,2 @@
+# Increase FreeRTOS tick rate to 1000 Hz
+CONFIG_FREERTOS_HZ=1000
diff --git a/examples/NonArduino/Pico/.gitignore b/examples/NonArduino/Pico/.gitignore
new file mode 100644
index 0000000000..d16386367f
--- /dev/null
+++ b/examples/NonArduino/Pico/.gitignore
@@ -0,0 +1 @@
+build/
\ No newline at end of file
diff --git a/examples/NonArduino/Pico/CMakeLists.txt b/examples/NonArduino/Pico/CMakeLists.txt
new file mode 100644
index 0000000000..84729dbe50
--- /dev/null
+++ b/examples/NonArduino/Pico/CMakeLists.txt
@@ -0,0 +1,34 @@
+cmake_minimum_required(VERSION 3.18)
+
+# Pull in SDK (must be before project)
+include(pico_sdk_import.cmake)
+
+project(pico-sx1276 C CXX ASM)
+set(CMAKE_C_STANDARD 11)
+set(CMAKE_CXX_STANDARD 17)
+
+# Initialize the SDK
+pico_sdk_init()
+
+add_compile_options(
+ -Wall
+ -Wno-format
+ -Wno-unused-function
+)
+
+add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../../../RadioLib" "${CMAKE_CURRENT_BINARY_DIR}/RadioLib")
+
+add_executable(${PROJECT_NAME}
+ main.cpp
+ "${CMAKE_CURRENT_SOURCE_DIR}/../../../../RadioLib/src/hal/RPiPico/PicoHal.cpp"
+)
+target_compile_definitions(${PROJECT_NAME} PUBLIC RADIOLIB_BUILD_RPI_PICO)
+
+# Pull in common dependencies
+target_link_libraries(${PROJECT_NAME} pico_stdlib hardware_spi hardware_gpio hardware_timer pico_multicore hardware_pwm RadioLib)
+
+pico_enable_stdio_usb(${PROJECT_NAME} 1)
+pico_enable_stdio_uart(${PROJECT_NAME} 0)
+
+# Create map/bin/hex file etc.
+pico_add_extra_outputs(${PROJECT_NAME})
diff --git a/examples/NonArduino/Pico/build.sh b/examples/NonArduino/Pico/build.sh
new file mode 100755
index 0000000000..1a556bf4c2
--- /dev/null
+++ b/examples/NonArduino/Pico/build.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+set -e
+mkdir -p build
+cd build
+cmake ..
+make
+cd ..
diff --git a/examples/NonArduino/Pico/clean.sh b/examples/NonArduino/Pico/clean.sh
new file mode 100755
index 0000000000..27cfe2641d
--- /dev/null
+++ b/examples/NonArduino/Pico/clean.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+rm -rf ./build
diff --git a/examples/NonArduino/Pico/main.cpp b/examples/NonArduino/Pico/main.cpp
new file mode 100644
index 0000000000..c0b007fa40
--- /dev/null
+++ b/examples/NonArduino/Pico/main.cpp
@@ -0,0 +1,86 @@
+/*
+ RadioLib Non-Arduino Raspberry Pi Pico library example
+
+ Licensed under the MIT License
+
+ Copyright (c) 2024 Cameron Goddard
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+
+// define pins to be used
+#define SPI_PORT spi0
+#define SPI_MISO 4
+#define SPI_MOSI 3
+#define SPI_SCK 2
+
+#define RFM_NSS 26
+#define RFM_RST 22
+#define RFM_DIO0 14
+#define RFM_DIO1 15
+
+#include
+
+// include the library
+#include
+
+// include the hardware abstraction layer
+#include "hal/RPiPico/PicoHal.h"
+
+// create a new instance of the HAL class
+PicoHal* hal = new PicoHal(SPI_PORT, SPI_MISO, SPI_MOSI, SPI_SCK);
+
+// now we can create the radio module
+// NSS pin: 26
+// DIO0 pin: 14
+// RESET pin: 22
+// DIO1 pin: 15
+SX1276 radio = new Module(hal, RFM_NSS, RFM_DIO0, RFM_RST, RFM_DIO1);
+
+int main() {
+ // initialize just like with Arduino
+ printf("[SX1276] Initializing ... ");
+ int state = radio.begin();
+ if (state != RADIOLIB_ERR_NONE) {
+ printf("failed, code %d\n", state);
+ return(1);
+ }
+ printf("success!\n");
+
+ // loop forever
+ for(;;) {
+ // send a packet
+ printf("[SX1276] Transmitting packet ... ");
+ state = radio.transmit("Hello World!");
+ if(state == RADIOLIB_ERR_NONE) {
+ // the packet was successfully transmitted
+ printf("success!\n");
+
+ // wait for a second before transmitting again
+ hal->delay(1000);
+
+ } else {
+ printf("failed, code %d\n", state);
+
+ }
+
+ }
+
+ return(0);
+}
diff --git a/examples/NonArduino/Pico/pico_sdk_import.cmake b/examples/NonArduino/Pico/pico_sdk_import.cmake
new file mode 100644
index 0000000000..65f8a6f7db
--- /dev/null
+++ b/examples/NonArduino/Pico/pico_sdk_import.cmake
@@ -0,0 +1,73 @@
+# This is a copy of /external/pico_sdk_import.cmake
+
+# This can be dropped into an external project to help locate this SDK
+# It should be include()ed prior to project()
+
+if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
+ set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
+ message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
+endif ()
+
+if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
+ set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
+ message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
+endif ()
+
+if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
+ set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
+ message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
+endif ()
+
+set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
+set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable")
+set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")
+
+if (NOT PICO_SDK_PATH)
+ if (PICO_SDK_FETCH_FROM_GIT)
+ include(FetchContent)
+ set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
+ if (PICO_SDK_FETCH_FROM_GIT_PATH)
+ get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
+ endif ()
+ # GIT_SUBMODULES_RECURSE was added in 3.17
+ if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0")
+ FetchContent_Declare(
+ pico_sdk
+ GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
+ GIT_TAG master
+ GIT_SUBMODULES_RECURSE FALSE
+ )
+ else ()
+ FetchContent_Declare(
+ pico_sdk
+ GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
+ GIT_TAG master
+ )
+ endif ()
+
+ if (NOT pico_sdk)
+ message("Downloading Raspberry Pi Pico SDK")
+ FetchContent_Populate(pico_sdk)
+ set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
+ endif ()
+ set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
+ else ()
+ message(FATAL_ERROR
+ "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
+ )
+ endif ()
+endif ()
+
+get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
+if (NOT EXISTS ${PICO_SDK_PATH})
+ message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
+endif ()
+
+set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
+if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
+ message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
+endif ()
+
+set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)
+
+include(${PICO_SDK_INIT_CMAKE_FILE})
diff --git a/examples/NonArduino/Raspberry/.gitignore b/examples/NonArduino/Raspberry/.gitignore
new file mode 100644
index 0000000000..567609b123
--- /dev/null
+++ b/examples/NonArduino/Raspberry/.gitignore
@@ -0,0 +1 @@
+build/
diff --git a/examples/NonArduino/Raspberry/CMakeLists.txt b/examples/NonArduino/Raspberry/CMakeLists.txt
new file mode 100644
index 0000000000..2e6d93497f
--- /dev/null
+++ b/examples/NonArduino/Raspberry/CMakeLists.txt
@@ -0,0 +1,22 @@
+cmake_minimum_required(VERSION 3.18)
+
+# create the project
+project(rpi-sx1261)
+
+# when using debuggers such as gdb, the following line can be used
+#set(CMAKE_BUILD_TYPE Debug)
+
+# if you did not build RadioLib as shared library (see wiki),
+# you will have to add it as source directory
+# the following is just an example, yours will likely be different
+add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../../../RadioLib" "${CMAKE_CURRENT_BINARY_DIR}/RadioLib")
+
+# add the executable
+add_executable(${PROJECT_NAME} main.cpp)
+
+# link both libraries
+target_link_libraries(${PROJECT_NAME} RadioLib lgpio)
+
+# you can also specify RadioLib compile-time flags here
+#target_compile_definitions(RadioLib PUBLIC RADIOLIB_DEBUG_BASIC RADIOLIB_DEBUG_SPI)
+#target_compile_definitions(RadioLib PUBLIC RADIOLIB_DEBUG_PORT=stdout)
diff --git a/examples/NonArduino/Raspberry/build.sh b/examples/NonArduino/Raspberry/build.sh
new file mode 100755
index 0000000000..55caae99a5
--- /dev/null
+++ b/examples/NonArduino/Raspberry/build.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+set -e
+mkdir -p build
+cd build
+cmake -G "CodeBlocks - Unix Makefiles" ..
+make
+cd ..
+size build/rpi-sx1261
diff --git a/examples/NonArduino/Raspberry/clean.sh b/examples/NonArduino/Raspberry/clean.sh
new file mode 100755
index 0000000000..27cfe2641d
--- /dev/null
+++ b/examples/NonArduino/Raspberry/clean.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+rm -rf ./build
diff --git a/examples/NonArduino/Raspberry/main.cpp b/examples/NonArduino/Raspberry/main.cpp
new file mode 100644
index 0000000000..702b197116
--- /dev/null
+++ b/examples/NonArduino/Raspberry/main.cpp
@@ -0,0 +1,70 @@
+/*
+ RadioLib Non-Arduino Raspberry Pi Example
+
+ This example shows how to use RadioLib without Arduino.
+ In this case, a Raspberry Pi with WaveShare SX1302 LoRaWAN Hat
+ using the lgpio library
+ https://abyz.me.uk/lg/lgpio.html
+
+ Can be used as a starting point to port RadioLib to any platform!
+ See this API reference page for details on the RadioLib hardware abstraction
+ https://jgromes.github.io/RadioLib/class_hal.html
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// include the hardware abstraction layer
+#include "hal/RPi/PiHal.h"
+
+// create a new instance of the HAL class
+// use SPI channel 1, because on Waveshare LoRaWAN Hat,
+// the SX1261 CS is connected to CE1
+PiHal* hal = new PiHal(1);
+
+// now we can create the radio module
+// pinout corresponds to the Waveshare LoRaWAN Hat
+// NSS pin: 7
+// DIO1 pin: 17
+// NRST pin: 22
+// BUSY pin: not connected
+SX1261 radio = new Module(hal, 7, 17, 22, RADIOLIB_NC);
+
+// the entry point for the program
+int main(int argc, char** argv) {
+ // initialize just like with Arduino
+ printf("[SX1261] Initializing ... ");
+ int state = radio.begin();
+ if (state != RADIOLIB_ERR_NONE) {
+ printf("failed, code %d\n", state);
+ return(1);
+ }
+ printf("success!\n");
+
+ // loop forever
+ int count = 0;
+ for(;;) {
+ // send a packet
+ printf("[SX1261] Transmitting packet ... ");
+ char str[64];
+ sprintf(str, "Hello World! #%d", count++);
+ state = radio.transmit(str);
+ if(state == RADIOLIB_ERR_NONE) {
+ // the packet was successfully transmitted
+ printf("success!\n");
+
+ // wait for a second before transmitting again
+ hal->delay(1000);
+
+ } else {
+ printf("failed, code %d\n", state);
+
+ }
+
+ }
+
+ return(0);
+}
diff --git a/examples/NonArduino/Tock/.gitignore b/examples/NonArduino/Tock/.gitignore
new file mode 100644
index 0000000000..3207b65aae
--- /dev/null
+++ b/examples/NonArduino/Tock/.gitignore
@@ -0,0 +1,2 @@
+build-*
+TockApp.tab
diff --git a/examples/NonArduino/Tock/CMakeLists.txt b/examples/NonArduino/Tock/CMakeLists.txt
new file mode 100644
index 0000000000..661968f849
--- /dev/null
+++ b/examples/NonArduino/Tock/CMakeLists.txt
@@ -0,0 +1,137 @@
+# RadioLib Non-Arduino Tock Library CMake script
+#
+# Licensed under the MIT License
+#
+# Copyright (c) 2023 Alistair Francis
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+cmake_minimum_required(VERSION 3.18)
+
+# create the project
+project(tock-sx1261)
+
+set(LINKER_SCRIPT $ENV{LIBTOCK_C_DIRECTORY}/userland_generic.ld)
+
+if (RISCV_BUILD)
+ include("tock-riscv.cmake")
+else()
+ include("tock-arm.cmake")
+endif()
+
+# when using debuggers such as gdb, the following line can be used
+#set(CMAKE_BUILD_TYPE Debug)
+
+# if you did not build RadioLib as shared library (see wiki),
+# you will have to add it as source directory
+# the following is just an example, yours will likely be different
+add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../../../RadioLib" "${CMAKE_CURRENT_BINARY_DIR}/RadioLib")
+
+# add the executable
+add_executable(${PROJECT_NAME} main.cpp)
+
+# link with RadioLib and libtock-c
+# The build system for libtock-c is a bit odd and the version of libraries
+# built changes based on compiler version.
+if (RISCV_BUILD)
+ if(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0")
+ target_link_libraries(${PROJECT_NAME} PUBLIC
+ RadioLib
+ $ENV{LIBTOCK_C_DIRECTORY}/libtock/build/rv32imc/libtock.a
+ $ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/rv32imc/libtocksync.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0/riscv/lib/gcc/riscv64-unknown-elf/14.1.0/rv32i/ilp32/libgcc.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libstdc++.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.4.0.20231231/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libc.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.4.0.20231231/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libm.a
+ )
+
+ target_include_directories(RadioLib AFTER PUBLIC
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/riscv/riscv64-unknown-elf/include/
+ )
+ elseif(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0")
+ target_link_libraries(${PROJECT_NAME} PUBLIC
+ RadioLib
+ $ENV{LIBTOCK_C_DIRECTORY}/libtock/build/rv32imc/libtock.a
+ $ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/rv32imc/libtocksync.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0/riscv/lib/gcc/riscv64-unknown-elf/13.2.0/rv32i/ilp32/libgcc.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libstdc++.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libc.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libm.a
+ )
+
+ target_include_directories(RadioLib AFTER PUBLIC
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/riscv/riscv64-unknown-elf/include/
+ )
+ else()
+ target_link_libraries(${PROJECT_NAME} PUBLIC
+ RadioLib
+ $ENV{LIBTOCK_C_DIRECTORY}/libtock/build/rv32imc/libtock.a
+ $ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/rv32imc/libtocksync.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-10.5.0/riscv/lib/gcc/riscv64-unknown-elf/10.5.0/rv32i/ilp32/libgcc.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-10.5.0/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libstdc++.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.2.0.20211231/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libc.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.2.0.20211231/riscv/riscv64-unknown-elf/lib/rv32i/ilp32/libm.a
+ )
+
+ target_include_directories(RadioLib AFTER PUBLIC
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.2.0.20211231/riscv/riscv64-unknown-elf/include/
+ )
+ endif()
+else()
+ if (EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0")
+ target_link_libraries(${PROJECT_NAME} PUBLIC
+ RadioLib
+ $ENV{LIBTOCK_C_DIRECTORY}/libtock/build/cortex-m4/libtock.a
+ $ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/cortex-m4/libtocksync.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0/arm/lib/gcc/arm-none-eabi/14.1.0/libgcc.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-14.1.0/arm/arm-none-eabi/lib/libstdc++.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.4.0.20231231/arm/arm-none-eabi/lib/libc.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.4.0.20231231/arm/arm-none-eabi/lib/libm.a
+ )
+ elseif(EXISTS "$ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0")
+ target_link_libraries(${PROJECT_NAME} PUBLIC
+ RadioLib
+ $ENV{LIBTOCK_C_DIRECTORY}/libtock/build/cortex-m4/libtock.a
+ $ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/cortex-m4/libtocksync.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0/arm/lib/gcc/arm-none-eabi/13.2.0/libgcc.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-13.2.0/arm/arm-none-eabi/lib/libstdc++.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/arm/arm-none-eabi/lib/libc.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.3.0.20230120/arm/arm-none-eabi/lib/libm.a
+ )
+ else()
+ target_link_libraries(${PROJECT_NAME} PUBLIC
+ RadioLib
+ $ENV{LIBTOCK_C_DIRECTORY}/libtock/build/cortex-m4/libtock.a
+ $ENV{LIBTOCK_C_DIRECTORY}/libtock-sync/build/cortex-m4/libtocksync.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-10.5.0/arm/lib/gcc/arm-none-eabi/10.5.0/libgcc.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-libc++-10.5.0/arm/arm-none-eabi/lib/libstdc++.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.2.0.20211231/arm/arm-none-eabi/lib/libc.a
+ $ENV{LIBTOCK_C_DIRECTORY}/lib/libtock-newlib-4.2.0.20211231/arm/arm-none-eabi/lib/libm.a
+ )
+ endif()
+endif()
+
+target_include_directories(${PROJECT_NAME} PUBLIC
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/
+ $ENV{LIBTOCK_C_DIRECTORY}
+)
+
+# you can also specify RadioLib compile-time flags here
+#target_compile_definitions(${PROJECT_NAME} PUBLIC RADIOLIB_DEBUG RADIOLIB_VERBOSE)
diff --git a/examples/NonArduino/Tock/README.md b/examples/NonArduino/Tock/README.md
new file mode 100644
index 0000000000..8022a303b9
--- /dev/null
+++ b/examples/NonArduino/Tock/README.md
@@ -0,0 +1,34 @@
+# RadioLib as Tock application
+
+[Tock](https://github.com/tock/tock) is an embedded operating system designed
+for running multiple concurrent, mutually distrustful applications on Cortex-M
+and RISC-V based embedded platforms.
+
+RadioLib can be built as a Tock application using
+[libtock-c](https://github.com/tock/libtock-c). This is an example of running
+RadioLib as a Tock application.
+
+This has been tested on the
+[SparkFun LoRa Thing Plus - expLoRaBLE board] (https://github.com/tock/tock/tree/master/boards/apollo3/lora_things_plus)
+but will work on any LoRa compatible Tock board (currently only the
+expLoRaBLE board).
+
+libtock-c by default is bulit for RISC-V and ARM. RadioLib is also built
+for both architectures by default. You can skip the RISC-V RadioLib build
+by setting the `SKIP_RISCV` varaible.
+
+The RadioLib example can be built with:
+
+```shell
+$ git clone https://github.com/jgromes/RadioLib.git
+$ cd RadioLib/examples/NonArduino/Tock/
+$ git clone https://github.com/tock/libtock-c.git
+$ cd libtock-c; git checkout c0202f9ab78da4a6e95f136cf5250701e3778f63; cd ../
+$ LIBTOCK_C_DIRECTORY="$(pwd)/libtock-c" ./build.sh
+```
+
+Then in the Tock repo you can flash the kernel and app with:
+
+```shell
+$ make flash; APP=RadioLib/examples/NonArduino/Tock/build-arm/tock-sx1261.tbf make flash-app
+```
diff --git a/examples/NonArduino/Tock/build.sh b/examples/NonArduino/Tock/build.sh
new file mode 100755
index 0000000000..2ac538e492
--- /dev/null
+++ b/examples/NonArduino/Tock/build.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+set -e
+
+rm -rf ./build-*
+
+pushd ${LIBTOCK_C_DIRECTORY}/examples/cxx_hello
+make -j4
+popd
+
+mkdir -p build-arm
+cd build-arm
+
+cmake -G "CodeBlocks - Unix Makefiles" ..
+make -j4
+
+cd ..
+
+if ! env | grep SKIP_RISCV; then
+ mkdir -p build-riscv
+ cd build-riscv
+
+ cmake -G "CodeBlocks - Unix Makefiles" -DRISCV_BUILD=1 ..
+ make -j4
+
+ cd ..
+fi
+
+elf2tab -n radio-lib --stack 4096 --app-heap 2048 --kernel-heap 2048 \
+ --kernel-major 2 --kernel-minor 1 \
+ -v ./build-arm/tock-sx1261
diff --git a/examples/NonArduino/Tock/main.cpp b/examples/NonArduino/Tock/main.cpp
new file mode 100644
index 0000000000..e0db2196e4
--- /dev/null
+++ b/examples/NonArduino/Tock/main.cpp
@@ -0,0 +1,81 @@
+/*
+ RadioLib Non-Arduino Tock Library test application
+
+ Licensed under the MIT License
+
+ Copyright (c) 2023 Alistair Francis
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+
+// include the library
+#include
+
+// include the hardware abstraction layer
+#include "RadioLib/libtockHal.h"
+
+// the entry point for the program
+int main(void) {
+ printf("[SX1261] Initialising Radio ... \r\n");
+
+ // create a new instance of the HAL class
+ TockRadioLibHal* hal = new TockRadioLibHal();
+
+ // now we can create the radio module
+ // pinout corresponds to the SparkFun LoRa Thing Plus - expLoRaBLE
+ // NSS pin: 0
+ // DIO1 pin: 2
+ // NRST pin: 4
+ // BUSY pin: 1
+ Module* tock_module = new Module(hal, RADIOLIB_RADIO_NSS, RADIOLIB_RADIO_DIO_1, RADIOLIB_RADIO_RESET, RADIOLIB_RADIO_BUSY);
+ SX1262* radio = new SX1262(tock_module);
+
+ // Setup the radio
+ // The settings here work for the SparkFun LoRa Thing Plus - expLoRaBLE
+ radio->XTAL = true;
+ int state = radio->begin(915.0);
+
+ if (state != RADIOLIB_ERR_NONE) {
+ printf("failed, code %d\r\n", state);
+ return 1;
+ }
+ printf("success!\r\n");
+
+ // loop forever
+ for(;;) {
+ yield_no_wait();
+ // send a packet
+ printf("[SX1261] Transmitting\r\n");
+
+ state = radio->transmit("Hello World!");
+
+ if(state == RADIOLIB_ERR_NONE) {
+ // the packet was successfully transmitted
+ printf("success!\r\n");
+
+ // wait for a second before transmitting again
+ hal->delay(1000);
+ } else {
+ printf("failed, code %d\r\n", state);
+ }
+
+ }
+
+ return 0;
+}
diff --git a/examples/NonArduino/Tock/tock-arm.cmake b/examples/NonArduino/Tock/tock-arm.cmake
new file mode 100644
index 0000000000..f557e2f3f1
--- /dev/null
+++ b/examples/NonArduino/Tock/tock-arm.cmake
@@ -0,0 +1,65 @@
+# Tock target specific CMake file
+#
+# Licensed under the MIT License
+#
+# Copyright (c) 2023 Alistair Francis
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# This is copied from https://github.com/Lora-net/LoRaMac-node/pull/1390
+# and has been relicensed by the original author
+
+if(NOT DEFINED LINKER_SCRIPT)
+message(FATAL_ERROR "No linker script defined")
+endif(NOT DEFINED LINKER_SCRIPT)
+message("Linker script: ${LINKER_SCRIPT}")
+
+#---------------------------------------------------------------------------------------
+# Set compiler/linker flags
+#---------------------------------------------------------------------------------------
+
+set(STACK_SIZE 4096)
+set(APP_HEAP_SIZE 2048)
+set(KERNEL_HEAP_SIZE 2048)
+
+set(TOOLCHAIN arm-none-eabi)
+
+find_program(TOOLCHAIN_PREFIX ${TOOLCHAIN}-gcc NO_CACHE)
+get_filename_component(TOOLCHAIN_PREFIX ${TOOLCHAIN_PREFIX} DIRECTORY)
+
+set(TOOLCHAIN_BIN_DIR ${TOOLCHAIN_PREFIX}/../bin)
+set(TOOLCHAIN_INC_DIR ${TOOLCHAIN_PREFIX}/../${TOOLCHAIN}/include)
+set(TOOLCHAIN_LIB_DIR ${TOOLCHAIN_PREFIX}/../${TOOLCHAIN}/lib)
+
+#---------------------------------------------------------------------------------------
+# Set compilers
+#---------------------------------------------------------------------------------------
+set(CMAKE_C_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc CACHE INTERNAL "C Compiler")
+set(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-g++ CACHE INTERNAL "C++ Compiler")
+set(CMAKE_ASM_COMPILER ${TOOLCHAIN_BIN_DIR}/${TOOLCHAIN}-gcc CACHE INTERNAL "ASM Compiler")
+
+# Object build options
+set(OBJECT_GEN_FLAGS "-mthumb -g2 -fno-builtin -mcpu=cortex-m4 -Wall -Wextra -pedantic -Wno-unused-parameter -ffunction-sections -fdata-sections -fomit-frame-pointer -mabi=aapcs -fno-unroll-loops -ffast-math -ftree-vectorize -frecord-gcc-switches -gdwarf-2 -Os -fdata-sections -ffunction-sections -fstack-usage -Wl,--emit-relocs -fPIC -mthumb -mfloat-abi=soft -msingle-pic-base -mpic-register=r9 -mno-pic-data-is-text-relative -D__TOCK__ -DSVCALL_AS_NORMAL_FUNCTION -DSOFTDEVICE_s130")
+
+set(CMAKE_C_FLAGS "${OBJECT_GEN_FLAGS} -std=gnu99 " CACHE INTERNAL "C Compiler options")
+set(CMAKE_CXX_FLAGS "${OBJECT_GEN_FLAGS} -std=c++20 " CACHE INTERNAL "C++ Compiler options")
+set(CMAKE_ASM_FLAGS "${OBJECT_GEN_FLAGS} -x assembler-with-cpp " CACHE INTERNAL "ASM Compiler options")
+
+# Linker flags
+set(CMAKE_EXE_LINKER_FLAGS "-Wl,--gc-sections --specs=nano.specs --specs=nosys.specs -mthumb -g2 -mcpu=cortex-m4 -mabi=aapcs -T${LINKER_SCRIPT} -Wl,-Map=${CMAKE_PROJECT_NAME}.map -Xlinker --defsym=STACK_SIZE=${STACK_SIZE} -Xlinker --defsym=APP_HEAP_SIZE=${APP_HEAP_SIZE} -Xlinker --defsym=KERNEL_HEAP_SIZE=${KERNEL_HEAP_SIZE} -nostdlib -Wl,--start-group" CACHE INTERNAL "Linker options")
diff --git a/examples/NonArduino/Tock/tock-riscv.cmake b/examples/NonArduino/Tock/tock-riscv.cmake
new file mode 100644
index 0000000000..3d842944df
--- /dev/null
+++ b/examples/NonArduino/Tock/tock-riscv.cmake
@@ -0,0 +1,76 @@
+# Tock target specific CMake file
+#
+# Licensed under the MIT License
+#
+# Copyright (c) 2023 Alistair Francis
+#
+# 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")
diff --git a/examples/Pager/Pager_Receive/Pager_Receive.ino b/examples/Pager/Pager_Receive/Pager_Receive.ino
new file mode 100644
index 0000000000..61a010f3d4
--- /dev/null
+++ b/examples/Pager/Pager_Receive/Pager_Receive.ino
@@ -0,0 +1,132 @@
+/*
+ RadioLib Pager (POCSAG) Receive Example
+
+ This example shows how to receive FSK packets without using
+ SX127x packet engine.
+
+ This example receives POCSAG messages using SX1278's
+ FSK modem in direct mode.
+
+ Other modules that can be used to receive POCSAG:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - Si443x/RFM2x
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1278 has the following connections:
+// NSS pin: 10
+// DIO0 pin: 2
+// RESET pin: 9
+// DIO1 pin: 3
+SX1278 radio = new Module(10, 2, 9, 3);
+
+// receiving packets requires connection
+// to the module direct output pin,
+// here connected to Arduino pin 5
+// SX127x/RFM9x: DIO2
+// RF69: DIO2
+// SX1231: DIO2
+// CC1101: GDO2
+// Si443x/RFM2x: GPIO
+const int pin = 5;
+
+// create Pager client instance using the FSK module
+PagerClient pager(&radio);
+
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+void setup() {
+ Serial.begin(9600);
+
+ // initialize SX1278 with default settings
+ Serial.print(F("[SX1278] Initializing ... "));
+ int state = radio.beginFSK();
+
+ // when using one of the non-LoRa modules
+ // (RF69, CC1101, Si4432 etc.), use the basic begin() method
+ // int state = radio.begin();
+
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // initialize Pager client
+ Serial.print(F("[Pager] Initializing ... "));
+ // base (center) frequency: 434.0 MHz
+ // speed: 1200 bps
+ state = pager.begin(434.0, 1200);
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // start receiving POCSAG messages
+ Serial.print(F("[Pager] Starting to listen ... "));
+ // address of this "pager": 1234567
+ state = pager.startReceive(pin, 1234567);
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+}
+
+void loop() {
+ // the number of batches to wait for
+ // 2 batches will usually be enough to fit short and medium messages
+ if (pager.available() >= 2) {
+ Serial.print(F("[Pager] Received pager data, decoding ... "));
+
+ // you can read the data as an Arduino String
+ String str;
+ int state = pager.readData(str);
+
+ // you can also receive data as byte array
+ /*
+ byte byteArr[8];
+ size_t numBytes = 0;
+ int state = radio.receive(byteArr, &numBytes);
+ */
+
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+
+ // print the received data
+ Serial.print(F("[Pager] Data:\t"));
+ Serial.println(str);
+
+ } else {
+ // some error occurred
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+
+ }
+ }
+}
diff --git a/examples/Pager/Pager_Transmit/Pager_Transmit.ino b/examples/Pager/Pager_Transmit/Pager_Transmit.ino
new file mode 100644
index 0000000000..67846e866e
--- /dev/null
+++ b/examples/Pager/Pager_Transmit/Pager_Transmit.ino
@@ -0,0 +1,108 @@
+/*
+ RadioLib Pager (POCSAG) Transmit Example
+
+ This example sends POCSAG messages using SX1278's
+ FSK modem.
+
+ Other modules that can be used to send POCSAG:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - SX126x
+ - nRF24
+ - Si443x/RFM2x
+ - SX128x
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1278 has the following connections:
+// NSS pin: 10
+// DIO0 pin: 2
+// RESET pin: 9
+// DIO1 pin: 3
+SX1278 radio = new Module(10, 2, 9, 3);
+
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// create Pager client instance using the FSK module
+PagerClient pager(&radio);
+
+void setup() {
+ Serial.begin(9600);
+
+ // initialize SX1278 with default settings
+ Serial.print(F("[SX1278] Initializing ... "));
+ int state = radio.beginFSK();
+
+ // when using one of the non-LoRa modules
+ // (RF69, CC1101, Si4432 etc.), use the basic begin() method
+ // int state = radio.begin();
+
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // initialize Pager client
+ Serial.print(F("[Pager] Initializing ... "));
+ // base (center) frequency: 434.0 MHz
+ // speed: 1200 bps
+ state = pager.begin(434.0, 1200);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+}
+
+void loop() {
+ Serial.print(F("[Pager] Transmitting messages ... "));
+
+ // the simples form of "message" is just a tone on the destination pager
+ int state = pager.sendTone(1234567);
+ delay(500);
+
+ // next, transmit numeric (BCD) message to the destination pager
+ // NOTE: Only characters 0123456789*U-() and space
+ // can be sent in a BCD message!
+ state |= pager.transmit("0123456789*U -()", 1234567);
+ delay(500);
+
+ // finally, let's transmit an ASCII message now
+ state |= pager.transmit("Hello World!", 1234567, RADIOLIB_PAGER_ASCII);
+ delay(500);
+
+ // we can also send only a tone
+ state |= pager.sendTone(1234567);
+ delay(500);
+
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ }
+
+ // wait for 3 seconds before transmitting again
+ delay(3000);
+}
diff --git a/examples/PhysicalLayer/PhysicalLayer_Interface/PhysicalLayer_Interface.ino b/examples/PhysicalLayer/PhysicalLayer_Interface/PhysicalLayer_Interface.ino
new file mode 100644
index 0000000000..cdea9d9159
--- /dev/null
+++ b/examples/PhysicalLayer/PhysicalLayer_Interface/PhysicalLayer_Interface.ino
@@ -0,0 +1,145 @@
+/*
+ RadioLib PhysicalLayer Interface Example
+
+ This example shows how to use the common PhysicalLayer
+ to interface with different radio modules using the same
+ methods.
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// select which radio to use
+// this can be any radio supported by RadioLib!
+#define RADIO_TYPE SX1278
+
+// set the pinout depending on the wiring and module type
+// SPI NSS pin: 10
+// interrupt pin: 2
+// reset pin: 9 (unused on some modules)
+// extra GPIO/interrupt pin: 3 (unused on some modules)
+RADIO_TYPE radio = new Module(10, 2, 9, 3);
+
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// get pointer to the common layer
+PhysicalLayer* phy = (PhysicalLayer*)&radio;
+
+void dummyISR(void) {
+ // nothing here, this example is just a showcase
+}
+
+void setup() {
+ Serial.begin(9600);
+
+ // now we can use "radio" to access the features
+ // specific to that radio type, such as the begin() method
+ Serial.print(F("[Radio] Initializing ... "));
+ int state = radio.begin();
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // or we can use the "phy" pointer to access the common layer
+ // PhysicalLayer has some common configuration
+ Serial.print(F("[PHY] Changing frequency ... "));
+ state = phy->setFrequency(433.5);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // PhysicalLayer also contains basic functionality
+ // like transmitting and receiving packets
+ Serial.print(F("[PHY] Sending packet ... "));
+ state = phy->transmit("Hello World!");
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // try to receive now - this will almost certainly timeout
+ // unless by chance there is a transmitter nearby,
+ // but the point of this example is to showcase the interface
+ String str;
+ Serial.print(F("[PHY] Listening for packets ... "));
+ state = phy->receive(str);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else if(state == RADIOLIB_ERR_RX_TIMEOUT) {
+ Serial.println(F("timeout!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // interrupt-driven versions of Rx/Tx are supported as well
+ // for these to work, you have to configure the interrupt actions
+ phy->setPacketReceivedAction(dummyISR);
+ phy->setPacketSentAction(dummyISR);
+
+ // now you can use methods like startTransmit(), startReceive(),
+ // readData() etc.
+
+ // interrupt actions can be cleared as well
+ phy->clearPacketReceivedAction();
+ phy->clearPacketSentAction();
+
+ // PhysicalLayer supports basic mode changes like sleep ...
+ Serial.print(F("[PHY] Going to sleep ... "));
+ state = phy->sleep();
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // ... or standby
+ Serial.print(F("[PHY] Going to standby ... "));
+ state = phy->standby();
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // there are also common SNR/RSSI measurement functions
+ Serial.print(F("[PHY] Measured SNR = "));
+ Serial.print(phy->getSNR());
+ Serial.println(F(" dB"));
+ Serial.print(F("[PHY] Measured RSSI = "));
+ Serial.print(phy->getRSSI());
+ Serial.println(F(" dBm"));
+
+ // and also a true random number generator
+ Serial.print(F("[PHY] Random number between 0 and 100 = "));
+ Serial.println(phy->random(100));
+}
+
+void loop() {
+ // nothing here, the example is just a showcase
+}
diff --git a/examples/RF69/RF69_Receive_AES/RF69_Receive_AES.ino b/examples/RF69/RF69_Receive_AES/RF69_Receive_AES.ino
index c1fa2816b0..62d1dca3e0 100644
--- a/examples/RF69/RF69_Receive_AES/RF69_Receive_AES.ino
+++ b/examples/RF69/RF69_Receive_AES/RF69_Receive_AES.ino
@@ -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.
- Packets are decrypted using hardware AES.
- NOTE: When using address filtering, the address byte is NOT encrypted!
+ This example receives packets using RF69 FSK radio module.
+ Packets are decrypted using hardware AES.
+ NOTE: When using address filtering, the address byte is NOT encrypted!
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -21,9 +21,13 @@
// RESET pin: 3
RF69 radio = new Module(10, 2, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//RF69 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -31,12 +35,12 @@ void setup() {
// initialize RF69 with default settings
Serial.print(F("[RF69] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set AES key that will be used to decrypt the packet
@@ -67,7 +71,7 @@ void loop() {
int state = radio.receive(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("success!"));
@@ -75,11 +79,11 @@ void loop() {
Serial.print(F("[RF69] Data:\t\t"));
Serial.println(str);
- } else if (state == ERR_RX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
// timeout occurred while waiting for a packet
Serial.println(F("timeout!"));
- } else if (state == ERR_CRC_MISMATCH) {
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
// packet was received, but is malformed
Serial.println(F("CRC error!"));
diff --git a/examples/RF69/RF69_Receive_Address/RF69_Receive_Address.ino b/examples/RF69/RF69_Receive_Address/RF69_Receive_Address.ino
index df20200c8d..f8d1fe91d6 100644
--- a/examples/RF69/RF69_Receive_Address/RF69_Receive_Address.ino
+++ b/examples/RF69/RF69_Receive_Address/RF69_Receive_Address.ino
@@ -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.
- Packets can have 1-byte address of the destination node.
- After setting node (or broadcast) address, this node will
- automatically filter out any packets that do not contain
- either node address or broadcast address.
+ This example receives packets using RF69 FSK radio module.
+ Packets can have 1-byte address of the destination node.
+ After setting node (or broadcast) address, this node will
+ automatically filter out any packets that do not contain
+ either node address or broadcast address.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -23,9 +23,13 @@
// RESET pin: 3
RF69 radio = new Module(10, 2, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//RF69 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -33,12 +37,12 @@ void setup() {
// initialize RF69 with default settings
Serial.print(F("[RF69] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set node address
@@ -46,12 +50,12 @@ void setup() {
// address filtering (node address only)
Serial.print(F("[RF69] Setting node address ... "));
state = radio.setNodeAddress(0x02);
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set broadcast address
@@ -59,12 +63,12 @@ void setup() {
// address filtering (node or broadcast address)
Serial.print(F("[RF69] Setting broadcast address ... "));
state = radio.setBroadcastAddress(0xFF);
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// address filtering can also be disabled
@@ -73,12 +77,12 @@ void setup() {
/*
Serial.print(F("[RF69] Disabling address filtering ... "));
state == radio.disableAddressFiltering();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
*/
}
@@ -96,7 +100,7 @@ void loop() {
int state = radio.receive(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("success!"));
@@ -104,11 +108,11 @@ void loop() {
Serial.print(F("[RF69] Data:\t\t"));
Serial.println(str);
- } else if (state == ERR_RX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
// timeout occurred while waiting for a packet
Serial.println(F("timeout!"));
- } else if (state == ERR_CRC_MISMATCH) {
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
// packet was received, but is malformed
Serial.println(F("CRC error!"));
diff --git a/examples/RF69/RF69_Receive/RF69_Receive.ino b/examples/RF69/RF69_Receive_Blocking/RF69_Receive_Blocking.ino
similarity index 56%
rename from examples/RF69/RF69_Receive/RF69_Receive.ino
rename to examples/RF69/RF69_Receive_Blocking/RF69_Receive_Blocking.ino
index fd9247557b..66f9aab550 100644
--- a/examples/RF69/RF69_Receive/RF69_Receive.ino
+++ b/examples/RF69/RF69_Receive_Blocking/RF69_Receive_Blocking.ino
@@ -1,19 +1,24 @@
/*
- RadioLib RF69 Receive Example
-
- This example receives packets using RF69 FSK radio module.
- To successfully receive data, the following settings have to be the same
- on both transmitter and receiver:
- - carrier frequency
- - bit rate
- - frequency deviation
- - sync word
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ RadioLib RF69 Blocking Receive Example
+
+ This example receives packets using RF69 FSK radio module.
+ To successfully receive data, the following settings have to be the same
+ on both transmitter and receiver:
+ - carrier frequency
+ - bit rate
+ - frequency deviation
+ - sync word
+
+ Using blocking receive is not recommended, as it will lead
+ to significant amount of timeouts, inefficient use of processor
+ time and can miss some packets!
+ Instead, interrupt receive is recommended.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -25,9 +30,13 @@
// RESET pin: 3
RF69 radio = new Module(10, 2, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//RF69 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -35,12 +44,12 @@ void setup() {
// initialize RF69 with default settings
Serial.print(F("[RF69] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
}
@@ -57,7 +66,7 @@ void loop() {
int state = radio.receive(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("success!"));
@@ -71,11 +80,11 @@ void loop() {
Serial.print(radio.getRSSI());
Serial.println(F(" dBm"));
- } else if (state == ERR_RX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
// timeout occurred while waiting for a packet
Serial.println(F("timeout!"));
- } else if (state == ERR_CRC_MISMATCH) {
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
// packet was received, but is malformed
Serial.println(F("CRC error!"));
diff --git a/examples/RF69/RF69_Receive_Interrupt/RF69_Receive_Interrupt.ino b/examples/RF69/RF69_Receive_Interrupt/RF69_Receive_Interrupt.ino
index 2a512783a4..e596a28317 100644
--- a/examples/RF69/RF69_Receive_Interrupt/RF69_Receive_Interrupt.ino
+++ b/examples/RF69/RF69_Receive_Interrupt/RF69_Receive_Interrupt.ino
@@ -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
- receive them. Once a packet is received, an interrupt is
- triggered.
+ This example listens for FSK transmissions and tries to
+ receive them. Once a packet is received, an interrupt is
+ triggered.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -21,9 +21,28 @@
// RESET pin: 3
RF69 radio = new Module(10, 2, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//RF69 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// flag to indicate that a packet was received
+volatile bool receivedFlag = false;
+
+// this function is called when a complete packet
+// is received by the module
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+#if defined(ESP8266) || defined(ESP32)
+ ICACHE_RAM_ATTR
+#endif
+void setFlag(void) {
+ // we got a packet, set the flag
+ receivedFlag = true;
+}
void setup() {
Serial.begin(9600);
@@ -31,27 +50,27 @@ void setup() {
// initialize RF69 with default settings
Serial.print(F("[RF69] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set the function that will be called
// when new packet is received
- radio.setDio0Action(setFlag);
+ radio.setPacketReceivedAction(setFlag);
// start listening for packets
Serial.print(F("[RF69] Starting to listen ... "));
state = radio.startReceive();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// if needed, 'listen' mode can be disabled by calling
@@ -64,33 +83,9 @@ void setup() {
// radio.readData();
}
-// flag to indicate that a packet was received
-volatile bool receivedFlag = false;
-
-// disable interrupt when it's not needed
-volatile bool enableInterrupt = true;
-
-// this function is called when a complete packet
-// is received by the module
-// IMPORTANT: this function MUST be 'void' type
-// and MUST NOT have any arguments!
-void setFlag(void) {
- // check if the interrupt is enabled
- if(!enableInterrupt) {
- return;
- }
-
- // we got a packet, set the flag
- receivedFlag = true;
-}
-
void loop() {
// check if the flag is set
if(receivedFlag) {
- // disable the interrupt service routine while
- // processing the data
- enableInterrupt = false;
-
// reset flag
receivedFlag = false;
@@ -101,10 +96,11 @@ void loop() {
// you can also read received data as byte array
/*
byte byteArr[8];
- int state = radio.readData(byteArr, 8);
+ int numBytes = radio.getPacketLength();
+ int state = radio.readData(byteArr, numBytes);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("[RF69] Received packet!"));
@@ -118,7 +114,7 @@ void loop() {
Serial.print(radio.getRSSI());
Serial.println(F(" dBm"));
- } else if (state == ERR_CRC_MISMATCH) {
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
// packet was received, but is malformed
Serial.println(F("CRC error!"));
@@ -131,10 +127,5 @@ void loop() {
// put module back to listen mode
radio.startReceive();
-
- // we're ready to receive more packets,
- // enable interrupt service routine
- enableInterrupt = true;
}
-
}
diff --git a/examples/RF69/RF69_Settings/RF69_Settings.ino b/examples/RF69/RF69_Settings/RF69_Settings.ino
index f936ee2e68..f8729d207a 100644
--- a/examples/RF69/RF69_Settings/RF69_Settings.ino
+++ b/examples/RF69/RF69_Settings/RF69_Settings.ino
@@ -1,21 +1,21 @@
/*
- RadioLib RF69 Settings Example
-
- This example shows how to change all the properties of RF69 radio.
- RadioLib currently supports the following settings:
- - pins (SPI slave select, digital IO 0, digital IO 1)
- - carrier frequency
- - bit rate
- - receiver bandwidth
- - allowed frequency deviation
- - output power during transmission
- - sync word
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ RadioLib RF69 Settings Example
+
+ This example shows how to change all the properties of RF69 radio.
+ RadioLib currently supports the following settings:
+ - pins (SPI slave select, digital IO 0, digital IO 1)
+ - carrier frequency
+ - bit rate
+ - receiver bandwidth
+ - allowed frequency deviation
+ - output power during transmission
+ - sync word
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -33,9 +33,13 @@ RF69 radio1 = new Module(10, 2, 3);
// RESET pin: 5
RF69 radio2 = new Module(9, 4, 5);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//RF69 radio3 = RadioShield.ModuleB;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio3 = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -43,12 +47,12 @@ void setup() {
// initialize RF69 with default settings
Serial.print(F("[RF69] Initializing ... "));
int state = radio1.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// initialize RF69 with non-default settings
@@ -60,64 +64,64 @@ void setup() {
// output power: 17 dBm
// preamble length: 32 bits
state = radio2.begin(868.0, 300.0, 60.0, 250.0, 17, 32);
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// you can also change the settings at runtime
// and check if the configuration was changed successfully
// set carrier frequency to 433.5 MHz
- if (radio1.setFrequency(433.5) == ERR_INVALID_FREQUENCY) {
+ if (radio1.setFrequency(433.5) == RADIOLIB_ERR_INVALID_FREQUENCY) {
Serial.println(F("[RF69] Selected frequency is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set bit rate to 100.0 kbps
state = radio1.setBitRate(100.0);
- if (state == ERR_INVALID_BIT_RATE) {
+ if (state == RADIOLIB_ERR_INVALID_BIT_RATE) {
Serial.println(F("[RF69] Selected bit rate is invalid for this module!"));
- while (true);
- } else if (state == ERR_INVALID_BIT_RATE_BW_RATIO) {
+ while (true) { delay(10); }
+ } else if (state == RADIOLIB_ERR_INVALID_BIT_RATE_BW_RATIO) {
Serial.println(F("[RF69] Selected bit rate to bandwidth ratio is invalid!"));
Serial.println(F("[RF69] Increase receiver bandwidth to set this bit rate."));
- while (true);
+ while (true) { delay(10); }
}
// set receiver bandwidth to 250.0 kHz
state = radio1.setRxBandwidth(250.0);
- if (state == ERR_INVALID_RX_BANDWIDTH) {
+ if (state == RADIOLIB_ERR_INVALID_RX_BANDWIDTH) {
Serial.println(F("[RF69] Selected receiver bandwidth is invalid for this module!"));
- while (true);
- } else if (state == ERR_INVALID_BIT_RATE_BW_RATIO) {
+ while (true) { delay(10); }
+ } else if (state == RADIOLIB_ERR_INVALID_BIT_RATE_BW_RATIO) {
Serial.println(F("[RF69] Selected bit rate to bandwidth ratio is invalid!"));
Serial.println(F("[RF69] Decrease bit rate to set this receiver bandwidth."));
- while (true);
+ while (true) { delay(10); }
}
// set allowed frequency deviation to 10.0 kHz
- if (radio1.setFrequencyDeviation(10.0) == 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!"));
- while (true);
+ while (true) { delay(10); }
}
// set output power to 2 dBm
- if (radio1.setOutputPower(2) == 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!"));
- while (true);
+ while (true) { delay(10); }
}
// up to 8 bytes can be set as sync word
// NOTE: sync word must not contain any zero bytes
// set sync word to 0x0123456789ABCDEF
uint8_t syncWord[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
- if (radio1.setSyncWord(syncWord, 8) == 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!"));
- while (true);
+ while (true) { delay(10); }
}
Serial.println(F("[RF69] All settings changed successfully!"));
diff --git a/examples/RF69/RF69_Transmit_AES/RF69_Transmit_AES.ino b/examples/RF69/RF69_Transmit_AES/RF69_Transmit_AES.ino
index d5bc2de27e..4c311a9ea5 100644
--- a/examples/RF69/RF69_Transmit_AES/RF69_Transmit_AES.ino
+++ b/examples/RF69/RF69_Transmit_AES/RF69_Transmit_AES.ino
@@ -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.
- Packets are encrypted using hardware AES.
- NOTE: When using address filtering, the address byte is NOT encrypted!
+ This example transmits packets using RF69 FSK radio module.
+ Packets are encrypted using hardware AES.
+ NOTE: When using address filtering, the address byte is NOT encrypted!
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -21,9 +21,13 @@
// RESET pin: 3
RF69 radio = new Module(10, 2, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//RF69 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -31,12 +35,12 @@ void setup() {
// initialize RF69 with default settings
Serial.print(F("[RF69] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set AES key to encrypt the packet
@@ -66,11 +70,11 @@ void loop() {
int state = radio.transmit(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// the packet was successfully transmitted
Serial.println(F("success!"));
- } else if (state == ERR_PACKET_TOO_LONG) {
+ } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
// the supplied packet was longer than 64 bytes
Serial.println(F("too long!"));
diff --git a/examples/RF69/RF69_Transmit_Address/RF69_Transmit_Address.ino b/examples/RF69/RF69_Transmit_Address/RF69_Transmit_Address.ino
index 5f91e1f621..6604c033b7 100644
--- a/examples/RF69/RF69_Transmit_Address/RF69_Transmit_Address.ino
+++ b/examples/RF69/RF69_Transmit_Address/RF69_Transmit_Address.ino
@@ -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.
- Packets can have 1-byte address of the destination node.
- After setting node (or broadcast) address, this node will
- automatically filter out any packets that do not contain
- either node address or broadcast address.
+ This example transmits packets using RF69 FSK radio module.
+ Packets can have 1-byte address of the destination node.
+ After setting node (or broadcast) address, this node will
+ automatically filter out any packets that do not contain
+ either node address or broadcast address.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -23,9 +23,13 @@
// RESET pin: 3
RF69 radio = new Module(10, 2, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//RF69 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -33,12 +37,12 @@ void setup() {
// initialize RF69 with default settings
Serial.print(F("[RF69] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set node address
@@ -46,12 +50,12 @@ void setup() {
// address filtering (node address only)
Serial.print(F("[RF69] Setting node address ... "));
state = radio.setNodeAddress(0x01);
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set broadcast address
@@ -59,12 +63,12 @@ void setup() {
// address filtering (node or broadcast address)
Serial.print(F("[RF69] Setting broadcast address ... "));
state = radio.setBroadcastAddress(0xFF);
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// address filtering can also be disabled
@@ -73,12 +77,12 @@ void setup() {
/*
Serial.print(F("[RF69] Disabling address filtering ... "));
state = radio.disableAddressFiltering();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
*/
}
@@ -106,11 +110,11 @@ void loop() {
int state = radio.transmit(byteArr, 8, 0xFF);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// the packet was successfully transmitted
Serial.println(F("success!"));
- } else if (state == ERR_PACKET_TOO_LONG) {
+ } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
// the supplied packet was longer than 64 bytes
Serial.println(F("too long!"));
diff --git a/examples/RF69/RF69_Transmit/RF69_Transmit.ino b/examples/RF69/RF69_Transmit_Blocking/RF69_Transmit_Blocking.ino
similarity index 57%
rename from examples/RF69/RF69_Transmit/RF69_Transmit.ino
rename to examples/RF69/RF69_Transmit_Blocking/RF69_Transmit_Blocking.ino
index c57122b2f8..fa70a7ad86 100644
--- a/examples/RF69/RF69_Transmit/RF69_Transmit.ino
+++ b/examples/RF69/RF69_Transmit_Blocking/RF69_Transmit_Blocking.ino
@@ -1,17 +1,21 @@
/*
- RadioLib RF69 Transmit Example
+ RadioLib RF69 Blocking Transmit Example
- This example transmits packets using RF69 FSK radio module.
- Each packet contains up to 64 bytes of data, in the form of:
- - Arduino String
- - null-terminated char array (C-string)
- - arbitrary binary data (byte array)
+ This example transmits packets using RF69 FSK radio module.
+ Each packet contains up to 64 bytes of data, in the form of:
+ - Arduino String
+ - null-terminated char array (C-string)
+ - arbitrary binary data (byte array)
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
+ Using blocking transmit is not recommended, as it will lead
+ to inefficient use of processor time!
+ Instead, interrupt transmit is recommended.
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -23,9 +27,13 @@
// RESET pin: 3
RF69 radio = new Module(10, 2, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//RF69 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -33,12 +41,12 @@ void setup() {
// initialize RF69 with default settings
Serial.print(F("[RF69] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// NOTE: some RF69 modules use high power output,
@@ -49,21 +57,25 @@ void setup() {
/*
Serial.print(F("[RF69] Setting high power module ... "));
state = radio.setOutputPower(20, true);
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
*/
}
+// counter to keep track of transmitted packets
+int count = 0;
+
void loop() {
Serial.print(F("[RF69] Transmitting packet ... "));
// you can transmit C-string or Arduino string up to 64 characters long
- int state = radio.transmit("Hello World!");
+ String str = "Hello World! #" + String(count++);
+ int state = radio.transmit(str);
// you can also transmit byte array up to 64 bytes long
/*
@@ -71,11 +83,11 @@ void loop() {
int state = radio.transmit(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// the packet was successfully transmitted
Serial.println(F("success!"));
- } else if (state == ERR_PACKET_TOO_LONG) {
+ } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
// the supplied packet was longer than 64 bytes
Serial.println(F("too long!"));
diff --git a/examples/RF69/RF69_Transmit_Interrupt/RF69_Transmit_Interrupt.ino b/examples/RF69/RF69_Transmit_Interrupt/RF69_Transmit_Interrupt.ino
index 0f03dad12d..63b9c8dac9 100644
--- a/examples/RF69/RF69_Transmit_Interrupt/RF69_Transmit_Interrupt.ino
+++ b/examples/RF69/RF69_Transmit_Interrupt/RF69_Transmit_Interrupt.ino
@@ -1,18 +1,18 @@
/*
- RadioLib RF69 Transmit with Interrupts Example
+ RadioLib RF69 Transmit with Interrupts Example
- This example transmits FSK packets with one second delays
- between them. Each packet contains up to 64 bytes
- of data, in the form of:
- - Arduino String
- - null-terminated char array (C-string)
- - arbitrary binary data (byte array)
+ This example transmits FSK packets with one second delays
+ between them. Each packet contains up to 64 bytes
+ of data, in the form of:
+ - Arduino String
+ - null-terminated char array (C-string)
+ - arbitrary binary data (byte array)
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -24,12 +24,31 @@
// RESET pin: 3
RF69 radio = new Module(10, 2, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//RF69 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// save transmission state between loops
-int transmissionState = ERR_NONE;
+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);
@@ -37,17 +56,17 @@ void setup() {
// initialize RF69 with default settings
Serial.print(F("[RF69] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set the function that will be called
// when packet transmission is finished
- radio.setDio0Action(setFlag);
+ radio.setPacketSentAction(setFlag);
// NOTE: some RF69 modules use high power output,
// those are usually marked RF69H(C/CW).
@@ -57,12 +76,12 @@ void setup() {
/*
Serial.print(F("[RF69] Setting high power module ... "));
state = radio.setOutputPower(20, true);
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
*/
@@ -81,50 +100,30 @@ void setup() {
*/
}
-// flag to indicate that a packet was sent
-volatile bool transmittedFlag = false;
-
-// disable interrupt when it's not needed
-volatile bool enableInterrupt = true;
-
-// this function is called when a complete packet
-// is transmitted by the module
-// IMPORTANT: this function MUST be 'void' type
-// and MUST NOT have any arguments!
-void setFlag(void) {
- // check if the interrupt is enabled
- if(!enableInterrupt) {
- return;
- }
-
- // we sent a packet, set the flag
- transmittedFlag = true;
-}
+// counter to keep track of transmitted packets
+int count = 0;
void loop() {
// check if the previous transmission finished
if(transmittedFlag) {
- // disable the interrupt service routine while
- // processing the data
- enableInterrupt = false;
-
// reset flag
transmittedFlag = false;
- if (transmissionState == ERR_NONE) {
+ 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);
@@ -132,18 +131,15 @@ void loop() {
Serial.print(F("[RF69] Sending another packet ... "));
// you can transmit C-string or Arduino string up to
- // 256 characters long
- transmissionState = radio.startTransmit("Hello World!");
+ // 64 characters long
+ String str = "Hello World! #" + String(count++);
+ transmissionState = radio.startTransmit(str);
// you can also transmit byte array up to 64 bytes long
/*
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
0x89, 0xAB, 0xCD, 0xEF};
- int state = radio.startTransmit(byteArr, 8);
+ transmissionState = radio.startTransmit(byteArr, 8);
*/
-
- // we're ready to send more packets,
- // enable interrupt service routine
- enableInterrupt = true;
}
}
diff --git a/examples/RTTY/RTTY_Transmit/RTTY_Transmit.ino b/examples/RTTY/RTTY_Transmit/RTTY_Transmit.ino
index f6d22a02f7..f839d878b0 100644
--- a/examples/RTTY/RTTY_Transmit/RTTY_Transmit.ino
+++ b/examples/RTTY/RTTY_Transmit/RTTY_Transmit.ino
@@ -1,24 +1,25 @@
/*
- RadioLib RTTY Transmit Example
-
- This example sends RTTY message using SX1278's
- FSK modem.
-
- Other modules that can be used for RTTY:
- - SX127x/RFM9x
- - RF69
- - SX1231
- - CC1101
- - SX126x
- - nRF24
- - Si443x/RFM2x
- - SX128x
-
- 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/
+ RadioLib RTTY Transmit Example
+
+ This example sends RTTY message using SX1278's
+ FSK modem.
+
+ Other modules that can be used for RTTY:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - SX126x
+ - nRF24
+ - Si443x/RFM2x
+ - SX128x
+ - LR11x0
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -31,9 +32,13 @@
// DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// create RTTY client instance using the FSK module
RTTYClient rtty(&radio);
@@ -49,12 +54,12 @@ void setup() {
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
// int state = radio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// initialize RTTY client
@@ -75,12 +80,12 @@ void setup() {
// encoding: ASCII (7-bit)
// stop bits: 1
state = rtty.begin(434.0, 183, 45);
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
/*
diff --git a/examples/RTTY/RTTY_Transmit_AFSK/RTTY_Transmit_AFSK.ino b/examples/RTTY/RTTY_Transmit_AFSK/RTTY_Transmit_AFSK.ino
index 243c3488d8..2d8830cf1e 100644
--- a/examples/RTTY/RTTY_Transmit_AFSK/RTTY_Transmit_AFSK.ino
+++ b/examples/RTTY/RTTY_Transmit_AFSK/RTTY_Transmit_AFSK.ino
@@ -1,21 +1,22 @@
/*
- RadioLib RTTY Transmit AFSK Example
+ RadioLib RTTY Transmit AFSK Example
- This example sends RTTY message using SX1278's
- FSK modem. The data is modulated as AFSK.
+ This example sends RTTY message using SX1278's
+ FSK modem. The data is modulated as AFSK.
- Other modules that can be used for RTTY:
- - SX127x/RFM9x
- - RF69
- - SX1231
- - CC1101
- - Si443x/RFM2x
+ Other modules that can be used for RTTY:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - Si443x/RFM2x
+ - SX126x/LLCC68
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration
+ For 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 full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -28,12 +29,23 @@
// DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// create AFSK client instance using the FSK module
-// pin 5 is connected to SX1278 DIO2
+// this requires connection to the module direct
+// input pin, here connected to Arduino pin 5
+// SX127x/RFM9x: DIO2
+// RF69: DIO2
+// SX1231: DIO2
+// CC1101: GDO2
+// Si443x/RFM2x: GPIO
+// SX126x/LLCC68: DIO2
AFSKClient audio(&radio, 5);
// create RTTY client instance using the AFSK instance
@@ -50,12 +62,12 @@ void setup() {
// (RF69, CC1101, Si4432 etc.), use the basic begin() method
// int state = radio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// initialize RTTY client
@@ -68,12 +80,12 @@ void setup() {
// encoding: ASCII (7-bit)
// stop bits: 1
state = rtty.begin(400, 170, 45);
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
/*
diff --git a/examples/SSTV/SSTV_Transmit/SSTV_Transmit.ino b/examples/SSTV/SSTV_Transmit/SSTV_Transmit.ino
index 6b06bae37d..cf072c403a 100644
--- a/examples/SSTV/SSTV_Transmit/SSTV_Transmit.ino
+++ b/examples/SSTV/SSTV_Transmit/SSTV_Transmit.ino
@@ -1,35 +1,35 @@
/*
- RadioLib SSTV Transmit Example
-
- The following example sends SSTV picture using
- SX1278's FSK modem.
-
- Other modules that can be used for SSTV:
- - SX127x/RFM9x
- - RF69
- - SX1231
- - SX126x
-
- NOTE: SSTV is an analog modulation, and
- requires precise frequency control.
- Some of the above modules can only
- set their frequency in rough steps,
- so the result can be distorted.
- Using high-precision radio with TCXO
- (like SX126x) is recommended.
-
- NOTE: Some platforms (such as Arduino Uno)
- might not be fast enough to correctly
- send pictures via high-speed modes
- like Scottie2 or Martin2. For those,
- lower speed modes such as Wrasse,
- Scottie1 or Martin1 are recommended.
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ RadioLib SSTV Transmit Example
+
+ The following example sends SSTV picture using
+ SX1278's FSK modem.
+
+ Other modules that can be used for SSTV:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - SX126x
+
+ NOTE: SSTV is an analog modulation, and
+ requires precise frequency control.
+ Some of the above modules can only
+ set their frequency in rough steps,
+ so the result can be distorted.
+ Using high-precision radio with TCXO
+ (like SX126x) is recommended.
+
+ NOTE: Some platforms (such as Arduino Uno)
+ might not be fast enough to correctly
+ send pictures via high-speed modes
+ like Scottie2 or Martin2. For those,
+ lower speed modes such as Wrasse,
+ Scottie1 or Martin1 are recommended.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -42,9 +42,13 @@
// DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// create SSTV client instance using the FSK module
SSTVClient sstv(&radio);
@@ -91,12 +95,12 @@ void setup() {
// initialize SX1278 with default settings
Serial.print(F("[SX1278] Initializing ... "));
int state = radio.beginFSK();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// when using one of the non-LoRa modules for SSTV
@@ -107,7 +111,16 @@ void setup() {
Serial.print(F("[SSTV] Initializing ... "));
// 0 Hz tone frequency: 434.0 MHz
// SSTV mode: Wrasse (SC2-180)
- // correction factor: 0.95
+ state = sstv.begin(434.0, Wrasse);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // set correction factor
// NOTE: Due to different speeds of various platforms
// supported by RadioLib (Arduino Uno, ESP32 etc),
// and because SSTV is analog protocol, incorrect
@@ -116,13 +129,14 @@ void setup() {
// to adjust the length of timing pulses
// (lower number = shorter pulses).
// The value is usually around 0.95 (95%).
- state = sstv.begin(434.0, Wrasse, 0.95);
- if(state == ERR_NONE) {
+ Serial.print(F("[SSTV] Setting correction ... "));
+ state = sstv.setCorrection(0.95);
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// to help tune the receiver, SSTVClient can send
@@ -131,7 +145,7 @@ void setup() {
// (SSTV header "leader tone")
/*
sstv.idle();
- while(true);
+ while (true) { delay(10); }
*/
}
diff --git a/examples/SSTV/SSTV_Transmit_AFSK/SSTV_Transmit_AFSK.ino b/examples/SSTV/SSTV_Transmit_AFSK/SSTV_Transmit_AFSK.ino
index e27bf67e38..667c436177 100644
--- a/examples/SSTV/SSTV_Transmit_AFSK/SSTV_Transmit_AFSK.ino
+++ b/examples/SSTV/SSTV_Transmit_AFSK/SSTV_Transmit_AFSK.ino
@@ -1,30 +1,31 @@
/*
- RadioLib SSTV Transmit AFSK Example
-
- The following example sends SSTV picture using
- SX1278's FSK modem. The data is modulated
- as AFSK.
-
- Other modules that can be used for SSTV:
- with AFSK modulation:
- - SX127x/RFM9x
- - RF69
- - SX1231
- - CC1101
- - Si443x/RFM2x
-
- NOTE: Some platforms (such as Arduino Uno)
- might not be fast enough to correctly
- send pictures via high-speed modes
- like Scottie2 or Martin2. For those,
- lower speed modes such as Wrasse,
- Scottie1 or Martin1 are recommended.
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ RadioLib SSTV Transmit AFSK Example
+
+ The following example sends SSTV picture using
+ SX1278's FSK modem. The data is modulated
+ as AFSK.
+
+ Other modules that can be used for SSTV:
+ with AFSK modulation:
+ - SX127x/RFM9x
+ - RF69
+ - SX1231
+ - CC1101
+ - Si443x/RFM2x
+ - SX126x/LLCC68
+
+ NOTE: Some platforms (such as Arduino Uno)
+ might not be fast enough to correctly
+ send pictures via high-speed modes
+ like Scottie2 or Martin2. For those,
+ lower speed modes such as Wrasse,
+ Scottie1 or Martin1 are recommended.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -37,12 +38,23 @@
// DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// create AFSK client instance using the FSK module
-// pin 5 is connected to SX1278 DIO2
+// this requires connection to the module direct
+// input pin, here connected to Arduino pin 5
+// SX127x/RFM9x: DIO2
+// RF69: DIO2
+// SX1231: DIO2
+// CC1101: GDO2
+// Si443x/RFM2x: GPIO
+// SX126x/LLCC68: DIO2
AFSKClient audio(&radio, 5);
// create SSTV client instance using the AFSK instance
@@ -90,12 +102,12 @@ void setup() {
// initialize SX1278 with default settings
Serial.print(F("[SX1278] Initializing ... "));
int state = radio.beginFSK();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// when using one of the non-LoRa modules for SSTV
@@ -105,7 +117,16 @@ void setup() {
// initialize SSTV client
Serial.print(F("[SSTV] Initializing ... "));
// SSTV mode: Wrasse (SC2-180)
- // correction factor: 0.95
+ state = sstv.begin(Wrasse);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // set correction factor
// NOTE: Due to different speeds of various platforms
// supported by RadioLib (Arduino Uno, ESP32 etc),
// and because SSTV is analog protocol, incorrect
@@ -114,20 +135,21 @@ void setup() {
// to adjust the length of timing pulses
// (lower number = shorter pulses).
// The value is usually around 0.95 (95%).
- state = sstv.begin(Wrasse, 0.95);
- if(state == ERR_NONE) {
+ Serial.print(F("[SSTV] Setting correction ... "));
+ state = sstv.setCorrection(0.95);
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// to help tune the receiver, SSTVClient can send
// continuous 1900 Hz beep
/*
sstv.idle();
- while(true);
+ while (true) { delay(10); }
*/
}
diff --git a/examples/STM32WLx/STM32WLx_Channel_Activity_Detection/STM32WLx_Channel_Activity_Detection.ino b/examples/STM32WLx/STM32WLx_Channel_Activity_Detection/STM32WLx_Channel_Activity_Detection.ino
new file mode 100644
index 0000000000..20401e9e82
--- /dev/null
+++ b/examples/STM32WLx/STM32WLx_Channel_Activity_Detection/STM32WLx_Channel_Activity_Detection.ino
@@ -0,0 +1,78 @@
+/*
+ RadioLib STM32WLx Channel Activity Detection Example
+
+ This example uses STM32WLx to scan the current LoRa
+ channel and detect ongoing LoRa transmissions.
+ Unlike SX127x CAD, SX126x/STM32WLx can detect any part
+ of LoRa transmission, not just the preamble.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// no need to configure pins, signals are routed to the radio internally
+STM32WLx radio = new STM32WLx_Module();
+
+// set RF switch configuration for Nucleo WL55JC1
+// NOTE: other boards may be different!
+// Some boards may not have either LP or HP.
+// For those, do not set the LP/HP entry in the table.
+static const uint32_t rfswitch_pins[] =
+ {PC3, PC4, PC5, RADIOLIB_NC, RADIOLIB_NC};
+static const Module::RfSwitchMode_t rfswitch_table[] = {
+ {STM32WLx::MODE_IDLE, {LOW, LOW, LOW}},
+ {STM32WLx::MODE_RX, {HIGH, HIGH, LOW}},
+ {STM32WLx::MODE_TX_LP, {HIGH, HIGH, HIGH}},
+ {STM32WLx::MODE_TX_HP, {HIGH, LOW, HIGH}},
+ END_OF_MODE_TABLE,
+};
+
+void setup() {
+ Serial.begin(9600);
+
+ // set RF switch control configuration
+ // this has to be done prior to calling begin()
+ radio.setRfSwitchTable(rfswitch_pins, rfswitch_table);
+
+ // initialize STM32WLx with default settings, except frequency
+ Serial.print(F("[STM32WLx] Initializing ... "));
+ int state = radio.begin(868.0);
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+}
+
+void loop() {
+ Serial.print(F("[STM32WLx] Scanning channel for LoRa transmission ... "));
+
+ // start scanning current channel
+ int state = radio.scanChannel();
+
+ if (state == RADIOLIB_LORA_DETECTED) {
+ // LoRa preamble was detected
+ Serial.println(F("detected!"));
+
+ } else if (state == RADIOLIB_CHANNEL_FREE) {
+ // no preamble was detected, channel is free
+ Serial.println(F("channel is free!"));
+
+ } else {
+ // some other error occurred
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+
+ }
+
+ // wait 100 ms before new scan
+ delay(100);
+}
diff --git a/examples/STM32WLx/STM32WLx_Channel_Activity_Detection_Interrupt/STM32WLx_Channel_Activity_Detection_Interrupt.ino b/examples/STM32WLx/STM32WLx_Channel_Activity_Detection_Interrupt/STM32WLx_Channel_Activity_Detection_Interrupt.ino
new file mode 100644
index 0000000000..b5a67e6764
--- /dev/null
+++ b/examples/STM32WLx/STM32WLx_Channel_Activity_Detection_Interrupt/STM32WLx_Channel_Activity_Detection_Interrupt.ino
@@ -0,0 +1,115 @@
+/*
+ RadioLib STM32WLx Channel Activity Detection Example
+
+ This example uses STM32WLx to scan the current LoRa
+ channel and detect ongoing LoRa transmissions.
+ Unlike SX127x CAD, SX126x/STM32WLx can detect any part
+ of LoRa transmission, not just the preamble.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// no need to configure pins, signals are routed to the radio internally
+STM32WLx radio = new STM32WLx_Module();
+
+// set RF switch configuration for Nucleo WL55JC1
+// NOTE: other boards may be different!
+// Some boards may not have either LP or HP.
+// For those, do not set the LP/HP entry in the table.
+static const uint32_t rfswitch_pins[] =
+ {PC3, PC4, PC5, RADIOLIB_NC, RADIOLIB_NC};
+static const Module::RfSwitchMode_t rfswitch_table[] = {
+ {STM32WLx::MODE_IDLE, {LOW, LOW, LOW}},
+ {STM32WLx::MODE_RX, {HIGH, HIGH, LOW}},
+ {STM32WLx::MODE_TX_LP, {HIGH, HIGH, HIGH}},
+ {STM32WLx::MODE_TX_HP, {HIGH, LOW, HIGH}},
+ END_OF_MODE_TABLE,
+};
+
+// flag to indicate that a packet was detected or CAD timed out
+volatile bool scanFlag = false;
+
+// this function is called when a complete packet
+// is received by the module
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+void setFlag(void) {
+ // something happened, set the flag
+ scanFlag = true;
+}
+
+void setup() {
+ Serial.begin(9600);
+
+ // set RF switch control configuration
+ // this has to be done prior to calling begin()
+ radio.setRfSwitchTable(rfswitch_pins, rfswitch_table);
+
+ // initialize STM32WLx with default settings, except frequency
+ Serial.print(F("[STM32WLx] Initializing ... "));
+ int state = radio.begin(868.0);
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // set the function that will be called
+ // when LoRa packet or timeout is detected
+ radio.setDio1Action(setFlag);
+
+ // start scanning the channel
+ Serial.print(F("[STM32WLx] Starting scan for LoRa preamble ... "));
+ state = radio.startChannelScan();
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ }
+}
+
+void loop() {
+ // check if the flag is set
+ if(scanFlag) {
+ // reset flag
+ scanFlag = false;
+
+ // check CAD result
+ int state = radio.getChannelScanResult();
+
+ if (state == RADIOLIB_LORA_DETECTED) {
+ // LoRa packet was detected
+ Serial.println(F("[STM32WLx] Packet detected!"));
+
+ } else if (state == RADIOLIB_CHANNEL_FREE) {
+ // channel is free
+ Serial.println(F("[STM32WLx] Channel is free!"));
+
+ } else {
+ // some other error occurred
+ Serial.print(F("[STM32WLx] Failed, code "));
+ Serial.println(state);
+
+ }
+
+ // start scanning the channel again
+ Serial.print(F("[STM32WLx] Starting scan for LoRa preamble ... "));
+ state = radio.startChannelScan();
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ }
+ }
+}
diff --git a/examples/STM32WLx/STM32WLx_Receive_Blocking/STM32WLx_Receive_Blocking.ino b/examples/STM32WLx/STM32WLx_Receive_Blocking/STM32WLx_Receive_Blocking.ino
new file mode 100644
index 0000000000..44163df24d
--- /dev/null
+++ b/examples/STM32WLx/STM32WLx_Receive_Blocking/STM32WLx_Receive_Blocking.ino
@@ -0,0 +1,128 @@
+/*
+ RadioLib STM32WLx Blocking Receive Example
+
+ This example listens for LoRa transmissions using STM32WL MCU with
+ integrated (SX126x) LoRa radio.
+
+ To successfully receive data, the following settings have to be the same
+ on both transmitter and receiver:
+ - carrier frequency
+ - bandwidth
+ - spreading factor
+ - coding rate
+ - sync word
+ - preamble length
+
+ This example assumes Nucleo WL55JC1 is used. For other Nucleo boards
+ or standalone STM32WL, some configuration such as TCXO voltage and
+ RF switch control may have to be adjusted.
+
+ Using blocking receive is not recommended, as it will lead
+ to significant amount of timeouts, inefficient use of processor
+ time and can some miss packets!
+ Instead, interrupt receive is recommended.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// no need to configure pins, signals are routed to the radio internally
+STM32WLx radio = new STM32WLx_Module();
+
+// set RF switch configuration for Nucleo WL55JC1
+// NOTE: other boards may be different!
+// Some boards may not have either LP or HP.
+// For those, do not set the LP/HP entry in the table.
+static const uint32_t rfswitch_pins[] =
+ {PC3, PC4, PC5, RADIOLIB_NC, RADIOLIB_NC};
+static const Module::RfSwitchMode_t rfswitch_table[] = {
+ {STM32WLx::MODE_IDLE, {LOW, LOW, LOW}},
+ {STM32WLx::MODE_RX, {HIGH, HIGH, LOW}},
+ {STM32WLx::MODE_TX_LP, {HIGH, HIGH, HIGH}},
+ {STM32WLx::MODE_TX_HP, {HIGH, LOW, HIGH}},
+ END_OF_MODE_TABLE,
+};
+
+void setup() {
+ Serial.begin(9600);
+
+ // set RF switch control configuration
+ // this has to be done prior to calling begin()
+ radio.setRfSwitchTable(rfswitch_pins, rfswitch_table);
+
+ // initialize STM32WL with default settings, except frequency
+ Serial.print(F("[STM32WL] Initializing ... "));
+ int state = radio.begin(868.0);
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // set appropriate TCXO voltage for Nucleo WL55JC1
+ state = radio.setTCXO(1.7);
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+}
+
+void loop() {
+ Serial.print(F("[STM32WL] Waiting for incoming transmission ... "));
+
+ // you can receive data as an Arduino String
+ String str;
+ int state = radio.receive(str);
+
+ // you can also receive data as byte array
+ /*
+ byte byteArr[8];
+ int state = radio.receive(byteArr, 8);
+ */
+
+ if (state == RADIOLIB_ERR_NONE) {
+ // packet was successfully received
+ Serial.println(F("success!"));
+
+ // print the data of the packet
+ Serial.print(F("[STM32WL] Data:\t\t"));
+ Serial.println(str);
+
+ // print the RSSI (Received Signal Strength Indicator)
+ // of the last received packet
+ Serial.print(F("[STM32WL] RSSI:\t\t"));
+ Serial.print(radio.getRSSI());
+ Serial.println(F(" dBm"));
+
+ // print the SNR (Signal-to-Noise Ratio)
+ // of the last received packet
+ Serial.print(F("[STM32WL] SNR:\t\t"));
+ Serial.print(radio.getSNR());
+ Serial.println(F(" dB"));
+
+ } else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
+ // timeout occurred while waiting for a packet
+ Serial.println(F("timeout!"));
+
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
+ // packet was received, but is malformed
+ Serial.println(F("CRC error!"));
+
+ } else {
+ // some other error occurred
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+
+ }
+}
diff --git a/examples/STM32WLx/STM32WLx_Receive_Interrupt/STM32WLx_Receive_Interrupt.ino b/examples/STM32WLx/STM32WLx_Receive_Interrupt/STM32WLx_Receive_Interrupt.ino
new file mode 100644
index 0000000000..dc62255dcf
--- /dev/null
+++ b/examples/STM32WLx/STM32WLx_Receive_Interrupt/STM32WLx_Receive_Interrupt.ino
@@ -0,0 +1,158 @@
+/*
+ RadioLib STM32WLx Receive with Interrupts Example
+
+ This example listens for LoRa transmissions and tries to
+ receive them. Once a packet is received, an interrupt is
+ triggered. To successfully receive data, the following
+ settings have to be the same on both transmitter
+ and receiver:
+ - carrier frequency
+ - bandwidth
+ - spreading factor
+ - coding rate
+ - sync word
+
+ This example assumes Nucleo WL55JC1 is used. For other Nucleo boards
+ or standalone STM32WL, some configuration such as TCXO voltage and
+ RF switch control may have to be adjusted.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// no need to configure pins, signals are routed to the radio internally
+STM32WLx radio = new STM32WLx_Module();
+
+// set RF switch configuration for Nucleo WL55JC1
+// NOTE: other boards may be different!
+// Some boards may not have either LP or HP.
+// For those, do not set the LP/HP entry in the table.
+static const uint32_t rfswitch_pins[] =
+ {PC3, PC4, PC5, RADIOLIB_NC, RADIOLIB_NC};
+static const Module::RfSwitchMode_t rfswitch_table[] = {
+ {STM32WLx::MODE_IDLE, {LOW, LOW, LOW}},
+ {STM32WLx::MODE_RX, {HIGH, HIGH, LOW}},
+ {STM32WLx::MODE_TX_LP, {HIGH, HIGH, HIGH}},
+ {STM32WLx::MODE_TX_HP, {HIGH, LOW, HIGH}},
+ END_OF_MODE_TABLE,
+};
+
+// flag to indicate that a packet was received
+volatile bool receivedFlag = false;
+
+// this function is called when a complete packet
+// is received by the module
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+void setFlag(void) {
+ // we got a packet, set the flag
+ receivedFlag = true;
+}
+
+void setup() {
+ Serial.begin(9600);
+
+ // set RF switch control configuration
+ // this has to be done prior to calling begin()
+ radio.setRfSwitchTable(rfswitch_pins, rfswitch_table);
+
+ // initialize STM32WL with default settings, except frequency
+ Serial.print(F("[STM32WL] Initializing ... "));
+ int state = radio.begin(868.0);
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // set appropriate TCXO voltage for Nucleo WL55JC1
+ state = radio.setTCXO(1.7);
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // set the function that will be called
+ // when new packet is received
+ radio.setDio1Action(setFlag);
+
+ // start listening for LoRa packets
+ Serial.print(F("[STM32WL] Starting to listen ... "));
+ state = radio.startReceive();
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // if needed, 'listen' mode can be disabled by calling
+ // any of the following methods:
+ //
+ // radio.standby()
+ // radio.sleep()
+ // radio.transmit();
+ // radio.receive();
+ // radio.readData();
+ // radio.scanChannel();
+}
+
+void loop() {
+ // check if the flag is set
+ if(receivedFlag) {
+ // reset flag
+ receivedFlag = false;
+
+ // you can read received data as an Arduino String
+ String str;
+ int state = radio.readData(str);
+
+ // you can also read received data as byte array
+ /*
+ byte byteArr[8];
+ int numBytes = radio.getPacketLength();
+ int state = radio.readData(byteArr, numBytes);
+ */
+
+ if (state == RADIOLIB_ERR_NONE) {
+ // packet was successfully received
+ Serial.println(F("[STM32WL] Received packet!"));
+
+ // print data of the packet
+ Serial.print(F("[STM32WL] Data:\t\t"));
+ Serial.println(str);
+
+ // print RSSI (Received Signal Strength Indicator)
+ Serial.print(F("[STM32WL] RSSI:\t\t"));
+ Serial.print(radio.getRSSI());
+ Serial.println(F(" dBm"));
+
+ // print SNR (Signal-to-Noise Ratio)
+ Serial.print(F("[STM32WL] SNR:\t\t"));
+ Serial.print(radio.getSNR());
+ Serial.println(F(" dB"));
+
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
+ // packet was received, but is malformed
+ Serial.println(F("CRC error!"));
+
+ } else {
+ // some other error occurred
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+
+ }
+ }
+}
diff --git a/examples/STM32WLx/STM32WLx_Transmit_Blocking/STM32WLx_Transmit_Blocking.ino b/examples/STM32WLx/STM32WLx_Transmit_Blocking/STM32WLx_Transmit_Blocking.ino
new file mode 100644
index 0000000000..4a366da32a
--- /dev/null
+++ b/examples/STM32WLx/STM32WLx_Transmit_Blocking/STM32WLx_Transmit_Blocking.ino
@@ -0,0 +1,114 @@
+/*
+ RadioLib STM32WLx Blocking Transmit Example
+
+ This example transmits packets using STM32WL MCU with integrated
+ (SX126x) LoRa radio.
+
+ Each packet contains up to 256 bytes of data, in the form of:
+ - Arduino String
+ - null-terminated char array (C-string)
+ - arbitrary binary data (byte array)
+
+ This example assumes Nucleo WL55JC1 is used. For other Nucleo boards
+ or standalone STM32WL, some configuration such as TCXO voltage and
+ RF switch control may have to be adjusted.
+
+ Using blocking transmit is not recommended, as it will lead
+ to inefficient use of processor time!
+ Instead, interrupt transmit is recommended.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// no need to configure pins, signals are routed to the radio internally
+STM32WLx radio = new STM32WLx_Module();
+
+// set RF switch configuration for Nucleo WL55JC1
+// NOTE: other boards may be different!
+// Some boards may not have either LP or HP.
+// For those, do not set the LP/HP entry in the table.
+static const uint32_t rfswitch_pins[] =
+ {PC3, PC4, PC5, RADIOLIB_NC, RADIOLIB_NC};
+static const Module::RfSwitchMode_t rfswitch_table[] = {
+ {STM32WLx::MODE_IDLE, {LOW, LOW, LOW}},
+ {STM32WLx::MODE_RX, {HIGH, HIGH, LOW}},
+ {STM32WLx::MODE_TX_LP, {HIGH, HIGH, HIGH}},
+ {STM32WLx::MODE_TX_HP, {HIGH, LOW, HIGH}},
+ END_OF_MODE_TABLE,
+};
+
+void setup() {
+ Serial.begin(9600);
+
+ // set RF switch control configuration
+ // this has to be done prior to calling begin()
+ radio.setRfSwitchTable(rfswitch_pins, rfswitch_table);
+
+ // initialize STM32WL with default settings, except frequency
+ Serial.print(F("[STM32WL] Initializing ... "));
+ int state = radio.begin(868.0);
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // set appropriate TCXO voltage for Nucleo WL55JC1
+ state = radio.setTCXO(1.7);
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+}
+
+// counter to keep track of transmitted packets
+int count = 0;
+
+void loop() {
+ Serial.print(F("[STM32WL] Transmitting packet ... "));
+
+ // you can transmit C-string or Arduino string up to
+ // 256 characters long
+ String str = "Hello World! #" + String(count++);
+ int state = radio.transmit(str);
+
+ // you can also transmit byte array up to 256 bytes long
+ /*
+ byte byteArr[] = {0x01, 0x23, 0x45, 0x56, 0x78, 0xAB, 0xCD, 0xEF};
+ int state = radio.transmit(byteArr, 8);
+ */
+
+ if (state == RADIOLIB_ERR_NONE) {
+ // the packet was successfully transmitted
+ Serial.println(F("success!"));
+
+ } 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);
+}
diff --git a/examples/STM32WLx/STM32WLx_Transmit_Interrupt/STM32WLx_Transmit_Interrupt.ino b/examples/STM32WLx/STM32WLx_Transmit_Interrupt/STM32WLx_Transmit_Interrupt.ino
new file mode 100644
index 0000000000..77dcc29b80
--- /dev/null
+++ b/examples/STM32WLx/STM32WLx_Transmit_Interrupt/STM32WLx_Transmit_Interrupt.ino
@@ -0,0 +1,142 @@
+/*
+ RadioLib STM32WLx Transmit with Interrupts Example
+
+ This example transmits LoRa packets with one second delays
+ between them. Each packet contains up to 256 bytes
+ of data, in the form of:
+ - Arduino String
+ - null-terminated char array (C-string)
+ - arbitrary binary data (byte array)
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// no need to configure pins, signals are routed to the radio internally
+STM32WLx radio = new STM32WLx_Module();
+
+// set RF switch configuration for Nucleo WL55JC1
+// NOTE: other boards may be different!
+// Some boards may not have either LP or HP.
+// For those, do not set the LP/HP entry in the table.
+static const uint32_t rfswitch_pins[] =
+ {PC3, PC4, PC5, RADIOLIB_NC, RADIOLIB_NC};
+static const Module::RfSwitchMode_t rfswitch_table[] = {
+ {STM32WLx::MODE_IDLE, {LOW, LOW, LOW}},
+ {STM32WLx::MODE_RX, {HIGH, HIGH, LOW}},
+ {STM32WLx::MODE_TX_LP, {HIGH, HIGH, HIGH}},
+ {STM32WLx::MODE_TX_HP, {HIGH, LOW, HIGH}},
+ END_OF_MODE_TABLE,
+};
+
+// save transmission state between loops
+int transmissionState = RADIOLIB_ERR_NONE;
+
+// flag to indicate that a packet was sent
+volatile bool transmittedFlag = false;
+
+// this function is called when a complete packet
+// is transmitted by the module
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+void setFlag(void) {
+ // we sent a packet, set the flag
+ transmittedFlag = true;
+}
+
+void setup() {
+ Serial.begin(9600);
+
+ // set RF switch control configuration
+ // this has to be done prior to calling begin()
+ radio.setRfSwitchTable(rfswitch_pins, rfswitch_table);
+
+ // initialize STM32WL with default settings, except frequency
+ Serial.print(F("[STM32WL] Initializing ... "));
+ int state = radio.begin(868.0);
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // set appropriate TCXO voltage for Nucleo WL55JC1
+ state = radio.setTCXO(1.7);
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // set the function that will be called
+ // when packet transmission is finished
+ radio.setDio1Action(setFlag);
+
+ // start transmitting the first packet
+ Serial.print(F("[STM32WL] Sending first packet ... "));
+
+ // you can transmit C-string or Arduino string up to
+ // 256 characters long
+ transmissionState = radio.startTransmit("Hello World!");
+
+ // you can also transmit byte array up to 256 bytes long
+ /*
+ byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
+ 0x89, 0xAB, 0xCD, 0xEF};
+ state = radio.startTransmit(byteArr, 8);
+ */
+}
+
+// counter to keep track of transmitted packets
+int count = 0;
+
+void loop() {
+ // check if the previous transmission finished
+ if(transmittedFlag) {
+ // reset flag
+ transmittedFlag = false;
+
+ if (transmissionState == RADIOLIB_ERR_NONE) {
+ // packet was successfully sent
+ Serial.println(F("transmission finished!"));
+
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(transmissionState);
+
+ }
+
+ // clean up after transmission is finished
+ // this will ensure transmitter is disabled,
+ // RF switch is powered down etc.
+ radio.finishTransmit();
+
+ // wait a second before transmitting again
+ delay(1000);
+
+ // send another one
+ Serial.print(F("[STM32WL] Sending another packet ... "));
+
+ // you can transmit C-string or Arduino string up to
+ // 256 characters long
+ String str = "Hello World! #" + String(count++);
+ transmissionState = radio.startTransmit(str);
+
+ // you can also transmit byte array up to 256 bytes long
+ /*
+ byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
+ 0x89, 0xAB, 0xCD, 0xEF};
+ transmissionState = radio.startTransmit(byteArr, 8);
+ */
+ }
+}
diff --git a/examples/SX1231/SX1231_Transmit/SX1231_Transmit.ino b/examples/SX1231/SX1231_Transmit/SX1231_Transmit.ino
deleted file mode 100644
index 0f8cd14bcd..0000000000
--- a/examples/SX1231/SX1231_Transmit/SX1231_Transmit.ino
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- RadioLib SX1231 Transmit Example
-
- This example transmits packets using SX1231 FSK radio module.
-
- NOTE: SX1231 offers the same features as RF69 and has the same
- interface. Please see RF69 examples for examples on AES,
- address filtering, interrupts and settings.
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
-*/
-
-// include the library
-#include
-
-// SX1231 has the following connections:
-// CS pin: 10
-// DIO0 pin: 2
-// RESET pin: 3
-SX1231 radio = new Module(10, 2, 3);
-
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1231 radio = RadioShield.ModuleA;
-
-void setup() {
- Serial.begin(9600);
-
- // initialize SX1231 with default settings
- Serial.print(F("[SX1231] Initializing ... "));
- int state = radio.begin();
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-}
-
-void loop() {
- Serial.print(F("[SX1231] Transmitting packet ... "));
-
- // you can transmit C-string or Arduino string up to 256 characters long
- int state = radio.transmit("Hello World!");
-
- // you can also transmit byte array up to 256 bytes long
- /*
- byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
- int state = radio.transmit(byteArr, 8);
- */
-
- if (state == ERR_NONE) {
- // the packet was successfully transmitted
- Serial.println(F("success!"));
-
- } else if (state == ERR_PACKET_TOO_LONG) {
- // the supplied packet was longer than 256 bytes
- Serial.println(F("too long!"));
-
- }
-
- // wait for a second before transmitting again
- delay(1000);
-}
diff --git a/examples/SX1231/SX1231_Receive/SX1231_Receive.ino b/examples/SX123x/SX123x_Receive_Blocking/SX123x_Receive_Blocking.ino
similarity index 51%
rename from examples/SX1231/SX1231_Receive/SX1231_Receive.ino
rename to examples/SX123x/SX123x_Receive_Blocking/SX123x_Receive_Blocking.ino
index 18d0354c8b..896e1ba752 100644
--- a/examples/SX1231/SX1231_Receive/SX1231_Receive.ino
+++ b/examples/SX123x/SX123x_Receive_Blocking/SX123x_Receive_Blocking.ino
@@ -1,17 +1,23 @@
/*
- RadioLib SX1231 Receive Example
+ RadioLib SX123x Blocking Receive Example
- This example receives packets using SX1231 FSK radio module.
+ This example receives packets using SX1231 FSK radio module.
+ Other modules from SX123x family can also be used.
- NOTE: SX1231 offers the same features as RF69 and has the same
- interface. Please see RF69 examples for examples on AES,
- address filtering, interrupts and settings.
+ NOTE: SX123x modules offer the same features as RF69 and have the same
+ interface. Please see RF69 examples for examples on AES,
+ address filtering, interrupts and settings.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
+ 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 full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -23,9 +29,13 @@
// RESET pin: 3
SX1231 radio = new Module(10, 2, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1231 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -33,12 +43,12 @@ void setup() {
// initialize SX1231 with default settings
Serial.print(F("[SX1231] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
}
@@ -55,7 +65,7 @@ void loop() {
int state = radio.receive(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("success!"));
@@ -63,11 +73,11 @@ void loop() {
Serial.print(F("[SX1231] Data:\t\t"));
Serial.println(str);
- } else if (state == ERR_RX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
// timeout occurred while waiting for a packet
Serial.println(F("timeout!"));
- } else if (state == ERR_CRC_MISMATCH) {
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
// packet was received, but is malformed
Serial.println(F("CRC error!"));
diff --git a/examples/SX123x/SX123x_Transmit_Blocking/SX123x_Transmit_Blocking.ino b/examples/SX123x/SX123x_Transmit_Blocking/SX123x_Transmit_Blocking.ino
new file mode 100644
index 0000000000..fd86924554
--- /dev/null
+++ b/examples/SX123x/SX123x_Transmit_Blocking/SX123x_Transmit_Blocking.ino
@@ -0,0 +1,82 @@
+/*
+ RadioLib SX123x Blocking Transmit Example
+
+ This example transmits packets using SX1231 FSK radio module.
+ Other modules from SX123x family can also be used.
+
+ NOTE: SX123x modules offer the same features as RF69 and have the same
+ interface. Please see RF69 examples for examples on AES,
+ address filtering, interrupts and settings.
+
+ Using blocking transmit is not recommended, as it will lead
+ to inefficient use of processor time!
+ Instead, interrupt transmit is recommended.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1231 has the following connections:
+// CS pin: 10
+// DIO0 pin: 2
+// RESET pin: 3
+SX1231 radio = new Module(10, 2, 3);
+
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+void setup() {
+ Serial.begin(9600);
+
+ // initialize SX1231 with default settings
+ Serial.print(F("[SX1231] Initializing ... "));
+ int state = radio.begin();
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+}
+
+// counter to keep track of transmitted packets
+int count = 0;
+
+void loop() {
+ Serial.print(F("[SX1231] Transmitting packet ... "));
+
+ // you can transmit C-string or Arduino string up to 256 characters long
+ String str = "Hello World! #" + String(count++);
+ int state = radio.transmit(str);
+
+ // you can also transmit byte array up to 256 bytes long
+ /*
+ byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
+ int state = radio.transmit(byteArr, 8);
+ */
+
+ if (state == RADIOLIB_ERR_NONE) {
+ // the packet was successfully transmitted
+ Serial.println(F("success!"));
+
+ } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
+ // the supplied packet was longer than 256 bytes
+ Serial.println(F("too long!"));
+
+ }
+
+ // wait for a second before transmitting again
+ delay(1000);
+}
diff --git a/examples/SX126x/SX126x_Channel_Activity_Detection/SX126x_Channel_Activity_Detection.ino b/examples/SX126x/SX126x_Channel_Activity_Detection/SX126x_Channel_Activity_Detection.ino
deleted file mode 100644
index b888a95d39..0000000000
--- a/examples/SX126x/SX126x_Channel_Activity_Detection/SX126x_Channel_Activity_Detection.ino
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- RadioLib SX126x Channel Activity Detection Example
-
- This example uses SX1262 to scan the current LoRa
- channel and detect ongoing LoRa transmissions.
- Unlike SX127x CAD, SX126x can detect any part
- of LoRa transmission, not just the preamble.
-
- Other modules from SX126x family can also be used.
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
-*/
-
-// include the library
-#include
-
-// SX1262 has the following connections:
-// NSS pin: 10
-// DIO1 pin: 2
-// NRST pin: 3
-// BUSY pin: 9
-SX1262 radio = new Module(10, 2, 3, 9);
-
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1262 radio = RadioShield.ModuleA;
-
-void setup() {
- Serial.begin(9600);
-
- // initialize SX1262 with default settings
- Serial.print(F("[SX1262] Initializing ... "));
- int state = radio.begin();
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-}
-
-void loop() {
- Serial.print(F("[SX1262] Scanning channel for LoRa transmission ... "));
-
- // start scanning current channel
- int state = radio.scanChannel();
-
- if (state == LORA_DETECTED) {
- // LoRa preamble was detected
- Serial.println(F("detected!"));
-
- } else if (state == 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);
-}
diff --git a/examples/SX126x/SX126x_Channel_Activity_Detection_Blocking/SX126x_Channel_Activity_Detection_Blocking.ino b/examples/SX126x/SX126x_Channel_Activity_Detection_Blocking/SX126x_Channel_Activity_Detection_Blocking.ino
new file mode 100644
index 0000000000..8c668e1a19
--- /dev/null
+++ b/examples/SX126x/SX126x_Channel_Activity_Detection_Blocking/SX126x_Channel_Activity_Detection_Blocking.ino
@@ -0,0 +1,79 @@
+/*
+ RadioLib SX126x Blocking Channel Activity Detection Example
+
+ This example uses SX1262 to scan the current LoRa
+ channel and detect ongoing LoRa transmissions.
+ Unlike SX127x CAD, SX126x can detect any part
+ of LoRa transmission, not just the preamble.
+
+ Other modules from SX126x family can also be used.
+
+ 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#sx126x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1262 has the following connections:
+// NSS pin: 10
+// DIO1 pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+SX1262 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
+Radio radio = new RadioModule();
+*/
+
+void setup() {
+ Serial.begin(9600);
+
+ // initialize SX1262 with default settings
+ Serial.print(F("[SX1262] Initializing ... "));
+ int state = radio.begin();
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+}
+
+void loop() {
+ Serial.print(F("[SX1262] 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);
+}
diff --git a/examples/SX126x/SX126x_Channel_Activity_Detection_Interrupt/SX126x_Channel_Activity_Detection_Interrupt.ino b/examples/SX126x/SX126x_Channel_Activity_Detection_Interrupt/SX126x_Channel_Activity_Detection_Interrupt.ino
new file mode 100644
index 0000000000..d47b58df2f
--- /dev/null
+++ b/examples/SX126x/SX126x_Channel_Activity_Detection_Interrupt/SX126x_Channel_Activity_Detection_Interrupt.ino
@@ -0,0 +1,114 @@
+/*
+ RadioLib SX126x Channel Activity Detection Example
+
+ This example uses SX1262 to scan the current LoRa
+ channel and detect ongoing LoRa transmissions.
+ Unlike SX127x CAD, SX126x can detect any part
+ of LoRa transmission, not just the preamble.
+
+ Other modules from SX126x family can also be used.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1262 has the following connections:
+// NSS pin: 10
+// DIO1 pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+SX1262 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
+Radio radio = new RadioModule();
+*/
+
+// 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 SX1262 with default settings
+ Serial.print(F("[SX1262] 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 LoRa packet or timeout is detected
+ radio.setDio1Action(setFlag);
+
+ // start scanning the channel
+ Serial.print(F("[SX1262] 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("[SX1262] Packet detected!"));
+
+ } else if (state == RADIOLIB_CHANNEL_FREE) {
+ // channel is free
+ Serial.println(F("[SX1262] Channel is free!"));
+
+ } else {
+ // some other error occurred
+ Serial.print(F("[SX1262] Failed, code "));
+ Serial.println(state);
+
+ }
+
+ // start scanning the channel again
+ Serial.print(F("[SX1262] 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);
+ }
+ }
+}
diff --git a/examples/SX126x/SX126x_Channel_Activity_Detection_Receive/SX126x_Channel_Activity_Detection_Receive.ino b/examples/SX126x/SX126x_Channel_Activity_Detection_Receive/SX126x_Channel_Activity_Detection_Receive.ino
new file mode 100644
index 0000000000..85b204d579
--- /dev/null
+++ b/examples/SX126x/SX126x_Channel_Activity_Detection_Receive/SX126x_Channel_Activity_Detection_Receive.ino
@@ -0,0 +1,187 @@
+/*
+ RadioLib SX126x Receive after Channel Activity Detection Example
+
+ This example uses SX1262 to scan the current LoRa
+ channel and detect ongoing LoRa transmissions.
+ Unlike SX127x CAD, SX126x can detect any part
+ of LoRa transmission, not just the preamble.
+ If a packet is detected, the module will switch
+ to receive mode and receive the packet.
+
+ Other modules from SX126x family can also be used.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1262 has the following connections:
+// NSS pin: 10
+// DIO1 pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+SX1262 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
+Radio radio = new RadioModule();
+*/
+
+// whether we are receiving, or scanning
+bool receiving = false;
+
+// 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 SX1262 with default settings
+ Serial.print(F("[SX1262] 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 LoRa packet or timeout is detected
+ radio.setDio1Action(setFlag);
+
+ // start scanning the channel
+ Serial.print(F("[SX1262] 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) {
+ int state = RADIOLIB_ERR_NONE;
+
+ // reset flag
+ scanFlag = false;
+
+ // check ongoing reception
+ if(receiving) {
+ // DIO triggered while reception is ongoing
+ // that means we got a packet
+
+ // you can read received data as an Arduino String
+ String str;
+ state = radio.readData(str);
+
+ // you can also read received data as byte array
+ /*
+ byte byteArr[8];
+ state = radio.readData(byteArr, 8);
+ */
+
+ if (state == RADIOLIB_ERR_NONE) {
+ // packet was successfully received
+ Serial.println(F("[SX1262] Received packet!"));
+
+ // print data of the packet
+ Serial.print(F("[SX1262] Data:\t\t"));
+ Serial.println(str);
+
+ // print RSSI (Received Signal Strength Indicator)
+ Serial.print(F("[SX1262] RSSI:\t\t"));
+ Serial.print(radio.getRSSI());
+ Serial.println(F(" dBm"));
+
+ // print SNR (Signal-to-Noise Ratio)
+ Serial.print(F("[SX1262] SNR:\t\t"));
+ Serial.print(radio.getSNR());
+ Serial.println(F(" dB"));
+
+ // print frequency error
+ Serial.print(F("[SX1262] Frequency error:\t"));
+ Serial.print(radio.getFrequencyError());
+ Serial.println(F(" Hz"));
+
+ } else {
+ // some other error occurred
+ Serial.print(F("[SX1262] Failed, code "));
+ Serial.println(state);
+
+ }
+
+ // reception is done now
+ receiving = false;
+
+ } else {
+ // check CAD result
+ state = radio.getChannelScanResult();
+
+ if (state == RADIOLIB_LORA_DETECTED) {
+ // LoRa packet was detected
+ Serial.print(F("[SX1262] Packet detected, starting reception ... "));
+ state = radio.startReceive();
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ }
+
+ // set the flag for ongoing reception
+ receiving = true;
+
+ } else if (state == RADIOLIB_CHANNEL_FREE) {
+ // channel is free
+ Serial.println(F("[SX1262] Channel is free!"));
+
+ } else {
+ // some other error occurred
+ Serial.print(F("[SX1262] Failed, code "));
+ Serial.println(state);
+
+ }
+
+ }
+
+ // if we're not receiving, start scanning again
+ if(!receiving) {
+ Serial.print(F("[SX1262] 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);
+ }
+
+ }
+
+ }
+
+}
diff --git a/examples/SX126x/SX126x_FSK_Modem/SX126x_FSK_Modem.ino b/examples/SX126x/SX126x_FSK_Modem/SX126x_FSK_Modem.ino
index d450f9c618..04dcbe58ff 100644
--- a/examples/SX126x/SX126x_FSK_Modem/SX126x_FSK_Modem.ino
+++ b/examples/SX126x/SX126x_FSK_Modem/SX126x_FSK_Modem.ino
@@ -1,19 +1,19 @@
/*
- RadioLib SX126x FSK Modem Example
+ RadioLib SX126x FSK Modem Example
- This example shows how to use FSK modem in SX126x chips.
+ This example shows how to use FSK modem in SX126x chips.
- NOTE: The sketch below is just a guide on how to use
- FSK modem, so this code should not be run directly!
- Instead, modify the other examples to use FSK
- modem and use the appropriate configuration
- methods.
+ NOTE: The sketch below is just a guide on how to use
+ FSK modem, so this code should not be run directly!
+ Instead, modify the other examples to use FSK
+ modem and use the appropriate configuration
+ methods.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---fsk-modem
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---fsk-modem
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -26,9 +26,13 @@
// BUSY pin: 9
SX1262 radio = new Module(10, 2, 3, 9);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1262 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -36,12 +40,12 @@ void setup() {
// initialize SX1262 FSK modem with default settings
Serial.print(F("[SX1262] Initializing ... "));
int state = radio.beginFSK();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// if needed, you can switch between LoRa and FSK modes
@@ -61,19 +65,12 @@ void setup() {
uint8_t syncWord[] = {0x01, 0x23, 0x45, 0x67,
0x89, 0xAB, 0xCD, 0xEF};
state = radio.setSyncWord(syncWord, 8);
- if (state != ERR_NONE) {
+ if (state != RADIOLIB_ERR_NONE) {
Serial.print(F("Unable to set configuration, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
- // FSK modem on SX126x 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);
-
// FSK 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)
@@ -94,11 +91,11 @@ void loop() {
0x89, 0xAB, 0xCD, 0xEF};
int state = radio.transmit(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("[SX1262] Packet transmitted successfully!"));
- } else if (state == ERR_PACKET_TOO_LONG) {
+ } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
Serial.println(F("[SX1262] Packet too long!"));
- } else if (state == ERR_TX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
Serial.println(F("[SX1262] Timed out while transmitting!"));
} else {
Serial.println(F("[SX1262] Failed to transmit packet, code "));
@@ -112,43 +109,14 @@ void loop() {
byte byteArr[8];
int state = radio.receive(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("[SX1262] Received packet!"));
Serial.print(F("[SX1262] Data:\t"));
Serial.println(str);
- } else if (state == ERR_RX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
Serial.println(F("[SX1262] Timed out while waiting for packet!"));
} else {
Serial.println(F("[SX1262] Failed to receive packet, code "));
Serial.println(state);
}
-
- // FSK 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 != ERR_NONE) {
- Serial.println(F("[SX1262] 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 != ERR_NONE) {
- Serial.println(F("Unable to remove address filter, code "));
- }
- */
}
diff --git a/examples/SX126x/SX126x_LR_FHSS_Transmit_Blocking/SX126x_LR_FHSS_Transmit_Blocking.ino b/examples/SX126x/SX126x_LR_FHSS_Transmit_Blocking/SX126x_LR_FHSS_Transmit_Blocking.ino
new file mode 100644
index 0000000000..8e72cb86c4
--- /dev/null
+++ b/examples/SX126x/SX126x_LR_FHSS_Transmit_Blocking/SX126x_LR_FHSS_Transmit_Blocking.ino
@@ -0,0 +1,108 @@
+/*
+ RadioLib SX126x LR-FHSS Modem Example
+
+ This example shows how to use LR-FHSS modem in SX126x chips.
+ This modem can only transmit data, and is not able to receive.
+
+ This example transmits packets using SX1262 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 SX126x family can also be used.
+
+ Using blocking transmit is not recommended, as it will lead
+ to inefficient use of processor time!
+ Instead, interrupt transmit is recommended.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lr-fhss-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1262 has the following connections:
+// NSS pin: 10
+// IRQ pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+SX1262 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
+Radio radio = new RadioModule();
+*/
+
+void setup() {
+ Serial.begin(9600);
+
+ // initialize SX1262 with default settings
+ Serial.print(F("[SX1262] 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); }
+ }
+
+ // some modules have an external RF switch
+ // controlled via two pins (RX enable, TX enable)
+ // to enable automatic control of the switch,
+ // call the following method
+ // RX enable: 4
+ // TX enable: 5
+ /*
+ radio.setRfSwitchPins(4, 5);
+ */
+}
+
+// counter to keep track of transmitted packets
+int count = 0;
+
+void loop() {
+ // LR-FHSS modem can only transmit!
+ Serial.print(F("[SX1262] Transmitting packet ... "));
+
+ // you can transmit C-string or Arduino string up to
+ // 256 characters long
+ String str = "Hello World! #" + String(count++);
+ int state = radio.transmit(str);
+
+ // you can also transmit byte array up to 256 bytes long
+ /*
+ byte byteArr[] = {0x01, 0x23, 0x45, 0x56, 0x78, 0xAB, 0xCD, 0xEF};
+ int state = radio.transmit(byteArr, 8);
+ */
+
+ if (state == RADIOLIB_ERR_NONE) {
+ // the packet was successfully transmitted
+ Serial.println(F("success!"));
+
+ } 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 occurred 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);
+}
diff --git a/examples/SX126x/SX126x_LR_FHSS_Transmit_Interrupt/SX126x_LR_FHSS_Transmit_Interrupt.ino b/examples/SX126x/SX126x_LR_FHSS_Transmit_Interrupt/SX126x_LR_FHSS_Transmit_Interrupt.ino
new file mode 100644
index 0000000000..d1812452cb
--- /dev/null
+++ b/examples/SX126x/SX126x_LR_FHSS_Transmit_Interrupt/SX126x_LR_FHSS_Transmit_Interrupt.ino
@@ -0,0 +1,147 @@
+/*
+ RadioLib SX126x LR-FHSS Transmit with Interrupts Example
+
+ This example shows how to use LR-FHSS modem in SX126x chips.
+ This modem can only transmit data, and is not able to receive.
+
+ This example transmits packets using SX1262 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 SX126x family can also be used.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lr-fhss-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1262 has the following connections:
+// NSS pin: 10
+// IRQ pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+SX1262 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
+Radio radio = new RadioModule();
+*/
+
+// save transmission state between loops
+int transmissionState = RADIOLIB_ERR_NONE;
+
+// flag to indicate that a packet was sent
+// or a frequency hop is needed
+volatile bool flag = 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 or need to hop, set the flag
+ flag = true;
+}
+
+void setup() {
+ Serial.begin(9600);
+
+ // initialize SX1262 with default settings
+ Serial.print(F("[SX1262] 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); }
+ }
+
+ // set the function that will be called
+ // when packet transmission is finished
+ radio.setPacketSentAction(setFlag);
+
+ // start transmitting the first packet
+ Serial.print(F("[SX1262] 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() {
+ // LR-FHSS modem can only transmit!
+
+ // check if the previous transmission finished
+ if(flag) {
+ // reset flag
+ flag = false;
+
+ // check if this was caused by hopping or transmission finished
+ if(radio.getIrqFlags() & RADIOLIB_SX126X_IRQ_LR_FHSS_HOP) {
+ radio.hopLRFHSS();
+
+ } else {
+ if (transmissionState == RADIOLIB_ERR_NONE) {
+ // packet was successfully sent
+ Serial.println(F("transmission finished!"));
+
+ } 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("[SX1262] 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);
+ */
+
+ }
+
+
+
+ }
+
+}
diff --git a/examples/SX126x/SX126x_PingPong/SX126x_PingPong.ino b/examples/SX126x/SX126x_PingPong/SX126x_PingPong.ino
index 946a175c69..ff409f34ce 100644
--- a/examples/SX126x/SX126x_PingPong/SX126x_PingPong.ino
+++ b/examples/SX126x/SX126x_PingPong/SX126x_PingPong.ino
@@ -1,11 +1,14 @@
/*
- RadioLib SX126x Ping-Pong Example
+ RadioLib SX126x Ping-Pong Example
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
+ This example is intended to run on two SX126x radios,
+ and send packets between the two.
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -22,19 +25,20 @@
// BUSY pin: 9
SX1262 radio = new Module(10, 2, 3, 9);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1262 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// save transmission states between loops
-int transmissionState = ERR_NONE;
+int transmissionState = RADIOLIB_ERR_NONE;
// flag to indicate transmission or reception state
bool transmitFlag = false;
-// disable interrupt when it's not needed
-volatile bool enableInterrupt = true;
-
// flag to indicate that a packet was sent or received
volatile bool operationDone = false;
@@ -42,13 +46,11 @@ volatile bool operationDone = false;
// 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) {
- // check if the interrupt is enabled
- if(!enableInterrupt) {
- return;
- }
-
- // we sent aor received packet, set the flag
+ // we sent or received a packet, set the flag
operationDone = true;
}
@@ -58,12 +60,12 @@ void setup() {
// initialize SX1262 with default settings
Serial.print(F("[SX1262] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set the function that will be called
@@ -79,12 +81,12 @@ void setup() {
// start listening for LoRa packets on this node
Serial.print(F("[SX1262] Starting to listen ... "));
state = radio.startReceive();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
#endif
}
@@ -92,54 +94,50 @@ void setup() {
void loop() {
// check if the previous operation finished
if(operationDone) {
- // disable the interrupt service routine while
- // processing the data
- enableInterrupt = false;
-
// reset flag
operationDone = false;
if(transmitFlag) {
// the previous operation was transmission, listen for response
// print the result
- if (transmissionState == ERR_NONE) {
+ 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 == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("[SX1262] Received packet!"));
-
+
// print data of the packet
Serial.print(F("[SX1262] Data:\t\t"));
Serial.println(str);
-
+
// print RSSI (Received Signal Strength Indicator)
Serial.print(F("[SX1262] RSSI:\t\t"));
Serial.print(radio.getRSSI());
Serial.println(F(" dBm"));
-
+
// print SNR (Signal-to-Noise Ratio)
Serial.print(F("[SX1262] SNR:\t\t"));
Serial.print(radio.getSNR());
Serial.println(F(" dB"));
-
+
}
// wait a second before transmitting again
@@ -150,10 +148,6 @@ void loop() {
transmissionState = radio.startTransmit("Hello World!");
transmitFlag = true;
}
-
- // we're ready to process more packets,
- // enable interrupt service routine
- enableInterrupt = true;
-
+
}
}
diff --git a/examples/SX126x/SX126x_Receive/SX126x_Receive.ino b/examples/SX126x/SX126x_Receive_Blocking/SX126x_Receive_Blocking.ino
similarity index 54%
rename from examples/SX126x/SX126x_Receive/SX126x_Receive.ino
rename to examples/SX126x/SX126x_Receive_Blocking/SX126x_Receive_Blocking.ino
index 23969cb192..a1641ed268 100644
--- a/examples/SX126x/SX126x_Receive/SX126x_Receive.ino
+++ b/examples/SX126x/SX126x_Receive_Blocking/SX126x_Receive_Blocking.ino
@@ -1,23 +1,28 @@
/*
- RadioLib SX126x Receive Example
-
- This example listens for LoRa transmissions using SX126x 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 SX126x family can also be used.
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ RadioLib SX126x Blocking Receive Example
+
+ This example listens for LoRa transmissions using SX126x 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 SX126x family can also be used.
+
+Using blocking receive is not recommended, as it will lead
+to significant amount of timeouts, inefficient use of processor
+time and can some miss packets!
+Instead, interrupt receive is recommended.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -30,9 +35,13 @@
// BUSY pin: 9
SX1262 radio = new Module(10, 2, 3, 9);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1262 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -40,12 +49,12 @@ void setup() {
// initialize SX1262 with default settings
Serial.print(F("[SX1262] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
}
@@ -53,9 +62,6 @@ void loop() {
Serial.print(F("[SX1262] Waiting for incoming transmission ... "));
// you can receive data as an Arduino String
- // NOTE: receive() is a blocking method!
- // See example ReceiveInterrupt for details
- // on non-blocking reception method.
String str;
int state = radio.receive(str);
@@ -65,7 +71,7 @@ void loop() {
int state = radio.receive(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("success!"));
@@ -85,11 +91,16 @@ void loop() {
Serial.print(radio.getSNR());
Serial.println(F(" dB"));
- } else if (state == ERR_RX_TIMEOUT) {
+ // print frequency error
+ Serial.print(F("[SX1262] Frequency error:\t"));
+ Serial.print(radio.getFrequencyError());
+ Serial.println(F(" Hz"));
+
+ } else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
// timeout occurred while waiting for a packet
Serial.println(F("timeout!"));
- } else if (state == ERR_CRC_MISMATCH) {
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
// packet was received, but is malformed
Serial.println(F("CRC error!"));
diff --git a/examples/SX126x/SX126x_Receive_Interrupt/SX126x_Receive_Interrupt.ino b/examples/SX126x/SX126x_Receive_Interrupt/SX126x_Receive_Interrupt.ino
index 3932f7b021..de1664bf4a 100644
--- a/examples/SX126x/SX126x_Receive_Interrupt/SX126x_Receive_Interrupt.ino
+++ b/examples/SX126x/SX126x_Receive_Interrupt/SX126x_Receive_Interrupt.ino
@@ -1,24 +1,24 @@
/*
- RadioLib SX126x 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 SX126x family can also be used.
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ RadioLib SX126x 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 SX126x family can also be used.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -31,9 +31,28 @@
// BUSY pin: 9
SX1262 radio = new Module(10, 2, 3, 9);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1262 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// flag to indicate that a packet was received
+volatile bool receivedFlag = false;
+
+// this function is called when a complete packet
+// is received by the module
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+#if defined(ESP8266) || defined(ESP32)
+ ICACHE_RAM_ATTR
+#endif
+void setFlag(void) {
+ // we got a packet, set the flag
+ receivedFlag = true;
+}
void setup() {
Serial.begin(9600);
@@ -41,27 +60,27 @@ void setup() {
// initialize SX1262 with default settings
Serial.print(F("[SX1262] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set the function that will be called
// when new packet is received
- radio.setDio1Action(setFlag);
+ radio.setPacketReceivedAction(setFlag);
// start listening for LoRa packets
Serial.print(F("[SX1262] Starting to listen ... "));
state = radio.startReceive();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// if needed, 'listen' mode can be disabled by calling
@@ -71,37 +90,12 @@ void setup() {
// radio.sleep()
// radio.transmit();
// radio.receive();
- // radio.readData();
// radio.scanChannel();
}
-// flag to indicate that a packet was received
-volatile bool receivedFlag = false;
-
-// disable interrupt when it's not needed
-volatile bool enableInterrupt = true;
-
-// this function is called when a complete packet
-// is received by the module
-// IMPORTANT: this function MUST be 'void' type
-// and MUST NOT have any arguments!
-void setFlag(void) {
- // check if the interrupt is enabled
- if(!enableInterrupt) {
- return;
- }
-
- // we got a packet, set the flag
- receivedFlag = true;
-}
-
void loop() {
// check if the flag is set
if(receivedFlag) {
- // disable the interrupt service routine while
- // processing the data
- enableInterrupt = false;
-
// reset flag
receivedFlag = false;
@@ -112,10 +106,11 @@ void loop() {
// you can also read received data as byte array
/*
byte byteArr[8];
- int state = radio.readData(byteArr, 8);
+ int numBytes = radio.getPacketLength();
+ int state = radio.readData(byteArr, numBytes);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("[SX1262] Received packet!"));
@@ -133,7 +128,12 @@ void loop() {
Serial.print(radio.getSNR());
Serial.println(F(" dB"));
- } else if (state == ERR_CRC_MISMATCH) {
+ // print frequency error
+ Serial.print(F("[SX1262] Frequency error:\t"));
+ Serial.print(radio.getFrequencyError());
+ Serial.println(F(" Hz"));
+
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
// packet was received, but is malformed
Serial.println(F("CRC error!"));
@@ -143,13 +143,5 @@ void loop() {
Serial.println(state);
}
-
- // put module back to listen mode
- radio.startReceive();
-
- // we're ready to receive more packets,
- // enable interrupt service routine
- enableInterrupt = true;
}
-
}
diff --git a/examples/SX126x/SX126x_Settings/SX126x_Settings.ino b/examples/SX126x/SX126x_Settings/SX126x_Settings.ino
index f485284f79..71a4d8fb62 100644
--- a/examples/SX126x/SX126x_Settings/SX126x_Settings.ino
+++ b/examples/SX126x/SX126x_Settings/SX126x_Settings.ino
@@ -1,27 +1,27 @@
/*
- RadioLib SX126x Settings Example
-
- This example shows how to change all the properties of LoRa transmission.
- RadioLib currently supports the following settings:
- - pins (SPI slave select, DIO1, DIO2, BUSY pin)
- - carrier frequency
- - bandwidth
- - spreading factor
- - coding rate
- - sync word
- - output power during transmission
- - CRC
- - preamble length
- - TCXO voltage
- - DIO2 RF switch control
-
- Other modules from SX126x family can also be used.
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ RadioLib SX126x Settings Example
+
+ This example shows how to change all the properties of LoRa transmission.
+ RadioLib currently supports the following settings:
+ - pins (SPI slave select, DIO1, DIO2, BUSY pin)
+ - carrier frequency
+ - bandwidth
+ - spreading factor
+ - coding rate
+ - sync word
+ - output power during transmission
+ - CRC
+ - preamble length
+ - TCXO voltage
+ - DIO2 RF switch control
+
+ Other modules from SX126x family can also be used.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -41,9 +41,13 @@ SX1262 radio1 = new Module(10, 2, 3, 9);
// BUSY pin: 6
SX1268 radio2 = new Module(8, 4, 5, 6);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1261 radio3 = RadioShield.ModuleB;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio3 = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -51,12 +55,12 @@ void setup() {
// initialize SX1268 with default settings
Serial.print(F("[SX1262] Initializing ... "));
int state = radio1.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// initialize the second LoRa instance with
@@ -71,88 +75,88 @@ void setup() {
// sync word: 0x34 (public network/LoRaWAN)
// output power: 2 dBm
// preamble length: 20 symbols
- state = radio2.begin(915.0, 500.0, 6, 5, 0x34, 20);
- if (state == ERR_NONE) {
+ state = radio2.begin(915.0, 500.0, 6, 5, 0x34, 2, 20);
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// you can also change the settings at runtime
// and check if the configuration was changed successfully
// set carrier frequency to 433.5 MHz
- if (radio1.setFrequency(433.5) == ERR_INVALID_FREQUENCY) {
+ if (radio1.setFrequency(433.5) == RADIOLIB_ERR_INVALID_FREQUENCY) {
Serial.println(F("Selected frequency is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set bandwidth to 250 kHz
- if (radio1.setBandwidth(250.0) == ERR_INVALID_BANDWIDTH) {
+ if (radio1.setBandwidth(250.0) == RADIOLIB_ERR_INVALID_BANDWIDTH) {
Serial.println(F("Selected bandwidth is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set spreading factor to 10
- if (radio1.setSpreadingFactor(10) == ERR_INVALID_SPREADING_FACTOR) {
+ if (radio1.setSpreadingFactor(10) == RADIOLIB_ERR_INVALID_SPREADING_FACTOR) {
Serial.println(F("Selected spreading factor is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set coding rate to 6
- if (radio1.setCodingRate(6) == ERR_INVALID_CODING_RATE) {
+ if (radio1.setCodingRate(6) == RADIOLIB_ERR_INVALID_CODING_RATE) {
Serial.println(F("Selected coding rate is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set LoRa sync word to 0xAB
- if (radio1.setSyncWord(0xAB) != ERR_NONE) {
+ if (radio1.setSyncWord(0xAB) != RADIOLIB_ERR_NONE) {
Serial.println(F("Unable to set sync word!"));
- while (true);
+ while (true) { delay(10); }
}
// set output power to 10 dBm (accepted range is -17 - 22 dBm)
- if (radio1.setOutputPower(10) == ERR_INVALID_OUTPUT_POWER) {
+ if (radio1.setOutputPower(10) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) {
Serial.println(F("Selected output power is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set over current protection limit to 80 mA (accepted range is 45 - 240 mA)
// NOTE: set value to 0 to disable overcurrent protection
- if (radio1.setCurrentLimit(80) == ERR_INVALID_CURRENT_LIMIT) {
+ if (radio1.setCurrentLimit(80) == RADIOLIB_ERR_INVALID_CURRENT_LIMIT) {
Serial.println(F("Selected current limit is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set LoRa preamble length to 15 symbols (accepted range is 0 - 65535)
- if (radio1.setPreambleLength(15) == ERR_INVALID_PREAMBLE_LENGTH) {
+ if (radio1.setPreambleLength(15) == RADIOLIB_ERR_INVALID_PREAMBLE_LENGTH) {
Serial.println(F("Selected preamble length is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// disable CRC
- if (radio1.setCRC(false) == ERR_INVALID_CRC_CONFIGURATION) {
+ if (radio1.setCRC(false) == RADIOLIB_ERR_INVALID_CRC_CONFIGURATION) {
Serial.println(F("Selected CRC is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// Some SX126x modules have TCXO (temperature compensated crystal
// oscillator). To configure TCXO reference voltage,
// the following method can be used.
- if (radio1.setTCXO(2.4) == ERR_INVALID_TCXO_VOLTAGE) {
+ if (radio1.setTCXO(2.4) == RADIOLIB_ERR_INVALID_TCXO_VOLTAGE) {
Serial.println(F("Selected TCXO voltage is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// Some SX126x modules use DIO2 as RF switch. To enable
// this feature, the following method can be used.
// NOTE: As long as DIO2 is configured to control RF switch,
// it can't be used as interrupt pin!
- if (radio1.setDio2AsRfSwitch() != ERR_NONE) {
+ if (radio1.setDio2AsRfSwitch() != RADIOLIB_ERR_NONE) {
Serial.println(F("Failed to set DIO2 as RF switch!"));
- while (true);
+ while (true) { delay(10); }
}
Serial.println(F("All settings succesfully changed!"));
diff --git a/examples/SX126x/SX126x_Spectrum_Scan/SX126x_Spectrum_Scan.ino b/examples/SX126x/SX126x_Spectrum_Scan/SX126x_Spectrum_Scan.ino
new file mode 100644
index 0000000000..bf28f36a44
--- /dev/null
+++ b/examples/SX126x/SX126x_Spectrum_Scan/SX126x_Spectrum_Scan.ino
@@ -0,0 +1,121 @@
+/*
+ RadioLib SX126x Spectrum Scan Example
+
+ This example shows how to perform a spectrum power scan using SX126x.
+ The output is in the form of scan lines, each line has 33 power bins.
+ First power bin corresponds to -11 dBm, the second to -15 dBm and so on.
+ Higher number of samples in a bin corresponds to more power received
+ at that level.
+
+ To show the results in a plot, run the Python script
+ RadioLib/extras/SX126x_Spectrum_Scan/SpectrumScan.py
+
+ WARNING: This functionality is experimental and requires a binary patch
+ to be uploaded to the SX126x device. There may be some undocumented
+ side effects!
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// this file contains binary patch for the SX1262
+#include
+
+// SX1262 has the following connections:
+// NSS pin: 10
+// DIO1 pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+SX1262 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
+Radio radio = new RadioModule();
+*/
+
+void setup() {
+ Serial.begin(115200);
+
+ // initialize SX1262 FSK modem with default settings
+ Serial.print(F("[SX1262] Initializing ... "));
+ int state = radio.beginFSK();
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // upload a patch to the SX1262 to enable spectral scan
+ // NOTE: this patch is uploaded into volatile memory,
+ // and must be re-uploaded on every power up
+ Serial.print(F("[SX1262] Uploading patch ... "));
+ state = radio.uploadPatch(sx126x_patch_scan, sizeof(sx126x_patch_scan));
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // configure scan bandwidth to 234.4 kHz
+ // and disable the data shaping
+ Serial.print(F("[SX1262] Setting scan parameters ... "));
+ state = radio.setRxBandwidth(234.3);
+ state |= radio.setDataShaping(RADIOLIB_SHAPING_NONE);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+}
+
+void loop() {
+ Serial.print(F("[SX1262] Starting spectral scan ... "));
+
+ // start spectral scan
+ // number of scans in each line is 2048
+ // number of samples: 2048 (fewer samples = better temporal resolution)
+ int state = radio.spectralScanStart(2048);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // wait for spectral scan to finish
+ while(radio.spectralScanGetStatus() != RADIOLIB_ERR_NONE) {
+ delay(10);
+ }
+
+ // read the results
+ uint16_t results[RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE];
+ state = radio.spectralScanGetResult(results);
+ if(state == RADIOLIB_ERR_NONE) {
+ // we have some results, print it
+ Serial.print("SCAN ");
+ for(uint8_t i = 0; i < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE; i++) {
+ Serial.print(results[i]);
+ Serial.print(',');
+ }
+ Serial.println(" END");
+ }
+
+ // wait a little bit before the next scan
+ delay(5);
+}
\ No newline at end of file
diff --git a/examples/SX126x/SX126x_Spectrum_Scan_Frequency/SX126x_Spectrum_Scan_Frequency.ino b/examples/SX126x/SX126x_Spectrum_Scan_Frequency/SX126x_Spectrum_Scan_Frequency.ino
new file mode 100644
index 0000000000..71d3445ab2
--- /dev/null
+++ b/examples/SX126x/SX126x_Spectrum_Scan_Frequency/SX126x_Spectrum_Scan_Frequency.ino
@@ -0,0 +1,137 @@
+/*
+ RadioLib SX126x Spectrum Scan Example
+
+ This example shows how to perform a spectrum power scan using SX126x.
+ The output is in the form of scan lines, each line has 33 power bins.
+ First power bin corresponds to -11 dBm, the second to -15 dBm and so on.
+ Higher number of samples in a bin corresponds to more power received
+ at that level. The example performs frequency sweep over a given range.
+
+ To show the results in a plot, run the Python script
+ RadioLib/extras/SX126x_Spectrum_Scan/SpectrumScan.py
+
+ WARNING: This functionality is experimental and requires a binary patch
+ to be uploaded to the SX126x device. There may be some undocumented
+ side effects!
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// this file contains binary patch for the SX1262
+#include
+
+// SX1262 has the following connections:
+// NSS pin: 10
+// DIO1 pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+SX1262 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
+Radio radio = new RadioModule();
+*/
+
+// frequency range in MHz to scan
+const float freqStart = 431;
+const float freqEnd = 435;
+
+void setup() {
+ Serial.begin(115200);
+
+ // initialize SX1262 FSK modem at the initial frequency
+ Serial.print(F("[SX1262] Initializing ... "));
+ int state = radio.beginFSK(freqStart);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // upload a patch to the SX1262 to enable spectral scan
+ // NOTE: this patch is uploaded into volatile memory,
+ // and must be re-uploaded on every power up
+ Serial.print(F("[SX1262] Uploading patch ... "));
+ state = radio.uploadPatch(sx126x_patch_scan, sizeof(sx126x_patch_scan));
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // configure scan bandwidth to 234.4 kHz
+ // and disable the data shaping
+ Serial.print(F("[SX1262] Setting scan parameters ... "));
+ state = radio.setRxBandwidth(234.3);
+ state |= radio.setDataShaping(RADIOLIB_SHAPING_NONE);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+}
+
+void loop() {
+ // perform scan over the entire frequency range
+ float freq = freqStart;
+ while(freq <= freqEnd) {
+ Serial.print("FREQ ");
+ Serial.println(freq, 2);
+
+ // start spectral scan
+ // number of samples: 2048 (fewer samples = better temporal resolution)
+ Serial.print(F("[SX1262] Starting spectral scan ... "));
+ int state = radio.spectralScanStart(2048);
+ if(state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // wait for spectral scan to finish
+ while(radio.spectralScanGetStatus() != RADIOLIB_ERR_NONE) {
+ delay(10);
+ }
+
+ // read the results
+ uint16_t results[RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE];
+ state = radio.spectralScanGetResult(results);
+ if(state == RADIOLIB_ERR_NONE) {
+ // we have some results, print it
+ Serial.print("SCAN ");
+ for(uint8_t i = 0; i < RADIOLIB_SX126X_SPECTRAL_SCAN_RES_SIZE; i++) {
+ Serial.print(results[i]);
+ Serial.print(',');
+ }
+ Serial.println(" END");
+ }
+
+ // wait a little bit before the next scan
+ delay(5);
+
+ // set the next frequency
+ // the frequency step should be slightly smaller
+ // or the same as the Rx bandwidth set in setup
+ freq += 0.2;
+ radio.setFrequency(freq);
+ }
+
+}
diff --git a/examples/SX126x/SX126x_Transmit/SX126x_Transmit.ino b/examples/SX126x/SX126x_Transmit_Blocking/SX126x_Transmit_Blocking.ino
similarity index 55%
rename from examples/SX126x/SX126x_Transmit/SX126x_Transmit.ino
rename to examples/SX126x/SX126x_Transmit_Blocking/SX126x_Transmit_Blocking.ino
index 541645eef8..3c34ecd92f 100644
--- a/examples/SX126x/SX126x_Transmit/SX126x_Transmit.ino
+++ b/examples/SX126x/SX126x_Transmit_Blocking/SX126x_Transmit_Blocking.ino
@@ -1,19 +1,23 @@
/*
- RadioLib SX126x Transmit Example
+ RadioLib SX126x Blocking Transmit Example
- This example transmits packets using SX1262 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)
+ This example transmits packets using SX1262 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 SX126x family can also be used.
+ Other modules from SX126x family can also be used.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
+ Using blocking transmit is not recommended, as it will lead
+ to inefficient use of processor time!
+ Instead, interrupt transmit is recommended.
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -26,9 +30,13 @@
// BUSY pin: 9
SX1262 radio = new Module(10, 2, 3, 9);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1262 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -36,12 +44,12 @@ void setup() {
// initialize SX1262 with default settings
Serial.print(F("[SX1262] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// some modules have an external RF switch
@@ -55,15 +63,16 @@ void setup() {
*/
}
+// counter to keep track of transmitted packets
+int count = 0;
+
void loop() {
Serial.print(F("[SX1262] Transmitting packet ... "));
// you can transmit C-string or Arduino string up to
// 256 characters long
- // NOTE: transmit() is a blocking method!
- // See example SX126x_Transmit_Interrupt for details
- // on non-blocking transmission method.
- int state = radio.transmit("Hello World!");
+ String str = "Hello World! #" + String(count++);
+ int state = radio.transmit(str);
// you can also transmit byte array up to 256 bytes long
/*
@@ -71,20 +80,15 @@ void loop() {
int state = radio.transmit(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// the packet was successfully transmitted
Serial.println(F("success!"));
- // print measured data rate
- Serial.print(F("[SX1262] Datarate:\t"));
- Serial.print(radio.getDataRate());
- Serial.println(F(" bps"));
-
- } else if (state == ERR_PACKET_TOO_LONG) {
+ } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
// the supplied packet was longer than 256 bytes
Serial.println(F("too long!"));
- } else if (state == ERR_TX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
// timeout occured while transmitting packet
Serial.println(F("timeout!"));
diff --git a/examples/SX126x/SX126x_Transmit_Interrupt/SX126x_Transmit_Interrupt.ino b/examples/SX126x/SX126x_Transmit_Interrupt/SX126x_Transmit_Interrupt.ino
index 20600a1161..b8a3f5c88f 100644
--- a/examples/SX126x/SX126x_Transmit_Interrupt/SX126x_Transmit_Interrupt.ino
+++ b/examples/SX126x/SX126x_Transmit_Interrupt/SX126x_Transmit_Interrupt.ino
@@ -1,20 +1,20 @@
/*
- RadioLib SX126x Transmit with Interrupts Example
+ RadioLib SX126x 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)
+ 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 SX126x family can also be used.
+ Other modules from SX126x family can also be used.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -27,12 +27,31 @@
// BUSY pin: 9
SX1262 radio = new Module(10, 2, 3, 9);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1262 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// save transmission state between loops
-int transmissionState = ERR_NONE;
+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);
@@ -40,17 +59,17 @@ void setup() {
// initialize SX1262 with default settings
Serial.print(F("[SX1262] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set the function that will be called
// when packet transmission is finished
- radio.setDio1Action(setFlag);
+ radio.setPacketSentAction(setFlag);
// start transmitting the first packet
Serial.print(F("[SX1262] Sending first packet ... "));
@@ -67,50 +86,30 @@ void setup() {
*/
}
-// flag to indicate that a packet was sent
-volatile bool transmittedFlag = false;
-
-// disable interrupt when it's not needed
-volatile bool enableInterrupt = true;
-
-// this function is called when a complete packet
-// is transmitted by the module
-// IMPORTANT: this function MUST be 'void' type
-// and MUST NOT have any arguments!
-void setFlag(void) {
- // check if the interrupt is enabled
- if(!enableInterrupt) {
- return;
- }
-
- // we sent a packet, set the flag
- transmittedFlag = true;
-}
+// counter to keep track of transmitted packets
+int count = 0;
void loop() {
// check if the previous transmission finished
if(transmittedFlag) {
- // disable the interrupt service routine while
- // processing the data
- enableInterrupt = false;
-
// reset flag
transmittedFlag = false;
- if (transmissionState == ERR_NONE) {
+ 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);
@@ -119,17 +118,14 @@ void loop() {
// you can transmit C-string or Arduino string up to
// 256 characters long
- transmissionState = radio.startTransmit("Hello World!");
+ 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};
- int state = radio.startTransmit(byteArr, 8);
+ transmissionState = radio.startTransmit(byteArr, 8);
*/
-
- // we're ready to send more packets,
- // enable interrupt service routine
- enableInterrupt = true;
}
}
diff --git a/examples/SX127x/SX127x_Channel_Activity_Detection/SX127x_Channel_Activity_Detection.ino b/examples/SX127x/SX127x_Channel_Activity_Detection/SX127x_Channel_Activity_Detection.ino
deleted file mode 100644
index ececb74716..0000000000
--- a/examples/SX127x/SX127x_Channel_Activity_Detection/SX127x_Channel_Activity_Detection.ino
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- RadioLib SX127x Channel Activity Detection Example
-
- This example scans the current LoRa channel and detects
- valid LoRa preambles. Preamble is the first part of
- LoRa transmission, so this can be used to check
- if the LoRa channel is free, or if you should start
- receiving a message.
-
- Other modules from SX127x/RFM9x family can also be used.
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
-*/
-
-// include the library
-#include
-
-// SX1278 has the following connections:
-// NSS pin: 10
-// DIO0 pin: 2
-// RESET pin: 9
-// DIO1 pin: 3
-SX1278 radio = new Module(10, 2, 9, 3);
-
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
-
-void setup() {
- Serial.begin(9600);
-
- // initialize SX1278 with default settings
- Serial.print(F("[SX1278] Initializing ... "));
- int state = radio.begin();
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-}
-
-void loop() {
- Serial.print(F("[SX1278] Scanning channel for LoRa preamble ... "));
-
- // start scanning current channel
- int state = radio.scanChannel();
-
- if (state == PREAMBLE_DETECTED) {
- // LoRa preamble was detected
- Serial.println(F("detected preamble!"));
-
- } else if (state == CHANNEL_FREE) {
- // no preamble was detected, channel is free
- Serial.println(F("channel is free!"));
-
- }
-
- // wait 100 ms before new scan
- delay(100);
-}
diff --git a/examples/SX127x/SX127x_Channel_Activity_Detection_Blocking/SX127x_Channel_Activity_Detection_Blocking.ino b/examples/SX127x/SX127x_Channel_Activity_Detection_Blocking/SX127x_Channel_Activity_Detection_Blocking.ino
new file mode 100644
index 0000000000..c88d934e83
--- /dev/null
+++ b/examples/SX127x/SX127x_Channel_Activity_Detection_Blocking/SX127x_Channel_Activity_Detection_Blocking.ino
@@ -0,0 +1,75 @@
+/*
+ RadioLib SX127x Blocking Channel Activity Detection Example
+
+ This example scans the current LoRa channel and detects
+ valid LoRa preambles. Preamble is the first part of
+ LoRa transmission, so this can be used to check
+ if the LoRa channel is free, or if you should start
+ receiving a message.
+
+ Other modules from SX127x/RFM9x family can also be used.
+
+ 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#sx127xrfm9x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1278 has the following connections:
+// NSS pin: 10
+// DIO0 pin: 2
+// RESET pin: 9
+// DIO1 pin: 3
+SX1278 radio = new Module(10, 2, 9, 3);
+
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+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) { delay(10); }
+ }
+}
+
+void loop() {
+ Serial.print(F("[SX1278] Scanning channel for LoRa preamble ... "));
+
+ // start scanning current channel
+ int state = radio.scanChannel();
+
+ if (state == RADIOLIB_PREAMBLE_DETECTED) {
+ // LoRa preamble was detected
+ Serial.println(F("detected preamble!"));
+
+ } else if (state == RADIOLIB_CHANNEL_FREE) {
+ // no preamble was detected, channel is free
+ Serial.println(F("channel is free!"));
+
+ }
+
+ // wait 100 ms before new scan
+ delay(100);
+}
diff --git a/examples/SX127x/SX127x_Channel_Activity_Detection_Interrupt/SX127x_Channel_Activity_Detection_Interrupt.ino b/examples/SX127x/SX127x_Channel_Activity_Detection_Interrupt/SX127x_Channel_Activity_Detection_Interrupt.ino
new file mode 100644
index 0000000000..4efbf4a2aa
--- /dev/null
+++ b/examples/SX127x/SX127x_Channel_Activity_Detection_Interrupt/SX127x_Channel_Activity_Detection_Interrupt.ino
@@ -0,0 +1,129 @@
+/*
+ RadioLib SX127x Channel Activity Detection with Interrupts Example
+
+ This example scans the current LoRa channel and detects
+ valid LoRa preambles. Preamble is the first part of
+ LoRa transmission, so this can be used to check
+ if the LoRa channel is free, or if you should start
+ receiving a message.
+
+ Other modules from SX127x/RFM9x family can also be used.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1278 has the following connections:
+// NSS pin: 10
+// DIO0 pin: 2
+// RESET pin: 9
+// DIO1 pin: 3
+SX1278 radio = new Module(10, 2, 9, 3);
+
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// flag to indicate that a preamble was not detected
+volatile bool timeoutFlag = false;
+
+// flag to indicate that a preamble was detected
+volatile bool detectedFlag = false;
+
+// this function is called when no preamble
+// is detected within timeout period
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+#if defined(ESP8266) || defined(ESP32)
+ ICACHE_RAM_ATTR
+#endif
+void setFlagTimeout(void) {
+ // we timed out, set the flag
+ timeoutFlag = true;
+}
+
+// this function is called when LoRa preamble
+// is detected within timeout period
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+#if defined(ESP8266) || defined(ESP32)
+ ICACHE_RAM_ATTR
+#endif
+void setFlagDetected(void) {
+ // we got a preamble, set the flag
+ detectedFlag = true;
+}
+
+void setup() {
+ // Serial port speed must be high enough for this example
+ Serial.begin(115200);
+
+ // 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) { delay(10); }
+ }
+
+ // set the function that will be called
+ // when LoRa preamble is not detected within CAD timeout period
+ radio.setDio0Action(setFlagTimeout, RISING);
+
+ // set the function that will be called
+ // when LoRa preamble is detected
+ radio.setDio1Action(setFlagDetected, RISING);
+
+ // start scanning the channel
+ Serial.print(F("[SX1278] 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 we need to restart channel activity detection
+ if(detectedFlag || timeoutFlag) {
+ // check if we got a preamble
+ if(detectedFlag) {
+ // LoRa preamble was detected
+ Serial.println(F("[SX1278] Preamble detected!"));
+ } else {
+ // nothing was detected
+ Serial.println(F("[SX1278] Channel free!"));
+ }
+
+ // start scanning the channel
+ Serial.print(F("[SX1278] Starting scan for LoRa preamble ... "));
+
+ // start scanning current channel
+ int state = radio.startChannelScan();
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ }
+
+ // reset flags
+ timeoutFlag = false;
+ detectedFlag = false;
+ }
+}
diff --git a/examples/SX127x/SX127x_Channel_Activity_Detection_Receive/SX127x_Channel_Activity_Detection_Receive.ino b/examples/SX127x/SX127x_Channel_Activity_Detection_Receive/SX127x_Channel_Activity_Detection_Receive.ino
new file mode 100644
index 0000000000..0e5670e849
--- /dev/null
+++ b/examples/SX127x/SX127x_Channel_Activity_Detection_Receive/SX127x_Channel_Activity_Detection_Receive.ino
@@ -0,0 +1,208 @@
+/*
+ RadioLib SX127x Receive after Channel Activity Detection Example
+
+ This example scans the current LoRa channel and detects
+ valid LoRa preambles. Preamble is the first part of
+ LoRa transmission, so this can be used to check
+ if the LoRa channel is free, or if you should start
+ receiving a message. If a preamble is detected,
+ the module will switch to receive mode and receive the packet.
+
+ For most use-cases, it should be enough to just use the
+ interrupt-driven reception described in the example
+ "SX127x_Receive_Interrupt".
+
+ Other modules from SX127x/RFM9x family can also be used.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1278 has the following connections:
+// NSS pin: 10
+// DIO0 pin: 2
+// RESET pin: 9
+// DIO1 pin: 3
+SX1278 radio = new Module(10, 2, 9, 3);
+
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// flag to indicate that a preamble was not detected
+volatile bool timeoutFlag = false;
+
+// flag to indicate that a preamble was detected
+volatile bool detectedFlag = false;
+
+// flag to indicate if we are currently receiving
+bool receiving = false;
+
+// this function is called when no preamble
+// is detected within timeout period
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+#if defined(ESP8266) || defined(ESP32)
+ ICACHE_RAM_ATTR
+#endif
+void setFlagTimeout(void) {
+ // we timed out, set the flag
+ timeoutFlag = true;
+}
+
+// this function is called when LoRa preamble
+// is detected within timeout period
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+#if defined(ESP8266) || defined(ESP32)
+ ICACHE_RAM_ATTR
+#endif
+void setFlagDetected(void) {
+ // we got a preamble, set the flag
+ detectedFlag = true;
+}
+
+void setup() {
+ // Serial port speed must be high enough for this example
+ Serial.begin(115200);
+
+ // 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) { delay(10); }
+ }
+
+ // set the function that will be called
+ // when LoRa preamble is not detected within CAD timeout period
+ // or when a packet is received
+ radio.setDio0Action(setFlagTimeout, RISING);
+
+ // set the function that will be called
+ // when LoRa preamble is detected
+ radio.setDio1Action(setFlagDetected, RISING);
+
+ // start scanning the channel
+ Serial.print(F("[SX1278] 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 we need to restart channel activity detection
+ if(detectedFlag || timeoutFlag) {
+ int state = RADIOLIB_ERR_NONE;
+
+ // check ongoing reception
+ if(receiving) {
+ // DIO triggered while reception is ongoing
+ // that means we got a packet
+
+ // reset flags first
+ detectedFlag = false;
+ timeoutFlag = false;
+
+ // you can read received data as an Arduino String
+ String str;
+ state = radio.readData(str);
+
+ // you can also read received data as byte array
+ /*
+ byte byteArr[8];
+ state = radio.readData(byteArr, 8);
+ */
+
+ if (state == RADIOLIB_ERR_NONE) {
+ // packet was successfully received
+ Serial.println(F("[SX1278] Received packet!"));
+
+ // print data of the packet
+ Serial.print(F("[SX1278] Data:\t\t"));
+ Serial.println(str);
+
+ // print RSSI (Received Signal Strength Indicator)
+ Serial.print(F("[SX1278] RSSI:\t\t"));
+ Serial.print(radio.getRSSI());
+ Serial.println(F(" dBm"));
+
+ // print SNR (Signal-to-Noise Ratio)
+ Serial.print(F("[SX1278] SNR:\t\t"));
+ Serial.print(radio.getSNR());
+ Serial.println(F(" dB"));
+
+ // print frequency error
+ Serial.print(F("[SX1278] Frequency error:\t"));
+ Serial.print(radio.getFrequencyError());
+ Serial.println(F(" Hz"));
+
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
+ // packet was received, but is malformed
+ Serial.println(F("[SX1278] CRC error!"));
+
+ } else {
+ // some other error occurred
+ Serial.print(F("[SX1278] Failed, code "));
+ Serial.println(state);
+
+ }
+
+ // reception is done now
+ receiving = false;
+
+ }
+
+ // check if we got a preamble
+ if(detectedFlag) {
+ // LoRa preamble was detected, start reception with timeout of 100 LoRa symbols
+ Serial.print(F("[SX1278] Preamble detected, starting reception ... "));
+ state = radio.startReceive(100);
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ }
+
+ // set the flag for ongoing reception
+ receiving = true;
+
+ } else if(!receiving) {
+ // nothing was detected
+ // do not print anything, it just spams the console
+
+ }
+
+ // if we're not receiving, start scanning again
+ if(!receiving) {
+ int state = radio.startChannelScan();
+ if (state != RADIOLIB_ERR_NONE) {
+ Serial.print(F("[SX1278] Starting new scan failed, code "));
+ Serial.println(state);
+ }
+
+ }
+
+ // reset flags
+ timeoutFlag = false;
+ detectedFlag = false;
+ }
+}
diff --git a/examples/SX127x/SX127x_FSK_Modem/SX127x_FSK_Modem.ino b/examples/SX127x/SX127x_FSK_Modem/SX127x_FSK_Modem.ino
index d6294889e4..0dae88c896 100644
--- a/examples/SX127x/SX127x_FSK_Modem/SX127x_FSK_Modem.ino
+++ b/examples/SX127x/SX127x_FSK_Modem/SX127x_FSK_Modem.ino
@@ -1,19 +1,19 @@
/*
- RadioLib SX127x FSK Modem Example
+ RadioLib SX127x FSK Modem Example
- This example shows how to use FSK modem in SX127x chips.
+ This example shows how to use FSK modem in SX127x chips.
- NOTE: The sketch below is just a guide on how to use
- FSK modem, so this code should not be run directly!
- Instead, modify the other examples to use FSK
- modem and use the appropriate configuration
- methods.
+ NOTE: The sketch below is just a guide on how to use
+ FSK modem, so this code should not be run directly!
+ Instead, modify the other examples to use FSK
+ modem and use the appropriate configuration
+ methods.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---fsk-modem
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---fsk-modem
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -26,9 +26,13 @@
// DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 fsk = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -36,12 +40,12 @@ void setup() {
// initialize SX1278 FSK modem with default settings
Serial.print(F("[SX1278] Initializing ... "));
int state = radio.beginFSK();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// if needed, you can switch between LoRa and FSK modes
@@ -61,10 +65,10 @@ void setup() {
uint8_t syncWord[] = {0x01, 0x23, 0x45, 0x67,
0x89, 0xAB, 0xCD, 0xEF};
state = radio.setSyncWord(syncWord, 8);
- if (state != ERR_NONE) {
+ if (state != RADIOLIB_ERR_NONE) {
Serial.print(F("Unable to set configuration, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// FSK modulation can be changed to OOK
@@ -74,10 +78,10 @@ void setup() {
// setDataShapingOOK() to set the correct shaping!
state = radio.setOOK(true);
state = radio.setDataShapingOOK(1);
- if (state != ERR_NONE) {
+ if (state != RADIOLIB_ERR_NONE) {
Serial.print(F("Unable to change modulation, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
#warning "This sketch is just an API guide! Read the note at line 6."
@@ -95,11 +99,11 @@ void loop() {
0x89, 0xAB, 0xCD, 0xEF};
int state = radio.transmit(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("[SX1278] Packet transmitted successfully!"));
- } else if (state == ERR_PACKET_TOO_LONG) {
+ } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
Serial.println(F("[SX1278] Packet too long!"));
- } else if (state == ERR_TX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
Serial.println(F("[SX1278] Timed out while transmitting!"));
} else {
Serial.println(F("[SX1278] Failed to transmit packet, code "));
@@ -113,11 +117,11 @@ void loop() {
byte byteArr[8];
int state = radio.receive(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("[SX1278] Received packet!"));
Serial.print(F("[SX1278] Data:\t"));
Serial.println(str);
- } else if (state == ERR_RX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
Serial.println(F("[SX1278] Timed out while waiting for packet!"));
} else {
Serial.println(F("[SX1278] Failed to receive packet, code "));
@@ -138,7 +142,7 @@ void loop() {
state = radio.setNodeAddress(0x02);
// set broadcast address to 0xFF
state = radio.setBroadcastAddress(0xFF);
- if (state != ERR_NONE) {
+ if (state != RADIOLIB_ERR_NONE) {
Serial.println(F("[SX1278] Unable to set address filter, code "));
Serial.println(state);
}
@@ -148,7 +152,7 @@ void loop() {
// node and broadcast address
/*
state = radio.disableAddressFiltering();
- if (state != ERR_NONE) {
+ if (state != RADIOLIB_ERR_NONE) {
Serial.println(F("Unable to remove address filter, code "));
}
*/
@@ -159,7 +163,7 @@ void loop() {
// activate direct mode transmitter
state = radio.transmitDirect();
- if (state != ERR_NONE) {
+ if (state != RADIOLIB_ERR_NONE) {
Serial.println(F("[SX1278] Unable to start direct transmission mode, code "));
Serial.println(state);
}
@@ -170,20 +174,21 @@ void loop() {
// it is recommended to set data shaping to 0
// (no shaping) when transmitting audio
state = radio.setDataShaping(0.0);
- if (state != ERR_NONE) {
+ if (state != RADIOLIB_ERR_NONE) {
Serial.println(F("[SX1278] Unable to set data shaping, code "));
Serial.println(state);
}
- // tone() function is not available on ESP32 and Arduino Due
- #if !defined(ESP32) && !defined(_VARIANT_ARDUINO_DUE_X_)
- // transmit FM tone at 1000 Hz for 1 second
+ // transmit FM tone at 1000 Hz for 1 second, then 500 Hz for 1 second
// (DIO2 is connected to Arduino pin 4)
+ // Note: tone() function is not available on Arduino Due and CubeCell
+ // on these platforms, the following will do nothing
+ #if !defined(RADIOLIB_TONE_UNSUPPORTED)
tone(4, 1000);
delay(1000);
- // transmit FM note at 500 Hz for 1 second
tone(4, 500);
delay(1000);
+ noTone(4);
#endif
// NOTE: after calling transmitDirect(), SX127x will start
@@ -194,7 +199,7 @@ void loop() {
// direct mode transmissions can also be received
// as bit stream on DIO1 (data) and DIO2 (clock)
state = radio.receiveDirect();
- if (state != ERR_NONE) {
+ if (state != RADIOLIB_ERR_NONE) {
Serial.println(F("[SX1278] Unable to start direct reception mode, code "));
Serial.println(state);
}
diff --git a/examples/SX127x/SX127x_PingPong/SX127x_PingPong.ino b/examples/SX127x/SX127x_PingPong/SX127x_PingPong.ino
new file mode 100644
index 0000000000..eb2cc04c87
--- /dev/null
+++ b/examples/SX127x/SX127x_PingPong/SX127x_PingPong.ino
@@ -0,0 +1,152 @@
+/*
+ RadioLib SX127x Ping-Pong Example
+
+ This example is intended to run on two SX126x radios,
+ and send packets between the two.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// uncomment the following only on one
+// of the nodes to initiate the pings
+//#define INITIATING_NODE
+
+// SX1278 has the following connections:
+// NSS pin: 10
+// DIO0 pin: 2
+// NRST pin: 9
+// DIO1 pin: 3
+SX1278 radio = new Module(10, 2, 9, 3);
+
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// 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 packet, set the flag
+ operationDone = true;
+}
+
+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) { delay(10); }
+ }
+
+ // set the function that will be called
+ // when new packet is received
+ radio.setDio0Action(setFlag, RISING);
+
+ #if defined(INITIATING_NODE)
+ // send the first packet on this node
+ Serial.print(F("[SX1278] Sending first packet ... "));
+ transmissionState = radio.startTransmit("Hello World!");
+ transmitFlag = true;
+ #else
+ // start listening for LoRa packets on this node
+ Serial.print(F("[SX1278] 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("[SX1278] Received packet!"));
+
+ // print data of the packet
+ Serial.print(F("[SX1278] Data:\t\t"));
+ Serial.println(str);
+
+ // print RSSI (Received Signal Strength Indicator)
+ Serial.print(F("[SX1278] RSSI:\t\t"));
+ Serial.print(radio.getRSSI());
+ Serial.println(F(" dBm"));
+
+ // print SNR (Signal-to-Noise Ratio)
+ Serial.print(F("[SX1278] 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("[SX1278] Sending another packet ... "));
+ transmissionState = radio.startTransmit("Hello World!");
+ transmitFlag = true;
+ }
+ }
+}
diff --git a/examples/SX127x/SX127x_Receive/SX127x_Receive.ino b/examples/SX127x/SX127x_Receive_Blocking/SX127x_Receive_Blocking.ino
similarity index 60%
rename from examples/SX127x/SX127x_Receive/SX127x_Receive.ino
rename to examples/SX127x/SX127x_Receive_Blocking/SX127x_Receive_Blocking.ino
index 0f839eec94..d52eef5327 100644
--- a/examples/SX127x/SX127x_Receive/SX127x_Receive.ino
+++ b/examples/SX127x/SX127x_Receive_Blocking/SX127x_Receive_Blocking.ino
@@ -1,23 +1,28 @@
/*
- RadioLib SX127x Receive Example
-
- This example listens for LoRa transmissions using SX127x 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 SX127x/RFM9x family can also be used.
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ RadioLib SX127x Blocking Receive Example
+
+ This example listens for LoRa transmissions using SX127x 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 SX127x/RFM9x family can also be used.
+
+ 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#sx127xrfm9x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -30,9 +35,13 @@
// DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -40,12 +49,12 @@ void setup() {
// initialize SX1278 with default settings
Serial.print(F("[SX1278] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
}
@@ -53,9 +62,6 @@ void loop() {
Serial.print(F("[SX1278] Waiting for incoming transmission ... "));
// you can receive data as an Arduino String
- // NOTE: receive() is a blocking method!
- // See example ReceiveInterrupt for details
- // on non-blocking reception method.
String str;
int state = radio.receive(str);
@@ -65,7 +71,7 @@ void loop() {
int state = radio.receive(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("success!"));
@@ -91,11 +97,11 @@ void loop() {
Serial.print(radio.getFrequencyError());
Serial.println(F(" Hz"));
- } else if (state == ERR_RX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
// timeout occurred while waiting for a packet
Serial.println(F("timeout!"));
- } else if (state == ERR_CRC_MISMATCH) {
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
// packet was received, but is malformed
Serial.println(F("CRC error!"));
diff --git a/examples/SX127x/SX127x_Receive_Direct/SX127x_Receive_Direct.ino b/examples/SX127x/SX127x_Receive_Direct/SX127x_Receive_Direct.ino
index 439dc1bd5d..ff9c443c2f 100644
--- a/examples/SX127x/SX127x_Receive_Direct/SX127x_Receive_Direct.ino
+++ b/examples/SX127x/SX127x_Receive_Direct/SX127x_Receive_Direct.ino
@@ -1,14 +1,14 @@
/*
- RadioLib SX127x Direct Receive Example
+ RadioLib SX127x Direct Receive Example
- This example shows how to receive FSK packets without using
- SX127x packet engine.
+ This example shows how to receive FSK packets without using
+ SX127x packet engine.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -24,9 +24,19 @@ SX1278 radio = new Module(10, 2, 9, 3);
// DIO2 pin: 5
const int pin = 5;
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// this function is called when a new bit is received
+void readBit(void) {
+ // read the data bit
+ radio.readBit(pin);
+}
void setup() {
Serial.begin(9600);
@@ -34,12 +44,12 @@ void setup() {
// initialize SX1278 with FSK modem at 9600 bps
Serial.print(F("[SX1278] Initializing ... "));
int state = radio.beginFSK(434.0, 9.6, 20.0);
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set the direct mode sync word
@@ -55,12 +65,6 @@ void setup() {
radio.receiveDirect();
}
-// this function is called when a new bit is received
-void readBit(void) {
- // read the data bit
- radio.readBit(pin);
-}
-
void loop() {
// we expect the packet to contain the string "Hello World!",
// a length byte and 2 CRC bytes, that's 15 bytes in total
diff --git a/examples/SX127x/SX127x_Receive_FHSS/SX127x_Receive_FHSS.ino b/examples/SX127x/SX127x_Receive_FHSS/SX127x_Receive_FHSS.ino
new file mode 100644
index 0000000000..c17cd34367
--- /dev/null
+++ b/examples/SX127x/SX127x_Receive_FHSS/SX127x_Receive_FHSS.ino
@@ -0,0 +1,189 @@
+/*
+ RadioLib SX127x Transmit with Frequency Hopping Example
+
+ This example transmits packets using SX1278 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 SX127x/RFM9x family can also be used.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+
+ SX127x supports FHSS or Frequency Hopping Spread Spectrum.
+ Once a hopping period is set and a transmission is started, the radio
+ will begin triggering interrupts every hop period where the radio frequency
+ is changed to the next channel.
+*/
+
+#include
+
+// SX1278 has the following connections:
+// NSS pin: 10
+// DIO0 pin: 2
+// RESET pin: 9
+// DIO1 pin: 3
+SX1278 radio = new Module(10, 2, 9, 3);
+
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// flag to indicate that a packet was received
+volatile bool receivedFlag = false;
+
+// flag to indicate frequency must be changed
+volatile bool fhssChangeFlag = false;
+
+// the channel frequencies can be generated randomly or hard coded
+// NOTE: The frequency list MUST be the same on both sides!
+float channels[] = { 433.0, 433.4, 433.2, 433.6, 434.0, 433.8 };
+int numberOfChannels = sizeof(channels) / sizeof(float);
+
+// counter to keep track of how many frequency hops were performed
+int hopsCompleted = 0;
+
+// 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 setRxFlag(void) {
+ receivedFlag = true;
+}
+
+// this function is called when FhssChangeChannel interrupt occurs
+// (at the beginning of each transmission)
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+#if defined(ESP8266) || defined(ESP32)
+ ICACHE_RAM_ATTR
+#endif
+void setFHSSFlag(void) {
+ fhssChangeFlag = true;
+}
+
+void setup() {
+ Serial.begin(9600);
+
+ // begin radio on home channel
+ Serial.print(F("[SX1278] Initializing ... "));
+ int state = radio.begin(channels[0]);
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // set hop period in symbols
+ // this will also enable FHSS
+ Serial.print(F("[SX1278] Setting hopping period ... "));
+ state = radio.setFHSSHoppingPeriod(9);
+ 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 to call when reception is finished
+ radio.setDio0Action(setRxFlag, RISING);
+
+ // set the function to call when we need to change frequency
+ radio.setDio1Action(setFHSSFlag, RISING);
+
+ // start listening for LoRa packets
+ Serial.print(F("[SX1278] 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); }
+ }
+}
+
+void loop() {
+ // check if the reception flag is set
+ if (receivedFlag == true) {
+ // 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("[SX1278] Received packet!"));
+
+ // print data of the packet
+ Serial.print(F("[SX1278] Data:\t\t"));
+ Serial.println(str);
+
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
+ // packet was received, but is malformed
+ Serial.println(F("[SX1278] CRC error!"));
+
+ } else {
+ // some other error occurred
+ Serial.print(F("[SX1278] Failed, code "));
+ Serial.println(state);
+
+ }
+
+ // print the number of hops it took
+ Serial.print(F("[SX1278] Hops completed: "));
+ Serial.println(hopsCompleted);
+
+ // reset the counter
+ hopsCompleted = 0;
+
+ // return to home channel before the next transaction
+ radio.setFrequency(channels[0]);
+
+ // put the module back to listen mode
+ radio.startReceive();
+
+ // we're ready to receive more packets, clear the flag
+ receivedFlag = false;
+ }
+
+ // check if we need to do another frequency hop
+ if (fhssChangeFlag == true) {
+ // we do, change it now
+ int state = radio.setFrequency(channels[radio.getFHSSChannel() % numberOfChannels]);
+ if (state != RADIOLIB_ERR_NONE) {
+ Serial.print(F("[SX1278] Failed to change frequency, code "));
+ Serial.println(state);
+ }
+
+ // increment the counter
+ hopsCompleted++;
+
+ // clear the FHSS interrupt
+ radio.clearFHSSInt();
+
+ // we're ready to do another hop, clear the flag
+ fhssChangeFlag = false;
+ }
+}
diff --git a/examples/SX127x/SX127x_Receive_Interrupt/SX127x_Receive_Interrupt.ino b/examples/SX127x/SX127x_Receive_Interrupt/SX127x_Receive_Interrupt.ino
index 8a755bb886..ebb0483218 100644
--- a/examples/SX127x/SX127x_Receive_Interrupt/SX127x_Receive_Interrupt.ino
+++ b/examples/SX127x/SX127x_Receive_Interrupt/SX127x_Receive_Interrupt.ino
@@ -1,24 +1,24 @@
/*
- RadioLib SX127x 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 SX127x/RFM9x family can also be used.
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ RadioLib SX127x 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 SX127x/RFM9x family can also be used.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -31,9 +31,28 @@
// DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// flag to indicate that a packet was received
+volatile bool receivedFlag = false;
+
+// this function is called when a complete packet
+// is received by the module
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+#if defined(ESP8266) || defined(ESP32)
+ ICACHE_RAM_ATTR
+#endif
+void setFlag(void) {
+ // we got a packet, set the flag
+ receivedFlag = true;
+}
void setup() {
Serial.begin(9600);
@@ -41,27 +60,27 @@ void setup() {
// initialize SX1278 with default settings
Serial.print(F("[SX1278] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set the function that will be called
// when new packet is received
- radio.setDio0Action(setFlag);
+ radio.setPacketReceivedAction(setFlag);
// start listening for LoRa packets
Serial.print(F("[SX1278] Starting to listen ... "));
state = radio.startReceive();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// if needed, 'listen' mode can be disabled by calling
@@ -71,37 +90,12 @@ void setup() {
// radio.sleep()
// radio.transmit();
// radio.receive();
- // radio.readData();
// radio.scanChannel();
}
-// flag to indicate that a packet was received
-volatile bool receivedFlag = false;
-
-// disable interrupt when it's not needed
-volatile bool enableInterrupt = true;
-
-// this function is called when a complete packet
-// is received by the module
-// IMPORTANT: this function MUST be 'void' type
-// and MUST NOT have any arguments!
-void setFlag(void) {
- // check if the interrupt is enabled
- if(!enableInterrupt) {
- return;
- }
-
- // we got a packet, set the flag
- receivedFlag = true;
-}
-
void loop() {
// check if the flag is set
if(receivedFlag) {
- // disable the interrupt service routine while
- // processing the data
- enableInterrupt = false;
-
// reset flag
receivedFlag = false;
@@ -112,10 +106,11 @@ void loop() {
// you can also read received data as byte array
/*
byte byteArr[8];
- int state = radio.readData(byteArr, 8);
+ int numBytes = radio.getPacketLength();
+ int state = radio.readData(byteArr, numBytes);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("[SX1278] Received packet!"));
@@ -138,7 +133,7 @@ void loop() {
Serial.print(radio.getFrequencyError());
Serial.println(F(" Hz"));
- } else if (state == ERR_CRC_MISMATCH) {
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
// packet was received, but is malformed
Serial.println(F("[SX1278] CRC error!"));
@@ -148,13 +143,5 @@ void loop() {
Serial.println(state);
}
-
- // put module back to listen mode
- radio.startReceive();
-
- // we're ready to receive more packets,
- // enable interrupt service routine
- enableInterrupt = true;
}
-
}
diff --git a/examples/SX127x/SX127x_Settings/SX127x_Settings.ino b/examples/SX127x/SX127x_Settings/SX127x_Settings.ino
index 84f31fac61..aee08ff1a4 100644
--- a/examples/SX127x/SX127x_Settings/SX127x_Settings.ino
+++ b/examples/SX127x/SX127x_Settings/SX127x_Settings.ino
@@ -1,23 +1,23 @@
/*
- RadioLib SX127x Settings Example
+ RadioLib SX127x Settings Example
- This example shows how to change all the properties of LoRa transmission.
- RadioLib currently supports the following settings:
- - pins (SPI slave select, digital IO 0, digital IO 1)
- - carrier frequency
- - bandwidth
- - spreading factor
- - coding rate
- - sync word
- - output power during transmission
+ This example shows how to change all the properties of LoRa transmission.
+ RadioLib currently supports the following settings:
+ - pins (SPI slave select, digital IO 0, digital IO 1)
+ - carrier frequency
+ - bandwidth
+ - spreading factor
+ - coding rate
+ - sync word
+ - output power during transmission
- Other modules from SX127x/RFM9x family can also be used.
+ Other modules from SX127x/RFM9x family can also be used.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -37,9 +37,13 @@ SX1278 radio1 = new Module(10, 2, 9, 3);
// DIO1 pin: 6
SX1272 radio2 = new Module(9, 4, 5, 6);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1276 radio3 = RadioShield.ModuleB;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio3 = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -47,12 +51,12 @@ void setup() {
// initialize SX1278 with default settings
Serial.print(F("[SX1278] Initializing ... "));
int state = radio1.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// initialize the second LoRa instance with
@@ -68,80 +72,80 @@ void setup() {
// bandwidth: 500.0 kHz
// spreading factor: 6
// coding rate: 5
- // sync word: 0x14
+ // sync word: 0x34
// output power: 2 dBm
// preamble length: 20 symbols
// amplifier gain: 1 (maximum gain)
- state = radio2.begin(915.0, 500.0, 6, 5, 0x14, 2, 20, 1);
- if (state == ERR_NONE) {
+ state = radio2.begin(915.0, 500.0, 6, 5, 0x34, 2, 20, 1);
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// you can also change the settings at runtime
// and check if the configuration was changed successfully
// set carrier frequency to 433.5 MHz
- if (radio1.setFrequency(433.5) == ERR_INVALID_FREQUENCY) {
+ if (radio1.setFrequency(433.5) == RADIOLIB_ERR_INVALID_FREQUENCY) {
Serial.println(F("Selected frequency is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set bandwidth to 250 kHz
- if (radio1.setBandwidth(250.0) == ERR_INVALID_BANDWIDTH) {
+ if (radio1.setBandwidth(250.0) == RADIOLIB_ERR_INVALID_BANDWIDTH) {
Serial.println(F("Selected bandwidth is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set spreading factor to 10
- if (radio1.setSpreadingFactor(10) == ERR_INVALID_SPREADING_FACTOR) {
+ if (radio1.setSpreadingFactor(10) == RADIOLIB_ERR_INVALID_SPREADING_FACTOR) {
Serial.println(F("Selected spreading factor is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set coding rate to 6
- if (radio1.setCodingRate(6) == ERR_INVALID_CODING_RATE) {
+ if (radio1.setCodingRate(6) == RADIOLIB_ERR_INVALID_CODING_RATE) {
Serial.println(F("Selected coding rate is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set LoRa sync word to 0x14
// NOTE: value 0x34 is reserved for LoRaWAN networks and should not be used
- if (radio1.setSyncWord(0x14) != ERR_NONE) {
+ if (radio1.setSyncWord(0x14) != RADIOLIB_ERR_NONE) {
Serial.println(F("Unable to set sync word!"));
- while (true);
+ while (true) { delay(10); }
}
// set output power to 10 dBm (accepted range is -3 - 17 dBm)
// NOTE: 20 dBm value allows high power operation, but transmission
// duty cycle MUST NOT exceed 1%
- if (radio1.setOutputPower(10) == ERR_INVALID_OUTPUT_POWER) {
+ if (radio1.setOutputPower(10) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) {
Serial.println(F("Selected output power is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set over current protection limit to 80 mA (accepted range is 45 - 240 mA)
// NOTE: set value to 0 to disable overcurrent protection
- if (radio1.setCurrentLimit(80) == ERR_INVALID_CURRENT_LIMIT) {
+ if (radio1.setCurrentLimit(80) == RADIOLIB_ERR_INVALID_CURRENT_LIMIT) {
Serial.println(F("Selected current limit is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set LoRa preamble length to 15 symbols (accepted range is 6 - 65535)
- if (radio1.setPreambleLength(15) == ERR_INVALID_PREAMBLE_LENGTH) {
+ if (radio1.setPreambleLength(15) == RADIOLIB_ERR_INVALID_PREAMBLE_LENGTH) {
Serial.println(F("Selected preamble length is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set amplifier gain to 1 (accepted range is 1 - 6, where 1 is maximum gain)
// NOTE: set value to 0 to enable automatic gain control
// leave at 0 unless you know what you're doing
- if (radio1.setGain(1) == ERR_INVALID_GAIN) {
+ if (radio1.setGain(1) == RADIOLIB_ERR_INVALID_GAIN) {
Serial.println(F("Selected gain is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
Serial.println(F("All settings successfully changed!"));
diff --git a/examples/SX127x/SX127x_Transmit/SX127x_Transmit.ino b/examples/SX127x/SX127x_Transmit_Blocking/SX127x_Transmit_Blocking.ino
similarity index 53%
rename from examples/SX127x/SX127x_Transmit/SX127x_Transmit.ino
rename to examples/SX127x/SX127x_Transmit_Blocking/SX127x_Transmit_Blocking.ino
index 6113046b57..28f5bea4cb 100644
--- a/examples/SX127x/SX127x_Transmit/SX127x_Transmit.ino
+++ b/examples/SX127x/SX127x_Transmit_Blocking/SX127x_Transmit_Blocking.ino
@@ -1,19 +1,23 @@
/*
- RadioLib SX127x Transmit Example
+ RadioLib SX127x Blocking Transmit Example
- This example transmits packets using SX1278 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)
+ This example transmits packets using SX1278 LoRa radio module.
+ Each packet contains up to 255 bytes of data, in the form of:
+ - Arduino String
+ - null-terminated char array (C-string)
+ - arbitrary binary data (byte array)
- Other modules from SX127x/RFM9x family can also be used.
+ Other modules from SX127x/RFM9x family can also be used.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
+ Using blocking transmit is not recommended, as it will lead
+ to inefficient use of processor time!
+ Instead, interrupt transmit is recommended.
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -26,9 +30,13 @@
// DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -36,12 +44,12 @@ void setup() {
// initialize SX1278 with default settings
Serial.print(F("[SX1278] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// some modules have an external RF switch
@@ -55,15 +63,16 @@ void setup() {
*/
}
+// counter to keep track of transmitted packets
+int count = 0;
+
void loop() {
Serial.print(F("[SX1278] Transmitting packet ... "));
// you can transmit C-string or Arduino string up to
- // 256 characters long
- // NOTE: transmit() is a blocking method!
- // See example SX127x_Transmit_Interrupt for details
- // on non-blocking transmission method.
- int state = radio.transmit("Hello World!");
+ // 255 characters long
+ String str = "Hello World! #" + String(count++);
+ int state = radio.transmit(str);
// you can also transmit byte array up to 256 bytes long
/*
@@ -71,20 +80,15 @@ void loop() {
int state = radio.transmit(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// the packet was successfully transmitted
Serial.println(F(" success!"));
- // print measured data rate
- Serial.print(F("[SX1278] Datarate:\t"));
- Serial.print(radio.getDataRate());
- Serial.println(F(" bps"));
-
- } else if (state == ERR_PACKET_TOO_LONG) {
+ } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
// the supplied packet was longer than 256 bytes
Serial.println(F("too long!"));
- } else if (state == ERR_TX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
// timeout occurred while transmitting packet
Serial.println(F("timeout!"));
diff --git a/examples/SX127x/SX127x_Transmit_FHSS/SX127x_Transmit_FHSS.ino b/examples/SX127x/SX127x_Transmit_FHSS/SX127x_Transmit_FHSS.ino
new file mode 100644
index 0000000000..dac0ce16fc
--- /dev/null
+++ b/examples/SX127x/SX127x_Transmit_FHSS/SX127x_Transmit_FHSS.ino
@@ -0,0 +1,187 @@
+/*
+ RadioLib SX127x Transmit with Frequency Hopping Example
+
+ This example transmits packets using SX1278 LoRa radio module.
+ Each packet contains up to 255 bytes of data, in the form of:
+ - Arduino String
+ - null-terminated char array (C-string)
+ - arbitrary binary data (byte array)
+
+ Other modules from SX127x/RFM9x family can also be used.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+
+ SX127x supports FHSS or Frequency Hopping Spread Spectrum.
+ Once a hopping period is set and a transmission is started, the radio
+ will begin triggering interrupts every hop period where the radio frequency
+ is changed to the next channel.
+*/
+
+#include
+
+// SX1278 has the following connections:
+// NSS pin: 10
+// DIO0 pin: 2
+// RESET pin: 9
+// DIO1 pin: 3
+SX1278 radio = new Module(10, 2, 9, 3);
+
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// flag to indicate that a packet was received
+volatile bool transmittedFlag = false;
+
+// flag to indicate frequency must be changed
+volatile bool fhssChangeFlag = false;
+
+// the channel frequencies can be generated randomly or hard coded
+// NOTE: The frequency list MUST be the same on both sides!
+float channels[] = { 433.0, 433.4, 433.2, 433.6, 434.0, 433.8 };
+int numberOfChannels = sizeof(channels) / sizeof(float);
+
+// counter to keep track of how many frequency hops were performed
+int hopsCompleted = 0;
+
+// counter that increments with each sent packet
+int packetCounter = 0;
+
+// save transmission state between loops
+int transmissionState = RADIOLIB_ERR_NONE;
+
+// this is the packet that will be sent
+String longPacket = "Let's create a really long packet to trigger \
+lots of hop interrupts. A packet can be up to 255 bytes long. \
+This packet is 222 bytes so using sf = 9, bw = 125, timeOnAir is \
+1488ms. 1488ms / (9*4.10ms) = 40 hops. Counter: ";
+
+// 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 setTxFlag(void) {
+ transmittedFlag = true;
+}
+
+// this function is called when FhssChangeChannel interrupt occurs
+// (at the beginning of each transmission)
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+#if defined(ESP8266) || defined(ESP32)
+ ICACHE_RAM_ATTR
+#endif
+void setFHSSFlag(void) {
+ fhssChangeFlag = true;
+}
+
+void setup() {
+ Serial.begin(9600);
+
+ // begin radio on home channel
+ Serial.print(F("[SX1278] Initializing ... "));
+ int state = radio.begin(channels[0]);
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // set hop period in symbols
+ // this will also enable FHSS
+ Serial.print(F("[SX1278] Setting hopping period ... "));
+ state = radio.setFHSSHoppingPeriod(9);
+ 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 to call when transmission is finished
+ radio.setDio0Action(setTxFlag, RISING);
+
+ // set the function to call when we need to change frequency
+ radio.setDio1Action(setFHSSFlag, RISING);
+
+ // start transmitting the first packet
+ Serial.print(F("[SX1278] Sending first packet ... "));
+ String packet = longPacket + packetCounter;
+ transmissionState = radio.startTransmit(packet);
+}
+
+void loop() {
+ // check if the transmission flag is set
+ if (transmittedFlag == true) {
+ // reset flag
+ transmittedFlag = false;
+
+ if (transmissionState == RADIOLIB_ERR_NONE) {
+ // packet was successfully sent
+ Serial.println(F("transmission finished!"));
+
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(transmissionState);
+
+ }
+
+ // The channel is automatically reset to 0 upon completion
+ Serial.print(F("[SX1278] Radio is on channel: "));
+ Serial.println(radio.getFHSSChannel());
+
+ // print the number of hops it took
+ Serial.print(F("[SX1278] Hops completed: "));
+ Serial.println(hopsCompleted);
+
+ // reset the counter
+ hopsCompleted = 0;
+
+ // return to home channel before the next transaction
+ radio.setFrequency(channels[0]);
+
+ // wait a second before transmitting again
+ delay(1000);
+
+ // increment the packet counter
+ packetCounter++;
+
+ // send another packet
+ Serial.print(F("[SX1278] Sending another packet ... "));
+ String packet = longPacket + packetCounter;
+ transmissionState = radio.startTransmit(packet);
+ }
+
+ // check if we need to do another frequency hop
+ if (fhssChangeFlag == true) {
+ // we do, change it now
+ int state = radio.setFrequency(channels[radio.getFHSSChannel() % numberOfChannels]);
+ if (state != RADIOLIB_ERR_NONE) {
+ Serial.print(F("[SX1278] Failed to change frequency, code "));
+ Serial.println(state);
+ }
+
+ // increment the counter
+ hopsCompleted++;
+
+ // clear the FHSS interrupt
+ radio.clearFHSSInt();
+
+ // we're ready to do another hop, clear the flag
+ fhssChangeFlag = false;
+ }
+}
diff --git a/examples/SX127x/SX127x_Transmit_Interrupt/SX127x_Transmit_Interrupt.ino b/examples/SX127x/SX127x_Transmit_Interrupt/SX127x_Transmit_Interrupt.ino
index 5e5578520a..773a0082f5 100644
--- a/examples/SX127x/SX127x_Transmit_Interrupt/SX127x_Transmit_Interrupt.ino
+++ b/examples/SX127x/SX127x_Transmit_Interrupt/SX127x_Transmit_Interrupt.ino
@@ -1,20 +1,20 @@
/*
- RadioLib SX127x Transmit with Interrupts Example
+ RadioLib SX127x 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)
+ This example transmits LoRa packets with one second delays
+ between them. Each packet contains up to 255 bytes
+ of data, in the form of:
+ - Arduino String
+ - null-terminated char array (C-string)
+ - arbitrary binary data (byte array)
- Other modules from SX127x/RFM9x family can also be used.
+ Other modules from SX127x/RFM9x family can also be used.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -27,12 +27,31 @@
// DIO1 pin: 3
SX1278 radio = new Module(10, 2, 9, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1278 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// save transmission state between loops
-int transmissionState = ERR_NONE;
+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);
@@ -40,81 +59,56 @@ void setup() {
// initialize SX1278 with default settings
Serial.print(F("[SX1278] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set the function that will be called
// when packet transmission is finished
- radio.setDio0Action(setFlag);
+ radio.setPacketSentAction(setFlag);
// start transmitting the first packet
Serial.print(F("[SX1278] Sending first packet ... "));
// you can transmit C-string or Arduino string up to
- // 256 characters long
+ // 255 characters long
transmissionState = radio.startTransmit("Hello World!");
- // you can also transmit byte array up to 256 bytes long
+ // you can also transmit byte array up to 255 bytes long
/*
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
0x89, 0xAB, 0xCD, 0xEF};
- state = radio.startTransmit(byteArr, 8);
+ transmissionState = radio.startTransmit(byteArr, 8);
*/
}
-// flag to indicate that a packet was sent
-volatile bool transmittedFlag = false;
-
-// disable interrupt when it's not needed
-volatile bool enableInterrupt = true;
-
-// this function is called when a complete packet
-// is transmitted by the module
-// IMPORTANT: this function MUST be 'void' type
-// and MUST NOT have any arguments!
-void setFlag(void) {
- // check if the interrupt is enabled
- if(!enableInterrupt) {
- return;
- }
-
- // we sent a packet, set the flag
- transmittedFlag = true;
-}
+// counter to keep track of transmitted packets
+int count = 0;
void loop() {
// check if the previous transmission finished
if(transmittedFlag) {
- // disable the interrupt service routine while
- // processing the data
- enableInterrupt = false;
-
// reset flag
transmittedFlag = false;
- if (transmissionState == ERR_NONE) {
+ 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);
}
- // NOTE: in FSK mode, SX127x will not automatically
- // turn transmitter off after sending a packet
- // set mode to standby to ensure we don't jam others
- //radio.standby()
+ // 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);
@@ -123,18 +117,15 @@ void loop() {
Serial.print(F("[SX1278] Sending another packet ... "));
// you can transmit C-string or Arduino string up to
- // 256 characters long
- transmissionState = radio.startTransmit("Hello World!");
+ // 255 characters long
+ String str = "Hello World! #" + String(count++);
+ transmissionState = radio.startTransmit(str);
- // you can also transmit byte array up to 256 bytes long
+ // you can also transmit byte array up to 255 bytes long
/*
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
0x89, 0xAB, 0xCD, 0xEF};
- int state = radio.startTransmit(byteArr, 8);
+ transmissionState = radio.startTransmit(byteArr, 8);
*/
-
- // we're ready to send more packets,
- // enable interrupt service routine
- enableInterrupt = true;
}
}
diff --git a/examples/SX128x/SX128x_BLE_Modem/SX128x_BLE_Modem.ino b/examples/SX128x/SX128x_BLE_Modem/SX128x_BLE_Modem.ino
index 96a96ffa20..04767da039 100644
--- a/examples/SX128x/SX128x_BLE_Modem/SX128x_BLE_Modem.ino
+++ b/examples/SX128x/SX128x_BLE_Modem/SX128x_BLE_Modem.ino
@@ -1,21 +1,21 @@
/*
- RadioLib SX128x BLE Modem Example
+ RadioLib SX128x BLE Modem Example
- This example shows how to use BLE modem in SX128x chips.
- RadioLib does not provide BLE protocol support (yet),
- only compatibility with the physical layer.
+ This example shows how to use BLE modem in SX128x chips.
+ RadioLib does not provide BLE protocol support (yet),
+ only compatibility with the physical layer.
- NOTE: The sketch below is just a guide on how to use
- BLE modem, so this code should not be run directly!
- Instead, modify the other examples to use BLE
- modem and use the appropriate configuration
- methods.
+ NOTE: The sketch below is just a guide on how to use
+ BLE modem, so this code should not be run directly!
+ Instead, modify the other examples to use BLE
+ modem and use the appropriate configuration
+ methods.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---ble-modem
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---ble-modem
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -28,9 +28,13 @@
// BUSY pin: 9
SX1280 radio = new Module(10, 2, 3, 9);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1280 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -38,12 +42,12 @@ void setup() {
// initialize SX1280 with default settings
Serial.print(F("[SX1280] Initializing ... "));
int state = radio.beginBLE();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// if needed, you can switch between any of the modems
@@ -59,13 +63,13 @@ void setup() {
state = radio.setOutputPower(5);
state = radio.setDataShaping(1.0);
state = radio.setAccessAddress(0x12345678);
- if (state != ERR_NONE) {
+ if (state != RADIOLIB_ERR_NONE) {
Serial.print(F("Unable to set configuration, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
- #warning "This sketch is just an API guide! Read the note at line 6."
+ #warning "This sketch is just an API guide! Read the note at line 8."
}
void loop() {
@@ -79,11 +83,11 @@ void loop() {
0x89, 0xAB, 0xCD, 0xEF};
int state = radio.transmit(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("[SX1280] Packet transmitted successfully!"));
- } else if (state == ERR_PACKET_TOO_LONG) {
+ } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
Serial.println(F("[SX1280] Packet too long!"));
- } else if (state == ERR_TX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
Serial.println(F("[SX1280] Timed out while transmitting!"));
} else {
Serial.print(F("[SX1280] Failed to transmit packet, code "));
@@ -97,11 +101,11 @@ void loop() {
byte byteArr[8];
int state = radio.receive(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("[SX1280] Received packet!"));
Serial.print(F("[SX1280] Data:\t"));
Serial.println(str);
- } else if (state == ERR_RX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
Serial.println(F("[SX1280] Timed out while waiting for packet!"));
} else {
Serial.print(F("[SX1280] Failed to receive packet, code "));
diff --git a/examples/SX128x/SX128x_Channel_Activity_Detection/SX128x_Channel_Activity_Detection.ino b/examples/SX128x/SX128x_Channel_Activity_Detection/SX128x_Channel_Activity_Detection.ino
deleted file mode 100644
index cec1560acb..0000000000
--- a/examples/SX128x/SX128x_Channel_Activity_Detection/SX128x_Channel_Activity_Detection.ino
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- RadioLib SX128x Channel Activity Detection Example
-
- This example uses SX1280 to scan the current LoRa
- channel and detect ongoing LoRa transmissions.
-
- Other modules from SX128x family can also be used.
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
-*/
-
-// include the library
-#include
-
-// SX1280 has the following connections:
-// NSS pin: 10
-// DIO1 pin: 2
-// NRST pin: 3
-// BUSY pin: 9
-SX1280 radio = new Module(10, 2, 3, 9);
-
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1280 radio = RadioShield.ModuleA;
-
-void setup() {
- Serial.begin(9600);
-
- // initialize SX1280 with default settings
- Serial.print(F("[SX1280] Initializing ... "));
- int state = radio.begin();
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-}
-
-void loop() {
- Serial.print(F("[SX1280] Scanning channel for LoRa transmission ... "));
-
- // start scanning current channel
- int state = radio.scanChannel();
-
- if (state == LORA_DETECTED) {
- // LoRa preamble was detected
- Serial.println(F("detected!"));
-
- } else if (state == 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);
-}
diff --git a/examples/SX128x/SX128x_Channel_Activity_Detection_Blocking/SX128x_Channel_Activity_Detection_Blocking.ino b/examples/SX128x/SX128x_Channel_Activity_Detection_Blocking/SX128x_Channel_Activity_Detection_Blocking.ino
new file mode 100644
index 0000000000..e12a08b5c0
--- /dev/null
+++ b/examples/SX128x/SX128x_Channel_Activity_Detection_Blocking/SX128x_Channel_Activity_Detection_Blocking.ino
@@ -0,0 +1,77 @@
+/*
+ RadioLib SX128x Blocking Channel Activity Detection Example
+
+ This example uses SX1280 to scan the current LoRa
+ channel and detect ongoing LoRa transmissions.
+
+ Other modules from SX128x family can also be used.
+
+ 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#sx128x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1280 has the following connections:
+// NSS pin: 10
+// DIO1 pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+SX1280 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
+Radio radio = new RadioModule();
+*/
+
+void setup() {
+ Serial.begin(9600);
+
+ // initialize SX1280 with default settings
+ Serial.print(F("[SX1280] Initializing ... "));
+ int state = radio.begin();
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+}
+
+void loop() {
+ Serial.print(F("[SX1280] 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);
+}
diff --git a/examples/SX128x/SX128x_Channel_Activity_Detection_Interrupt/SX128x_Channel_Activity_Detection_Interrupt.ino b/examples/SX128x/SX128x_Channel_Activity_Detection_Interrupt/SX128x_Channel_Activity_Detection_Interrupt.ino
new file mode 100644
index 0000000000..8e3ab594a6
--- /dev/null
+++ b/examples/SX128x/SX128x_Channel_Activity_Detection_Interrupt/SX128x_Channel_Activity_Detection_Interrupt.ino
@@ -0,0 +1,112 @@
+/*
+ RadioLib SX128x Channel Activity Detection Example
+
+ This example uses SX1280 to scan the current LoRa
+ channel and detect ongoing LoRa transmissions.
+
+ Other modules from SX128x family can also be used.
+
+ For default module settings, see the wiki page
+https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1280 has the following connections:
+// NSS pin: 10
+// DIO1 pin: 2
+// NRST pin: 3
+// BUSY pin: 9
+SX1280 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
+Radio radio = new RadioModule();
+*/
+
+// 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 SX1280 with default settings
+ Serial.print(F("[SX1280] 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 LoRa packet or timeout is detected
+ radio.setDio1Action(setFlag);
+
+ // start scanning the channel
+ Serial.print(F("[SX1280] 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("[SX1280] Packet detected!"));
+
+ } else if (state == RADIOLIB_CHANNEL_FREE) {
+ // channel is free
+ Serial.println(F("[SX1280] Channel is free!"));
+
+ } else {
+ // some other error occurred
+ Serial.print(F("[SX1280] Failed, code "));
+ Serial.println(state);
+
+ }
+
+ // start scanning the channel again
+ Serial.print(F("[SX1280] 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);
+ }
+ }
+}
diff --git a/examples/SX128x/SX128x_FLRC_Modem/SX128x_FLRC_Modem.ino b/examples/SX128x/SX128x_FLRC_Modem/SX128x_FLRC_Modem.ino
index cf2d0e7cc1..fb6bb1a59c 100644
--- a/examples/SX128x/SX128x_FLRC_Modem/SX128x_FLRC_Modem.ino
+++ b/examples/SX128x/SX128x_FLRC_Modem/SX128x_FLRC_Modem.ino
@@ -1,19 +1,19 @@
/*
- RadioLib SX128x FLRC Modem Example
+ RadioLib SX128x FLRC Modem Example
- This example shows how to use FLRC modem in SX128x chips.
+ This example shows how to use FLRC modem in SX128x chips.
- NOTE: The sketch below is just a guide on how to use
- FLRC modem, so this code should not be run directly!
- Instead, modify the other examples to use FLRC
- modem and use the appropriate configuration
- methods.
+ NOTE: The sketch below is just a guide on how to use
+ FLRC modem, so this code should not be run directly!
+ Instead, modify the other examples to use FLRC
+ modem and use the appropriate configuration
+ methods.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---flrc-modem
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---flrc-modem
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -26,9 +26,13 @@
// BUSY pin: 9
SX1280 radio = new Module(10, 2, 3, 9);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1280 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -36,12 +40,12 @@ void setup() {
// initialize SX1280 with default settings
Serial.print(F("[SX1280] Initializing ... "));
int state = radio.beginFLRC();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// if needed, you can switch between any of the modems
@@ -58,10 +62,10 @@ void setup() {
state = radio.setDataShaping(1.0);
uint8_t syncWord[] = {0x01, 0x23, 0x45, 0x67};
state = radio.setSyncWord(syncWord, 4);
- if (state != ERR_NONE) {
+ if (state != RADIOLIB_ERR_NONE) {
Serial.print(F("Unable to set configuration, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
#warning "This sketch is just an API guide! Read the note at line 6."
@@ -78,11 +82,11 @@ void loop() {
0x89, 0xAB, 0xCD, 0xEF};
int state = radio.transmit(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("[SX1280] Packet transmitted successfully!"));
- } else if (state == ERR_PACKET_TOO_LONG) {
+ } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
Serial.println(F("[SX1280] Packet too long!"));
- } else if (state == ERR_TX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
Serial.println(F("[SX1280] Timed out while transmitting!"));
} else {
Serial.println(F("[SX1280] Failed to transmit packet, code "));
@@ -96,11 +100,11 @@ void loop() {
byte byteArr[8];
int state = radio.receive(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("[SX1280] Received packet!"));
Serial.print(F("[SX1280] Data:\t"));
Serial.println(str);
- } else if (state == ERR_RX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
Serial.println(F("[SX1280] Timed out while waiting for packet!"));
} else {
Serial.print(F("[SX1280] Failed to receive packet, code "));
diff --git a/examples/SX128x/SX128x_GFSK_Modem/SX128x_GFSK_Modem.ino b/examples/SX128x/SX128x_GFSK_Modem/SX128x_GFSK_Modem.ino
index 2df0d6acf1..05c8e6c2b3 100644
--- a/examples/SX128x/SX128x_GFSK_Modem/SX128x_GFSK_Modem.ino
+++ b/examples/SX128x/SX128x_GFSK_Modem/SX128x_GFSK_Modem.ino
@@ -1,19 +1,19 @@
/*
- RadioLib SX128x GFSK Modem Example
+ RadioLib SX128x GFSK Modem Example
- This example shows how to use GFSK modem in SX128x chips.
+ This example shows how to use GFSK modem in SX128x 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.
+ 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#sx128x---gfsk-modem
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---gfsk-modem
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -26,9 +26,13 @@
// BUSY pin: 9
SX1280 radio = new Module(10, 2, 3, 9);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1280 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -36,12 +40,12 @@ void setup() {
// initialize SX1280 with default settings
Serial.print(F("[SX1280] Initializing ... "));
int state = radio.beginGFSK();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// if needed, you can switch between any of the modems
@@ -58,10 +62,10 @@ void setup() {
state = radio.setDataShaping(RADIOLIB_SHAPING_1_0);
uint8_t syncWord[] = {0x01, 0x23, 0x45, 0x67, 0x89};
state = radio.setSyncWord(syncWord, 5);
- if (state != ERR_NONE) {
+ if (state != RADIOLIB_ERR_NONE) {
Serial.print(F("Unable to set configuration, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
#warning "This sketch is just an API guide! Read the note at line 6."
@@ -78,11 +82,11 @@ void loop() {
0x89, 0xAB, 0xCD, 0xEF};
int state = radio.transmit(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("[SX1280] Packet transmitted successfully!"));
- } else if (state == ERR_PACKET_TOO_LONG) {
+ } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
Serial.println(F("[SX1280] Packet too long!"));
- } else if (state == ERR_TX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
Serial.println(F("[SX1280] Timed out while transmitting!"));
} else {
Serial.println(F("[SX1280] Failed to transmit packet, code "));
@@ -96,11 +100,11 @@ void loop() {
byte byteArr[8];
int state = radio.receive(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("[SX1280] Received packet!"));
Serial.print(F("[SX1280] Data:\t"));
Serial.println(str);
- } else if (state == ERR_RX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
Serial.println(F("[SX1280] Timed out while waiting for packet!"));
} else {
Serial.print(F("[SX1280] Failed to receive packet, code "));
diff --git a/examples/SX128x/SX128x_Ranging/SX128x_Ranging.ino b/examples/SX128x/SX128x_Ranging/SX128x_Ranging.ino
index f53b1a2d38..9f6a92b650 100644
--- a/examples/SX128x/SX128x_Ranging/SX128x_Ranging.ino
+++ b/examples/SX128x/SX128x_Ranging/SX128x_Ranging.ino
@@ -1,18 +1,21 @@
/*
- RadioLib SX128x Ranging Example
+ RadioLib SX128x Ranging Example
- This example performs ranging exchange between two
- SX1280 LoRa radio modules. Ranging allows to measure
- distance between the modules using time-of-flight
- measurement.
+ This example performs ranging exchange between two
+ SX1280 LoRa radio modules. Ranging allows to measure
+ distance between the modules using time-of-flight
+ measurement.
- Only SX1280 and SX1282 support ranging!
+ Only SX1280 and SX1282 without external RF switch support ranging!
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem
+ Note that to get accurate ranging results, calibration is needed!
+ The process is described in Semtech SX1280 Application Note AN1200.29
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -25,9 +28,13 @@
// BUSY pin: 9
SX1280 radio = new Module(10, 2, 3, 9);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1280 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -35,12 +42,12 @@ void setup() {
// initialize SX1280 with default settings
Serial.print(F("[SX1280] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
}
@@ -57,14 +64,26 @@ void loop() {
int state = radio.range(false, 0x12345678);
*/
- if (state == ERR_NONE) {
+ // if ranging calibration is known, it can be provided
+ // this should improve the accuracy and precision
+ /*
+ uint16_t calibration[3][6] = {
+ { 10299, 10271, 10244, 10242, 10230, 10246 },
+ { 11486, 11474, 11453, 11426, 11417, 11401 },
+ { 13308, 13493, 13528, 13515, 13430, 13376 }
+ };
+
+ int state = radio.range(true, 0x12345678, calibration);
+ */
+
+ if (state == RADIOLIB_ERR_NONE) {
// ranging finished successfully
Serial.println(F("success!"));
Serial.print(F("[SX1280] Distance:\t\t\t"));
Serial.print(radio.getRangingResult());
- Serial.println(F(" meters"));
+ Serial.println(F(" meters (raw)"));
- } else if (state == ERR_RANGING_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_RANGING_TIMEOUT) {
// timed out waiting for ranging packet
Serial.println(F("timed out!"));
diff --git a/examples/SX128x/SX128x_Receive/SX128x_Receive.ino b/examples/SX128x/SX128x_Receive_Blocking/SX128x_Receive_Blocking.ino
similarity index 55%
rename from examples/SX128x/SX128x_Receive/SX128x_Receive.ino
rename to examples/SX128x/SX128x_Receive_Blocking/SX128x_Receive_Blocking.ino
index ff5adc4156..809b2c4a3a 100644
--- a/examples/SX128x/SX128x_Receive/SX128x_Receive.ino
+++ b/examples/SX128x/SX128x_Receive_Blocking/SX128x_Receive_Blocking.ino
@@ -1,23 +1,28 @@
/*
- RadioLib SX128x Receive Example
+ RadioLib SX128x Blocking Receive Example
- This example listens for LoRa transmissions using SX126x 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
+ This example listens for LoRa transmissions using SX126x 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 SX128x family can also be used.
+ Other modules from SX128x family can also be used.
+
+ 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#sx128x---lora-modem
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -30,9 +35,13 @@
// BUSY pin: 9
SX1280 radio = new Module(10, 2, 3, 9);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1280 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -40,12 +49,12 @@ void setup() {
// initialize SX1280 with default settings
Serial.print(F("[SX1280] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
}
@@ -53,9 +62,6 @@ void loop() {
Serial.print(F("[SX1280] Waiting for incoming transmission ... "));
// you can receive data as an Arduino String
- // NOTE: receive() is a blocking method!
- // See example ReceiveInterrupt for details
- // on non-blocking reception method.
String str;
int state = radio.receive(str);
@@ -65,7 +71,7 @@ void loop() {
int state = radio.receive(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("success!"));
@@ -85,11 +91,17 @@ void loop() {
Serial.print(radio.getSNR());
Serial.println(F(" dB"));
- } else if (state == ERR_RX_TIMEOUT) {
+ // print the Frequency Error
+ // of the last received packet
+ Serial.print(F("[SX1280] Frequency Error:\t"));
+ Serial.print(radio.getFrequencyError());
+ Serial.println(F(" Hz"));
+
+ } else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
// timeout occurred while waiting for a packet
Serial.println(F("timeout!"));
- } else if (state == ERR_CRC_MISMATCH) {
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
// packet was received, but is malformed
Serial.println(F("CRC error!"));
diff --git a/examples/SX128x/SX128x_Receive_Interrupt/SX128x_Receive_Interrupt.ino b/examples/SX128x/SX128x_Receive_Interrupt/SX128x_Receive_Interrupt.ino
index 65e03f7d73..984db2428b 100644
--- a/examples/SX128x/SX128x_Receive_Interrupt/SX128x_Receive_Interrupt.ino
+++ b/examples/SX128x/SX128x_Receive_Interrupt/SX128x_Receive_Interrupt.ino
@@ -1,24 +1,24 @@
/*
- RadioLib SX128x 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 SX128x family can also be used.
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ RadioLib SX128x 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 SX128x family can also be used.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -31,9 +31,28 @@
// BUSY pin: 9
SX1280 radio = new Module(10, 2, 3, 9);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1280 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// flag to indicate that a packet was received
+volatile bool receivedFlag = false;
+
+// this function is called when a complete packet
+// is received by the module
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+#if defined(ESP8266) || defined(ESP32)
+ ICACHE_RAM_ATTR
+#endif
+void setFlag(void) {
+ // we got a packet, set the flag
+ receivedFlag = true;
+}
void setup() {
Serial.begin(9600);
@@ -41,27 +60,27 @@ void setup() {
// initialize SX1280 with default settings
Serial.print(F("[SX1280] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set the function that will be called
// when new packet is received
- radio.setDio1Action(setFlag);
+ radio.setPacketReceivedAction(setFlag);
// start listening for LoRa packets
Serial.print(F("[SX1280] Starting to listen ... "));
state = radio.startReceive();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// if needed, 'listen' mode can be disabled by calling
@@ -75,33 +94,9 @@ void setup() {
// radio.scanChannel();
}
-// flag to indicate that a packet was received
-volatile bool receivedFlag = false;
-
-// disable interrupt when it's not needed
-volatile bool enableInterrupt = true;
-
-// this function is called when a complete packet
-// is received by the module
-// IMPORTANT: this function MUST be 'void' type
-// and MUST NOT have any arguments!
-void setFlag(void) {
- // check if the interrupt is enabled
- if(!enableInterrupt) {
- return;
- }
-
- // we got a packet, set the flag
- receivedFlag = true;
-}
-
void loop() {
// check if the flag is set
if(receivedFlag) {
- // disable the interrupt service routine while
- // processing the data
- enableInterrupt = false;
-
// reset flag
receivedFlag = false;
@@ -112,10 +107,11 @@ void loop() {
// you can also read received data as byte array
/*
byte byteArr[8];
- int state = radio.readData(byteArr, 8);
+ int numBytes = radio.getPacketLength();
+ int state = radio.readData(byteArr, numBytes);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("[SX1280] Received packet!"));
@@ -133,7 +129,13 @@ void loop() {
Serial.print(radio.getSNR());
Serial.println(F(" dB"));
- } else if (state == ERR_CRC_MISMATCH) {
+ // print the Frequency Error
+ // of the last received packet
+ Serial.print(F("[SX1280] Frequency Error:\t"));
+ Serial.print(radio.getFrequencyError());
+ Serial.println(F(" Hz"));
+
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
// packet was received, but is malformed
Serial.println(F("CRC error!"));
@@ -146,10 +148,5 @@ void loop() {
// put module back to listen mode
radio.startReceive();
-
- // we're ready to receive more packets,
- // enable interrupt service routine
- enableInterrupt = true;
}
-
}
diff --git a/examples/SX128x/SX128x_Settings/SX128x_Settings.ino b/examples/SX128x/SX128x_Settings/SX128x_Settings.ino
index 0963d85a96..5792dc07e9 100644
--- a/examples/SX128x/SX128x_Settings/SX128x_Settings.ino
+++ b/examples/SX128x/SX128x_Settings/SX128x_Settings.ino
@@ -1,24 +1,24 @@
/*
- RadioLib SX128x Settings Example
-
- This example shows how to change all the properties of LoRa transmission.
- RadioLib currently supports the following settings:
- - pins (SPI slave select, DIO1, DIO2, BUSY pin)
- - carrier frequency
- - bandwidth
- - spreading factor
- - coding rate
- - output power during transmission
- - CRC
- - preamble length
-
- Other modules from SX128x family can also be used.
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ RadioLib SX128x Settings Example
+
+ This example shows how to change all the properties of LoRa transmission.
+ RadioLib currently supports the following settings:
+ - pins (SPI slave select, DIO1, DIO2, BUSY pin)
+ - carrier frequency
+ - bandwidth
+ - spreading factor
+ - coding rate
+ - output power during transmission
+ - CRC
+ - preamble length
+
+ Other modules from SX128x family can also be used.
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -38,9 +38,13 @@ SX1280 radio1 = new Module(10, 2, 3, 9);
// BUSY pin: 6
SX1281 radio2 = new Module(8, 4, 5, 6);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1282 radio3 = RadioShield.ModuleB;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio3 = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -48,12 +52,12 @@ void setup() {
// initialize SX1280 with default settings
Serial.print(F("[SX1280] Initializing ... "));
int state = radio1.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// initialize the second LoRa instance with
@@ -65,60 +69,61 @@ void setup() {
// bandwidth: 1625.0 kHz
// spreading factor: 7
// coding rate: 5
+ // sync word: 0x12 (private network)
// output power: 2 dBm
// preamble length: 20 symbols
- state = radio2.begin(2450.0, 1625.0, 7, 5, 2, 20);
- if (state == ERR_NONE) {
+ state = radio2.begin(2450.0, 1625.0, 7, 5, 0x12, 2, 20);
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// you can also change the settings at runtime
// and check if the configuration was changed successfully
// set carrier frequency to 2410.5 MHz
- if (radio1.setFrequency(2410.5) == ERR_INVALID_FREQUENCY) {
+ if (radio1.setFrequency(2410.5) == RADIOLIB_ERR_INVALID_FREQUENCY) {
Serial.println(F("Selected frequency is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set bandwidth to 203.125 kHz
- if (radio1.setBandwidth(203.125) == ERR_INVALID_BANDWIDTH) {
+ if (radio1.setBandwidth(203.125) == RADIOLIB_ERR_INVALID_BANDWIDTH) {
Serial.println(F("Selected bandwidth is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set spreading factor to 10
- if (radio1.setSpreadingFactor(10) == ERR_INVALID_SPREADING_FACTOR) {
+ if (radio1.setSpreadingFactor(10) == RADIOLIB_ERR_INVALID_SPREADING_FACTOR) {
Serial.println(F("Selected spreading factor is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set coding rate to 6
- if (radio1.setCodingRate(6) == ERR_INVALID_CODING_RATE) {
+ if (radio1.setCodingRate(6) == RADIOLIB_ERR_INVALID_CODING_RATE) {
Serial.println(F("Selected coding rate is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set output power to -2 dBm
- if (radio1.setOutputPower(-2) == ERR_INVALID_OUTPUT_POWER) {
+ if (radio1.setOutputPower(-2) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) {
Serial.println(F("Selected output power is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set LoRa preamble length to 16 symbols (accepted range is 2 - 65535)
- if (radio1.setPreambleLength(16) == ERR_INVALID_PREAMBLE_LENGTH) {
+ if (radio1.setPreambleLength(16) == RADIOLIB_ERR_INVALID_PREAMBLE_LENGTH) {
Serial.println(F("Selected preamble length is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// disable CRC
- if (radio1.setCRC(false) == ERR_INVALID_CRC_CONFIGURATION) {
+ if (radio1.setCRC(false) == RADIOLIB_ERR_INVALID_CRC_CONFIGURATION) {
Serial.println(F("Selected CRC is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
Serial.println(F("All settings succesfully changed!"));
diff --git a/examples/SX128x/SX128x_Transmit/SX128x_Transmit.ino b/examples/SX128x/SX128x_Transmit_Blocking/SX128x_Transmit_Blocking.ino
similarity index 59%
rename from examples/SX128x/SX128x_Transmit/SX128x_Transmit.ino
rename to examples/SX128x/SX128x_Transmit_Blocking/SX128x_Transmit_Blocking.ino
index a4037def4c..ea0fb169b8 100644
--- a/examples/SX128x/SX128x_Transmit/SX128x_Transmit.ino
+++ b/examples/SX128x/SX128x_Transmit_Blocking/SX128x_Transmit_Blocking.ino
@@ -1,19 +1,23 @@
/*
- RadioLib SX128x Transmit Example
+ RadioLib SX128x Blocking Transmit Example
- This example transmits packets using SX1280 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)
+ This example transmits packets using SX1280 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 SX128x family can also be used.
+ Other modules from SX128x family can also be used.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem
+ Using blocking transmit is not recommended, as it will lead
+ to inefficient use of processor time!
+ Instead, interrupt transmit is recommended.
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -26,9 +30,13 @@
// BUSY pin: 9
SX1280 radio = new Module(10, 2, 3, 9);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1280 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -43,12 +51,12 @@ void setup() {
// preamble length: 12 symbols
// CRC: enabled
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// some modules have an external RF switch
@@ -62,15 +70,16 @@ void setup() {
*/
}
+// counter to keep track of transmitted packets
+int count = 0;
+
void loop() {
Serial.print(F("[SX1280] Transmitting packet ... "));
// you can transmit C-string or Arduino string up to
// 256 characters long
- // NOTE: transmit() is a blocking method!
- // See example SX128x_Transmit_Interrupt for details
- // on non-blocking transmission method.
- int state = radio.transmit("Hello World!");
+ String str = "Hello World! #" + String(count++);
+ int state = radio.transmit(str);
// you can also transmit byte array up to 256 bytes long
/*
@@ -78,11 +87,11 @@ void loop() {
int state = radio.transmit(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// the packet was successfully transmitted
Serial.println(F("success!"));
- } else if (state == ERR_PACKET_TOO_LONG) {
+ } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
// the supplied packet was longer than 256 bytes
Serial.println(F("too long!"));
diff --git a/examples/SX128x/SX128x_Transmit_Interrupt/SX128x_Transmit_Interrupt.ino b/examples/SX128x/SX128x_Transmit_Interrupt/SX128x_Transmit_Interrupt.ino
index ecdd9312d5..340efd1d5d 100644
--- a/examples/SX128x/SX128x_Transmit_Interrupt/SX128x_Transmit_Interrupt.ino
+++ b/examples/SX128x/SX128x_Transmit_Interrupt/SX128x_Transmit_Interrupt.ino
@@ -1,20 +1,20 @@
/*
- RadioLib SX128x Transmit with Interrupts Example
+ RadioLib SX128x 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)
+ 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 SX128x family can also be used.
+ Other modules from SX128x family can also be used.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -27,12 +27,31 @@
// BUSY pin: 9
SX1280 radio = new Module(10, 2, 3, 9);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//SX1280 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// save transmission state between loops
-int transmissionState = ERR_NONE;
+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);
@@ -40,17 +59,17 @@ void setup() {
// initialize SX1280 with default settings
Serial.print(F("[SX1280] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set the function that will be called
// when packet transmission is finished
- radio.setDio1Action(setFlag);
+ radio.setPacketSentAction(setFlag);
// start transmitting the first packet
Serial.print(F("[SX1280] Sending first packet ... "));
@@ -67,37 +86,16 @@ void setup() {
*/
}
-// flag to indicate that a packet was sent
-volatile bool transmittedFlag = false;
-
-// disable interrupt when it's not needed
-volatile bool enableInterrupt = true;
-
-// this function is called when a complete packet
-// is transmitted by the module
-// IMPORTANT: this function MUST be 'void' type
-// and MUST NOT have any arguments!
-void setFlag(void) {
- // check if the interrupt is enabled
- if(!enableInterrupt) {
- return;
- }
-
- // we sent a packet, set the flag
- transmittedFlag = true;
-}
+// counter to keep track of transmitted packets
+int count = 0;
void loop() {
// check if the previous transmission finished
if(transmittedFlag) {
- // disable the interrupt service routine while
- // processing the data
- enableInterrupt = false;
-
// reset flag
transmittedFlag = false;
- if (transmissionState == ERR_NONE) {
+ if (transmissionState == RADIOLIB_ERR_NONE) {
// packet was successfully sent
Serial.println(F("transmission finished!"));
@@ -107,6 +105,11 @@ void loop() {
}
+ // 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);
@@ -115,17 +118,14 @@ void loop() {
// you can transmit C-string or Arduino string up to
// 256 characters long
- transmissionState = radio.startTransmit("Hello World!");
+ 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};
- int state = radio.startTransmit(byteArr, 8);
+ transmissionState = radio.startTransmit(byteArr, 8);
*/
-
- // we're ready to send more packets,
- // enable interrupt service routine
- enableInterrupt = true;
}
}
diff --git a/examples/Si443x/Si443x_Receive/Si443x_Receive.ino b/examples/Si443x/Si443x_Receive_Blocking/Si443x_Receive_Blocking.ino
similarity index 51%
rename from examples/Si443x/Si443x_Receive/Si443x_Receive.ino
rename to examples/Si443x/Si443x_Receive_Blocking/Si443x_Receive_Blocking.ino
index 846e46e306..8ab9942bcc 100644
--- a/examples/Si443x/Si443x_Receive/Si443x_Receive.ino
+++ b/examples/Si443x/Si443x_Receive_Blocking/Si443x_Receive_Blocking.ino
@@ -1,21 +1,26 @@
/*
- RadioLib Si443x Receive Example
+ RadioLib Si443x Blocking Receive Example
- This example receives packets using Si443x FSK radio module.
- To successfully receive data, the following settings have to be the same
- on both transmitter and receiver:
- - carrier frequency
- - bit rate
- - frequency deviation
- - sync word
+ This example receives packets using Si443x FSK radio module.
+ To successfully receive data, the following settings have to be the same
+ on both transmitter and receiver:
+ - carrier frequency
+ - bit rate
+ - frequency deviation
+ - sync word
- Other modules from Si443x/RFM2x family can also be used.
+ 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#si443xrfm2x
+ Other modules from Si443x/RFM2x family can also be used.
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#si443xrfm2x
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -27,9 +32,13 @@
// SDN pin: 9
Si4432 radio = new Module(10, 2, 9);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//Si4432 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -37,12 +46,12 @@ void setup() {
// initialize Si4432 with default settings
Serial.print(F("[Si4432] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
}
@@ -59,7 +68,7 @@ void loop() {
int state = radio.receive(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("success!"));
@@ -67,11 +76,11 @@ void loop() {
Serial.print(F("[Si4432] Data:\t\t"));
Serial.println(str);
- } else if (state == ERR_RX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
// timeout occurred while waiting for a packet
Serial.println(F("timeout!"));
- } else if (state == ERR_CRC_MISMATCH) {
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
// packet was received, but is malformed
Serial.println(F("CRC error!"));
diff --git a/examples/Si443x/Si443x_Receive_Interrupt/Si443x_Receive_Interrupt.ino b/examples/Si443x/Si443x_Receive_Interrupt/Si443x_Receive_Interrupt.ino
index e890b08d62..63be2b4166 100644
--- a/examples/Si443x/Si443x_Receive_Interrupt/Si443x_Receive_Interrupt.ino
+++ b/examples/Si443x/Si443x_Receive_Interrupt/Si443x_Receive_Interrupt.ino
@@ -1,17 +1,17 @@
/*
- RadioLib Si443x Receive with Interrupts Example
+ RadioLib Si443x Receive with Interrupts Example
- This example listens for FSK transmissions and tries to
- receive them. Once a packet is received, an interrupt is
- triggered.
+ This example listens for FSK transmissions and tries to
+ receive them. Once a packet is received, an interrupt is
+ triggered.
- Other modules from Si443x/RFM2x family can also be used.
+ Other modules from Si443x/RFM2x family can also be used.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#si443xrfm2x
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#si443xrfm2x
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -23,9 +23,28 @@
// SDN pin: 9
Si4432 radio = new Module(10, 2, 9);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//Si4432 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// flag to indicate that a packet was received
+volatile bool receivedFlag = false;
+
+// this function is called when a complete packet
+// is received by the module
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+#if defined(ESP8266) || defined(ESP32)
+ ICACHE_RAM_ATTR
+#endif
+void setFlag(void) {
+ // we got a packet, set the flag
+ receivedFlag = true;
+}
void setup() {
Serial.begin(9600);
@@ -33,27 +52,27 @@ void setup() {
// initialize Si4432 with default settings
Serial.print(F("[Si4432] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set the function that will be called
// when new packet is received
- radio.setIrqAction(setFlag);
+ radio.setPacketReceivedAction(setFlag);
// start listening for packets
Serial.print(F("[Si4432] Starting to listen ... "));
state = radio.startReceive();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// if needed, 'listen' mode can be disabled by calling
@@ -66,33 +85,9 @@ void setup() {
// radio.readData();
}
-// flag to indicate that a packet was received
-volatile bool receivedFlag = false;
-
-// disable interrupt when it's not needed
-volatile bool enableInterrupt = true;
-
-// this function is called when a complete packet
-// is received by the module
-// IMPORTANT: this function MUST be 'void' type
-// and MUST NOT have any arguments!
-void setFlag(void) {
- // check if the interrupt is enabled
- if(!enableInterrupt) {
- return;
- }
-
- // we got a packet, set the flag
- receivedFlag = true;
-}
-
void loop() {
// check if the flag is set
if(receivedFlag) {
- // disable the interrupt service routine while
- // processing the data
- enableInterrupt = false;
-
// reset flag
receivedFlag = false;
@@ -103,10 +98,11 @@ void loop() {
// you can also read received data as byte array
/*
byte byteArr[8];
- int state = radio.readData(byteArr, 8);
+ int numBytes = radio.getPacketLength();
+ int state = radio.readData(byteArr, numBytes);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("[Si4432] Received packet!"));
@@ -114,7 +110,7 @@ void loop() {
Serial.print(F("[Si4432] Data:\t\t\t"));
Serial.println(str);
- } else if (state == ERR_CRC_MISMATCH) {
+ } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
// packet was received, but is malformed
Serial.println(F("CRC error!"));
@@ -127,10 +123,5 @@ void loop() {
// put module back to listen mode
radio.startReceive();
-
- // we're ready to receive more packets,
- // enable interrupt service routine
- enableInterrupt = true;
}
-
}
diff --git a/examples/Si443x/Si443x_Settings/Si443x_Settings.ino b/examples/Si443x/Si443x_Settings/Si443x_Settings.ino
index cd42050528..39a9dbe274 100644
--- a/examples/Si443x/Si443x_Settings/Si443x_Settings.ino
+++ b/examples/Si443x/Si443x_Settings/Si443x_Settings.ino
@@ -1,21 +1,21 @@
/*
- RadioLib Si443x Settings Example
-
- This example shows how to change all the properties of RF69 radio.
- RadioLib currently supports the following settings:
- - pins (SPI slave select, nIRQ, shutdown)
- - carrier frequency
- - bit rate
- - receiver bandwidth
- - frequency deviation
- - output power during transmission
- - sync word
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#si443xrfm2x
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ RadioLib Si443x Settings Example
+
+ This example shows how to change all the properties of RF69 radio.
+ RadioLib currently supports the following settings:
+ - pins (SPI slave select, nIRQ, shutdown)
+ - carrier frequency
+ - bit rate
+ - receiver bandwidth
+ - frequency deviation
+ - output power during transmission
+ - sync word
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#si443xrfm2x
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -33,9 +33,13 @@ Si4432 radio1 = new Module(10, 2, 9);
// SDN pin: 7
Si4432 radio2 = new Module(8, 3, 7);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//Si4432 radio3 = RadioShield.ModuleB;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio3 = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -43,12 +47,12 @@ void setup() {
// initialize Si4432 with default settings
Serial.print(F("[Si4432] Initializing ... "));
int state = radio1.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// initialize Si4432 with non-default settings
@@ -60,59 +64,59 @@ void setup() {
// output power: 17 dBm
// preamble length: 32 bits
state = radio2.begin(868.0, 200.0, 60.0, 335.5, 17, 32);
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// you can also change the settings at runtime
// and check if the configuration was changed successfully
// set carrier frequency to 433.5 MHz
- if (radio1.setFrequency(433.5) == ERR_INVALID_FREQUENCY) {
+ if (radio1.setFrequency(433.5) == RADIOLIB_ERR_INVALID_FREQUENCY) {
Serial.println(F("[Si4432] Selected frequency is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set bit rate to 100.0 kbps
state = radio1.setBitRate(100.0);
- if (state == ERR_INVALID_BIT_RATE) {
+ if (state == RADIOLIB_ERR_INVALID_BIT_RATE) {
Serial.println(F("[Si4432] Selected bit rate is invalid for this module!"));
- while (true);
- } else if (state == ERR_INVALID_BIT_RATE_BW_RATIO) {
+ while (true) { delay(10); }
+ } else if (state == RADIOLIB_ERR_INVALID_BIT_RATE_BW_RATIO) {
Serial.println(F("[Si4432] Selected bit rate to bandwidth ratio is invalid!"));
Serial.println(F("[Si4432] Increase receiver bandwidth to set this bit rate."));
- while (true);
+ while (true) { delay(10); }
}
// set receiver bandwidth to 284.8 kHz
state = radio1.setRxBandwidth(284.8);
- if (state == ERR_INVALID_RX_BANDWIDTH) {
+ if (state == RADIOLIB_ERR_INVALID_RX_BANDWIDTH) {
Serial.println(F("[Si4432] Selected receiver bandwidth is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set frequency deviation to 10.0 kHz
- if (radio1.setFrequencyDeviation(10.0) == ERR_INVALID_FREQUENCY_DEVIATION) {
+ if (radio1.setFrequencyDeviation(10.0) == RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION) {
Serial.println(F("[Si4432] Selected frequency deviation is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// set output power to 2 dBm
- if (radio1.setOutputPower(2) == ERR_INVALID_OUTPUT_POWER) {
+ if (radio1.setOutputPower(2) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) {
Serial.println(F("[Si4432] Selected output power is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
// up to 4 bytes can be set as sync word
// set sync word to 0x01234567
uint8_t syncWord[] = {0x01, 0x23, 0x45, 0x67};
- if (radio1.setSyncWord(syncWord, 4) == ERR_INVALID_SYNC_WORD) {
+ if (radio1.setSyncWord(syncWord, 4) == RADIOLIB_ERR_INVALID_SYNC_WORD) {
Serial.println(F("[Si4432] Selected sync word is invalid for this module!"));
- while (true);
+ while (true) { delay(10); }
}
Serial.println(F("[Si4432] All settings changed successfully!"));
diff --git a/examples/Si443x/Si443x_Transmit/Si443x_Transmit.ino b/examples/Si443x/Si443x_Transmit_Blocking/Si443x_Transmit_Blocking.ino
similarity index 50%
rename from examples/Si443x/Si443x_Transmit/Si443x_Transmit.ino
rename to examples/Si443x/Si443x_Transmit_Blocking/Si443x_Transmit_Blocking.ino
index ca267624f3..1137482b08 100644
--- a/examples/Si443x/Si443x_Transmit/Si443x_Transmit.ino
+++ b/examples/Si443x/Si443x_Transmit_Blocking/Si443x_Transmit_Blocking.ino
@@ -1,19 +1,23 @@
/*
- RadioLib Si443x Transmit Example
+ RadioLib Si443x Blocking Transmit Example
- This example transmits packets using Si4432 FSK radio module.
- Each packet contains up to 64 bytes of data, in the form of:
- - Arduino String
- - null-terminated char array (C-string)
- - arbitrary binary data (byte array)
+ This example transmits packets using Si4432 FSK radio module.
+ Each packet contains up to 64 bytes of data, in the form of:
+ - Arduino String
+ - null-terminated char array (C-string)
+ - arbitrary binary data (byte array)
- Other modules from Si443x/RFM2x family can also be used.
+ Other modules from Si443x/RFM2x family can also be used.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#si443xrfm2x
+ Using blocking transmit is not recommended, as it will lead
+ to inefficient use of processor time!
+ Instead, interrupt transmit is recommended.
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#si443xrfm2x
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -25,9 +29,13 @@
// SDN pin: 9
Si4432 radio = new Module(10, 2, 9);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//Si4432 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -35,24 +43,25 @@ void setup() {
// initialize Si4432 with default settings
Serial.print(F("[Si4432] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
}
+// counter to keep track of transmitted packets
+int count = 0;
+
void loop() {
Serial.print(F("[Si4432] Transmitting packet ... "));
// you can transmit C-string or Arduino string up to
// 64 characters long
- // NOTE: transmit() is a blocking method!
- // See example Si443x_Transmit_Interrupt for details
- // on non-blocking transmission method.
- int state = radio.transmit("Hello World!");
+ String str = "Hello World! #" + String(count++);
+ int state = radio.transmit(str);
// you can also transmit byte array up to 64 bytes long
/*
@@ -60,15 +69,15 @@ void loop() {
int state = radio.transmit(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// the packet was successfully transmitted
Serial.println(F(" success!"));
- } else if (state == ERR_PACKET_TOO_LONG) {
+ } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
// the supplied packet was longer than 256 bytes
Serial.println(F(" too long!"));
- } else if (state == ERR_TX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
// timeout occured while transmitting packet
Serial.println(F(" timeout!"));
diff --git a/examples/Si443x/Si443x_Transmit_Interrupt/Si443x_Transmit_Interrupt.ino b/examples/Si443x/Si443x_Transmit_Interrupt/Si443x_Transmit_Interrupt.ino
index 82c5364dce..d2e433c0e4 100644
--- a/examples/Si443x/Si443x_Transmit_Interrupt/Si443x_Transmit_Interrupt.ino
+++ b/examples/Si443x/Si443x_Transmit_Interrupt/Si443x_Transmit_Interrupt.ino
@@ -1,19 +1,19 @@
/*
- RadioLib Si443x Transmit with Interrupts Example
+ RadioLib Si443x Transmit with Interrupts Example
- This example transmits packets using Si4432 FSK radio module.
- Each packet contains up to 64 bytes of data, in the form of:
- - Arduino String
- - null-terminated char array (C-string)
- - arbitrary binary data (byte array)
+ This example transmits packets using Si4432 FSK radio module.
+ Each packet contains up to 64 bytes of data, in the form of:
+ - Arduino String
+ - null-terminated char array (C-string)
+ - arbitrary binary data (byte array)
- Other modules from Si443x/RFM2x family can also be used.
+ Other modules from Si443x/RFM2x family can also be used.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#si443xrfm2x
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#si443xrfm2x
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -25,12 +25,31 @@
// SDN pin: 9
Si4432 radio = new Module(10, 2, 9);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//Si4432 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// save transmission state between loops
-int transmissionState = ERR_NONE;
+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);
@@ -38,17 +57,17 @@ void setup() {
// initialize Si4432 with default settings
Serial.print(F("[Si4432] Initializing ... "));
int state = radio.begin();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// set the function that will be called
// when packet transmission is finished
- radio.setIrqAction(setFlag);
+ radio.setPacketSentAction(setFlag);
// start transmitting the first packet
Serial.print(F("[Si4432] Sending first packet ... "));
@@ -65,37 +84,16 @@ void setup() {
*/
}
-// flag to indicate that a packet was sent
-volatile bool transmittedFlag = false;
-
-// disable interrupt when it's not needed
-volatile bool enableInterrupt = true;
-
-// this function is called when a complete packet
-// is transmitted by the module
-// IMPORTANT: this function MUST be 'void' type
-// and MUST NOT have any arguments!
-void setFlag(void) {
- // check if the interrupt is enabled
- if(!enableInterrupt) {
- return;
- }
-
- // we sent a packet, set the flag
- transmittedFlag = true;
-}
+// counter to keep track of transmitted packets
+int count = 0;
void loop() {
// check if the previous transmission finished
if(transmittedFlag) {
- // disable the interrupt service routine while
- // processing the data
- enableInterrupt = false;
-
// reset flag
transmittedFlag = false;
- if (transmissionState == ERR_NONE) {
+ if (transmissionState == RADIOLIB_ERR_NONE) {
// packet was successfully sent
Serial.println(F("transmission finished!"));
@@ -105,6 +103,11 @@ void loop() {
}
+ // 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);
@@ -113,17 +116,14 @@ void loop() {
// you can transmit C-string or Arduino string up to
// 256 characters long
- transmissionState = radio.startTransmit("Hello World!");
+ String str = "Hello World! #" + String(count++);
+ transmissionState = radio.startTransmit(str);
// you can also transmit byte array up to 64 bytes long
/*
byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
0x89, 0xAB, 0xCD, 0xEF};
- int state = radio.startTransmit(byteArr, 8);
+ transmissionState = radio.startTransmit(byteArr, 8);
*/
-
- // we're ready to send more packets,
- // enable interrupt service routine
- enableInterrupt = true;
}
}
diff --git a/examples/Stream/Stream_Receive/Stream_Receive.ino b/examples/Stream/Stream_Receive/Stream_Receive.ino
new file mode 100644
index 0000000000..0abffd1756
--- /dev/null
+++ b/examples/Stream/Stream_Receive/Stream_Receive.ino
@@ -0,0 +1,131 @@
+/*
+ RadioLib Stream Receive Example
+
+ This example shows how to receive data in "Stream" mode.
+ In this mode, arbitrary length of data may be sent, up to
+ "infinite" continuous transmission between two devices.
+
+ Caveats:
+ - CRC of the payload is not supported
+ - the length of the payload must be known in advance
+
+ Modules that can be used for Stream are:
+ - SX127x/RFM9x (FSK mode only)
+ - RF69
+ - SX1231
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1278 has the following connections:
+// NSS pin: 10
+// DIO0 pin: 2
+// RESET pin: 9
+// DIO1 pin: 3
+SX1278 radio = new Module(10, 2, 9, 3);
+
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+void setup() {
+ Serial.begin(9600);
+
+ // initialize SX1278 with default settings
+ Serial.print(F("[SX1278] Initializing ... "));
+ int state = radio.beginFSK();
+
+ // when using one of the non-LoRa modules for Stream transmit
+ // (RF69, CC1101, Si4432 etc.), use the basic begin() method
+ // int state = radio.begin();
+
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // set the function that will be called
+ // when receive buffer is full
+ radio.setFifoFullAction(fifoGet);
+
+ // fixed packet length mode is required
+ radio.fixedPacketLengthMode(0);
+
+ // start listening for packets
+ Serial.print(F("[SX1278] Starting to listen ... "));
+ state = radio.startReceive();
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // if needed, 'listen' mode can be disabled by calling
+ // any of the following methods:
+ //
+ // radio.standby()
+ // radio.sleep()
+ // radio.transmit();
+ // radio.receive();
+ // radio.readData();
+ // radio.scanChannel();
+}
+
+// flag to indicate that a packet was received
+volatile bool receivedFlag = false;
+
+// how many bytes are there in total
+const int totalLength = 512;
+
+// counter to keep track of how many bytes have been received so far
+volatile int receivedLength = 0;
+
+// buffer to save the received data into
+volatile uint8_t rxBuffer[totalLength + 1];
+
+// this function is called when the radio receive buffer
+// is full and ready to be read
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+#if defined(ESP8266) || defined(ESP32)
+ ICACHE_RAM_ATTR
+#endif
+void fifoGet(void) {
+ // set the flag when we receive the full packet
+ receivedFlag = radio.fifoGet(rxBuffer, totalLength, &receivedLength);
+}
+
+void loop() {
+ // check if the flag is set
+ if(receivedFlag) {
+ // packet was successfully received
+ Serial.println(F("[SX1278] Received packet!"));
+
+ // print data of the packet
+ Serial.print(F("[SX1278] Data:\t\t"));
+ Serial.println((char*)rxBuffer);
+
+ // reset flag
+ receivedFlag = false;
+ receivedLength = 0;
+
+ // put module back to listen mode
+ radio.startReceive();
+ }
+}
diff --git a/examples/Stream/Stream_Transmit/Stream_Transmit.ino b/examples/Stream/Stream_Transmit/Stream_Transmit.ino
new file mode 100644
index 0000000000..8280a405af
--- /dev/null
+++ b/examples/Stream/Stream_Transmit/Stream_Transmit.ino
@@ -0,0 +1,151 @@
+/*
+ RadioLib Stream Transmit Example
+
+ This example shows how to transmit data in "Stream" mode.
+ In this mode, arbitrary length of data may be sent, up to
+ "infinite" continuous transmission between two devices.
+
+ Caveats:
+ - CRC of the payload is not supported
+ - the length of the payload must be known in advance
+
+ Modules that can be used for Stream are:
+ - SX127x/RFM9x (FSK mode only)
+ - RF69
+ - SX1231
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
+*/
+
+// include the library
+#include
+
+// SX1278 has the following connections:
+// NSS pin: 10
+// DIO0 pin: 2
+// RESET pin: 9
+// DIO1 pin: 3
+SX1278 radio = new Module(10, 2, 9, 3);
+
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// save transmission state between loops
+int transmissionState = RADIOLIB_ERR_NONE;
+
+// this packet is much longer than would normally fit
+// into SX1278's internal buffer
+String longPacket = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\
+ Maecenas at urna ut nunc imperdiet laoreet. Aliquam erat volutpat.\
+ Etiam mattis mauris vitae posuere tincidunt. In sit amet bibendum nisl,\
+ a ultrices lorem. Duis hendrerit ultricies condimentum. Phasellus eget nisi\
+ eget massa aliquam bibendum. Pellentesque ante neque, aliquam non diam non,\
+ fringilla facilisis ipsum. Morbi in molestie orci. Vestibulum luctus\
+ venenatis arcu sit amet pellentesque. Nulla posuere sit amet turpis\
+ id pharetra. Curabitur nec.";
+
+void setup() {
+ Serial.begin(9600);
+
+ // initialize SX1278 with default settings
+ Serial.print(F("[SX1278] Initializing ... "));
+ int state = radio.beginFSK();
+
+ // when using one of the non-LoRa modules for Stream transmit
+ // (RF69, CC1101, Si4432 etc.), use the basic begin() method
+ // int state = radio.begin();
+
+ if (state == RADIOLIB_ERR_NONE) {
+ Serial.println(F("success!"));
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(state);
+ while (true) { delay(10); }
+ }
+
+ // set the function that will be called
+ // when transmit buffer is empty
+ radio.setFifoEmptyAction(fifoAdd);
+
+ // fixed packet length mode is required
+ radio.fixedPacketLengthMode(0);
+
+ // start transmitting the long packet
+ Serial.print(F("[SX1278] Sending a very long packet ... "));
+ transmissionState = radio.startTransmit(longPacket);
+}
+
+// flag to indicate we can keep adding more bytes to FIFO
+volatile bool fifoEmpty = false;
+
+// flag to indicate that a packet was sent
+bool transmittedFlag = false;
+
+// how many bytes are there in total
+int totalLength = longPacket.length();
+
+// counter to keep track of how many bytes still need to be sent
+int remLength = totalLength;
+
+// this function is called when the radio transmit buffer
+// is empty and ready to be refilled
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+#if defined(ESP8266) || defined(ESP32)
+ ICACHE_RAM_ATTR
+#endif
+void fifoAdd(void) {
+ // we can send more bytes
+ fifoEmpty = true;
+}
+
+void loop() {
+ if(fifoEmpty) {
+ // reset flag
+ fifoEmpty = false;
+
+ // add more bytes to the transmit buffer
+ uint8_t* txBuffPtr = (uint8_t*)longPacket.c_str();
+ transmittedFlag = radio.fifoAdd(txBuffPtr, totalLength, &remLength);
+ }
+
+ // check if the previous transmission finished
+ if(transmittedFlag) {
+ // reset flag
+ transmittedFlag = false;
+
+ // reset the counter
+ remLength = totalLength;
+
+ if (transmissionState == RADIOLIB_ERR_NONE) {
+ // packet was successfully sent
+ Serial.println(F("transmission finished!"));
+
+ } else {
+ Serial.print(F("failed, code "));
+ Serial.println(transmissionState);
+
+ }
+
+ // NOTE: in FSK mode, SX127x will not automatically
+ // turn transmitter off after sending a packet
+ // set mode to standby to ensure we don't jam others
+ radio.standby();
+
+ // wait a second before transmitting again
+ delay(1000);
+
+ // send another one
+ Serial.print(F("[SX1278] Sending another long packet ... "));
+ transmissionState = radio.startTransmit(longPacket);
+ }
+}
diff --git a/examples/XBee/XBee_Receive/XBee_Receive.ino b/examples/XBee/XBee_Receive/XBee_Receive.ino
deleted file mode 100644
index f5825efb4c..0000000000
--- a/examples/XBee/XBee_Receive/XBee_Receive.ino
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- RadioLib XBee API Receive Example
-
- This example receives packets using XBee API mode.
- In API mode, many XBee modules can form a mesh network.
-
- IMPORTANT: Before uploading this example, make sure that the XBee module
- is running API ROUTER/ENDPOINT firmware!
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
-*/
-
-// include the library
-#include
-
-// XBee has the following connections:
-// TX pin: 9
-// RX pin: 8
-// RESET pin: 3
-XBee bee = new SerialModule(9, 8, 3);
-
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//XBee bee = RadioShield.ModuleA;
-
-void setup() {
- Serial.begin(9600);
-
- // initialize XBee module with baudrate 9600
- Serial.print(F("[XBee] Initializing ... "));
- int state = bee.begin(9600);
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-
- // set PAN ID to 0x0123456789ABCDEF
- Serial.print(F("[XBee] Setting PAN ID ... "));
- uint8_t panId[] = {0x01, 0x23, 0x45, 0x67,
- 0x89, 0xAB, 0xCD, 0xEF};
- state = bee.setPanId(panId);
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-}
-
-void loop() {
- // check if XBee received some data
- if (bee.available() > 0) {
- // print source address
- Serial.print(F("[XBee] Packet source:\t"));
- Serial.println(bee.getPacketSource());
-
- // print data
- Serial.print(F("[XBee] Packet data:\t"));
- Serial.println(bee.getPacketData());
- }
-}
diff --git a/examples/XBee/XBee_Transmit/XBee_Transmit.ino b/examples/XBee/XBee_Transmit/XBee_Transmit.ino
deleted file mode 100644
index cc33faf3d4..0000000000
--- a/examples/XBee/XBee_Transmit/XBee_Transmit.ino
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- RadioLib XBee API Transmit Example
-
- This example transmits packets using XBee API mode.
- In API mode, many XBee modules can form a mesh network.
-
- IMPORTANT: Before uploading this example, make sure that the XBee module
- is running API COORDINATOR firmware!
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
-*/
-
-// include the library
-#include
-
-// XBee has the following connections:
-// TX pin: 9
-// RX pin: 8
-// RESET pin: 3
-XBee bee = new SerialModule(9, 8, 3);
-
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//XBee bee = RadioShield.ModuleA;
-
-void setup() {
- Serial.begin(9600);
-
- // initialize XBee module with baudrate 9600
- Serial.print(F("[XBee] Initializing ... "));
- int state = bee.begin(9600);
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-
- // set PAN ID to 0x0123456789ABCDEF
- Serial.print(F("[XBee] Setting PAN ID ... "));
- uint8_t panId[] = {0x01, 0x23, 0x45, 0x67,
- 0x89, 0xAB, 0xCD, 0xEF};
- state = bee.setPanId(panId);
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-}
-
-void loop() {
- // transmit data to the destination module
- uint8_t dest[] = {0x00, 0x13, 0xA2, 0x00,
- 0x40, 0xA5, 0x8A, 0x6B};
- Serial.print(F("[XBee] Transmitting message ... "));
- int state = bee.transmit(dest, "Hello World!");
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- }
-
- delay(1000);
-}
diff --git a/examples/XBee/XBee_Transparent/XBee_Transparent.ino b/examples/XBee/XBee_Transparent/XBee_Transparent.ino
deleted file mode 100644
index b063df8338..0000000000
--- a/examples/XBee/XBee_Transparent/XBee_Transparent.ino
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- RadioLib XBee Transparent Operation Example
-
- This example transmits packets using XBee Transparent mode.
- In Transparent mode, two XBee modules act like a Serial line.
- Both modules must have the same PAN ID, and the destination
- addresses have to be set properly.
-
- IMPORTANT: Before uploading this example, make sure that the XBee modules
- are running AT COORDINATOR and AT ROUTER firmware!
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
-*/
-
-// include the library
-#include
-
-// XBee has the following connections:
-// TX pin: 9
-// RX pin: 8
-// RESET pin: 3
-XBeeSerial bee = new SerialModule(9, 8, 3);
-
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//XBeeSerial bee = RadioShield.ModuleA;
-
-void setup() {
- Serial.begin(9600);
-
- // initialize XBee module with baudrate 9600
- Serial.print(F("[XBee] Initializing ... "));
- int state = bee.begin(9600);
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-
- // set PAN ID to 0123456789ABCDEF
- Serial.print(F("[XBee] Setting PAN ID ... "));
- state = bee.setPanId("0123456789ABCDEF");
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-
- // set destination address to the address of the second module
- Serial.print(F("[XBee] Setting destination address ... "));
- state = bee.setDestinationAddress("0013A200", "40A58A5D");
- if (state == ERR_NONE) {
- Serial.println(F("success!"));
- } else {
- Serial.print(F("failed, code "));
- Serial.println(state);
- while (true);
- }
-}
-
-void loop() {
- // XBeeSerial supports all methods of the Serial class
- // read data incoming from Serial port and write them to XBee
- while (Serial.available() > 0) {
- bee.write(Serial.read());
- }
-
- // read data incoming from XBee and write them to Serial port
- while (bee.available() > 0) {
- Serial.write(bee.read());
- }
-}
diff --git a/examples/nRF24/nRF24_Receive/nRF24_Receive.ino b/examples/nRF24/nRF24_Receive_Blocking/nRF24_Receive_Blocking.ino
similarity index 59%
rename from examples/nRF24/nRF24_Receive/nRF24_Receive.ino
rename to examples/nRF24/nRF24_Receive_Blocking/nRF24_Receive_Blocking.ino
index 2c036fd64c..a3028cda77 100644
--- a/examples/nRF24/nRF24_Receive/nRF24_Receive.ino
+++ b/examples/nRF24/nRF24_Receive_Blocking/nRF24_Receive_Blocking.ino
@@ -1,19 +1,23 @@
/*
- RadioLib nRF24 Receive Example
+ RadioLib nRF24 Blocking Receive Example
- This example listens for FSK transmissions using nRF24 2.4 GHz radio module.
- To successfully receive data, the following settings have to be the same
- on both transmitter and receiver:
- - carrier frequency
- - data rate
- - transmit pipe on transmitter must match receive pipe
- on receiver
+ This example listens for FSK transmissions using nRF24 2.4 GHz radio module.
+ To successfully receive data, the following settings have to be the same
+ on both transmitter and receiver:
+ - carrier frequency
+ - data rate
+ - transmit pipe on transmitter must match receive pipe on receiver
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#nrf24
+ 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 full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#nrf24
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -25,9 +29,13 @@
// CE pin: 3
nRF24 radio = new Module(10, 2, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//nRF24 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -35,12 +43,12 @@ void setup() {
// initialize nRF24 with default settings
Serial.print(F("[nRF24] Initializing ... "));
int state = radio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// set receive pipe 0 address
@@ -50,12 +58,12 @@ void setup() {
Serial.print(F("[nRF24] Setting address for receive pipe 0 ... "));
byte addr[] = {0x01, 0x23, 0x45, 0x67, 0x89};
state = radio.setReceivePipe(0, addr);
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
}
@@ -75,7 +83,7 @@ void loop() {
int state = radio.receive(byteArr, 8);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("success!"));
@@ -83,7 +91,7 @@ void loop() {
Serial.print(F("[nRF24] Data:\t\t"));
Serial.println(str);
- } else if (state == ERR_RX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_RX_TIMEOUT) {
// timeout occurred while waiting for a packet
Serial.println(F("timeout!"));
diff --git a/examples/nRF24/nRF24_Receive_Interrupt/nRF24_Receive_Interrupt.ino b/examples/nRF24/nRF24_Receive_Interrupt/nRF24_Receive_Interrupt.ino
index 6d964bd1b8..cb19db0cf2 100644
--- a/examples/nRF24/nRF24_Receive_Interrupt/nRF24_Receive_Interrupt.ino
+++ b/examples/nRF24/nRF24_Receive_Interrupt/nRF24_Receive_Interrupt.ino
@@ -1,20 +1,20 @@
/*
- RadioLib nRF24 Receive Example
-
- This example listens for FSK transmissions using nRF24 2.4 GHz radio module.
- 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
- - data rate
- - transmit pipe on transmitter must match receive pipe
- on receiver
-
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#nrf24
-
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ RadioLib nRF24 Receive Example
+
+ This example listens for FSK transmissions using nRF24 2.4 GHz radio module.
+ 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
+ - data rate
+ - transmit pipe on transmitter must match receive pipe
+ on receiver
+
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#nrf24
+
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -26,9 +26,28 @@
// CE pin: 3
nRF24 radio = new Module(10, 2, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//nRF24 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
+
+// flag to indicate that a packet was received
+volatile bool receivedFlag = false;
+
+// this function is called when a complete packet
+// is received by the module
+// IMPORTANT: this function MUST be 'void' type
+// and MUST NOT have any arguments!
+#if defined(ESP8266) || defined(ESP32)
+ ICACHE_RAM_ATTR
+#endif
+void setFlag(void) {
+ // we got a packet, set the flag
+ receivedFlag = true;
+}
void setup() {
Serial.begin(9600);
@@ -36,12 +55,12 @@ void setup() {
// initialize nRF24 with default settings
Serial.print(F("[nRF24] Initializing ... "));
int state = radio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// set receive pipe 0 address
@@ -51,27 +70,27 @@ void setup() {
Serial.print(F("[nRF24] Setting address for receive pipe 0 ... "));
byte addr[] = {0x01, 0x23, 0x45, 0x67, 0x89};
state = radio.setReceivePipe(0, addr);
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// set the function that will be called
// when new packet is received
- radio.setIrqAction(setFlag);
+ radio.setPacketReceivedAction(setFlag);
// start listening
Serial.print(F("[nRF24] Starting to listen ... "));
state = radio.startReceive();
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while (true);
+ while (true) { delay(10); }
}
// if needed, 'listen' mode can be disabled by calling
@@ -84,33 +103,9 @@ void setup() {
// radio.readData();
}
-// flag to indicate that a packet was received
-volatile bool receivedFlag = false;
-
-// disable interrupt when it's not needed
-volatile bool enableInterrupt = true;
-
-// this function is called when a complete packet
-// is received by the module
-// IMPORTANT: this function MUST be 'void' type
-// and MUST NOT have any arguments!
-void setFlag(void) {
- // check if the interrupt is enabled
- if(!enableInterrupt) {
- return;
- }
-
- // we got a packet, set the flag
- receivedFlag = true;
-}
-
void loop() {
// check if the flag is set
if(receivedFlag) {
- // disable the interrupt service routine while
- // processing the data
- enableInterrupt = false;
-
// reset flag
receivedFlag = false;
@@ -121,10 +116,11 @@ void loop() {
// you can also read received data as byte array
/*
byte byteArr[8];
- int state = radio.readData(byteArr, 8);
+ int numBytes = radio.getPacketLength();
+ int state = radio.readData(byteArr, numBytes);
*/
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// packet was successfully received
Serial.println(F("[nRF24] Received packet!"));
@@ -141,10 +137,5 @@ void loop() {
// put module back to listen mode
radio.startReceive();
-
- // we're ready to receive more packets,
- // enable interrupt service routine
- enableInterrupt = true;
}
-
}
diff --git a/examples/nRF24/nRF24_Transmit/nRF24_Transmit.ino b/examples/nRF24/nRF24_Transmit_Blocking/nRF24_Transmit_Blocking.ino
similarity index 56%
rename from examples/nRF24/nRF24_Transmit/nRF24_Transmit.ino
rename to examples/nRF24/nRF24_Transmit_Blocking/nRF24_Transmit_Blocking.ino
index c692e8a8ff..603b4bd571 100644
--- a/examples/nRF24/nRF24_Transmit/nRF24_Transmit.ino
+++ b/examples/nRF24/nRF24_Transmit_Blocking/nRF24_Transmit_Blocking.ino
@@ -1,19 +1,19 @@
/*
- RadioLib nRF24 Transmit Example
+ RadioLib nRF24 Transmit Example
- This example transmits packets using nRF24 2.4 GHz radio module.
- Each packet contains up to 32 bytes of data, in the form of:
- - Arduino String
- - null-terminated char array (C-string)
- - arbitrary binary data (byte array)
+ This example transmits packets using nRF24 2.4 GHz radio module.
+ Each packet contains up to 32 bytes of data, in the form of:
+ - Arduino String
+ - null-terminated char array (C-string)
+ - arbitrary binary data (byte array)
- Packet delivery is automatically acknowledged by the receiver.
+ Packet delivery is automatically acknowledged by the receiver.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#nrf24
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#nrf24
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -25,9 +25,13 @@
// CE pin: 3
nRF24 radio = new Module(10, 2, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//nRF24 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
void setup() {
Serial.begin(9600);
@@ -35,12 +39,12 @@ void setup() {
// initialize nRF24 with default settings
Serial.print(F("[nRF24] Initializing ... "));
int state = radio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// set transmit address
@@ -50,36 +54,40 @@ void setup() {
byte addr[] = {0x01, 0x23, 0x45, 0x67, 0x89};
Serial.print(F("[nRF24] Setting transmit pipe ... "));
state = radio.setTransmitPipe(addr);
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
}
+// counter to keep track of transmitted packets
+int count = 0;
+
void loop() {
Serial.print(F("[nRF24] Transmitting packet ... "));
// you can transmit C-string or Arduino string up to
// 32 characters long
- int state = radio.transmit("Hello World!");
+ String str = "Hello World! #" + String(count++);
+ int state = radio.transmit(str);
- if (state == ERR_NONE) {
+ if (state == RADIOLIB_ERR_NONE) {
// the packet was successfully transmitted
Serial.println(F("success!"));
- } else if (state == ERR_PACKET_TOO_LONG) {
+ } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) {
// the supplied packet was longer than 32 bytes
Serial.println(F("too long!"));
- } else if (state == ERR_ACK_NOT_RECEIVED) {
+ } else if (state == RADIOLIB_ERR_ACK_NOT_RECEIVED) {
// acknowledge from destination module
// was not received within 15 retries
Serial.println(F("ACK not received!"));
- } else if (state == ERR_TX_TIMEOUT) {
+ } else if (state == RADIOLIB_ERR_TX_TIMEOUT) {
// timed out while transmitting
Serial.println(F("timeout!"));
diff --git a/examples/nRF24/nRF24_Transmit_Interrupt/nRF24_Transmit_Interrupt.ino b/examples/nRF24/nRF24_Transmit_Interrupt/nRF24_Transmit_Interrupt.ino
index 81b064b3cf..5d5f5de656 100644
--- a/examples/nRF24/nRF24_Transmit_Interrupt/nRF24_Transmit_Interrupt.ino
+++ b/examples/nRF24/nRF24_Transmit_Interrupt/nRF24_Transmit_Interrupt.ino
@@ -1,19 +1,19 @@
/*
- RadioLib nRF24 Transmit with Interrupts Example
+ RadioLib nRF24 Transmit with Interrupts Example
- This example transmits packets using nRF24 2.4 GHz radio module.
- Each packet contains up to 32 bytes of data, in the form of:
- - Arduino String
- - null-terminated char array (C-string)
- - arbitrary binary data (byte array)
+ This example transmits packets using nRF24 2.4 GHz radio module.
+ Each packet contains up to 32 bytes of data, in the form of:
+ - Arduino String
+ - null-terminated char array (C-string)
+ - arbitrary binary data (byte array)
- Packet delivery is automatically acknowledged by the receiver.
+ Packet delivery is automatically acknowledged by the receiver.
- For default module settings, see the wiki page
- https://github.com/jgromes/RadioLib/wiki/Default-configuration#nrf24
+ For default module settings, see the wiki page
+ https://github.com/jgromes/RadioLib/wiki/Default-configuration#nrf24
- For full API reference, see the GitHub Pages
- https://jgromes.github.io/RadioLib/
+ For full API reference, see the GitHub Pages
+ https://jgromes.github.io/RadioLib/
*/
// include the library
@@ -25,12 +25,31 @@
// CE pin: 3
nRF24 radio = new Module(10, 2, 3);
-// or using RadioShield
-// https://github.com/jgromes/RadioShield
-//nRF24 radio = RadioShield.ModuleA;
+// or detect the pinout automatically using RadioBoards
+// https://github.com/radiolib-org/RadioBoards
+/*
+#define RADIO_BOARD_AUTO
+#include
+Radio radio = new RadioModule();
+*/
// save transmission state between loops
-int transmissionState = ERR_NONE;
+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);
@@ -38,12 +57,12 @@ void setup() {
// initialize nRF24 with default settings
Serial.print(F("[nRF24] Initializing ... "));
int state = radio.begin();
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// set transmit address
@@ -53,17 +72,17 @@ void setup() {
byte addr[] = {0x01, 0x23, 0x45, 0x67, 0x89};
Serial.print(F("[nRF24] Setting transmit pipe ... "));
state = radio.setTransmitPipe(addr);
- if(state == ERR_NONE) {
+ if(state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
- while(true);
+ while (true) { delay(10); }
}
// set the function that will be called
// when packet transmission is finished
- radio.setIrqAction(setFlag);
+ radio.setPacketSentAction(setFlag);
// start transmitting the first packet
Serial.print(F("[nRF24] Sending first packet ... "));
@@ -80,50 +99,30 @@ void setup() {
*/
}
-// flag to indicate that a packet was sent
-volatile bool transmittedFlag = false;
-
-// disable interrupt when it's not needed
-volatile bool enableInterrupt = true;
-
-// this function is called when a complete packet
-// is transmitted by the module
-// IMPORTANT: this function MUST be 'void' type
-// and MUST NOT have any arguments!
-void setFlag(void) {
- // check if the interrupt is enabled
- if(!enableInterrupt) {
- return;
- }
-
- // we sent a packet, set the flag
- transmittedFlag = true;
-}
+// counter to keep track of transmitted packets
+int count = 0;
void loop() {
// check if the previous transmission finished
if(transmittedFlag) {
- // disable the interrupt service routine while
- // processing the data
- enableInterrupt = false;
-
// reset flag
transmittedFlag = false;
- if (transmissionState == ERR_NONE) {
+ 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);
@@ -131,8 +130,9 @@ void loop() {
Serial.print(F("[nRF24] Sending another packet ... "));
// you can transmit C-string or Arduino string up to
- // 256 characters long
- transmissionState = radio.startTransmit("Hello World!");
+ // 32 characters long
+ String str = "Hello World! #" + String(count++);
+ transmissionState = radio.startTransmit(str);
// you can also transmit byte array up to 256 bytes long
/*
@@ -140,9 +140,5 @@ void loop() {
0x89, 0xAB, 0xCD, 0xEF};
int state = radio.startTransmit(byteArr, 8);
*/
-
- // we're ready to send more packets,
- // enable interrupt service routine
- enableInterrupt = true;
}
}
diff --git a/extras/ADSB_Monitor/ADSBMonitorServer.py b/extras/ADSB_Monitor/ADSBMonitorServer.py
new file mode 100755
index 0000000000..3fbb490c7b
--- /dev/null
+++ b/extras/ADSB_Monitor/ADSBMonitorServer.py
@@ -0,0 +1,141 @@
+#!/usr/bin/python3
+# -*- encoding: utf-8 -*-
+
+import argparse
+import sys
+import zmq
+import serial
+import threading
+import queue
+import time
+
+from argparse import RawTextHelpFormatter
+
+# default settings
+DEFAULT_BAUDRATE = 115200
+DEFAULT_SERVER_PORT = 30002
+
+# marker to filter out ADS-B messages from the rest of the serial stream
+ADSB_MESSAGE_MARKER = '[ADS-B]'
+
+class SerialToZMQBridge:
+ def __init__(self, serial_port, baudrate, zmq_host="0.0.0.0", zmq_port=5555):
+ self.serial_port = serial_port
+ self.baudrate = baudrate
+ self.zmq_host = zmq_host
+ self.zmq_port = zmq_port
+
+ self.context = zmq.Context()
+ self.socket = self.context.socket(zmq.STREAM)
+ self.socket.setsockopt(zmq.LINGER, 0)
+ self.socket.bind(f"tcp://{self.zmq_host}:{self.zmq_port}")
+
+ self.serial = serial.Serial(
+ port=self.serial_port,
+ baudrate=self.baudrate,
+ timeout=1
+ )
+
+ self.clients = set()
+ self.serial_queue = queue.Queue()
+
+ self.running = True
+
+ def serial_reader(self):
+ """Continuously read from serial and queue messages."""
+ while self.running:
+ try:
+ line = self.serial.readline()
+ if line:
+ line = line.decode(errors='ignore').strip()
+ print(f"[SERIAL RX] {line}")
+
+ # read the ADS-B frames and add the markers expected by pyModeS
+ if ADSB_MESSAGE_MARKER in line:
+ msg = '*' + line.split(' ')[1].strip() + ';'
+ self.serial_queue.put(msg.encode('utf-8'))
+
+ except Exception as e:
+ print(f"Serial read error: {e}")
+ time.sleep(1)
+
+ def run(self):
+ print(f"ZMQ STREAM server listening on tcp://{self.zmq_host}:{self.zmq_port}")
+ print(f"Listening to serial port {self.serial_port} @ {self.baudrate}")
+
+ threading.Thread(target=self.serial_reader, daemon=True).start()
+
+ poller = zmq.Poller()
+ poller.register(self.socket, zmq.POLLIN)
+
+ try:
+ while self.running:
+ # Poll ZMQ socket
+ events = dict(poller.poll(100))
+
+ if self.socket in events:
+ identity, message = self.socket.recv_multipart()
+
+ if message == b'':
+ # Connection event
+ print(f"[ZMQ] Client connected/disconnected: {identity}")
+ self.clients.add(identity)
+ continue
+
+ print(f"[ZMQ RX] {identity}: {message.decode(errors='ignore')}")
+
+ # Send serial data to all connected clients
+ while not self.serial_queue.empty():
+ data = self.serial_queue.get()
+ for client_id in list(self.clients):
+ try:
+ self.socket.send_multipart([client_id, data])
+ print(f"[ZMQ TX] Sent to {client_id}")
+ except zmq.ZMQError:
+ self.clients.discard(client_id)
+
+ except KeyboardInterrupt:
+ print("Shutting down...")
+
+ finally:
+ self.running = False
+ self.serial.close()
+ self.socket.close()
+ self.context.term()
+
+
+def main():
+ parser = argparse.ArgumentParser(formatter_class=RawTextHelpFormatter, description='''
+ RadioLib ADS-B Monitor script. Serves as server for "modeslive" live traffic decoder from pyModeS
+ (https://github.com/junzis/pyModeS).
+
+ Depends on pyserial and pyModeS, install by:
+ 'python3 -m pip install pyserial pyModeS'
+
+ Step-by-step guide on how to use the script:
+ 1. Upload the ADSB_Monitor example to your Arduino board with LR2021 connected.
+ 2. Run the script with appropriate arguments.
+ 3. Run "modeslive --source net --connect localhost 30002 raw"
+ ''')
+ parser.add_argument('port',
+ type=str,
+ help='COM port to connect to the device')
+ parser.add_argument('--speed',
+ default=DEFAULT_BAUDRATE,
+ type=int,
+ help=f'COM port baudrate (defaults to {DEFAULT_BAUDRATE})')
+ parser.add_argument('--server-port',
+ default=DEFAULT_SERVER_PORT,
+ type=int,
+ help=f'server port to be used by modeslive (defaults to {DEFAULT_SERVER_PORT})')
+ args = parser.parse_args()
+
+ bridge = SerialToZMQBridge(
+ serial_port=args.port,
+ baudrate=args.speed,
+ zmq_port=args.server_port
+ )
+ bridge.run()
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/extras/SSTV_Image_Converter/.gitignore b/extras/SSTV_Image_Converter/.gitignore
new file mode 100644
index 0000000000..bb45c8d1ba
--- /dev/null
+++ b/extras/SSTV_Image_Converter/.gitignore
@@ -0,0 +1,4 @@
+# ignore all output files
+*.h
+*.png
+!radiolib.png
diff --git a/extras/SSTV_Image_Converter/ImageConverter.py b/extras/SSTV_Image_Converter/ImageConverter.py
new file mode 100755
index 0000000000..844446572e
--- /dev/null
+++ b/extras/SSTV_Image_Converter/ImageConverter.py
@@ -0,0 +1,50 @@
+#!/usr/bin/python3
+# -*- encoding: utf-8 -*-
+
+import argparse
+import numpy as np
+from PIL import Image
+from argparse import RawTextHelpFormatter
+
+def main():
+ parser = argparse.ArgumentParser(formatter_class=RawTextHelpFormatter, description='''
+ RadioLib image to array conversion tool.
+
+ Input is a PNG image to be transmitted via RadioLib SSTV.
+ The image must have correct size for the chose SSTV mode!
+
+ Output is a file (by default named "img.h") which can be included and transmitted.
+ The resulting array will be very large (typically 320 kB),
+ make sure your platform has sufficient Flash/RAM space.
+ ''')
+ parser.add_argument('input',
+ type=str,
+ help='Input PNG file')
+ parser.add_argument('output',
+ type=str,
+ nargs='?',
+ default='img',
+ help='Output header file')
+ args = parser.parse_args()
+ outfile = f'{args.output}.h'
+ print(f'Converting "{args.input}" to "{outfile}"')
+
+ # open the image as numpy array
+ img = Image.open(args.input)
+ arr = np.array(img)
+
+ # open the output file
+ with open(outfile, 'w') as f:
+ print(f'const uint32_t img[{arr.shape[0]}][{arr.shape[1]}] = {{', file=f)
+ for row in arr:
+ print(' { ', end='', file=f)
+ for pix in row:
+ rgb = pix[0] << 16 | pix[1] << 8 | pix[2]
+ print(hex(rgb), end=', ', file=f)
+ print(' },', file=f)
+ print('};', file=f)
+
+ print('Done!')
+
+if __name__ == "__main__":
+ main()
diff --git a/extras/SSTV_Image_Converter/radiolib.png b/extras/SSTV_Image_Converter/radiolib.png
new file mode 100644
index 0000000000..6a20aa85eb
Binary files /dev/null and b/extras/SSTV_Image_Converter/radiolib.png differ
diff --git a/extras/SX126x_Spectrum_Scan/SpectrumScan.py b/extras/SX126x_Spectrum_Scan/SpectrumScan.py
new file mode 100644
index 0000000000..435a27a81d
--- /dev/null
+++ b/extras/SX126x_Spectrum_Scan/SpectrumScan.py
@@ -0,0 +1,176 @@
+#!/usr/bin/python3
+# -*- encoding: utf-8 -*-
+
+import argparse
+import serial
+import sys
+import numpy as np
+import matplotlib as mpl
+import matplotlib.pyplot as plt
+
+from datetime import datetime
+from argparse import RawTextHelpFormatter
+
+# number of samples in each scanline
+SCAN_WIDTH = 33
+
+# scanline Serial start/end markers
+SCAN_MARK_START = 'SCAN '
+SCAN_MARK_FREQ = 'FREQ '
+SCAN_MARK_END = ' END'
+
+# output path
+OUT_PATH = 'out'
+
+# default settings
+DEFAULT_BAUDRATE = 115200
+DEFAULT_COLOR_MAP = 'viridis'
+DEFAULT_SCAN_LEN = 200
+DEFAULT_RSSI_OFFSET = -11
+
+# Print iterations progress
+# from https://stackoverflow.com/questions/3173320/text-progress-bar-in-terminal-with-block-characters
+def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 1, length = 50, fill = 'â–ˆ', printEnd = "\r"):
+ """
+ Call in a loop to create terminal progress bar
+ @params:
+ iteration - Required : current iteration (Int)
+ total - Required : total iterations (Int)
+ prefix - Optional : prefix string (Str)
+ suffix - Optional : suffix string (Str)
+ decimals - Optional : positive number of decimals in percent complete (Int)
+ length - Optional : character length of bar (Int)
+ fill - Optional : bar fill character (Str)
+ printEnd - Optional : end character (e.g. "\r", "\r\n") (Str)
+ """
+ percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
+ filledLength = int(length * iteration // total)
+ bar = fill * filledLength + '-' * (length - filledLength)
+ print(f'\r{prefix} |{bar}| {percent}% {suffix}', end = printEnd)
+ if iteration == total:
+ print()
+
+
+def main():
+ parser = argparse.ArgumentParser(formatter_class=RawTextHelpFormatter, description='''
+ RadioLib SX126x_Spectrum_Scan plotter script. Displays output from SX126x_Spectrum_Scan example
+ as grayscale and
+
+ Depends on pyserial and matplotlib, install by:
+ 'python3 -m pip install pyserial matplotlib'
+
+ Step-by-step guide on how to use the script:
+ 1. Upload the SX126x_Spectrum_Scan example to your Arduino board with SX1262 connected.
+ 2. Run the script with appropriate arguments.
+ 3. Once the scan is complete, output files will be saved to out/
+ ''')
+ parser.add_argument('port',
+ type=str,
+ help='COM port to connect to the device')
+ parser.add_argument('--speed',
+ default=DEFAULT_BAUDRATE,
+ type=int,
+ help=f'COM port baudrate (defaults to {DEFAULT_BAUDRATE})')
+ parser.add_argument('--map',
+ default=DEFAULT_COLOR_MAP,
+ type=str,
+ help=f'Matplotlib color map to use for the output (defaults to "{DEFAULT_COLOR_MAP}")')
+ parser.add_argument('--len',
+ default=DEFAULT_SCAN_LEN,
+ type=int,
+ help=f'Number of scanlines to record (defaults to {DEFAULT_SCAN_LEN})')
+ parser.add_argument('--offset',
+ default=DEFAULT_RSSI_OFFSET,
+ type=int,
+ help=f'Default RSSI offset in dBm (defaults to {DEFAULT_RSSI_OFFSET})')
+ parser.add_argument('--freq',
+ default=-1,
+ type=float,
+ help=f'Default starting frequency in MHz')
+ args = parser.parse_args()
+
+ freq_mode = False
+ scan_len = args.len
+ if (args.freq != -1):
+ freq_mode = True
+ scan_len = 1000
+
+ # create the color map and the result array
+ arr = np.zeros((SCAN_WIDTH, scan_len))
+
+ # scanline counter
+ row = 0
+
+ # list of frequencies in frequency mode
+ freq_list = []
+
+ # open the COM port
+ with serial.Serial(args.port, args.speed, timeout=None) as com:
+ while(True):
+ # update the progress bar
+ if not freq_mode:
+ printProgressBar(row, scan_len)
+
+ # read a single line
+ try:
+ line = com.readline().decode('utf-8')
+ except:
+ continue
+
+ if SCAN_MARK_FREQ in line:
+ new_freq = float(line.split(' ')[1])
+ if (len(freq_list) > 1) and (new_freq < freq_list[-1]):
+ break
+
+ freq_list.append(new_freq)
+ print('{:.3f}'.format(new_freq), end = '\r')
+ continue
+
+ # check the markers
+ if (SCAN_MARK_START in line) and (SCAN_MARK_END in line):
+ # get the values
+ scanline = line[len(SCAN_MARK_START):-len(SCAN_MARK_END)].split(',')
+ for col in range(SCAN_WIDTH):
+ arr[col][row] = int(scanline[col])
+
+ # increment the row counter
+ row = row + 1
+
+ # check if we're done
+ if (not freq_mode) and (row >= scan_len):
+ break
+
+ # scale to the number of scans (sum of any given scanline)
+ num_samples = arr.sum(axis=0)[0]
+ arr *= (num_samples/arr.max())
+
+ if freq_mode:
+ scan_len = len(freq_list)
+
+ # create the figure
+ fig, ax = plt.subplots()
+
+ # display the result as heatmap
+ extent = [0, scan_len, -4*(SCAN_WIDTH + 1), args.offset]
+ if freq_mode:
+ extent[0] = freq_list[0]
+ extent[1] = freq_list[-1]
+ im = ax.imshow(arr[:,:scan_len], cmap=args.map, extent=extent)
+ fig.colorbar(im)
+
+ # set some properites and show
+ timestamp = datetime.now().strftime('%y-%m-%d %H-%M-%S')
+ title = f'RadioLib SX126x Spectral Scan {timestamp}'
+ if freq_mode:
+ plt.xlabel("Frequency [Hz]")
+ else:
+ plt.xlabel("Time [sample]")
+ plt.ylabel("RSSI [dBm]")
+ ax.set_aspect('auto')
+ fig.suptitle(title)
+ fig.canvas.manager.set_window_title(title)
+ plt.savefig(f'{OUT_PATH}/{title.replace(" ", "_")}.png', dpi=300)
+ plt.show()
+
+if __name__ == "__main__":
+ main()
diff --git a/extras/SX126x_Spectrum_Scan/out/.gitignore b/extras/SX126x_Spectrum_Scan/out/.gitignore
new file mode 100644
index 0000000000..9a219e8f1e
--- /dev/null
+++ b/extras/SX126x_Spectrum_Scan/out/.gitignore
@@ -0,0 +1,2 @@
+# all output pictures
+*.png
diff --git a/extras/bin/AiThinker_ESP8266_DIO_32M_32M_20160615_V1.5.4.bin b/extras/bin/AiThinker_ESP8266_DIO_32M_32M_20160615_V1.5.4.bin
deleted file mode 100644
index 792594c7ce..0000000000
Binary files a/extras/bin/AiThinker_ESP8266_DIO_32M_32M_20160615_V1.5.4.bin and /dev/null differ
diff --git a/extras/bin/AiThinker_ESP8266_DIO_8M_8M_20160615_V1.5.4.bin b/extras/bin/AiThinker_ESP8266_DIO_8M_8M_20160615_V1.5.4.bin
deleted file mode 100644
index ebfe5d9cd4..0000000000
Binary files a/extras/bin/AiThinker_ESP8266_DIO_8M_8M_20160615_V1.5.4.bin and /dev/null differ
diff --git a/extras/cppcheck/check_file.sh b/extras/cppcheck/check_file.sh
new file mode 100755
index 0000000000..45c32744c7
--- /dev/null
+++ b/extras/cppcheck/check_file.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+if [[ $# -lt 1 ]]; then
+ echo "Usage: $0 "
+ exit 1
+fi
+
+path=$1
+
+cppcheck --version
+cppcheck $path --enable=all \
+ --force \
+ --inline-suppr \
+ --suppress=ConfigurationNotChecked \
+ --suppress=unusedFunction \
+ --suppress=missingIncludeSystem \
+ --suppress=missingInclude \
+ --quiet
diff --git a/extras/cppcheck/cppcheck.sh b/extras/cppcheck/cppcheck.sh
new file mode 100755
index 0000000000..08e9a01e54
--- /dev/null
+++ b/extras/cppcheck/cppcheck.sh
@@ -0,0 +1,27 @@
+#! /bin/bash
+
+file=cppcheck.txt
+cppcheck --version
+cppcheck src --enable=all \
+ --force \
+ --inline-suppr \
+ --suppress=ConfigurationNotChecked \
+ --suppress=unusedFunction \
+ --suppress=missingIncludeSystem \
+ --suppress=missingInclude \
+ --quiet >> $file 2>&1
+echo "Cppcheck finished with exit code $?"
+
+error=$(grep ": error:" $file | wc -l)
+warning=$(grep ": warning:" $file | wc -l)
+style=$(grep ": style:" $file | wc -l)
+performance=$(grep ": performance:" $file | wc -l)
+echo "found $error erros, $warning warnings, $style style and $performance performance issues"
+if [ $error -gt "0" ] || [ $warning -gt "0" ] || [ $style -gt "0" ] || [ $performance -gt "0" ]
+then
+ cat $file
+ exitcode=1
+fi
+
+rm $file
+exit $exitcode
diff --git a/extras/decoder/DebugDecoder.py b/extras/decoder/DebugDecoder.py
deleted file mode 100644
index 330326f61f..0000000000
--- a/extras/decoder/DebugDecoder.py
+++ /dev/null
@@ -1,112 +0,0 @@
-import re, sys, argparse
-from pathlib import Path
-from argparse import RawTextHelpFormatter
-
-
-'''
-TODO list:
- 1. Parse macro values (the names of bits in all registers in header file)
- 2. Failed SPI write handling
- 3. SX126x/SX128x handling
- 4. AT handling
-'''
-
-
-def get_macro_name(value, macros):
- for macro in macros:
- if macro[1] == value:
- return macro[0]
- return 'UNKNOWN_VALUE'
-
-
-def get_macro_value(value):
- return ' 0x{0:02X}\n'.format(int(value, 16))
-
-
-parser = argparse.ArgumentParser(formatter_class=RawTextHelpFormatter, description='''
- RadioLib debug output decoder script. Turns RadioLib Serial dumps into readable text.
-
- Step-by-step guid on how to use the decoder:
- 1. Uncomment lines 312 (#define RADIOLIB_DEBUG) and 313 (#define RADIOLIB_VERBOSE) in RadioLib/src/BuildOpt.h
- 2. Recompile and upload the failing Arduino sketch
- 3. Open Arduino IDE Serial Monitor and enable timestamps
- 4. Copy the Serial output and save it into a .txt file
- 5. Run this script
-
- Output will be saved in the file specified by --out and printed to the terminal
-''')
-parser.add_argument('file', metavar='file', type=str, help='Text file of the debug output')
-parser.add_argument('--out', metavar='out', default='./out.txt', type=str, help='Where to save the decoded file (defaults to ./out.txt)')
-args = parser.parse_args()
-
-# open the log file
-log = open(args.file, 'r').readlines()
-
-# find modules that are in use
-used_modules = []
-pattern_module = re.compile('(([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?.[0-9]{3} -> )?M\t')
-for entry in log:
- m = pattern_module.search(entry)
- if m != None:
- used_modules.append(entry[m.end():].rstrip())
-
-# get paths to all relevant header files
-header_files = []
-for path in Path('../../src').rglob('*.h'):
- for module in used_modules:
- if module in path.name:
- header_files.append(path)
-
-# extract names of address macros from the header files
-macro_addresses = []
-pattern_define = re.compile('#define \w* +\w*(\n| +\/\/){1}')
-for path in header_files:
- file = open(path, 'r').readlines()
- for line in file:
- m = pattern_define.search(line)
- if m != None:
- s = re.split(' +', m.group().rstrip())
- if (s.__len__() > 1) and ('_REG' in s[1]):
- macro_addresses.append([s[1], int(s[2], 0)])
-
-'''
-# extract names of value macros for each adddress macro
-macro_values = []
-for path in header_files:
- file = open(path, 'r').readlines()
- for line in file:
- for module in used_modules:
- pattern_addr_macro = re.compile('\/\/ SI443X_REG_\w+'.format(module.capitalize()))
-'''
-
-# parse every line in the log file
-out = []
-pattern_debug = re.compile('(([01]?[0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?.[0-9]{3} -> )?[RWM]\t.+')
-for entry in log:
- m = pattern_debug.search(entry)
- if m != None:
- s = re.split('( |\t)+', entry.rstrip())
- cmd_len = int((s.__len__() - 7)/2)
- new_entry = s[0] + s[1] + s[2] + s[3]
- if s[4] == 'W':
- macro_address = int(s[6], 16)
- new_entry += 'write {0:>2} 0x{1:02X} {2}\n'.format(cmd_len, macro_address, get_macro_name(macro_address, macro_addresses))
- for i in range(cmd_len):
- new_entry += get_macro_value(s[8 + 2*i]);
- elif s[4] == 'R':
- macro_address = int(s[6], 16)
- new_entry += 'read {0:>2} 0x{1:02X} {2}\n'.format(cmd_len, macro_address, get_macro_name(macro_address, macro_addresses))
- for i in range(cmd_len):
- new_entry += get_macro_value(s[8 + 2*i]);
- elif s[4] == 'M':
- new_entry += 'module {}\n'.format(s[6])
- out.append(new_entry)
- else:
- out.append(entry)
-
-# write the output file
-out_file = open(args.out, 'w')
-for line in out:
- print(line, end='')
- out_file.write(line)
-out_file.close()
diff --git a/extras/template/ModuleTemplate.cpp b/extras/template/ModuleTemplate.cpp
index 07267305af..1efb1fc069 100644
--- a/extras/template/ModuleTemplate.cpp
+++ b/extras/template/ModuleTemplate.cpp
@@ -17,6 +17,6 @@ int16_t ::begin() {
/*
"begin" method SHOULD implement some sort of mechanism to verify the connection between Arduino and the module.
- For example, sending AT command for UART modules, or reading a version register for SPI/I2C modules
+ For example, reading a version register
*/
}
diff --git a/extras/template/ModuleTemplate.h b/extras/template/ModuleTemplate.h
index 4d957cb0ee..ee121942ff 100644
--- a/extras/template/ModuleTemplate.h
+++ b/extras/template/ModuleTemplate.h
@@ -13,7 +13,7 @@
*/
#if !defined(_RADIOLIB__H) && !defined(RADIOLIB_EXCLUDE_)
-#ifndef _RADIOLIB__H
+#if !defined(_RADIOLIB__H)
#define _RADIOLIB__H
/*
@@ -23,16 +23,6 @@
#include "../../Module.h"
#include "../../TypeDef.h"
-/*
- Only use the following include if the module implements methods for OSI transport layer control.
- This concerns only modules similar to e.g. ESP8266.
-
- In this case, your class MUST implement all virtual methods of TransportLayer class.
- You also MUST provide crystal oscillator frequency and frequency configuration divisor step resolution
- to the TransportLayer constructor.
-*/
-//#include "../../protocols/PhysicalLayer/TransportLayer.h"
-
/*
Only use the following include if the module implements methods for OSI physical layer control.
This concerns only modules similar to SX127x/RF69/CC1101 etc.
@@ -43,7 +33,7 @@
/*
Register map
- Definition of SPI/I2C register map SHOULD be placed here. The register map SHOULD have two parts:
+ Definition of SPI register map SHOULD be placed here. The register map SHOULD have two parts:
1 - Address map: only defines register names and addresses. Register names MUST match names in
official documentation (datasheets etc.).
@@ -52,11 +42,11 @@
See RF69 and SX127x header files for examples of register maps.
*/
-// register map | spaces up to this point
-#define _REG_ 0x00
+// register map | spaces up to this point
+#define RADIOLIB__REG_ 0x00
-// _REG_ MSB LSB DESCRIPTION
-#define _ 0b00000000 // 7 0
+// _REG_ MSB LSB DESCRIPTION
+#define RADIOLIB__ 0b00000000 // 7 0
/*
@@ -64,10 +54,8 @@
The module class MAY inherit from the following classes:
- 1 - ISerial: Interface for Arduino Serial class, intended as a thin wrapper for modules that directly take
- Serial input (e.g. HC-05).
- 2 - TransportLayer: In case the module implements methods for OSI transport layer control (e.g. ESP8266).
- 3 - PhysicalLayer: In case the module implements methods for OSI physical layer control (e.g. SX127x).
+ 1 - PhysicalLayer: In case the module implements methods for OSI physical layer control (e.g. SX127x).
+ 2 - Common class: In case the module further specifies some more generic class (e.g. SX127x/SX1278)
*/
class