├── lib ├── RadioLib │ ├── CODE_OF_CONDUCT.md │ ├── extras │ │ ├── test │ │ │ └── SX126x │ │ │ │ ├── clean.sh │ │ │ │ ├── build.sh │ │ │ │ ├── main.cpp │ │ │ │ └── CMakeLists.txt │ │ └── template │ │ │ └── ModuleTemplate.cpp │ ├── examples │ │ ├── NonArduino │ │ │ ├── Raspberry │ │ │ │ ├── clean.sh │ │ │ │ ├── build.sh │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── main.cpp │ │ │ └── ESP-IDF │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── main │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── idf_component.yml │ │ │ │ └── main.cpp │ │ ├── STM32WLx │ │ │ ├── STM32WLx_Channel_Activity_Detection │ │ │ │ └── STM32WLx_Channel_Activity_Detection.ino │ │ │ └── STM32WLx_Channel_Activity_Detection_Interrupt │ │ │ │ └── STM32WLx_Channel_Activity_Detection_Interrupt.ino │ │ ├── SX128x │ │ │ ├── SX128x_Channel_Activity_Detection_Blocking │ │ │ │ └── SX128x_Channel_Activity_Detection_Blocking.ino │ │ │ ├── SX128x_Ranging │ │ │ │ └── SX128x_Ranging.ino │ │ │ ├── SX128x_Transmit_Blocking │ │ │ │ └── SX128x_Transmit_Blocking.ino │ │ │ └── SX128x_Receive_Blocking │ │ │ │ └── SX128x_Receive_Blocking.ino │ │ ├── SX127x │ │ │ ├── SX127x_Channel_Activity_Detection_Blocking │ │ │ │ └── SX127x_Channel_Activity_Detection_Blocking.ino │ │ │ ├── SX127x_Receive_Direct │ │ │ │ └── SX127x_Receive_Direct.ino │ │ │ ├── SX127x_Transmit_Blocking │ │ │ │ └── SX127x_Transmit_Blocking.ino │ │ │ └── SX127x_Receive_Blocking │ │ │ │ └── SX127x_Receive_Blocking.ino │ │ ├── SX1231 │ │ │ ├── SX1231_Transmit │ │ │ │ └── SX1231_Transmit.ino │ │ │ └── SX1231_Receive │ │ │ │ └── SX1231_Receive.ino │ │ ├── SX126x │ │ │ ├── SX126x_Channel_Activity_Detection_Blocking │ │ │ │ └── SX126x_Channel_Activity_Detection_Blocking.ino │ │ │ └── SX126x_Transmit_Blocking │ │ │ │ └── SX126x_Transmit_Blocking.ino │ │ ├── CC1101 │ │ │ ├── CC1101_Transmit_Blocking │ │ │ │ └── CC1101_Transmit_Blocking.ino │ │ │ └── CC1101_Receive_Blocking │ │ │ │ └── CC1101_Receive_Blocking.ino │ │ ├── AFSK │ │ │ ├── AFSK_Tone │ │ │ │ └── AFSK_Tone.ino │ │ │ ├── AFSK_External_Radio │ │ │ │ └── AFSK_External_Radio.ino │ │ │ ├── AFSK_Tone_AM │ │ │ │ └── AFSK_Tone_AM.ino │ │ │ └── AFSK_Imperial_March │ │ │ │ └── AFSK_Imperial_March.ino │ │ ├── RF69 │ │ │ ├── RF69_Transmit_AES │ │ │ │ └── RF69_Transmit_AES.ino │ │ │ ├── RF69_Receive_AES │ │ │ │ └── RF69_Receive_AES.ino │ │ │ ├── RF69_Receive_Blocking │ │ │ │ └── RF69_Receive_Blocking.ino │ │ │ └── RF69_Transmit_Blocking │ │ │ │ └── RF69_Transmit_Blocking.ino │ │ ├── Si443x │ │ │ ├── Si443x_Receive_Blocking │ │ │ │ └── Si443x_Receive_Blocking.ino │ │ │ └── Si443x_Transmit_Blocking │ │ │ │ └── Si443x_Transmit_Blocking.ino │ │ ├── AX25 │ │ │ └── AX25_Transmit │ │ │ │ └── AX25_Transmit.ino │ │ ├── Pager │ │ │ └── Pager_Transmit │ │ │ │ └── Pager_Transmit.ino │ │ ├── nRF24 │ │ │ ├── nRF24_Transmit_Blocking │ │ │ │ └── nRF24_Transmit_Blocking.ino │ │ │ └── nRF24_Receive_Blocking │ │ │ │ └── nRF24_Receive_Blocking.ino │ │ ├── BellModem │ │ │ └── BellModem_Transmit │ │ │ │ └── BellModem_Transmit.ino │ │ ├── Morse │ │ │ ├── Morse_Receive_AM │ │ │ │ └── Morse_Receive_AM.ino │ │ │ └── Morse_Transmit_SSB │ │ │ │ └── Morse_Transmit_SSB.ino │ │ └── Hellschreiber │ │ │ └── Hellschreiber_Transmit │ │ │ └── Hellschreiber_Transmit.ino │ ├── src │ │ ├── modules │ │ │ ├── SX128x │ │ │ │ ├── SX1281.cpp │ │ │ │ ├── SX1282.cpp │ │ │ │ ├── SX1281.h │ │ │ │ ├── SX1282.h │ │ │ │ └── SX1280.h │ │ │ ├── RFM2x │ │ │ │ ├── RFM22.h │ │ │ │ └── RFM23.h │ │ │ ├── SX126x │ │ │ │ ├── SX1261.cpp │ │ │ │ ├── SX1261.h │ │ │ │ ├── STM32WLx_Module.h │ │ │ │ ├── SX1268.cpp │ │ │ │ └── SX1262.cpp │ │ │ ├── Si443x │ │ │ │ ├── Si4431.cpp │ │ │ │ ├── Si4430.cpp │ │ │ │ ├── Si4432.cpp │ │ │ │ ├── Si4431.h │ │ │ │ ├── Si4430.h │ │ │ │ └── Si4432.h │ │ │ ├── RFM9x │ │ │ │ ├── RFM97.cpp │ │ │ │ ├── RFM97.h │ │ │ │ ├── RFM95.cpp │ │ │ │ └── RFM96.cpp │ │ │ ├── LLCC68 │ │ │ │ ├── LLCC68.cpp │ │ │ │ └── LLCC68.h │ │ │ ├── SX127x │ │ │ │ ├── SX1273.cpp │ │ │ │ ├── SX1276.cpp │ │ │ │ ├── SX1279.cpp │ │ │ │ ├── SX1273.h │ │ │ │ └── SX1277.cpp │ │ │ └── SX1231 │ │ │ │ └── SX1231.cpp │ │ ├── BuildOptUser.h │ │ ├── protocols │ │ │ ├── ExternalRadio │ │ │ │ ├── ExternalRadio.cpp │ │ │ │ └── ExternalRadio.h │ │ │ ├── AFSK │ │ │ │ ├── AFSK.cpp │ │ │ │ └── AFSK.h │ │ │ ├── Print │ │ │ │ ├── Print.h │ │ │ │ ├── ITA2String.h │ │ │ │ └── ITA2String.cpp │ │ │ ├── RTTY │ │ │ │ ├── RTTY.h │ │ │ │ └── RTTY.cpp │ │ │ ├── BellModem │ │ │ │ └── BellModem.cpp │ │ │ ├── Hellschreiber │ │ │ │ └── Hellschreiber.cpp │ │ │ └── FSK4 │ │ │ │ └── FSK4.h │ │ ├── utils │ │ │ ├── CRC.cpp │ │ │ ├── CRC.h │ │ │ └── FEC.h │ │ ├── Hal.cpp │ │ └── ArduinoHal.h │ ├── SECURITY.md │ ├── library.properties │ ├── library.json │ ├── license.txt │ └── CMakeLists.txt └── README ├── .gitignore ├── src ├── coredump.h ├── patterns.h ├── unicon.hpp ├── BCH3121A.h ├── customfont.h ├── BCH3121.hpp ├── coredump.cpp ├── sdlog.hpp └── BCH3121.md ├── test └── README ├── platformio.ini └── include └── README /lib/RadioLib/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | Don't be an a*shole. 4 | -------------------------------------------------------------------------------- /lib/RadioLib/extras/test/SX126x/clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -rf ./build 4 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/NonArduino/Raspberry/clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -rf ./build 4 | -------------------------------------------------------------------------------- /lib/RadioLib/extras/test/SX126x/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | mkdir -p build 5 | cd build 6 | cmake -G "CodeBlocks - Unix Makefiles" .. 7 | make -j4 8 | cd .. 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | logs 3 | .vscode 4 | .idea 5 | /COREDUMP*.bin 6 | /coredump.txt 7 | /readcd_bin.bat 8 | /readcd_bin.ps1 9 | /readcd_txt.bat 10 | .clang-format 11 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/NonArduino/Raspberry/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | mkdir -p build 5 | cd build 6 | cmake -G "CodeBlocks - Unix Makefiles" .. 7 | make 8 | cd .. 9 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/SX128x/SX1281.cpp: -------------------------------------------------------------------------------- 1 | #include "SX1281.h" 2 | #if !defined(RADIOLIB_EXCLUDE_SX128X) 3 | 4 | SX1281::SX1281(Module* mod) : SX128x(mod) { 5 | 6 | } 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/SX128x/SX1282.cpp: -------------------------------------------------------------------------------- 1 | #include "SX1282.h" 2 | #if !defined(RADIOLIB_EXCLUDE_SX128X) 3 | 4 | /// \todo implement advanced ranging 5 | SX1282::SX1282(Module* mod) : SX1280(mod) { 6 | 7 | } 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/NonArduino/ESP-IDF/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | 3 | # include the top-level cmake 4 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 5 | 6 | # name the project something nice 7 | project(esp-sx1261) 8 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/NonArduino/ESP-IDF/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # register the component and set "RadioLib", "esp_timer" and "driver" as required 2 | idf_component_register(SRCS "main.cpp" 3 | INCLUDE_DIRS "." 4 | REQUIRES RadioLib esp_timer driver) 5 | -------------------------------------------------------------------------------- /lib/RadioLib/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | RadioLib is provided as-is without any warranty, and is not intended to be used in security-critical applications. However, if you discover a vulnerability within the library code, please report it to gromes.jan@gmail.com. 6 | -------------------------------------------------------------------------------- /src/coredump.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by FLN1021 on 2023/10/31. 3 | // 4 | 5 | #ifndef PAGER_RECEIVE_COREDUMP_H 6 | #define PAGER_RECEIVE_COREDUMP_H 7 | 8 | #include "networks.hpp" 9 | #include 10 | #include "sdlog.hpp" 11 | 12 | extern bool have_cd; 13 | 14 | void readCoreDump(); 15 | 16 | #endif //PAGER_RECEIVE_COREDUMP_H 17 | -------------------------------------------------------------------------------- /lib/RadioLib/src/BuildOptUser.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_USER_BUILD_OPTIONS_H) 2 | #define _RADIOLIB_USER_BUILD_OPTIONS_H 3 | 4 | // this file can be used to define any user build options 5 | // most commonly, RADIOLIB_EXCLUDE_* macros 6 | // or enabling debug output 7 | 8 | //#define RADIOLIB_DEBUG 9 | //#define RADIOLIB_VERBOSE 10 | //#define RADIOLIB_GODMODE 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/NonArduino/ESP-IDF/main/idf_component.yml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | RadioLib: 3 | # referenced locally because the example is a part of the repository itself 4 | # under normal circumstances, it's preferrable to reference the repository instead 5 | # for other options, see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html 6 | path: ../../../../../RadioLib 7 | #git: https://github.com/jgromes/RadioLib.git 8 | -------------------------------------------------------------------------------- /lib/RadioLib/library.properties: -------------------------------------------------------------------------------- 1 | name=RadioLib 2 | version=6.1.0 3 | author=Jan Gromes 4 | maintainer=Jan Gromes 5 | sentence=Universal wireless communication library 6 | paragraph=User-friendly library for sub-GHz radio modules (SX1278, RF69, CC1101, SX1268, and many others), as well as ham radio digital modes (RTTY, SSTV, AX.25 etc.). 7 | category=Communication 8 | url=https://github.com/jgromes/RadioLib 9 | architectures=* 10 | includes=RadioLib.h 11 | -------------------------------------------------------------------------------- /lib/RadioLib/src/protocols/ExternalRadio/ExternalRadio.cpp: -------------------------------------------------------------------------------- 1 | #include "ExternalRadio.h" 2 | 3 | #if defined(RADIOLIB_BUILD_ARDUINO) 4 | ExternalRadio::ExternalRadio() : PhysicalLayer(1, 0) { 5 | mod = new Module(RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC); 6 | } 7 | #endif 8 | 9 | ExternalRadio::ExternalRadio(RadioLibHal *hal) : PhysicalLayer(1, 0) { 10 | mod = new Module(hal, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC); 11 | } 12 | 13 | Module* ExternalRadio::getMod() { 14 | return(mod); 15 | } -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/RFM2x/RFM22.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_RFM22_H) 2 | #define _RADIOLIB_RFM22_H 3 | 4 | #include "../../TypeDef.h" 5 | 6 | #if !defined(RADIOLIB_EXCLUDE_RFM2X) 7 | 8 | #include "../../Module.h" 9 | #include "../Si443x/Si443x.h" 10 | #include "../Si443x/Si4432.h" 11 | 12 | /*! 13 | \class RFM22 14 | \brief Only exists as alias for Si4432, since there seems to be no difference between %RFM22 and %Si4432 modules. 15 | */ 16 | RADIOLIB_TYPE_ALIAS(Si4432, RFM22); 17 | 18 | #endif 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/RFM2x/RFM23.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_RFM23_H) 2 | #define _RADIOLIB_RFM23_H 3 | 4 | #include "../../TypeDef.h" 5 | 6 | #if !defined(RADIOLIB_EXCLUDE_RFM2X) 7 | 8 | #include "../../Module.h" 9 | #include "../Si443x/Si443x.h" 10 | #include "../Si443x/Si4431.h" 11 | 12 | /*! 13 | \class RFM23 14 | \brief Only exists as alias for Si4431, since there seems to be no difference between %RFM23 and %Si4431 modules. 15 | */ 16 | RADIOLIB_TYPE_ALIAS(Si4431, RFM23); 17 | 18 | #endif 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/patterns.h: -------------------------------------------------------------------------------- 1 | #ifndef PATTERNS_H 2 | #define PATTERNS_H 3 | 4 | static unsigned char bitmap_test[] = { 5 | 0xff, 0xff, 6 | 0xff, 0xff, 7 | 0xff, 0xff, 8 | 0xff, 0xff, 9 | 0xff, 0xff, 10 | 0xff, 0xff, 11 | 0xff, 0xff, 12 | 0xff, 0xff, 13 | 0xff, 0xff, 14 | 0xff, 0xff, 15 | 0xff, 0xff, 16 | 0xff, 0xff, 17 | 0xff, 0xff, 18 | 0xff, 0xff, 19 | 0xff, 0xff, 20 | 0xff, 0xff, 21 | }; 22 | 23 | 24 | #endif // PATTERNS_H -------------------------------------------------------------------------------- /test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Test Runner and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/en/latest/advanced/unit-testing/index.html 12 | -------------------------------------------------------------------------------- /lib/RadioLib/src/protocols/ExternalRadio/ExternalRadio.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_EXTERNAL_RADIO_H) 2 | #define _RADIOLIB_EXTERNAL_RADIO_H 3 | 4 | #include "../../TypeDef.h" 5 | #include "../../Module.h" 6 | #if defined(RADIOLIB_BUILD_ARDUINO) 7 | #include "../../ArduinoHal.h" 8 | #endif 9 | 10 | #include "../PhysicalLayer/PhysicalLayer.h" 11 | 12 | class ExternalRadio: public PhysicalLayer { 13 | public: 14 | #if defined(RADIOLIB_BUILD_ARDUINO) 15 | ExternalRadio(); 16 | #endif 17 | ExternalRadio(RadioLibHal *hal); 18 | 19 | Module* getMod(); 20 | private: 21 | Module* mod; 22 | }; 23 | 24 | #endif -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/SX128x/SX1281.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_SX1281_H) 2 | #define _RADIOLIB_SX1281_H 3 | 4 | #include "../../TypeDef.h" 5 | 6 | #if !defined(RADIOLIB_EXCLUDE_SX128X) 7 | 8 | #include "../../Module.h" 9 | #include "SX128x.h" 10 | 11 | /*! 12 | \class SX1281 13 | \brief Derived class for %SX1281 modules. 14 | */ 15 | class SX1281: public SX128x { 16 | public: 17 | /*! 18 | \brief Default constructor. 19 | \param mod Instance of Module that will be used to communicate with the radio. 20 | */ 21 | SX1281(Module* mod); 22 | 23 | #if !defined(RADIOLIB_GODMODE) 24 | private: 25 | #endif 26 | 27 | }; 28 | 29 | #endif 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /lib/RadioLib/extras/template/ModuleTemplate.cpp: -------------------------------------------------------------------------------- 1 | #include ".h" 2 | #if !defined(RADIOLIB_EXCLUDE_) 3 | 4 | ::(Module* mod) { 5 | /* 6 | Constructor implementation MUST assign the provided "mod" pointer to the private "_mod" pointer. 7 | */ 8 | _mod = mod; 9 | } 10 | 11 | int16_t ::begin() { 12 | /* 13 | "begin" method implementation MUST call the "init" method with appropriate settings. 14 | */ 15 | _mod->init(); 16 | 17 | /* 18 | "begin" method SHOULD implement some sort of mechanism to verify the connection between Arduino and the module. 19 | 20 | For example, reading a version register 21 | */ 22 | } 23 | -------------------------------------------------------------------------------- /src/unicon.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by FLN1021 on 2023/9/4. 3 | // 4 | 5 | #ifndef ESP32_TEST_UNICON_H 6 | #define ESP32_TEST_UNICON_H 7 | 8 | #include 9 | typedef unsigned int UINT; /* int must be 16-bit or 32-bit */ 10 | typedef unsigned char BYTE; /* char must be 8-bit */ 11 | typedef uint16_t WORD; /* 16-bit unsigned integer */ 12 | typedef uint16_t WCHAR; /* 16-bit unsigned integer */ 13 | typedef uint32_t DWORD; /* 32-bit unsigned integer */ 14 | typedef uint64_t QWORD; /* 64-bit unsigned integer */ 15 | #define MERGE2(a, b) a ## b 16 | #define CVTBL(tbl, cp) MERGE2(tbl, cp) 17 | #define FF_CODE_PAGE 936 18 | WCHAR ff_oem2uni (WCHAR oem, WORD cp); 19 | 20 | #endif //ESP32_TEST_UNICON_H 21 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/SX128x/SX1282.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_SX1282_H) 2 | #define _RADIOLIB_SX1282_H 3 | 4 | #include "../../TypeDef.h" 5 | 6 | #if !defined(RADIOLIB_EXCLUDE_SX128X) 7 | 8 | #include "../../Module.h" 9 | #include "SX128x.h" 10 | #include "SX1280.h" 11 | 12 | /*! 13 | \class SX1282 14 | \brief Derived class for %SX1282 modules. 15 | */ 16 | class SX1282: public SX1280 { 17 | public: 18 | /*! 19 | \brief Default constructor. 20 | \param mod Instance of Module that will be used to communicate with the radio. 21 | */ 22 | SX1282(Module* mod); 23 | 24 | #if !defined(RADIOLIB_GODMODE) 25 | private: 26 | #endif 27 | 28 | }; 29 | 30 | #endif 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /lib/RadioLib/extras/test/SX126x/main.cpp: -------------------------------------------------------------------------------- 1 | // this is an autotest file for the SX126x 2 | // runs on Raspberry Pi with Waveshare LoRaWAN hat 3 | 4 | #include 5 | #include "PiHal.h" 6 | 7 | #define RADIOLIB_TEST_ASSERT(STATEVAR) { if((STATEVAR) != RADIOLIB_ERR_NONE) { return(-1*(STATEVAR)); } } 8 | 9 | PiHal* hal = new PiHal(1); 10 | SX1261 radio = new Module(hal, 7, 17, 22, RADIOLIB_NC); 11 | 12 | // the entry point for the program 13 | int main(int argc, char** argv) { 14 | int state = RADIOLIB_ERR_UNKNOWN; 15 | 16 | state = radio.begin(); 17 | printf("[SX1261] Test:begin() = %d\n", state); 18 | RADIOLIB_TEST_ASSERT(state); 19 | 20 | state = radio.transmit("Hello World!"); 21 | printf("[SX1261] Test:transmit() = %d\n", state); 22 | RADIOLIB_TEST_ASSERT(state); 23 | 24 | hal->term(); 25 | return(0); 26 | } 27 | -------------------------------------------------------------------------------- /src/BCH3121A.h: -------------------------------------------------------------------------------- 1 | // 2 | // Multimon-NG POCSAG BCH(31,21) Correction Functions. 3 | // From https://github.com/EliasOenal/multimon-ng/blob/master/pocsag.c 4 | // Migrated by FLN1021 on 2023/9/1. 5 | // 6 | 7 | #ifndef PAGER_RECEIVE_BCH3121A_H 8 | #define PAGER_RECEIVE_BCH3121A_H 9 | 10 | #include "string.h" 11 | 12 | /* 13 | * the code used by POCSAG is a (n=31,k=21) BCH Code with dmin=5, 14 | * thus it could correct two bit errors in a 31-Bit codeword. 15 | * It is a systematic code. 16 | * The generator polynomial is: 17 | * g(x) = x^10+x^9+x^8+x^6+x^5+x^3+1 18 | * The parity check polynomial is: 19 | * h(x) = x^21+x^20+x^18+x^16+x^14+x^13+x^12+x^11+x^8+x^5+x^3+1 20 | * g(x) * h(x) = x^n+1 21 | */ 22 | #define BCH_POLY 03551 /* octal */ 23 | #define BCH_N 31 24 | #define BCH_K 21 25 | 26 | 27 | #endif //PAGER_RECEIVE_BCH3121A_H 28 | -------------------------------------------------------------------------------- /lib/RadioLib/extras/test/SX126x/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.18) 2 | 3 | # create the project 4 | project(rpi-sx1261) 5 | 6 | # when using debuggers such as gdb, the following line can be used 7 | #set(CMAKE_BUILD_TYPE Debug) 8 | 9 | # if you did not build RadioLib as shared library (see README), 10 | # you will have to add it as source directory 11 | # the following is just an example, yours will likely be different 12 | #add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../../../RadioLib" "${CMAKE_CURRENT_BINARY_DIR}/RadioLib") 13 | 14 | # add the executable 15 | add_executable(${PROJECT_NAME} main.cpp) 16 | 17 | # link both libraries 18 | target_link_libraries(${PROJECT_NAME} RadioLib pigpio) 19 | 20 | # you can also specify RadioLib compile-time flags here 21 | #target_compile_definitions(${PROJECT_NAME} PUBLIC RADIOLIB_DEBUG RADIOLIB_VERBOSE) 22 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/NonArduino/Raspberry/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.18) 2 | 3 | # create the project 4 | project(rpi-sx1261) 5 | 6 | # when using debuggers such as gdb, the following line can be used 7 | #set(CMAKE_BUILD_TYPE Debug) 8 | 9 | # if you did not build RadioLib as shared library (see wiki), 10 | # you will have to add it as source directory 11 | # the following is just an example, yours will likely be different 12 | add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../../../RadioLib" "${CMAKE_CURRENT_BINARY_DIR}/RadioLib") 13 | 14 | # add the executable 15 | add_executable(${PROJECT_NAME} main.cpp) 16 | 17 | # link both libraries 18 | target_link_libraries(${PROJECT_NAME} RadioLib pigpio) 19 | 20 | # you can also specify RadioLib compile-time flags here 21 | #target_compile_definitions(${PROJECT_NAME} PUBLIC RADIOLIB_DEBUG RADIOLIB_VERBOSE) 22 | -------------------------------------------------------------------------------- /lib/RadioLib/src/utils/CRC.cpp: -------------------------------------------------------------------------------- 1 | #include "CRC.h" 2 | 3 | RadioLibCRC::RadioLibCRC() { 4 | 5 | } 6 | 7 | uint32_t RadioLibCRC::checksum(uint8_t* buff, size_t len) { 8 | uint32_t crc = this->init; 9 | size_t pos = 0; 10 | for(size_t i = 0; i < 8*len; i++) { 11 | if(i % 8 == 0) { 12 | uint32_t in = buff[pos++]; 13 | if(this->refIn) { 14 | in = Module::reflect(in, 8); 15 | } 16 | crc ^= (in << (this->size - 8)); 17 | } 18 | 19 | if(crc & ((uint32_t)1 << (this->size - 1))) { 20 | crc <<= (uint32_t)1; 21 | crc ^= this->poly; 22 | } else { 23 | crc <<= (uint32_t)1; 24 | } 25 | } 26 | 27 | crc ^= this->out; 28 | if(this->refOut) { 29 | crc = Module::reflect(crc, this->size); 30 | } 31 | crc &= (uint32_t)0xFFFFFFFF >> (32 - this->size); 32 | return(crc); 33 | } 34 | 35 | RadioLibCRC RadioLibCRCInstance; 36 | -------------------------------------------------------------------------------- /lib/RadioLib/src/Hal.cpp: -------------------------------------------------------------------------------- 1 | #include "Hal.h" 2 | 3 | RadioLibHal::RadioLibHal(const uint32_t input, const uint32_t output, const uint32_t low, const uint32_t high, const uint32_t rising, const uint32_t falling) 4 | : GpioModeInput(input), 5 | GpioModeOutput(output), 6 | GpioLevelLow(low), 7 | GpioLevelHigh(high), 8 | GpioInterruptRising(rising), 9 | GpioInterruptFalling(falling) {} 10 | 11 | void RadioLibHal::init() { 12 | 13 | } 14 | 15 | void RadioLibHal::term() { 16 | 17 | } 18 | 19 | void RadioLibHal::tone(uint32_t pin, unsigned int frequency, unsigned long duration) { 20 | (void)pin; 21 | (void)frequency; 22 | (void)duration; 23 | } 24 | 25 | void RadioLibHal::noTone(uint32_t pin) { 26 | (void)pin; 27 | } 28 | 29 | void RadioLibHal::yield() { 30 | 31 | } 32 | 33 | uint32_t RadioLibHal::pinToInterrupt(uint32_t pin) { 34 | return(pin); 35 | } 36 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/SX126x/SX1261.cpp: -------------------------------------------------------------------------------- 1 | #include "SX1261.h" 2 | #if !defined(RADIOLIB_EXCLUDE_SX126X) 3 | 4 | SX1261::SX1261(Module* mod): SX1262(mod) { 5 | chipType = RADIOLIB_SX1261_CHIP_TYPE; 6 | } 7 | 8 | int16_t SX1261::setOutputPower(int8_t power) { 9 | RADIOLIB_CHECK_RANGE(power, -17, 14, RADIOLIB_ERR_INVALID_OUTPUT_POWER); 10 | 11 | // get current OCP configuration 12 | uint8_t ocp = 0; 13 | int16_t state = readRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1); 14 | RADIOLIB_ASSERT(state); 15 | 16 | // set PA config 17 | state = SX126x::setPaConfig(0x04, RADIOLIB_SX126X_PA_CONFIG_SX1261, 0x00); 18 | RADIOLIB_ASSERT(state); 19 | 20 | // set output power 21 | /// \todo power ramp time configuration 22 | state = SX126x::setTxParams(power); 23 | RADIOLIB_ASSERT(state); 24 | 25 | // restore OCP configuration 26 | return(writeRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1)); 27 | } 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/Si443x/Si4431.cpp: -------------------------------------------------------------------------------- 1 | #include "Si4431.h" 2 | #if !defined(RADIOLIB_EXCLUDE_SI443X) 3 | 4 | Si4431::Si4431(Module* mod) : Si4432(mod) { 5 | 6 | } 7 | 8 | int16_t Si4431::begin(float freq, float br, float freqDev, float rxBw, int8_t power, uint8_t preambleLen) { 9 | // execute common part 10 | int16_t state = Si443x::begin(br, freqDev, rxBw, preambleLen); 11 | RADIOLIB_ASSERT(state); 12 | RADIOLIB_DEBUG_PRINTLN("M\tSi4431"); 13 | 14 | // configure publicly accessible settings 15 | state = setFrequency(freq); 16 | RADIOLIB_ASSERT(state); 17 | 18 | state = setOutputPower(power); 19 | RADIOLIB_ASSERT(state); 20 | 21 | return(state); 22 | } 23 | 24 | int16_t Si4431::setOutputPower(int8_t power) { 25 | RADIOLIB_CHECK_RANGE(power, -8, 13, RADIOLIB_ERR_INVALID_OUTPUT_POWER); 26 | 27 | // set output power 28 | return(this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_TX_POWER, (uint8_t)((power + 8) / 3), 2, 0)); 29 | } 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /lib/RadioLib/src/protocols/AFSK/AFSK.cpp: -------------------------------------------------------------------------------- 1 | #include "AFSK.h" 2 | #if !defined(RADIOLIB_EXCLUDE_AFSK) 3 | 4 | AFSKClient::AFSKClient(PhysicalLayer* phy, uint32_t pin): outPin(pin) { 5 | phyLayer = phy; 6 | } 7 | 8 | AFSKClient::AFSKClient(AFSKClient* aud) { 9 | phyLayer = aud->phyLayer; 10 | outPin = aud->outPin; 11 | } 12 | 13 | int16_t AFSKClient::begin() { 14 | return(phyLayer->startDirect()); 15 | } 16 | 17 | int16_t AFSKClient::tone(uint16_t freq, bool autoStart) { 18 | if(freq == 0) { 19 | return(RADIOLIB_ERR_INVALID_FREQUENCY); 20 | } 21 | 22 | if(autoStart) { 23 | int16_t state = phyLayer->transmitDirect(); 24 | RADIOLIB_ASSERT(state); 25 | } 26 | 27 | Module* mod = phyLayer->getMod(); 28 | mod->hal->tone(outPin, freq); 29 | return(RADIOLIB_ERR_NONE); 30 | } 31 | 32 | int16_t AFSKClient::noTone(bool keepOn) { 33 | Module* mod = phyLayer->getMod(); 34 | mod->hal->noTone(outPin); 35 | if(keepOn) { 36 | return(0); 37 | } 38 | 39 | return(phyLayer->standby()); 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /lib/RadioLib/library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RadioLib", 3 | "version": "6.1.0", 4 | "description": "Universal wireless communication library. User-friendly library for sub-GHz radio modules (SX1278, RF69, CC1101, SX1268, and many others), as well as ham radio digital modes (RTTY, SSTV, AX.25 etc.).", 5 | "keywords": "radio, communication, morse, cc1101, aprs, sx1276, sx1278, sx1272, rtty, ax25, afsk, nrf24, rfm96, sx1231, rfm96, rfm98, sstv, sx1278, sx1272, sx1276, sx1280, sx1281, sx1282, sx1261, sx1262, sx1268, si4432, rfm22, llcc68, pager, pocsag", 6 | "homepage": "https://github.com/jgromes/RadioLib", 7 | "repository": 8 | { 9 | "type": "git", 10 | "url": "https://github.com/jgromes/RadioLib.git" 11 | }, 12 | "authors": 13 | { 14 | "name": "Jan Gromeš", 15 | "email": "gromes.jan@gmail.com", 16 | "maintainer": true 17 | }, 18 | "license": "MIT", 19 | "frameworks": "*", 20 | "platforms": "*", 21 | "headers": "RadioLib.h", 22 | "build": 23 | { 24 | "libLDFMode": "chain+" 25 | } 26 | } -------------------------------------------------------------------------------- /lib/RadioLib/license.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Jan Gromeš 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:esp32dev] 12 | platform = espressif32 13 | board = esp32dev 14 | framework = arduino 15 | monitor_filters = 16 | esp32_exception_decoder 17 | time 18 | ;send_on_enter 19 | ;colorize 20 | ;log2file 21 | monitor_speed = 115200 22 | monitor_encoding = UTF-8 23 | upload_speed = 1024000 24 | build_flags = -DLILYGO_T3_V1_6 25 | ; -DCORE_DEBUG_LEVEL=6 26 | ; -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG 27 | board_build.partitions = huge_app.csv 28 | lib_deps = 29 | lennarthennigs/ESP Telnet @ ^2.1.2 30 | olikraus/U8g2@^2.35.4 31 | madhephaestus/ESP32AnalogRead@^0.2.1 32 | adafruit/RTClib@^2.1.3 33 | ;knolleary/PubSubClient@^2.8 34 | ;northernwidget/DS3231@^1.1.2 35 | ;paulstoffregen/Time @ ^1.6.1 36 | -------------------------------------------------------------------------------- /src/customfont.h: -------------------------------------------------------------------------------- 1 | #ifndef _MYFONT_H 2 | #define _MYFONT_H 3 | 4 | #include 5 | #include 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #ifndef U8G2_USE_LARGE_FONTS 12 | #define U8G2_USE_LARGE_FONTS 13 | #endif 14 | 15 | #ifndef U8X8_FONT_SECTION 16 | 17 | #ifdef __GNUC__ 18 | # define U8X8_SECTION(name) __attribute__ ((section (name))) 19 | #else 20 | # define U8X8_SECTION(name) 21 | #endif 22 | 23 | #if defined(__GNUC__) && defined(__AVR__) 24 | # define U8X8_FONT_SECTION(name) U8X8_SECTION(".progmem." name) 25 | #endif 26 | 27 | #if defined(ESP8266) 28 | # define U8X8_FONT_SECTION(name) __attribute__((section(".text." name))) 29 | #endif 30 | 31 | #ifndef U8X8_FONT_SECTION 32 | # define U8X8_FONT_SECTION(name) 33 | #endif 34 | 35 | #endif 36 | 37 | #ifndef U8G2_FONT_SECTION 38 | #define U8G2_FONT_SECTION(name) U8X8_FONT_SECTION(name) 39 | #endif 40 | 41 | extern const uint8_t u8g2_font_wqy15_t_custom[] U8G2_FONT_SECTION("u8g2_font_wqy15_t_custom"); 42 | extern const uint8_t u8g2_font_profont12_custom_tf[] U8G2_FONT_SECTION("u8g2_font_profont12_custom_tf"); 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | 48 | #endif -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/RFM9x/RFM97.cpp: -------------------------------------------------------------------------------- 1 | #include "RFM97.h" 2 | #if !defined(RADIOLIB_EXCLUDE_RFM9X) 3 | 4 | RFM97::RFM97(Module* mod) : RFM95(mod) { 5 | 6 | }; 7 | 8 | int16_t RFM97::setSpreadingFactor(uint8_t sf) { 9 | // check active modem 10 | if(getActiveModem() != RADIOLIB_SX127X_LORA) { 11 | return(RADIOLIB_ERR_WRONG_MODEM); 12 | } 13 | 14 | uint8_t newSpreadingFactor; 15 | 16 | // check allowed spreading factor values 17 | switch(sf) { 18 | case 6: 19 | newSpreadingFactor = RADIOLIB_SX127X_SF_6; 20 | break; 21 | case 7: 22 | newSpreadingFactor = RADIOLIB_SX127X_SF_7; 23 | break; 24 | case 8: 25 | newSpreadingFactor = RADIOLIB_SX127X_SF_8; 26 | break; 27 | case 9: 28 | newSpreadingFactor = RADIOLIB_SX127X_SF_9; 29 | break; 30 | default: 31 | return(RADIOLIB_ERR_INVALID_SPREADING_FACTOR); 32 | } 33 | 34 | // set spreading factor and if successful, save the new setting 35 | int16_t state = SX1278::setSpreadingFactorRaw(newSpreadingFactor); 36 | if(state == RADIOLIB_ERR_NONE) { 37 | SX127x::spreadingFactor = sf; 38 | } 39 | return(state); 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/Si443x/Si4430.cpp: -------------------------------------------------------------------------------- 1 | #include "Si4430.h" 2 | #if !defined(RADIOLIB_EXCLUDE_SI443X) 3 | 4 | Si4430::Si4430(Module* mod) : Si4432(mod) { 5 | 6 | } 7 | 8 | int16_t Si4430::begin(float freq, float br, float freqDev, float rxBw, int8_t power, uint8_t preambleLen) { 9 | // execute common part 10 | int16_t state = Si443x::begin(br, freqDev, rxBw, preambleLen); 11 | RADIOLIB_ASSERT(state); 12 | RADIOLIB_DEBUG_PRINTLN("M\tSi4430"); 13 | 14 | // configure publicly accessible settings 15 | state = setFrequency(freq); 16 | RADIOLIB_ASSERT(state); 17 | 18 | state = setOutputPower(power); 19 | RADIOLIB_ASSERT(state); 20 | 21 | return(state); 22 | } 23 | 24 | int16_t Si4430::setFrequency(float freq) { 25 | RADIOLIB_CHECK_RANGE(freq, 900.0, 960.0, RADIOLIB_ERR_INVALID_FREQUENCY); 26 | 27 | // set frequency 28 | return(Si443x::setFrequencyRaw(freq)); 29 | } 30 | 31 | int16_t Si4430::setOutputPower(int8_t power) { 32 | RADIOLIB_CHECK_RANGE(power, -8, 13, RADIOLIB_ERR_INVALID_OUTPUT_POWER); 33 | 34 | // set output power 35 | return(this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_TX_POWER, (uint8_t)((power + 8) / 3), 2, 0)); 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/Si443x/Si4432.cpp: -------------------------------------------------------------------------------- 1 | #include "Si4432.h" 2 | #if !defined(RADIOLIB_EXCLUDE_SI443X) 3 | 4 | Si4432::Si4432(Module* mod) : Si443x(mod) { 5 | 6 | } 7 | 8 | int16_t Si4432::begin(float freq, float br, float freqDev, float rxBw, int8_t power, uint8_t preambleLen) { 9 | // execute common part 10 | int16_t state = Si443x::begin(br, freqDev, rxBw, preambleLen); 11 | RADIOLIB_ASSERT(state); 12 | RADIOLIB_DEBUG_PRINTLN("M\tSi4432"); 13 | 14 | // configure publicly accessible settings 15 | state = setFrequency(freq); 16 | RADIOLIB_ASSERT(state); 17 | 18 | state = setOutputPower(power); 19 | RADIOLIB_ASSERT(state); 20 | 21 | return(state); 22 | } 23 | 24 | int16_t Si4432::setFrequency(float freq) { 25 | RADIOLIB_CHECK_RANGE(freq, 240.0, 930.0, RADIOLIB_ERR_INVALID_FREQUENCY); 26 | 27 | // set frequency 28 | return(Si443x::setFrequencyRaw(freq)); 29 | } 30 | 31 | int16_t Si4432::setOutputPower(int8_t power) { 32 | RADIOLIB_CHECK_RANGE(power, -1, 20, RADIOLIB_ERR_INVALID_OUTPUT_POWER); 33 | 34 | // set output power 35 | return(this->mod->SPIsetRegValue(RADIOLIB_SI443X_REG_TX_POWER, (uint8_t)((power + 1) / 3), 2, 0)); 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/SX126x/SX1261.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_SX1261_H) 2 | #define _RADIOLIB_SX1261_H 3 | 4 | #include "../../TypeDef.h" 5 | 6 | #if !defined(RADIOLIB_EXCLUDE_SX126X) 7 | 8 | #include "../../Module.h" 9 | #include "SX126x.h" 10 | #include "SX1262.h" 11 | 12 | //RADIOLIB_SX126X_CMD_SET_PA_CONFIG 13 | #define RADIOLIB_SX126X_PA_CONFIG_SX1261 0x01 14 | 15 | //RADIOLIB_SX126X_REG_VERSION_STRING 16 | #define RADIOLIB_SX1261_CHIP_TYPE "SX1261" 17 | 18 | /*! 19 | \class SX1261 20 | \brief Derived class for %SX1261 modules. 21 | */ 22 | class SX1261 : public SX1262 { 23 | public: 24 | /*! 25 | \brief Default constructor. 26 | \param mod Instance of Module that will be used to communicate with the radio. 27 | */ 28 | SX1261(Module* mod); 29 | 30 | /*! 31 | \brief Sets output power. Allowed values are in range from -17 to 14 dBm. 32 | \param power Output power to be set in dBm. 33 | \returns \ref status_codes 34 | */ 35 | int16_t setOutputPower(int8_t power); 36 | 37 | #if !defined(RADIOLIB_GODMODE) 38 | private: 39 | #endif 40 | 41 | }; 42 | 43 | #endif 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/SX126x/STM32WLx_Module.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright (c) 2022 STMicroelectronics 4 | 5 | This file is licensed under the MIT License: https://opensource.org/licenses/MIT 6 | */ 7 | 8 | #if !defined(_RADIOLIB_STM32WLX_MODULE_H) 9 | #define _RADIOLIB_STM32WLX_MODULE_H 10 | 11 | #include "../../TypeDef.h" 12 | 13 | #if !defined(RADIOLIB_EXCLUDE_STM32WLX) 14 | 15 | #include "../../Module.h" 16 | 17 | /*! 18 | * \class STM32WLx_Module 19 | * 20 | * This is a subclass of Module to be used with the STM32WLx driver. 21 | * 22 | * It is used to override some callbacks, allowing access to some of the 23 | * radio control signals that are wired to internal registers instead of 24 | * actual GPIO pins. 25 | */ 26 | class STM32WLx_Module : public Module { 27 | // Note: We cannot easily override any methods here, since most calls 28 | // are non-virtual and made through a Module*, so they would not be 29 | // calling any overridden methods. This means this class works by 30 | // overriding some of the callbacks in its constructor. 31 | 32 | public: 33 | STM32WLx_Module(); 34 | }; 35 | 36 | #endif // !defined(RADIOLIB_EXCLUDE_STM32WLX) 37 | 38 | #endif // _RADIOLIB_STM32WLX_MODULE_H 39 | -------------------------------------------------------------------------------- /lib/RadioLib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | 3 | if(ESP_PLATFORM) 4 | # Build RadioLib as an ESP-IDF component 5 | # required because ESP-IDF runs cmake in script mode 6 | # and needs idf_component_register() 7 | file(GLOB_RECURSE RADIOLIB_ESP_SOURCES 8 | "src/*.*" 9 | ) 10 | 11 | idf_component_register( 12 | SRCS ${RADIOLIB_ESP_SOURCES} 13 | INCLUDE_DIRS . src 14 | ) 15 | 16 | return() 17 | endif() 18 | 19 | if(CMAKE_SCRIPT_MODE_FILE) 20 | message(FATAL_ERROR "Attempted to build RadioLib in script mode") 21 | endif() 22 | 23 | project(radiolib) 24 | 25 | file(GLOB_RECURSE RADIOLIB_SOURCES 26 | "src/*.cpp" 27 | ) 28 | 29 | add_library(RadioLib ${RADIOLIB_SOURCES}) 30 | 31 | target_include_directories(RadioLib 32 | PUBLIC $ 33 | $) 34 | 35 | include(GNUInstallDirs) 36 | 37 | install(TARGETS RadioLib 38 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 39 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 40 | ) 41 | 42 | install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/ 43 | DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/RadioLib 44 | FILES_MATCHING PATTERN "*.h" 45 | ) 46 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/RFM9x/RFM97.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_RFM97_H) 2 | #define _RADIOLIB_RFM97_H 3 | 4 | #include "../../TypeDef.h" 5 | 6 | #if !defined(RADIOLIB_EXCLUDE_RFM9X) 7 | 8 | #include "../../Module.h" 9 | #include "../SX127x/SX127x.h" 10 | #include "../SX127x/SX1278.h" 11 | #include "RFM95.h" 12 | 13 | /*! 14 | \class RFM97 15 | \brief Derived class for %RFM97 modules. Overrides some methods from RFM95 due to different parameter ranges. 16 | */ 17 | class RFM97: public RFM95 { 18 | public: 19 | 20 | // constructor 21 | 22 | /*! 23 | \brief Default constructor. Called from Arduino sketch when creating new LoRa instance. 24 | \param mod Instance of Module that will be used to communicate with the %LoRa chip. 25 | */ 26 | RFM97(Module* mod); 27 | 28 | // configuration methods 29 | 30 | /*! 31 | \brief Sets %LoRa link spreading factor. Allowed values range from 6 to 9. Only available in %LoRa mode. 32 | \param sf %LoRa link spreading factor to be set. 33 | \returns \ref status_codes 34 | */ 35 | int16_t setSpreadingFactor(uint8_t sf); 36 | 37 | #if !defined(RADIOLIB_GODMODE) 38 | private: 39 | #endif 40 | 41 | }; 42 | 43 | #endif 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /src/BCH3121.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 by Andy Uribe CA6JAU 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 2 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 | */ 18 | 19 | #if !defined(BCH3121_H) 20 | #define BCH3121_H 21 | 22 | class CBCH3121 { 23 | public: 24 | CBCH3121(); 25 | 26 | void encode(uint32_t &data); 27 | 28 | bool decode(uint32_t &data, uint16_t &errors, bool &parity); 29 | 30 | private: 31 | void calc_syndrome(uint32_t data); 32 | 33 | static bool calc_parity(uint32_t data); 34 | 35 | static uint16_t check_parity(uint32_t &data); 36 | 37 | int8_t m_S1; 38 | int8_t m_S3; 39 | 40 | }; 41 | 42 | #endif -------------------------------------------------------------------------------- /include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /lib/RadioLib/src/utils/CRC.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_CRC_H) 2 | #define _RADIOLIB_CRC_H 3 | 4 | #include "../TypeDef.h" 5 | #include "../Module.h" 6 | #if defined(RADIOLIB_BUILD_ARDUINO) 7 | #include "../ArduinoHal.h" 8 | #endif 9 | 10 | // CCITT CRC properties (used by AX.25) 11 | #define RADIOLIB_CRC_CCITT_POLY (0x1021) 12 | #define RADIOLIB_CRC_CCITT_INIT (0xFFFF) 13 | #define RADIOLIB_CRC_CCITT_OUT (0xFFFF) 14 | 15 | /*! 16 | \class RadioLibCRC 17 | \brief Class to calculate CRCs of varying formats. 18 | */ 19 | class RadioLibCRC { 20 | public: 21 | /*! 22 | \brief CRC size in bits. 23 | */ 24 | uint8_t size; 25 | 26 | /*! 27 | \brief CRC polynomial. 28 | */ 29 | uint32_t poly; 30 | 31 | /*! 32 | \brief Initial value. 33 | */ 34 | uint32_t init; 35 | 36 | /*! 37 | \brief Final XOR value. 38 | */ 39 | uint32_t out; 40 | 41 | /*! 42 | \brief Whether to reflect input bytes. 43 | */ 44 | bool refIn; 45 | 46 | /*! 47 | \brief Whether to reflect the result. 48 | */ 49 | bool refOut; 50 | 51 | /*! 52 | \brief Default constructor. 53 | */ 54 | RadioLibCRC(); 55 | 56 | /*! 57 | \brief Calcualte checksum of a buffer. 58 | \param buff Buffer to calculate the checksum over. 59 | \param len Size of the buffer in bytes. 60 | \returns The resulting checksum. 61 | */ 62 | uint32_t checksum(uint8_t* buff, size_t len); 63 | }; 64 | 65 | // the global singleton 66 | extern RadioLibCRC RadioLibCRCInstance; 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/SX128x/SX1280.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_SX1280_H) 2 | #define _RADIOLIB_SX1280_H 3 | 4 | #include "../../TypeDef.h" 5 | 6 | #if !defined(RADIOLIB_EXCLUDE_SX128X) 7 | 8 | #include "../../Module.h" 9 | #include "SX128x.h" 10 | #include "SX1281.h" 11 | 12 | /*! 13 | \class SX1280 14 | \brief Derived class for %SX1280 modules. 15 | */ 16 | class SX1280: public SX1281 { 17 | public: 18 | /*! 19 | \brief Default constructor. 20 | \param mod Instance of Module that will be used to communicate with the radio. 21 | */ 22 | SX1280(Module* mod); 23 | 24 | /*! 25 | \brief Blocking ranging method. 26 | \param master Whether to execute ranging in master mode (true) or slave mode (false). 27 | \param addr Ranging address to be used. 28 | \param calTable Ranging calibration table - set to NULL to use the default. 29 | \returns \ref status_codes 30 | */ 31 | int16_t range(bool master, uint32_t addr, uint16_t calTable[3][6] = NULL); 32 | 33 | /*! 34 | \brief Interrupt-driven ranging method. 35 | \param master Whether to execute ranging in master mode (true) or slave mode (false). 36 | \param addr Ranging address to be used. 37 | \param calTable Ranging calibration table - set to NULL to use the default. 38 | \returns \ref status_codes 39 | */ 40 | int16_t startRanging(bool master, uint32_t addr, uint16_t calTable[3][6] = NULL); 41 | 42 | /*! 43 | \brief Gets ranging result of the last ranging exchange. 44 | \returns Ranging result in meters. 45 | */ 46 | float getRangingResult(); 47 | 48 | #if !defined(RADIOLIB_GODMODE) 49 | private: 50 | #endif 51 | 52 | }; 53 | 54 | #endif 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/LLCC68/LLCC68.cpp: -------------------------------------------------------------------------------- 1 | #include "LLCC68.h" 2 | #if !defined(RADIOLIB_EXCLUDE_SX126X) 3 | 4 | LLCC68::LLCC68(Module* mod) : SX1262(mod) { 5 | chipType = RADIOLIB_LLCC68_CHIP_TYPE; 6 | } 7 | 8 | int16_t LLCC68::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t pwr, uint16_t preambleLength, float tcxoVoltage, bool useRegulatorLDO) { 9 | // execute common part 10 | int16_t state = SX126x::begin(cr, syncWord, preambleLength, tcxoVoltage, useRegulatorLDO); 11 | RADIOLIB_ASSERT(state); 12 | 13 | // configure publicly accessible settings 14 | state = setFrequency(freq); 15 | RADIOLIB_ASSERT(state); 16 | 17 | state = setBandwidth(bw); 18 | RADIOLIB_ASSERT(state); 19 | 20 | state = setSpreadingFactor(sf); 21 | RADIOLIB_ASSERT(state); 22 | 23 | state = setOutputPower(pwr); 24 | RADIOLIB_ASSERT(state); 25 | 26 | state = SX126x::fixPaClamping(); 27 | RADIOLIB_ASSERT(state); 28 | 29 | return(state); 30 | } 31 | 32 | int16_t LLCC68::setBandwidth(float bw) { 33 | RADIOLIB_CHECK_RANGE(bw, 100.0, 510.0, RADIOLIB_ERR_INVALID_BANDWIDTH); 34 | return(SX1262::setBandwidth(bw)); 35 | } 36 | 37 | int16_t LLCC68::setSpreadingFactor(uint8_t sf) { 38 | switch(SX126x::bandwidth) { 39 | case RADIOLIB_SX126X_LORA_BW_125_0: 40 | RADIOLIB_CHECK_RANGE(sf, 5, 9, RADIOLIB_ERR_INVALID_SPREADING_FACTOR); 41 | break; 42 | case RADIOLIB_SX126X_LORA_BW_250_0: 43 | RADIOLIB_CHECK_RANGE(sf, 5, 10, RADIOLIB_ERR_INVALID_SPREADING_FACTOR); 44 | break; 45 | case RADIOLIB_SX126X_LORA_BW_500_0: 46 | RADIOLIB_CHECK_RANGE(sf, 5, 11, RADIOLIB_ERR_INVALID_SPREADING_FACTOR); 47 | break; 48 | default: 49 | return(RADIOLIB_ERR_INVALID_SPREADING_FACTOR); 50 | } 51 | 52 | return(SX1262::setSpreadingFactor(sf)); 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /lib/RadioLib/src/utils/FEC.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_FEC_H) 2 | #define _RADIOLIB_FEC_H 3 | 4 | #include "../TypeDef.h" 5 | #include "../Module.h" 6 | #if defined(RADIOLIB_BUILD_ARDUINO) 7 | #include "../ArduinoHal.h" 8 | #endif 9 | 10 | // BCH(31, 21) code constants 11 | #define RADIOLIB_PAGER_BCH_N (31) 12 | #define RADIOLIB_PAGER_BCH_K (21) 13 | #define RADIOLIB_PAGER_BCH_PRIMITIVE_POLY (0x25) 14 | 15 | /*! 16 | \class RadioLibBCH 17 | \brief Class to calculate Bose–Chaudhuri–Hocquenghem (BCH) class of forward error correction codes. 18 | In theory, this should be able to calculate an arbitrary BCH(N, K) code, 19 | but so far it was only tested for BCH(31, 21). 20 | */ 21 | class RadioLibBCH { 22 | public: 23 | /*! 24 | \brief Default constructor. 25 | */ 26 | RadioLibBCH(); 27 | 28 | /*! 29 | \brief Initialization method. 30 | \param n Code word length in bits, up to 32. 31 | \param k Data portion length in bits, up to "n". 32 | \param poly Powers of the irreducible polynomial. 33 | */ 34 | void begin(uint8_t n, uint8_t k, uint32_t poly); 35 | 36 | /*! 37 | \brief Encoding method - encodes one data word (without check bits) into a code word (with check bits). 38 | \param dataword Data word without check bits. The caller is responsible to make sure the data is 39 | on the correct bit positions! 40 | \returns Code word with error check bits. 41 | */ 42 | uint32_t encode(uint32_t dataword); 43 | 44 | private: 45 | uint8_t n; 46 | uint8_t k; 47 | uint32_t poly; 48 | uint8_t m; 49 | int32_t* alphaTo; 50 | int32_t* indexOf; 51 | int32_t* generator; 52 | }; 53 | 54 | // the global singleton 55 | extern RadioLibBCH RadioLibBCHInstance; 56 | 57 | #endif -------------------------------------------------------------------------------- /lib/RadioLib/examples/STM32WLx/STM32WLx_Channel_Activity_Detection/STM32WLx_Channel_Activity_Detection.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib STM32WLx Channel Activity Detection Example 3 | 4 | This example uses STM32WLx to scan the current LoRa 5 | channel and detect ongoing LoRa transmissions. 6 | Unlike SX127x CAD, SX126x/STM32WLx can detect any part 7 | of LoRa transmission, not just the preamble. 8 | 9 | For default module settings, see the wiki page 10 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem 11 | 12 | For full API reference, see the GitHub Pages 13 | https://jgromes.github.io/RadioLib/ 14 | */ 15 | 16 | // include the library 17 | #include 18 | 19 | // no need to configure pins, signals are routed to the radio internally 20 | STM32WLx radio = new STM32WLx_Module(); 21 | 22 | 23 | void setup() { 24 | Serial.begin(9600); 25 | 26 | // initialize STM32WLx with default settings 27 | Serial.print(F("[STM32WLx] Initializing ... ")); 28 | int state = radio.begin(868.0); 29 | if (state == RADIOLIB_ERR_NONE) { 30 | Serial.println(F("success!")); 31 | } else { 32 | Serial.print(F("failed, code ")); 33 | Serial.println(state); 34 | while (true); 35 | } 36 | } 37 | 38 | void loop() { 39 | Serial.print(F("[STM32WLx] Scanning channel for LoRa transmission ... ")); 40 | 41 | // start scanning current channel 42 | int state = radio.scanChannel(); 43 | 44 | if (state == RADIOLIB_LORA_DETECTED) { 45 | // LoRa preamble was detected 46 | Serial.println(F("detected!")); 47 | 48 | } else if (state == RADIOLIB_CHANNEL_FREE) { 49 | // no preamble was detected, channel is free 50 | Serial.println(F("channel is free!")); 51 | 52 | } else { 53 | // some other error occurred 54 | Serial.print(F("failed, code ")); 55 | Serial.println(state); 56 | 57 | } 58 | 59 | // wait 100 ms before new scan 60 | delay(100); 61 | } 62 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/SX127x/SX1273.cpp: -------------------------------------------------------------------------------- 1 | #include "SX1273.h" 2 | #if !defined(RADIOLIB_EXCLUDE_SX127X) 3 | 4 | SX1273::SX1273(Module* mod) : SX1272(mod) { 5 | 6 | } 7 | 8 | int16_t SX1273::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, uint8_t gain) { 9 | // execute common part 10 | int16_t state = SX127x::begin(RADIOLIB_SX1272_CHIP_VERSION, syncWord, preambleLength); 11 | RADIOLIB_ASSERT(state); 12 | 13 | // configure publicly accessible settings 14 | state = setBandwidth(bw); 15 | RADIOLIB_ASSERT(state); 16 | 17 | state = setFrequency(freq); 18 | RADIOLIB_ASSERT(state); 19 | 20 | state = setSpreadingFactor(sf); 21 | RADIOLIB_ASSERT(state); 22 | 23 | state = setCodingRate(cr); 24 | RADIOLIB_ASSERT(state); 25 | 26 | state = setOutputPower(power); 27 | RADIOLIB_ASSERT(state); 28 | 29 | state = setGain(gain); 30 | RADIOLIB_ASSERT(state); 31 | 32 | // set publicly accessible settings that are not a part of begin method 33 | state = setCRC(true); 34 | RADIOLIB_ASSERT(state); 35 | 36 | return(state); 37 | } 38 | 39 | int16_t SX1273::setSpreadingFactor(uint8_t sf) { 40 | uint8_t newSpreadingFactor; 41 | 42 | // check allowed spreading factor values 43 | switch(sf) { 44 | case 6: 45 | newSpreadingFactor = RADIOLIB_SX127X_SF_6; 46 | break; 47 | case 7: 48 | newSpreadingFactor = RADIOLIB_SX127X_SF_7; 49 | break; 50 | case 8: 51 | newSpreadingFactor = RADIOLIB_SX127X_SF_8; 52 | break; 53 | case 9: 54 | newSpreadingFactor = RADIOLIB_SX127X_SF_9; 55 | break; 56 | default: 57 | return(RADIOLIB_ERR_INVALID_SPREADING_FACTOR); 58 | } 59 | 60 | // set spreading factor and if successful, save the new setting 61 | int16_t state = setSpreadingFactorRaw(newSpreadingFactor); 62 | if(state == RADIOLIB_ERR_NONE) { 63 | SX127x::spreadingFactor = sf; 64 | } 65 | 66 | return(state); 67 | } 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/NonArduino/Raspberry/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib Non-Arduino Raspberry Pi Example 3 | 4 | This example shows how to use RadioLib without Arduino. 5 | In this case, a Raspberry Pi with WaveShare SX1302 LoRaWAN Hat 6 | using the pigpio library. 7 | 8 | Can be used as a starting point to port RadioLib to any platform! 9 | See this API reference page for details on the RadioLib hardware abstraction 10 | https://jgromes.github.io/RadioLib/class_hal.html 11 | 12 | For full API reference, see the GitHub Pages 13 | https://jgromes.github.io/RadioLib/ 14 | */ 15 | 16 | // include the library 17 | #include 18 | 19 | // include the hardware abstraction layer 20 | #include "PiHal.h" 21 | 22 | // create a new instance of the HAL class 23 | // use SPI channel 1, because on Waveshare LoRaWAN Hat, 24 | // the SX1261 CS is connected to CE1 25 | PiHal* hal = new PiHal(1); 26 | 27 | // now we can create the radio module 28 | // pinout corresponds to the Waveshare LoRaWAN Hat 29 | // NSS pin: 7 30 | // DIO1 pin: 17 31 | // NRST pin: 22 32 | // BUSY pin: not connected 33 | SX1261 radio = new Module(hal, 7, 17, 22, RADIOLIB_NC); 34 | 35 | // the entry point for the program 36 | int main(int argc, char** argv) { 37 | // initialize just like with Arduino 38 | printf("[SX1261] Initializing ... "); 39 | int state = radio.begin(); 40 | if (state != RADIOLIB_ERR_NONE) { 41 | printf("failed, code %d\n", state); 42 | return(1); 43 | } 44 | printf("success!\n"); 45 | 46 | // loop forever 47 | for(;;) { 48 | // send a packet 49 | printf("[SX1261] Transmitting packet ... "); 50 | state = radio.transmit("Hello World!"); 51 | if(state == RADIOLIB_ERR_NONE) { 52 | // the packet was successfully transmitted 53 | printf("success!\n"); 54 | 55 | // wait for a second before transmitting again 56 | hal->delay(1000); 57 | 58 | } else { 59 | printf("failed, code %d\n", state); 60 | 61 | } 62 | 63 | } 64 | 65 | return(0); 66 | } 67 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/NonArduino/ESP-IDF/main/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib Non-Arduino ESP-IDF Example 3 | 4 | This example shows how to use RadioLib without Arduino. 5 | In this case, a Liligo T-BEAM (ESP32 and SX1276) 6 | is used. 7 | 8 | Can be used as a starting point to port RadioLib to any platform! 9 | See this API reference page for details on the RadioLib hardware abstraction 10 | https://jgromes.github.io/RadioLib/class_hal.html 11 | 12 | For full API reference, see the GitHub Pages 13 | https://jgromes.github.io/RadioLib/ 14 | */ 15 | 16 | // include the library 17 | #include 18 | 19 | // include the hardware abstraction layer 20 | #include "EspHal.h" 21 | 22 | // create a new instance of the HAL class 23 | EspHal* hal = new EspHal(5, 19, 27); 24 | 25 | // now we can create the radio module 26 | // NSS pin: 18 27 | // DIO0 pin: 26 28 | // NRST pin: 14 29 | // DIO1 pin: 33 30 | SX1276 radio = new Module(hal, 18, 26, 14, 33); 31 | 32 | static const char *TAG = "main"; 33 | 34 | // the entry point for the program 35 | // it must be declared as "extern C" because the compiler assumes this will be a C function 36 | extern "C" void app_main(void) { 37 | // initialize just like with Arduino 38 | ESP_LOGI(TAG, "[SX1276] Initializing ... "); 39 | int state = radio.begin(); 40 | if (state != RADIOLIB_ERR_NONE) { 41 | ESP_LOGI(TAG, "failed, code %d\n", state); 42 | while(true) { 43 | hal->delay(1000); 44 | } 45 | } 46 | ESP_LOGI(TAG, "success!\n"); 47 | 48 | // loop forever 49 | for(;;) { 50 | // send a packet 51 | ESP_LOGI(TAG, "[SX1276] Transmitting packet ... "); 52 | state = radio.transmit("Hello World!"); 53 | if(state == RADIOLIB_ERR_NONE) { 54 | // the packet was successfully transmitted 55 | ESP_LOGI(TAG, "success!"); 56 | 57 | } else { 58 | ESP_LOGI(TAG, "failed, code %d\n", state); 59 | 60 | } 61 | 62 | // wait for a second before transmitting again 63 | hal->delay(1000); 64 | 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/Si443x/Si4431.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_SI4431_H) 2 | #define _RADIOLIB_SI4431_H 3 | 4 | #include "../../TypeDef.h" 5 | 6 | #if !defined(RADIOLIB_EXCLUDE_SI443X) 7 | 8 | #include "../../Module.h" 9 | #include "Si4432.h" 10 | 11 | /*! 12 | \class Si4431 13 | \brief Derived class for %Si4431 modules. 14 | */ 15 | class Si4431: public Si4432 { 16 | public: 17 | 18 | // constructor 19 | 20 | /*! 21 | \brief Default constructor. 22 | \param mod Instance of Module that will be used to communicate with the radio chip. 23 | */ 24 | Si4431(Module* mod); 25 | 26 | // basic methods 27 | 28 | /*! 29 | \brief Initialization method. Must be called at least once from Arduino sketch to initialize the module. 30 | \param freq Carrier frequency in MHz. Allowed values range from 240.0 MHz to 930.0 MHz. 31 | \param br Bit rate of the FSK transmission in kbps (kilobits per second). Allowed values range from 0.123 to 256.0 kbps. 32 | \param freqDev Frequency deviation of the FSK transmission in kHz. Allowed values range from 0.625 to 320.0 kbps. 33 | \param rxBw Receiver bandwidth in kHz. Allowed values range from 2.6 to 620.7 kHz. 34 | \param power Transmission output power in dBm. Allowed values range from -8 to 13 dBm in 3 dBm steps. 35 | \param preambleLen Preamble Length in bits. Defaults to 16 bits. 36 | \returns \ref status_codes 37 | */ 38 | int16_t begin(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 181.1, int8_t power = 10, uint8_t preambleLen = 16); 39 | 40 | // configuration methods 41 | 42 | /*! 43 | \brief Sets output power. Allowed values range from -8 to 13 dBm in 3 dBm steps. 44 | \param power Output power to be set in dBm. 45 | \returns \ref status_codes 46 | */ 47 | int16_t setOutputPower(int8_t power); 48 | 49 | #if !defined(RADIOLIB_GODMODE) 50 | protected: 51 | #endif 52 | 53 | #if !defined(RADIOLIB_GODMODE) 54 | private: 55 | #endif 56 | }; 57 | 58 | #endif 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /lib/RadioLib/src/protocols/AFSK/AFSK.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_AFSK_H) 2 | #define _RADIOLIB_AFSK_H 3 | 4 | #include "../../TypeDef.h" 5 | 6 | #if !defined(RADIOLIB_EXCLUDE_AFSK) 7 | 8 | #include "../../Module.h" 9 | 10 | #include "../PhysicalLayer/PhysicalLayer.h" 11 | 12 | /*! 13 | \class AFSKClient 14 | \brief Client for audio-based transmissions. Requires Arduino tone() function, and a module capable of direct mode transmission using DIO pins. 15 | */ 16 | class AFSKClient { 17 | public: 18 | /*! 19 | \brief Default contructor. 20 | \param phy Pointer to the wireless module providing PhysicalLayer communication. 21 | \param pin The pin that will be used for audio output. 22 | */ 23 | AFSKClient(PhysicalLayer* phy, uint32_t pin); 24 | 25 | /*! 26 | \brief Copy contructor. 27 | \param aud Pointer to the AFSKClient instance to copy. 28 | */ 29 | AFSKClient(AFSKClient* aud); 30 | 31 | /*! 32 | \brief Initialization method. 33 | \returns \ref status_codes 34 | */ 35 | int16_t begin(); 36 | 37 | /*! 38 | \brief Start transmitting audio tone. 39 | \param freq Frequency of the tone in Hz. 40 | \param autoStart Whether to automatically enter transmission mode. Defaults to true. 41 | \returns \ref status_codes 42 | */ 43 | int16_t tone(uint16_t freq, bool autoStart = true); 44 | 45 | /*! 46 | \brief Stops transmitting audio tone. 47 | \param freq Keep transmitter on - this may limit noise when switching transmitter on or off. 48 | \returns \ref status_codes 49 | */ 50 | int16_t noTone(bool keepOn = false); 51 | 52 | #if !defined(RADIOLIB_GODMODE) 53 | private: 54 | #endif 55 | PhysicalLayer* phyLayer; 56 | uint32_t outPin; 57 | 58 | // allow specific classes access the private PhysicalLayer pointer 59 | friend class RTTYClient; 60 | friend class MorseClient; 61 | friend class HellClient; 62 | friend class SSTVClient; 63 | friend class AX25Client; 64 | friend class FSK4Client; 65 | friend class BellClient; 66 | }; 67 | 68 | #endif 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /lib/RadioLib/src/protocols/Print/Print.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_PRINT_H) 2 | #define _RADIOLIB_PRINT_H 3 | 4 | #include 5 | 6 | #include "ITA2String.h" 7 | 8 | // supported encoding schemes 9 | #define RADIOLIB_ASCII 0 10 | #define RADIOLIB_ASCII_EXTENDED 1 11 | #define RADIOLIB_ITA2 2 12 | 13 | // based on Arduino Print class 14 | class RadioLibPrint { 15 | public: 16 | virtual size_t write(uint8_t) = 0; 17 | size_t write(const char *str) { 18 | if (str == NULL) return 0; 19 | return write((const uint8_t *)str, strlen(str)); 20 | } 21 | virtual size_t write(const uint8_t *buffer, size_t size); 22 | size_t write(const char *buffer, size_t size) { 23 | return write((const uint8_t *)buffer, size); 24 | } 25 | 26 | size_t print(ITA2String& ita2); 27 | size_t println(ITA2String& ita2); 28 | 29 | #if defined(RADIOLIB_BUILD_ARDUINO) 30 | size_t print(const __FlashStringHelper *); 31 | size_t print(const String &); 32 | 33 | size_t println(const __FlashStringHelper *); 34 | size_t println(const String &); 35 | #endif 36 | 37 | size_t print(const char[]); 38 | size_t print(char); 39 | size_t print(unsigned char, int = DEC); 40 | size_t print(int, int = DEC); 41 | size_t print(unsigned int, int = DEC); 42 | size_t print(long, int = DEC); 43 | size_t print(unsigned long, int = DEC); 44 | size_t print(double, int = 2); 45 | 46 | size_t println(const char[]); 47 | size_t println(char); 48 | size_t println(unsigned char, int = DEC); 49 | size_t println(int, int = DEC); 50 | size_t println(unsigned int, int = DEC); 51 | size_t println(long, int = DEC); 52 | size_t println(unsigned long, int = DEC); 53 | size_t println(double, int = 2); 54 | size_t println(void); 55 | 56 | #if !defined(RADIOLIB_GODMODE) 57 | protected: 58 | #endif 59 | uint8_t encoding = RADIOLIB_ASCII_EXTENDED; 60 | const char* lineFeed; 61 | 62 | size_t printNumber(unsigned long, uint8_t); 63 | size_t printFloat(double, uint8_t); 64 | 65 | }; 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/SX128x/SX128x_Channel_Activity_Detection_Blocking/SX128x_Channel_Activity_Detection_Blocking.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib SX128x Blocking Channel Activity Detection Example 3 | 4 | This example uses SX1280 to scan the current LoRa 5 | channel and detect ongoing LoRa transmissions. 6 | 7 | Other modules from SX128x family can also be used. 8 | 9 | Using blocking CAD is not recommended, as it will lead 10 | to significant amount of timeouts, inefficient use of processor 11 | time and can some miss packets! 12 | Instead, interrupt CAD is recommended. 13 | 14 | For default module settings, see the wiki page 15 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem 16 | 17 | For full API reference, see the GitHub Pages 18 | https://jgromes.github.io/RadioLib/ 19 | */ 20 | 21 | // include the library 22 | #include 23 | 24 | // SX1280 has the following connections: 25 | // NSS pin: 10 26 | // DIO1 pin: 2 27 | // NRST pin: 3 28 | // BUSY pin: 9 29 | SX1280 radio = new Module(10, 2, 3, 9); 30 | 31 | // or using RadioShield 32 | // https://github.com/jgromes/RadioShield 33 | //SX1280 radio = RadioShield.ModuleA; 34 | 35 | void setup() { 36 | Serial.begin(9600); 37 | 38 | // initialize SX1280 with default settings 39 | Serial.print(F("[SX1280] Initializing ... ")); 40 | int state = radio.begin(); 41 | if (state == RADIOLIB_ERR_NONE) { 42 | Serial.println(F("success!")); 43 | } else { 44 | Serial.print(F("failed, code ")); 45 | Serial.println(state); 46 | while (true); 47 | } 48 | } 49 | 50 | void loop() { 51 | Serial.print(F("[SX1280] Scanning channel for LoRa transmission ... ")); 52 | 53 | // start scanning current channel 54 | int state = radio.scanChannel(); 55 | 56 | if (state == RADIOLIB_LORA_DETECTED) { 57 | // LoRa preamble was detected 58 | Serial.println(F("detected!")); 59 | 60 | } else if (state == RADIOLIB_CHANNEL_FREE) { 61 | // no preamble was detected, channel is free 62 | Serial.println(F("channel is free!")); 63 | 64 | } else { 65 | // some other error occurred 66 | Serial.print(F("failed, code ")); 67 | Serial.println(state); 68 | 69 | } 70 | 71 | // wait 100 ms before new scan 72 | delay(100); 73 | } 74 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/SX127x/SX127x_Channel_Activity_Detection_Blocking/SX127x_Channel_Activity_Detection_Blocking.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib SX127x Blocking Channel Activity Detection Example 3 | 4 | This example scans the current LoRa channel and detects 5 | valid LoRa preambles. Preamble is the first part of 6 | LoRa transmission, so this can be used to check 7 | if the LoRa channel is free, or if you should start 8 | receiving a message. 9 | 10 | Other modules from SX127x/RFM9x family can also be used. 11 | 12 | Using blocking CAD is not recommended, as it will lead 13 | to significant amount of timeouts, inefficient use of processor 14 | time and can some miss packets! 15 | Instead, interrupt CAD is recommended. 16 | 17 | For default module settings, see the wiki page 18 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem 19 | 20 | For full API reference, see the GitHub Pages 21 | https://jgromes.github.io/RadioLib/ 22 | */ 23 | 24 | // include the library 25 | #include 26 | 27 | // SX1278 has the following connections: 28 | // NSS pin: 10 29 | // DIO0 pin: 2 30 | // RESET pin: 9 31 | // DIO1 pin: 3 32 | SX1278 radio = new Module(10, 2, 9, 3); 33 | 34 | // or using RadioShield 35 | // https://github.com/jgromes/RadioShield 36 | //SX1278 radio = RadioShield.ModuleA; 37 | 38 | void setup() { 39 | Serial.begin(9600); 40 | 41 | // initialize SX1278 with default settings 42 | Serial.print(F("[SX1278] Initializing ... ")); 43 | int state = radio.begin(); 44 | if (state == RADIOLIB_ERR_NONE) { 45 | Serial.println(F("success!")); 46 | } else { 47 | Serial.print(F("failed, code ")); 48 | Serial.println(state); 49 | while (true); 50 | } 51 | } 52 | 53 | void loop() { 54 | Serial.print(F("[SX1278] Scanning channel for LoRa preamble ... ")); 55 | 56 | // start scanning current channel 57 | int state = radio.scanChannel(); 58 | 59 | if (state == RADIOLIB_PREAMBLE_DETECTED) { 60 | // LoRa preamble was detected 61 | Serial.println(F("detected preamble!")); 62 | 63 | } else if (state == RADIOLIB_CHANNEL_FREE) { 64 | // no preamble was detected, channel is free 65 | Serial.println(F("channel is free!")); 66 | 67 | } 68 | 69 | // wait 100 ms before new scan 70 | delay(100); 71 | } 72 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/Si443x/Si4430.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_SI4430_H) 2 | #define _RADIOLIB_SI4430_H 3 | 4 | #include "../../TypeDef.h" 5 | 6 | #if !defined(RADIOLIB_EXCLUDE_SI443X) 7 | 8 | #include "../../Module.h" 9 | #include "Si4432.h" 10 | 11 | /*! 12 | \class Si4430 13 | \brief Derived class for %Si4430 modules. 14 | */ 15 | class Si4430: public Si4432 { 16 | public: 17 | 18 | // constructor 19 | 20 | /*! 21 | \brief Default constructor. 22 | \param mod Instance of Module that will be used to communicate with the radio chip. 23 | */ 24 | Si4430(Module* mod); 25 | 26 | // basic methods 27 | 28 | /*! 29 | \brief Initialization method. Must be called at least once from Arduino sketch to initialize the module. 30 | \param freq Carrier frequency in MHz. Allowed values range from 900.0 MHz to 960.0 MHz. 31 | \param br Bit rate of the FSK transmission in kbps (kilobits per second). Allowed values range from 0.123 to 256.0 kbps. 32 | \param freqDev Frequency deviation of the FSK transmission in kHz. Allowed values range from 0.625 to 320.0 kbps. 33 | \param rxBw Receiver bandwidth in kHz. Allowed values range from 2.6 to 620.7 kHz. 34 | \param power Transmission output power in dBm. Allowed values range from -8 to 13 dBm in 3 dBm steps. 35 | \param preambleLen Preamble Length in bits. Defaults to 16 bits. 36 | \returns \ref status_codes 37 | */ 38 | int16_t begin(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 181.1, int8_t power = 10, uint8_t preambleLen = 16); 39 | 40 | // configuration methods 41 | 42 | /*! 43 | \brief Sets carrier frequency. Allowed values range from 900.0 MHz to 960.0 MHz. 44 | \param freq Carrier frequency to be set in MHz. 45 | \returns \ref status_codes 46 | */ 47 | int16_t setFrequency(float freq); 48 | 49 | /*! 50 | \brief Sets output power. Allowed values range from -8 to 13 dBm in 3 dBm steps. 51 | \param power Output power to be set in dBm. 52 | \returns \ref status_codes 53 | */ 54 | int16_t setOutputPower(int8_t power); 55 | 56 | #if !defined(RADIOLIB_GODMODE) 57 | protected: 58 | #endif 59 | 60 | #if !defined(RADIOLIB_GODMODE) 61 | private: 62 | #endif 63 | }; 64 | 65 | #endif 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/Si443x/Si4432.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_SI4432_H) 2 | #define _RADIOLIB_SI4432_H 3 | 4 | #include "../../TypeDef.h" 5 | 6 | #if !defined(RADIOLIB_EXCLUDE_SI443X) 7 | 8 | #include "../../Module.h" 9 | #include "Si443x.h" 10 | 11 | /*! 12 | \class Si4432 13 | \brief Derived class for %Si4432 modules. 14 | */ 15 | class Si4432: public Si443x { 16 | public: 17 | 18 | // constructor 19 | 20 | /*! 21 | \brief Default constructor. 22 | \param mod Instance of Module that will be used to communicate with the radio chip. 23 | */ 24 | Si4432(Module* mod); 25 | 26 | // basic methods 27 | 28 | /*! 29 | \brief Initialization method. Must be called at least once from Arduino sketch to initialize the module. 30 | \param freq Carrier frequency in MHz. Allowed values range from 240.0 MHz to 930.0 MHz. 31 | \param br Bit rate of the FSK transmission in kbps (kilobits per second). Allowed values range from 0.123 to 256.0 kbps. 32 | \param freqDev Frequency deviation of the FSK transmission in kHz. Allowed values range from 0.625 to 320.0 kbps. 33 | \param rxBw Receiver bandwidth in kHz. Allowed values range from 2.6 to 620.7 kHz. 34 | \param power Transmission output power in dBm. Allowed values range from -1 to 20 dBm in 3 dBm steps. 35 | \param preambleLen Preamble Length in bits. Defaults to 16 bits. 36 | \returns \ref status_codes 37 | */ 38 | int16_t begin(float freq = 434.0, float br = 4.8, float freqDev = 5.0, float rxBw = 181.1, int8_t power = 10, uint8_t preambleLen = 16); 39 | 40 | // configuration methods 41 | 42 | /*! 43 | \brief Sets carrier frequency. Allowed values range from 240.0 MHz to 930.0 MHz. 44 | \param freq Carrier frequency to be set in MHz. 45 | \returns \ref status_codes 46 | */ 47 | int16_t setFrequency(float freq); 48 | 49 | /*! 50 | \brief Sets output power. Allowed values range from -1 to 20 dBm in 3 dBm steps. 51 | \param power Output power to be set in dBm. 52 | \returns \ref status_codes 53 | */ 54 | int16_t setOutputPower(int8_t power); 55 | 56 | #if !defined(RADIOLIB_GODMODE) 57 | protected: 58 | #endif 59 | 60 | #if !defined(RADIOLIB_GODMODE) 61 | private: 62 | #endif 63 | }; 64 | 65 | #endif 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/SX127x/SX127x_Receive_Direct/SX127x_Receive_Direct.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib SX127x Direct Receive Example 3 | 4 | This example shows how to receive FSK packets without using 5 | SX127x packet engine. 6 | 7 | For default module settings, see the wiki page 8 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem 9 | 10 | For full API reference, see the GitHub Pages 11 | https://jgromes.github.io/RadioLib/ 12 | */ 13 | 14 | // include the library 15 | #include 16 | 17 | // SX1278 has the following connections: 18 | // NSS pin: 10 19 | // DIO0 pin: 2 20 | // RESET pin: 9 21 | // DIO1 pin: 3 22 | SX1278 radio = new Module(10, 2, 9, 3); 23 | 24 | // DIO2 pin: 5 25 | const int pin = 5; 26 | 27 | // or using RadioShield 28 | // https://github.com/jgromes/RadioShield 29 | //SX1278 radio = RadioShield.ModuleA; 30 | 31 | void setup() { 32 | Serial.begin(9600); 33 | 34 | // initialize SX1278 with FSK modem at 9600 bps 35 | Serial.print(F("[SX1278] Initializing ... ")); 36 | int state = radio.beginFSK(434.0, 9.6, 20.0); 37 | if (state == RADIOLIB_ERR_NONE) { 38 | Serial.println(F("success!")); 39 | } else { 40 | Serial.print(F("failed, code ")); 41 | Serial.println(state); 42 | while (true); 43 | } 44 | 45 | // set the direct mode sync word 46 | // the default RadioLib FSK sync word is 0x12AD 47 | // we can add in some preamble bits, to lower the chance 48 | // of false detection 49 | radio.setDirectSyncWord(0x555512AD, 32); 50 | 51 | // set function that will be called each time a bit is received 52 | radio.setDirectAction(readBit); 53 | 54 | // start direct mode reception 55 | radio.receiveDirect(); 56 | } 57 | 58 | // this function is called when a new bit is received 59 | void readBit(void) { 60 | // read the data bit 61 | radio.readBit(pin); 62 | } 63 | 64 | void loop() { 65 | // we expect the packet to contain the string "Hello World!", 66 | // a length byte and 2 CRC bytes, that's 15 bytes in total 67 | if(radio.available() >= 15) { 68 | Serial.println("[SX1278] Received packet in direct mode!"); 69 | while(radio.available()) { 70 | // read a byte 71 | byte b = radio.read(); 72 | 73 | // print it 74 | Serial.print(b, HEX); 75 | Serial.print('\t'); 76 | Serial.write(b); 77 | Serial.println(); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/coredump.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by FLN1021 on 2023/10/31. 3 | // Migrated from https://github.com/MathieuDeprez/ESP32_CoreDump_Arduino_1.0.6/blob/master/src/main.cpp 4 | // 5 | 6 | #include "coredump.h" 7 | 8 | void readCoreDump() { 9 | size_t size = 0; 10 | size_t address = 0; 11 | if (esp_core_dump_image_get(&address, &size) == ESP_OK) { 12 | Serial.println("[CoreDump] Find core dump."); 13 | have_cd = true; 14 | const esp_partition_t *pt; 15 | pt = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_COREDUMP, "coredump"); 16 | 17 | if (pt != nullptr) { 18 | uint8_t bf[256]; 19 | char str_dst[640]; 20 | size_t toRead; 21 | // "-------------------------------------------------" 22 | sd1.append("========================= BEGIN COREDUMP =========================\n"); 23 | sd1.beginCD("/COREDUMP"); 24 | Serial.println("[CoreDump] ========================= BEGIN COREDUMP ========================="); 25 | for (size_t i = 0; i < (size / 256) + 1; i++) { 26 | strcpy(str_dst, ""); 27 | toRead = (size - i * 256) > 256 ? 256 : (size - i * 256); 28 | 29 | esp_err_t er = esp_partition_read(pt, i * 256, bf, toRead); 30 | if (er != ESP_OK) { 31 | Serial.printf("FAIL [%x]\n", er); 32 | break; 33 | } 34 | 35 | for (unsigned char j: bf) { 36 | char str_tmp[3]; 37 | sprintf(str_tmp, "%02x", j); 38 | strcat(str_dst, str_tmp); 39 | } 40 | 41 | Serial.printf("%s", str_dst); 42 | sd1.append("%s", str_dst); 43 | sd1.appendCD(bf, sizeof bf); 44 | } 45 | sd1.append("\n========================= END COREDUMP =========================\n"); 46 | sd1.endCD(); 47 | Serial.println("\n[CoreDump] ========================= END COREDUMP ========================="); 48 | } else { 49 | Serial.println("[CoreDump] Core dump partition not found."); 50 | } 51 | if (esp_core_dump_image_erase() == ESP_OK) 52 | Serial.println("[CoreDump] Core dump erased."); 53 | } else { 54 | Serial.println("[CoreDump] No core dump available."); 55 | } 56 | } -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/SX127x/SX1276.cpp: -------------------------------------------------------------------------------- 1 | #include "SX1276.h" 2 | #if !defined(RADIOLIB_EXCLUDE_SX127X) 3 | 4 | SX1276::SX1276(Module* mod) : SX1278(mod) { 5 | 6 | } 7 | 8 | int16_t SX1276::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, uint8_t gain) { 9 | // execute common part 10 | int16_t state = SX127x::begin(RADIOLIB_SX1278_CHIP_VERSION, syncWord, preambleLength); 11 | RADIOLIB_ASSERT(state); 12 | 13 | // configure publicly accessible settings 14 | state = setBandwidth(bw); 15 | RADIOLIB_ASSERT(state); 16 | 17 | state = setFrequency(freq); 18 | RADIOLIB_ASSERT(state); 19 | 20 | state = setSpreadingFactor(sf); 21 | RADIOLIB_ASSERT(state); 22 | 23 | state = setCodingRate(cr); 24 | RADIOLIB_ASSERT(state); 25 | 26 | state = setOutputPower(power); 27 | RADIOLIB_ASSERT(state); 28 | 29 | state = setGain(gain); 30 | RADIOLIB_ASSERT(state); 31 | 32 | // set publicly accessible settings that are not a part of begin method 33 | state = setCRC(true); 34 | RADIOLIB_ASSERT(state); 35 | 36 | return(state); 37 | } 38 | 39 | int16_t SX1276::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, bool enableOOK) { 40 | // execute common part 41 | int16_t state = SX127x::beginFSK(RADIOLIB_SX1278_CHIP_VERSION, freqDev, rxBw, preambleLength, enableOOK); 42 | RADIOLIB_ASSERT(state); 43 | 44 | // configure settings not accessible by API 45 | state = configFSK(); 46 | RADIOLIB_ASSERT(state); 47 | 48 | // configure publicly accessible settings 49 | state = setFrequency(freq); 50 | RADIOLIB_ASSERT(state); 51 | 52 | state = setBitRate(br); 53 | RADIOLIB_ASSERT(state); 54 | 55 | state = setOutputPower(power); 56 | RADIOLIB_ASSERT(state); 57 | 58 | if(enableOOK) { 59 | state = setDataShapingOOK(RADIOLIB_SHAPING_NONE); 60 | RADIOLIB_ASSERT(state); 61 | } else { 62 | state = setDataShaping(RADIOLIB_SHAPING_NONE); 63 | RADIOLIB_ASSERT(state); 64 | } 65 | 66 | return(state); 67 | } 68 | 69 | int16_t SX1276::setFrequency(float freq) { 70 | RADIOLIB_CHECK_RANGE(freq, 137.0, 1020.0, RADIOLIB_ERR_INVALID_FREQUENCY); 71 | 72 | // set frequency and if successful, save the new setting 73 | int16_t state = SX127x::setFrequencyRaw(freq); 74 | if(state == RADIOLIB_ERR_NONE) { 75 | SX127x::frequency = freq; 76 | } 77 | return(state); 78 | } 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/SX127x/SX1279.cpp: -------------------------------------------------------------------------------- 1 | #include "SX1279.h" 2 | #if !defined(RADIOLIB_EXCLUDE_SX127X) 3 | 4 | SX1279::SX1279(Module* mod) : SX1278(mod) { 5 | 6 | } 7 | 8 | int16_t SX1279::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, uint8_t gain) { 9 | // execute common part 10 | int16_t state = SX127x::begin(RADIOLIB_SX1278_CHIP_VERSION, syncWord, preambleLength); 11 | RADIOLIB_ASSERT(state); 12 | 13 | // configure publicly accessible settings 14 | state = setBandwidth(bw); 15 | RADIOLIB_ASSERT(state); 16 | 17 | state = setFrequency(freq); 18 | RADIOLIB_ASSERT(state); 19 | 20 | state = setSpreadingFactor(sf); 21 | RADIOLIB_ASSERT(state); 22 | 23 | state = setCodingRate(cr); 24 | RADIOLIB_ASSERT(state); 25 | 26 | state = setOutputPower(power); 27 | RADIOLIB_ASSERT(state); 28 | 29 | state = setGain(gain); 30 | RADIOLIB_ASSERT(state); 31 | 32 | // set publicly accessible settings that are not a part of begin method 33 | state = setCRC(true); 34 | RADIOLIB_ASSERT(state); 35 | 36 | return(state); 37 | } 38 | 39 | int16_t SX1279::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, bool enableOOK) { 40 | // execute common part 41 | int16_t state = SX127x::beginFSK(RADIOLIB_SX1278_CHIP_VERSION, freqDev, rxBw, preambleLength, enableOOK); 42 | RADIOLIB_ASSERT(state); 43 | 44 | // configure settings not accessible by API 45 | state = configFSK(); 46 | RADIOLIB_ASSERT(state); 47 | 48 | // configure publicly accessible settings 49 | state = setFrequency(freq); 50 | RADIOLIB_ASSERT(state); 51 | 52 | state = setBitRate(br); 53 | RADIOLIB_ASSERT(state); 54 | 55 | state = setOutputPower(power); 56 | RADIOLIB_ASSERT(state); 57 | 58 | if(enableOOK) { 59 | state = setDataShapingOOK(RADIOLIB_SHAPING_NONE); 60 | RADIOLIB_ASSERT(state); 61 | } else { 62 | state = setDataShaping(RADIOLIB_SHAPING_NONE); 63 | RADIOLIB_ASSERT(state); 64 | } 65 | 66 | return(state); 67 | } 68 | 69 | int16_t SX1279::setFrequency(float freq) { 70 | RADIOLIB_CHECK_RANGE(freq, 137.0, 960.0, RADIOLIB_ERR_INVALID_FREQUENCY); 71 | 72 | // set frequency and if successful, save the new setting 73 | int16_t state = SX127x::setFrequencyRaw(freq); 74 | if(state == RADIOLIB_ERR_NONE) { 75 | SX127x::frequency = freq; 76 | } 77 | return(state); 78 | } 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/SX1231/SX1231_Transmit/SX1231_Transmit.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib SX1231 Blocking Transmit Example 3 | 4 | This example transmits packets using SX1231 FSK radio module. 5 | 6 | NOTE: SX1231 offers the same features as RF69 and has the same 7 | interface. Please see RF69 examples for examples on AES, 8 | address filtering, interrupts and settings. 9 | 10 | Using blocking transmit is not recommended, as it will lead 11 | to inefficient use of processor time! 12 | Instead, interrupt transmit is recommended. 13 | 14 | For default module settings, see the wiki page 15 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231 16 | 17 | For full API reference, see the GitHub Pages 18 | https://jgromes.github.io/RadioLib/ 19 | */ 20 | 21 | // include the library 22 | #include 23 | 24 | // SX1231 has the following connections: 25 | // CS pin: 10 26 | // DIO0 pin: 2 27 | // RESET pin: 3 28 | SX1231 radio = new Module(10, 2, 3); 29 | 30 | // or using RadioShield 31 | // https://github.com/jgromes/RadioShield 32 | //SX1231 radio = RadioShield.ModuleA; 33 | 34 | void setup() { 35 | Serial.begin(9600); 36 | 37 | // initialize SX1231 with default settings 38 | Serial.print(F("[SX1231] Initializing ... ")); 39 | int state = radio.begin(); 40 | if (state == RADIOLIB_ERR_NONE) { 41 | Serial.println(F("success!")); 42 | } else { 43 | Serial.print(F("failed, code ")); 44 | Serial.println(state); 45 | while (true); 46 | } 47 | } 48 | 49 | // counter to keep track of transmitted packets 50 | int count = 0; 51 | 52 | void loop() { 53 | Serial.print(F("[SX1231] Transmitting packet ... ")); 54 | 55 | // you can transmit C-string or Arduino string up to 256 characters long 56 | String str = "Hello World! #" + String(count++); 57 | int state = radio.transmit(str); 58 | 59 | // you can also transmit byte array up to 256 bytes long 60 | /* 61 | byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; 62 | int state = radio.transmit(byteArr, 8); 63 | */ 64 | 65 | if (state == RADIOLIB_ERR_NONE) { 66 | // the packet was successfully transmitted 67 | Serial.println(F("success!")); 68 | 69 | } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) { 70 | // the supplied packet was longer than 256 bytes 71 | Serial.println(F("too long!")); 72 | 73 | } 74 | 75 | // wait for a second before transmitting again 76 | delay(1000); 77 | } 78 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/SX126x/SX126x_Channel_Activity_Detection_Blocking/SX126x_Channel_Activity_Detection_Blocking.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib SX126x Blocking Channel Activity Detection Example 3 | 4 | This example uses SX1262 to scan the current LoRa 5 | channel and detect ongoing LoRa transmissions. 6 | Unlike SX127x CAD, SX126x can detect any part 7 | of LoRa transmission, not just the preamble. 8 | 9 | Other modules from SX126x family can also be used. 10 | 11 | Using blocking CAD is not recommended, as it will lead 12 | to significant amount of timeouts, inefficient use of processor 13 | time and can some miss packets! 14 | Instead, interrupt CAD is recommended. 15 | 16 | For default module settings, see the wiki page 17 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem 18 | 19 | For full API reference, see the GitHub Pages 20 | https://jgromes.github.io/RadioLib/ 21 | */ 22 | 23 | // include the library 24 | #include 25 | 26 | // SX1262 has the following connections: 27 | // NSS pin: 10 28 | // DIO1 pin: 2 29 | // NRST pin: 3 30 | // BUSY pin: 9 31 | SX1262 radio = new Module(10, 2, 3, 9); 32 | 33 | // or using RadioShield 34 | // https://github.com/jgromes/RadioShield 35 | //SX1262 radio = RadioShield.ModuleA; 36 | 37 | // or using CubeCell 38 | //SX1262 radio = new Module(RADIOLIB_BUILTIN_MODULE); 39 | 40 | void setup() { 41 | Serial.begin(9600); 42 | 43 | // initialize SX1262 with default settings 44 | Serial.print(F("[SX1262] Initializing ... ")); 45 | int state = radio.begin(); 46 | if (state == RADIOLIB_ERR_NONE) { 47 | Serial.println(F("success!")); 48 | } else { 49 | Serial.print(F("failed, code ")); 50 | Serial.println(state); 51 | while (true); 52 | } 53 | } 54 | 55 | void loop() { 56 | Serial.print(F("[SX1262] Scanning channel for LoRa transmission ... ")); 57 | 58 | // start scanning current channel 59 | int state = radio.scanChannel(); 60 | 61 | if (state == RADIOLIB_LORA_DETECTED) { 62 | // LoRa preamble was detected 63 | Serial.println(F("detected!")); 64 | 65 | } else if (state == RADIOLIB_CHANNEL_FREE) { 66 | // no preamble was detected, channel is free 67 | Serial.println(F("channel is free!")); 68 | 69 | } else { 70 | // some other error occurred 71 | Serial.print(F("failed, code ")); 72 | Serial.println(state); 73 | 74 | } 75 | 76 | // wait 100 ms before new scan 77 | delay(100); 78 | } 79 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/LLCC68/LLCC68.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_LLCC68_H) 2 | #define _RADIOLIB_LLCC68_H 3 | 4 | #include "../../TypeDef.h" 5 | 6 | #if !defined(RADIOLIB_EXCLUDE_SX126X) 7 | 8 | #include "../../Module.h" 9 | #include "../SX126x/SX1262.h" 10 | 11 | //RADIOLIB_SX126X_REG_VERSION_STRING 12 | #define RADIOLIB_LLCC68_CHIP_TYPE "LLCC68" 13 | 14 | /*! 15 | \class LLCC68 16 | \brief Derived class for %LLCC68 modules. 17 | */ 18 | class LLCC68: public SX1262 { 19 | public: 20 | /*! 21 | \brief Default constructor. 22 | \param mod Instance of Module that will be used to communicate with the radio. 23 | */ 24 | LLCC68(Module* mod); 25 | 26 | /*! 27 | \brief Initialization method for LoRa modem. 28 | \param freq Carrier frequency in MHz. Defaults to 434.0 MHz. 29 | \param bw LoRa bandwidth in kHz. Defaults to 125.0 kHz. 30 | \param sf LoRa spreading factor. Defaults to 9. 31 | \param cr LoRa coding rate denominator. Defaults to 7 (coding rate 4/7). 32 | \param syncWord 1-byte LoRa sync word. Defaults to RADIOLIB_SX126X_SYNC_WORD_PRIVATE (0x12). 33 | \param pwr Output power in dBm. Defaults to 10 dBm. 34 | \param preambleLength LoRa preamble length in symbols. Defaults to 8 symbols. 35 | \param tcxoVoltage TCXO reference voltage to be set on DIO3. Defaults to 1.6 V, set to 0 to skip. 36 | \param useRegulatorLDO Whether to use only LDO regulator (true) or DC-DC regulator (false). Defaults to false. 37 | \returns \ref status_codes 38 | */ 39 | int16_t begin(float freq = 434.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX126X_SYNC_WORD_PRIVATE, int8_t pwr = 10, uint16_t preambleLength = 8, float tcxoVoltage = 1.6, bool useRegulatorLDO = false); 40 | 41 | // configuration methods 42 | 43 | /*! 44 | \brief Sets LoRa bandwidth. Allowed values are 125.0, 250.0 and 500.0 kHz. 45 | \param bw LoRa bandwidth to be set in kHz. 46 | \returns \ref status_codes 47 | */ 48 | int16_t setBandwidth(float bw); 49 | 50 | /*! 51 | \brief Sets LoRa spreading factor. Allowed values range from 5 to 11, depending on currently set spreading factor. 52 | \param sf LoRa spreading factor to be set. 53 | \returns \ref status_codes 54 | */ 55 | int16_t setSpreadingFactor(uint8_t sf); 56 | 57 | #if !defined(RADIOLIB_GODMODE) 58 | private: 59 | #endif 60 | 61 | }; 62 | 63 | #endif 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/SX127x/SX1273.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_SX1273_H) 2 | #define _RADIOLIB_SX1273_H 3 | 4 | #include "../../TypeDef.h" 5 | 6 | #if !defined(RADIOLIB_EXCLUDE_SX127X) 7 | 8 | #include "SX1272.h" 9 | 10 | /*! 11 | \class SX1273 12 | \brief Derived class for %SX1273 modules. Overrides some methods from SX1272 due to different parameter ranges. 13 | */ 14 | class SX1273: public SX1272 { 15 | public: 16 | 17 | // constructor 18 | 19 | /*! 20 | \brief Default constructor. Called from Arduino sketch when creating new LoRa instance. 21 | \param mod Instance of Module that will be used to communicate with the %LoRa chip. 22 | */ 23 | SX1273(Module* mod); 24 | 25 | // basic methods 26 | 27 | /*! 28 | \brief %LoRa modem initialization method. Must be called at least once from Arduino sketch to initialize the module. 29 | \param freq Carrier frequency in MHz. Allowed values range from 860.0 MHz to 1020.0 MHz. 30 | \param bw %LoRa link bandwidth in kHz. Allowed values are 125, 250 and 500 kHz. 31 | \param sf %LoRa link spreading factor. Allowed values range from 6 to 9. 32 | \param cr %LoRa link coding rate denominator. Allowed values range from 5 to 8. 33 | \param syncWord %LoRa sync word. Can be used to distinguish different networks. Note that value 0x34 is reserved for LoRaWAN networks. 34 | \param power Transmission output power in dBm. Allowed values range from 2 to 17 dBm. 35 | \param preambleLength Length of %LoRa transmission preamble in symbols. The actual preamble length is 4.25 symbols longer than the set number. 36 | Allowed values range from 6 to 65535. 37 | \param gain Gain of receiver LNA (low-noise amplifier). Can be set to any integer in range 1 to 6 where 1 is the highest gain. 38 | Set to 0 to enable automatic gain control (recommended). 39 | \returns \ref status_codes 40 | */ 41 | int16_t begin(float freq = 915.0, float bw = 125.0, uint8_t sf = 9, uint8_t cr = 7, uint8_t syncWord = RADIOLIB_SX127X_SYNC_WORD, int8_t power = 10, uint16_t preambleLength = 8, uint8_t gain = 0); 42 | 43 | // configuration methods 44 | 45 | /*! 46 | \brief Sets %LoRa link spreading factor. Allowed values range from 6 to 9. Only available in %LoRa mode. 47 | \param sf %LoRa link spreading factor to be set. 48 | \returns \ref status_codes 49 | */ 50 | int16_t setSpreadingFactor(uint8_t sf); 51 | 52 | #if !defined(RADIOLIB_GODMODE) 53 | private: 54 | #endif 55 | 56 | }; 57 | 58 | #endif 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /lib/RadioLib/src/protocols/Print/ITA2String.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_ITA2_STRING_H) 2 | #define _RADIOLIB_ITA2_STRING_H 3 | 4 | #include "../../TypeDef.h" 5 | 6 | #define RADIOLIB_ITA2_FIGS 0x1B 7 | #define RADIOLIB_ITA2_LTRS 0x1F 8 | #define RADIOLIB_ITA2_LENGTH 32 9 | 10 | // ITA2 character table: - position in array corresponds to 5-bit ITA2 code 11 | // - characters to the left are in letters shift, characters to the right in figures shift 12 | // - characters marked 0x7F do not have ASCII equivalent 13 | static const char ITA2Table[RADIOLIB_ITA2_LENGTH][2] RADIOLIB_NONVOLATILE = { 14 | {'\0', '\0'}, {'E', '3'}, {'\n', '\n'}, {'A', '-'}, {' ', ' '}, {'S', '\''}, {'I', '8'}, {'U', '7'}, 15 | {'\r', '\r'}, {'D', 0x05}, {'R', '4'}, {'J', '\a'}, {'N', ','}, {'F', '!'}, {'C', ':'}, {'K', '('}, 16 | {'T', '5'}, {'Z', '+'}, {'L', ')'}, {'W', '2'}, {'H', 0x7F}, {'Y', '6'}, {'P', '0'}, {'Q', '1'}, 17 | {'O', '9'}, {'B', '?'}, {'G', '&'}, {0x7F, 0x7F}, {'M', '.'}, {'X', '/'}, {'V', ';'}, {0x7F, 0x7F} 18 | }; 19 | 20 | /*! 21 | \class ITA2String 22 | \brief ITA2-encoded string. 23 | */ 24 | class ITA2String { 25 | public: 26 | /*! 27 | \brief Default single-character constructor. 28 | \param c ASCII-encoded character to encode as ITA2. 29 | */ 30 | ITA2String(char c); 31 | 32 | /*! 33 | \brief Default string constructor. 34 | \param str ASCII-encoded string to encode as ITA2. 35 | */ 36 | ITA2String(const char* str); 37 | 38 | /*! 39 | \brief Default destructor. 40 | */ 41 | ~ITA2String(); 42 | 43 | /*! 44 | \brief Gets the length of the ITA2 string. This number is not the same as the length of ASCII-encoded string! 45 | \returns Length of ITA2-encoded string. 46 | */ 47 | size_t length(); 48 | 49 | /*! 50 | \brief Gets the ITA2 representation of the ASCII string set in constructor. 51 | \returns Pointer to dynamically allocated array, which contains ITA2-encoded bytes. 52 | It is the caller's responsibility to deallocate this memory! 53 | */ 54 | uint8_t* byteArr(); 55 | 56 | #if !defined(RADIOLIB_GODMODE) 57 | private: 58 | #endif 59 | #if defined(RADIOLIB_STATIC_ONLY) 60 | char strAscii[RADIOLIB_STATIC_ARRAY_SIZE]; 61 | #else 62 | char* strAscii; 63 | #endif 64 | size_t asciiLen; 65 | size_t ita2Len; 66 | 67 | static uint16_t getBits(char c); 68 | }; 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/CC1101/CC1101_Transmit_Blocking/CC1101_Transmit_Blocking.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib CC1101 Blocking Transmit Example 3 | 4 | This example transmits packets using CC1101 FSK radio module. 5 | Each packet contains up to 64 bytes of data, in the form of: 6 | - Arduino String 7 | - null-terminated char array (C-string) 8 | - arbitrary binary data (byte array) 9 | 10 | Using blocking transmit is not recommended, as it will lead 11 | to inefficient use of processor time! 12 | Instead, interrupt transmit is recommended. 13 | 14 | For default module settings, see the wiki page 15 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101 16 | 17 | For full API reference, see the GitHub Pages 18 | https://jgromes.github.io/RadioLib/ 19 | */ 20 | 21 | // include the library 22 | #include 23 | 24 | // CC1101 has the following connections: 25 | // CS pin: 10 26 | // GDO0 pin: 2 27 | // RST pin: unused 28 | // GDO2 pin: 3 29 | CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3); 30 | 31 | // or using RadioShield 32 | // https://github.com/jgromes/RadioShield 33 | //CC1101 radio = RadioShield.ModuleA; 34 | 35 | void setup() { 36 | Serial.begin(9600); 37 | 38 | // initialize CC1101 with default settings 39 | Serial.print(F("[CC1101] Initializing ... ")); 40 | int state = radio.begin(); 41 | if (state == RADIOLIB_ERR_NONE) { 42 | Serial.println(F("success!")); 43 | } else { 44 | Serial.print(F("failed, code ")); 45 | Serial.println(state); 46 | while (true); 47 | } 48 | } 49 | 50 | // counter to keep track of transmitted packets 51 | int count = 0; 52 | 53 | void loop() { 54 | Serial.print(F("[CC1101] Transmitting packet ... ")); 55 | 56 | // you can transmit C-string or Arduino string up to 63 characters long 57 | String str = "Hello World! #" + String(count++); 58 | int state = radio.transmit(str); 59 | 60 | // you can also transmit byte array up to 63 bytes long 61 | /* 62 | byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; 63 | int state = radio.transmit(byteArr, 8); 64 | */ 65 | 66 | if (state == RADIOLIB_ERR_NONE) { 67 | // the packet was successfully transmitted 68 | Serial.println(F("success!")); 69 | 70 | } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) { 71 | // the supplied packet was longer than 64 bytes 72 | Serial.println(F("too long!")); 73 | 74 | } else { 75 | // some other error occurred 76 | Serial.print(F("failed, code ")); 77 | Serial.println(state); 78 | 79 | } 80 | 81 | // wait for a second before transmitting again 82 | delay(1000); 83 | } 84 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/SX1231/SX1231_Receive/SX1231_Receive.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib SX1231 Blocking Receive Example 3 | 4 | This example receives packets using SX1231 FSK radio module. 5 | 6 | NOTE: SX1231 offers the same features as RF69 and has the same 7 | interface. Please see RF69 examples for examples on AES, 8 | address filtering, interrupts and settings. 9 | 10 | Using blocking receive is not recommended, as it will lead 11 | to significant amount of timeouts, inefficient use of processor 12 | time and can some miss packets! 13 | Instead, interrupt receive is recommended. 14 | 15 | For default module settings, see the wiki page 16 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231 17 | 18 | For full API reference, see the GitHub Pages 19 | https://jgromes.github.io/RadioLib/ 20 | */ 21 | 22 | // include the library 23 | #include 24 | 25 | // SX1231 has the following connections: 26 | // CS pin: 10 27 | // DIO0 pin: 2 28 | // RESET pin: 3 29 | SX1231 radio = new Module(10, 2, 3); 30 | 31 | // or using RadioShield 32 | // https://github.com/jgromes/RadioShield 33 | //SX1231 radio = RadioShield.ModuleA; 34 | 35 | void setup() { 36 | Serial.begin(9600); 37 | 38 | // initialize SX1231 with default settings 39 | Serial.print(F("[SX1231] Initializing ... ")); 40 | int state = radio.begin(); 41 | if (state == RADIOLIB_ERR_NONE) { 42 | Serial.println(F("success!")); 43 | } else { 44 | Serial.print(F("failed, code ")); 45 | Serial.println(state); 46 | while (true); 47 | } 48 | } 49 | 50 | void loop() { 51 | Serial.print(F("[SX1231] Waiting for incoming transmission ... ")); 52 | 53 | // you can receive data as an Arduino String 54 | String str; 55 | int state = radio.receive(str); 56 | 57 | // you can also receive data as byte array 58 | /* 59 | byte byteArr[8]; 60 | int state = radio.receive(byteArr, 8); 61 | */ 62 | 63 | if (state == RADIOLIB_ERR_NONE) { 64 | // packet was successfully received 65 | Serial.println(F("success!")); 66 | 67 | // print the data of the packet 68 | Serial.print(F("[SX1231] Data:\t\t")); 69 | Serial.println(str); 70 | 71 | } else if (state == RADIOLIB_ERR_RX_TIMEOUT) { 72 | // timeout occurred while waiting for a packet 73 | Serial.println(F("timeout!")); 74 | 75 | } else if (state == RADIOLIB_ERR_CRC_MISMATCH) { 76 | // packet was received, but is malformed 77 | Serial.println(F("CRC error!")); 78 | 79 | } else { 80 | // some other error occurred 81 | Serial.print(F("failed, code ")); 82 | Serial.println(state); 83 | 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /lib/RadioLib/src/protocols/RTTY/RTTY.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_RTTY_H) 2 | #define _RADIOLIB_RTTY_H 3 | 4 | #include "../../TypeDef.h" 5 | 6 | #if !defined(RADIOLIB_EXCLUDE_RTTY) 7 | 8 | #include "../PhysicalLayer/PhysicalLayer.h" 9 | #include "../AFSK/AFSK.h" 10 | #include "../Print/Print.h" 11 | #include "../Print/ITA2String.h" 12 | 13 | /*! 14 | \class RTTYClient 15 | \brief Client for RTTY communication. The public interface is the same as Arduino Serial. 16 | */ 17 | class RTTYClient: public RadioLibPrint { 18 | public: 19 | /*! 20 | \brief Constructor for 2-FSK mode. 21 | \param phy Pointer to the wireless module providing PhysicalLayer communication. 22 | */ 23 | explicit RTTYClient(PhysicalLayer* phy); 24 | 25 | #if !defined(RADIOLIB_EXCLUDE_AFSK) 26 | /*! 27 | \brief Constructor for AFSK mode. 28 | \param audio Pointer to the AFSK instance providing audio. 29 | */ 30 | explicit RTTYClient(AFSKClient* audio); 31 | #endif 32 | 33 | // basic methods 34 | 35 | /*! 36 | \brief Initialization method. 37 | \param base Base (space) frequency to be used in MHz (in 2-FSK mode), or the space tone frequency in Hz (in AFSK mode) 38 | \param shift Frequency shift between mark and space in Hz. 39 | \param rate Baud rate to be used during transmission. 40 | \param enc Encoding to be used. Defaults to ASCII. 41 | \param stopBits Number of stop bits to be used. 42 | \returns \ref status_codes 43 | */ 44 | int16_t begin(float base, uint32_t shift, uint16_t rate, uint8_t enc = RADIOLIB_ASCII, uint8_t stopBits = 1); 45 | 46 | /*! 47 | \brief Send out idle condition (RF tone at mark frequency). 48 | */ 49 | void idle(); 50 | 51 | /*! 52 | \brief Stops transmitting. 53 | \returns \ref status_codes 54 | */ 55 | int16_t standby(); 56 | 57 | /*! 58 | \brief Write one byte. Implementation of interface of the RadioLibPrint/Print class. 59 | \param b Byte to write. 60 | \returns 1 if the byte was written, 0 otherwise. 61 | */ 62 | size_t write(uint8_t b); 63 | 64 | #if !defined(RADIOLIB_GODMODE) 65 | private: 66 | #endif 67 | PhysicalLayer* phyLayer; 68 | #if !defined(RADIOLIB_EXCLUDE_AFSK) 69 | AFSKClient* audioClient; 70 | #endif 71 | 72 | uint32_t baseFreq = 0, baseFreqHz = 0; 73 | uint32_t shiftFreq = 0, shiftFreqHz = 0; 74 | uint32_t bitDuration = 0; 75 | uint8_t stopBitsNum = 0; 76 | 77 | void mark(); 78 | void space(); 79 | 80 | int16_t transmitDirect(uint32_t freq = 0, uint32_t freqHz = 0); 81 | }; 82 | 83 | #endif 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /lib/RadioLib/src/protocols/BellModem/BellModem.cpp: -------------------------------------------------------------------------------- 1 | #include "BellModem.h" 2 | #if !defined(RADIOLIB_EXCLUDE_BELL) 3 | 4 | const struct BellModem_t Bell101 { 5 | .freqMark = 1270, 6 | .freqSpace = 1070, 7 | .baudRate = 110, 8 | .freqMarkReply = 2225, 9 | .freqSpaceReply = 2025, 10 | }; 11 | 12 | const struct BellModem_t Bell103 { 13 | .freqMark = 1270, 14 | .freqSpace = 1070, 15 | .baudRate = 300, 16 | .freqMarkReply = 2225, 17 | .freqSpaceReply = 2025, 18 | }; 19 | 20 | const struct BellModem_t Bell202 { 21 | .freqMark = 1200, 22 | .freqSpace = 2200, 23 | .baudRate = 1200, 24 | .freqMarkReply = 1200, 25 | .freqSpaceReply = 2200, 26 | }; 27 | 28 | BellClient::BellClient(PhysicalLayer* phy, uint32_t pin) : AFSKClient(phy, pin) { 29 | this->reply = false; 30 | } 31 | 32 | BellClient::BellClient(AFSKClient* aud) : AFSKClient(aud) { 33 | this->reply = false; 34 | } 35 | 36 | int16_t BellClient::begin(const BellModem_t& modem) { 37 | int16_t state = setModem(modem); 38 | RADIOLIB_ASSERT(state); 39 | 40 | state = phyLayer->startDirect(); 41 | return(state); 42 | } 43 | 44 | int16_t BellClient::setModem(const BellModem_t& modem) { 45 | this->modemType = modem; 46 | this->toneLen = (1000000.0/(float)this->modemType.baudRate)*this->correction; 47 | return(RADIOLIB_ERR_NONE); 48 | } 49 | 50 | int16_t BellClient::setCorrection(float corr) { 51 | this->correction = corr; 52 | return(RADIOLIB_ERR_NONE); 53 | } 54 | 55 | size_t BellClient::write(uint8_t b) { 56 | // first get the frequencies 57 | uint16_t toneMark = this->modemType.freqMark; 58 | uint16_t toneSpace = this->modemType.freqSpace; 59 | if(this->reply) { 60 | toneMark = this->modemType.freqMarkReply; 61 | toneMark = this->modemType.freqSpaceReply; 62 | } 63 | 64 | // get the Module pointer to access HAL 65 | Module* mod = this->phyLayer->getMod(); 66 | 67 | if(this->autoStart) { 68 | phyLayer->transmitDirect(); 69 | } 70 | 71 | // iterate over the bits and set correct frequencies 72 | for(uint16_t mask = 0x80; mask >= 0x01; mask >>= 1) { 73 | uint32_t start = mod->hal->micros(); 74 | if(b & mask) { 75 | this->tone(toneMark, false); 76 | } else { 77 | this->tone(toneSpace, false); 78 | } 79 | mod->waitForMicroseconds(start, this->toneLen); 80 | } 81 | 82 | if(this->autoStart) { 83 | phyLayer->standby(); 84 | } 85 | return(1); 86 | } 87 | 88 | int16_t BellClient::idle() { 89 | this->autoStart = false; 90 | return(phyLayer->transmitDirect()); 91 | } 92 | 93 | int16_t BellClient::standby() { 94 | this->autoStart = true; 95 | return(phyLayer->standby()); 96 | } 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/AFSK/AFSK_Tone/AFSK_Tone.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib AFSK Example 3 | 4 | This example shows hot to send audio FSK tones 5 | using SX1278's FSK modem. 6 | 7 | Other modules that can be used for AFSK: 8 | - SX127x/RFM9x 9 | - RF69 10 | - SX1231 11 | - CC1101 12 | - Si443x/RFM2x 13 | - SX126x/LLCC68 (only devices without TCXO!) 14 | 15 | For default module settings, see the wiki page 16 | https://github.com/jgromes/RadioLib/wiki/Default-configuration 17 | 18 | For full API reference, see the GitHub Pages 19 | https://jgromes.github.io/RadioLib/ 20 | */ 21 | 22 | // include the library 23 | #include 24 | 25 | // SX1278 has the following connections: 26 | // NSS pin: 10 27 | // DIO0 pin: 2 28 | // RESET pin: 9 29 | // DIO1 pin: 3 30 | SX1278 radio = new Module(10, 2, 9, 3); 31 | 32 | // create AFSK client instance using the FSK module 33 | // this requires connection to the module direct 34 | // input pin, here connected to Arduino pin 5 35 | // SX127x/RFM9x: DIO2 36 | // RF69: DIO2 37 | // SX1231: DIO2 38 | // CC1101: GDO2 39 | // Si443x/RFM2x: GPIO 40 | // SX126x/LLCC68: DIO2 41 | AFSKClient audio(&radio, 5); 42 | 43 | void setup() { 44 | Serial.begin(9600); 45 | 46 | // initialize SX1278 with default settings 47 | Serial.print(F("[SX1278] Initializing ... ")); 48 | int state = radio.beginFSK(); 49 | 50 | // when using one of the non-LoRa modules for AFSK 51 | // (RF69, CC1101, Si4432 etc.), use the basic begin() method 52 | // int state = radio.begin(); 53 | 54 | if(state == RADIOLIB_ERR_NONE) { 55 | Serial.println(F("success!")); 56 | } else { 57 | Serial.print(F("failed, code ")); 58 | Serial.println(state); 59 | while(true); 60 | } 61 | 62 | // initialize AFSK client 63 | Serial.print(F("[AFSK] Initializing ... ")); 64 | state = audio.begin(); 65 | if(state == RADIOLIB_ERR_NONE) { 66 | Serial.println(F("success!")); 67 | } else { 68 | Serial.print(F("failed, code ")); 69 | Serial.println(state); 70 | while(true); 71 | } 72 | } 73 | 74 | void loop() { 75 | // AFSKClient can be used to transmit tones, 76 | // same as Arduino tone() function 77 | 78 | // 400 Hz tone 79 | Serial.print(F("[AFSK] 400 Hz tone ... ")); 80 | audio.tone(400); 81 | delay(1000); 82 | 83 | // silence 84 | Serial.println(F("done!")); 85 | audio.noTone(); 86 | delay(1000); 87 | 88 | // AFSKClient can also be used to transmit HAM-friendly 89 | // RTTY, Morse code, Hellschreiber, SSTV and AX.25. 90 | // Details on how to use AFSK are in the example 91 | // folders for each of the above modes. 92 | } 93 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/RF69/RF69_Transmit_AES/RF69_Transmit_AES.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib RF69 Transmit with AES Example 3 | 4 | This example transmits packets using RF69 FSK radio module. 5 | Packets are encrypted using hardware AES. 6 | NOTE: When using address filtering, the address byte is NOT encrypted! 7 | 8 | For default module settings, see the wiki page 9 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231 10 | 11 | For full API reference, see the GitHub Pages 12 | https://jgromes.github.io/RadioLib/ 13 | */ 14 | 15 | // include the library 16 | #include 17 | 18 | // RF69 has the following connections: 19 | // CS pin: 10 20 | // DIO0 pin: 2 21 | // RESET pin: 3 22 | RF69 radio = new Module(10, 2, 3); 23 | 24 | // or using RadioShield 25 | // https://github.com/jgromes/RadioShield 26 | //RF69 radio = RadioShield.ModuleA; 27 | 28 | void setup() { 29 | Serial.begin(9600); 30 | 31 | // initialize RF69 with default settings 32 | Serial.print(F("[RF69] Initializing ... ")); 33 | int state = radio.begin(); 34 | if (state == RADIOLIB_ERR_NONE) { 35 | Serial.println(F("success!")); 36 | } else { 37 | Serial.print(F("failed, code ")); 38 | Serial.println(state); 39 | while (true); 40 | } 41 | 42 | // set AES key to encrypt the packet 43 | // NOTE: the key must be exactly 16 bytes long! 44 | uint8_t key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 45 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; 46 | radio.setAESKey(key); 47 | 48 | // enable AES encryption 49 | radio.enableAES(); 50 | 51 | // AES encryption can also be disabled 52 | /* 53 | radio.disableAES(); 54 | */ 55 | } 56 | 57 | void loop() { 58 | Serial.print(F("[RF69] Transmitting packet ... ")); 59 | 60 | // you can transmit C-string or Arduino string up to 64 characters long 61 | int state = radio.transmit("Hello World!"); 62 | 63 | // you can also transmit byte array up to 64 bytes long 64 | /* 65 | byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; 66 | int state = radio.transmit(byteArr, 8); 67 | */ 68 | 69 | if (state == RADIOLIB_ERR_NONE) { 70 | // the packet was successfully transmitted 71 | Serial.println(F("success!")); 72 | 73 | } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) { 74 | // the supplied packet was longer than 64 bytes 75 | Serial.println(F("too long!")); 76 | 77 | } else { 78 | // some other error occurred 79 | Serial.print(F("failed, code ")); 80 | Serial.println(state); 81 | 82 | } 83 | 84 | // wait for a second before transmitting again 85 | delay(1000); 86 | } 87 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/Si443x/Si443x_Receive_Blocking/Si443x_Receive_Blocking.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib Si443x Blocking Receive Example 3 | 4 | This example receives packets using Si443x FSK radio module. 5 | To successfully receive data, the following settings have to be the same 6 | on both transmitter and receiver: 7 | - carrier frequency 8 | - bit rate 9 | - frequency deviation 10 | - sync word 11 | 12 | Using blocking receive is not recommended, as it will lead 13 | to significant amount of timeouts, inefficient use of processor 14 | time and can some miss packets! 15 | Instead, interrupt receive is recommended. 16 | 17 | Other modules from Si443x/RFM2x family can also be used. 18 | 19 | For default module settings, see the wiki page 20 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#si443xrfm2x 21 | 22 | For full API reference, see the GitHub Pages 23 | https://jgromes.github.io/RadioLib/ 24 | */ 25 | 26 | // include the library 27 | #include 28 | 29 | // Si4432 has the following connections: 30 | // nSEL pin: 10 31 | // nIRQ pin: 2 32 | // SDN pin: 9 33 | Si4432 radio = new Module(10, 2, 9); 34 | 35 | // or using RadioShield 36 | // https://github.com/jgromes/RadioShield 37 | //Si4432 radio = RadioShield.ModuleA; 38 | 39 | void setup() { 40 | Serial.begin(9600); 41 | 42 | // initialize Si4432 with default settings 43 | Serial.print(F("[Si4432] Initializing ... ")); 44 | int state = radio.begin(); 45 | if (state == RADIOLIB_ERR_NONE) { 46 | Serial.println(F("success!")); 47 | } else { 48 | Serial.print(F("failed, code ")); 49 | Serial.println(state); 50 | while (true); 51 | } 52 | } 53 | 54 | void loop() { 55 | Serial.print(F("[Si4432] Waiting for incoming transmission ... ")); 56 | 57 | // you can receive data as an Arduino String 58 | String str; 59 | int state = radio.receive(str); 60 | 61 | // you can also receive data as byte array 62 | /* 63 | byte byteArr[8]; 64 | int state = radio.receive(byteArr, 8); 65 | */ 66 | 67 | if (state == RADIOLIB_ERR_NONE) { 68 | // packet was successfully received 69 | Serial.println(F("success!")); 70 | 71 | // print the data of the packet 72 | Serial.print(F("[Si4432] Data:\t\t")); 73 | Serial.println(str); 74 | 75 | } else if (state == RADIOLIB_ERR_RX_TIMEOUT) { 76 | // timeout occurred while waiting for a packet 77 | Serial.println(F("timeout!")); 78 | 79 | } else if (state == RADIOLIB_ERR_CRC_MISMATCH) { 80 | // packet was received, but is malformed 81 | Serial.println(F("CRC error!")); 82 | 83 | } else { 84 | // some other error occurred 85 | Serial.print(F("failed, code ")); 86 | Serial.println(state); 87 | 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/AX25/AX25_Transmit/AX25_Transmit.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib AX.25 Transmit Example 3 | 4 | This example sends AX.25 messages using 5 | SX1278's FSK modem. 6 | 7 | Other modules that can be used for AX.25: 8 | - SX127x/RFM9x 9 | - RF69 10 | - SX1231 11 | - CC1101 12 | - SX126x 13 | - nRF24 14 | - Si443x/RFM2x 15 | 16 | For default module settings, see the wiki page 17 | https://github.com/jgromes/RadioLib/wiki/Default-configuration 18 | 19 | For full API reference, see the GitHub Pages 20 | https://jgromes.github.io/RadioLib/ 21 | */ 22 | 23 | // include the library 24 | #include 25 | 26 | // SX1278 has the following connections: 27 | // NSS pin: 10 28 | // DIO0 pin: 2 29 | // RESET pin: 9 30 | // DIO1 pin: 3 31 | SX1278 radio = new Module(10, 2, 9, 3); 32 | 33 | // or using RadioShield 34 | // https://github.com/jgromes/RadioShield 35 | //SX1278 radio = RadioShield.ModuleA; 36 | 37 | // create AX.25 client instance using the FSK module 38 | AX25Client ax25(&radio); 39 | 40 | void setup() { 41 | Serial.begin(9600); 42 | 43 | // initialize SX1278 44 | Serial.print(F("[SX1278] Initializing ... ")); 45 | // carrier frequency: 434.0 MHz 46 | // bit rate: 1.2 kbps (1200 baud 2-FSK AX.25) 47 | int state = radio.beginFSK(434.0, 1.2); 48 | 49 | // when using one of the non-LoRa modules for AX.25 50 | // (RF69, CC1101,, Si4432 etc.), use the basic begin() method 51 | // int state = radio.begin(); 52 | 53 | if(state == RADIOLIB_ERR_NONE) { 54 | Serial.println(F("success!")); 55 | } else { 56 | Serial.print(F("failed, code ")); 57 | Serial.println(state); 58 | while(true); 59 | } 60 | 61 | // initialize AX.25 client 62 | Serial.print(F("[AX.25] Initializing ... ")); 63 | // source station callsign: "N7LEM" 64 | // source station SSID: 0 65 | // preamble length: 8 bytes 66 | state = ax25.begin("N7LEM"); 67 | if(state == RADIOLIB_ERR_NONE) { 68 | Serial.println(F("success!")); 69 | } else { 70 | Serial.print(F("failed, code ")); 71 | Serial.println(state); 72 | while(true); 73 | } 74 | } 75 | 76 | void loop() { 77 | // send AX.25 unnumbered information frame 78 | Serial.print(F("[AX.25] Sending UI frame ... ")); 79 | // destination station callsign: "NJ7P" 80 | // destination station SSID: 0 81 | int state = ax25.transmit("Hello World!", "NJ7P"); 82 | if (state == RADIOLIB_ERR_NONE) { 83 | // the packet was successfully transmitted 84 | Serial.println(F("success!")); 85 | 86 | } else { 87 | // some error occurred 88 | Serial.print(F("failed, code ")); 89 | Serial.println(state); 90 | 91 | } 92 | 93 | delay(1000); 94 | } 95 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/RF69/RF69_Receive_AES/RF69_Receive_AES.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib RF69 Receive with AES Example 3 | 4 | This example receives packets using RF69 FSK radio module. 5 | Packets are decrypted using hardware AES. 6 | NOTE: When using address filtering, the address byte is NOT encrypted! 7 | 8 | For default module settings, see the wiki page 9 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231 10 | 11 | For full API reference, see the GitHub Pages 12 | https://jgromes.github.io/RadioLib/ 13 | */ 14 | 15 | // include the library 16 | #include 17 | 18 | // RF69 has the following connections: 19 | // CS pin: 10 20 | // DIO0 pin: 2 21 | // RESET pin: 3 22 | RF69 radio = new Module(10, 2, 3); 23 | 24 | // or using RadioShield 25 | // https://github.com/jgromes/RadioShield 26 | //RF69 radio = RadioShield.ModuleA; 27 | 28 | void setup() { 29 | Serial.begin(9600); 30 | 31 | // initialize RF69 with default settings 32 | Serial.print(F("[RF69] Initializing ... ")); 33 | int state = radio.begin(); 34 | if (state == RADIOLIB_ERR_NONE) { 35 | Serial.println(F("success!")); 36 | } else { 37 | Serial.print(F("failed, code ")); 38 | Serial.println(state); 39 | while (true); 40 | } 41 | 42 | // set AES key that will be used to decrypt the packet 43 | // NOTE: the key must be exactly 16 bytes long! 44 | uint8_t key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 45 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; 46 | radio.setAESKey(key); 47 | 48 | // enable AES encryption 49 | radio.enableAES(); 50 | 51 | // AES encryption can also be disabled 52 | /* 53 | radio.disableAES(); 54 | */ 55 | } 56 | 57 | void loop() { 58 | Serial.print(F("[RF69] Waiting for incoming transmission ... ")); 59 | 60 | // you can receive data as an Arduino String 61 | String str; 62 | int state = radio.receive(str); 63 | 64 | // you can also receive data as byte array 65 | /* 66 | byte byteArr[8]; 67 | int state = radio.receive(byteArr, 8); 68 | */ 69 | 70 | if (state == RADIOLIB_ERR_NONE) { 71 | // packet was successfully received 72 | Serial.println(F("success!")); 73 | 74 | // print the data of the packet 75 | Serial.print(F("[RF69] Data:\t\t")); 76 | Serial.println(str); 77 | 78 | } else if (state == RADIOLIB_ERR_RX_TIMEOUT) { 79 | // timeout occurred while waiting for a packet 80 | Serial.println(F("timeout!")); 81 | 82 | } else if (state == RADIOLIB_ERR_CRC_MISMATCH) { 83 | // packet was received, but is malformed 84 | Serial.println(F("CRC error!")); 85 | 86 | } else { 87 | // some other error occurred 88 | Serial.print(F("failed, code ")); 89 | Serial.println(state); 90 | 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/AFSK/AFSK_External_Radio/AFSK_External_Radio.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib AFSK External Radio example 3 | 4 | This example shows how to use your Arduino 5 | as modulator for an external analogue FM radio. 6 | 7 | The example sends APRS position reports with 8 | audio modulated as AFSK at 1200 baud using 9 | Bell 202 tones. However, any other AFSK 10 | protocol (RTTY, SSTV, etc.) may be used as well. 11 | 12 | DO NOT transmit in APRS bands unless 13 | you have a ham radio license! 14 | 15 | For full API reference, see the GitHub Pages 16 | https://jgromes.github.io/RadioLib/ 17 | */ 18 | 19 | // include the library 20 | #include 21 | 22 | // create a dummy radio module 23 | ExternalRadio radio; 24 | 25 | // create AFSK client instance using the external radio 26 | // pin 5 is connected to the radio sound input 27 | AFSKClient audio(&radio, 5); 28 | 29 | // create AX.25 client instance using the AFSK instance 30 | AX25Client ax25(&audio); 31 | 32 | // create APRS client instance using the AX.25 client 33 | APRSClient aprs(&ax25); 34 | 35 | void setup() { 36 | Serial.begin(9600); 37 | 38 | // initialize AX.25 client 39 | Serial.print(F("[AX.25] Initializing ... ")); 40 | // source station callsign: "N7LEM" 41 | // source station SSID: 0 42 | // preamble length: 8 bytes 43 | int16_t state = ax25.begin("N7LEM"); 44 | if(state == RADIOLIB_ERR_NONE) { 45 | Serial.println(F("success!")); 46 | } else { 47 | Serial.print(F("failed, code ")); 48 | Serial.println(state); 49 | while(true); 50 | } 51 | 52 | // initialize APRS client 53 | Serial.print(F("[APRS] Initializing ... ")); 54 | // symbol: '>' (car) 55 | state = aprs.begin('>'); 56 | if(state == RADIOLIB_ERR_NONE) { 57 | Serial.println(F("success!")); 58 | } else { 59 | Serial.print(F("failed, code ")); 60 | Serial.println(state); 61 | while(true); 62 | } 63 | } 64 | 65 | void loop() { 66 | Serial.print(F("[APRS] Sending position ... ")); 67 | 68 | // send a location without message or timestamp 69 | int state = aprs.sendPosition("N0CALL", 0, "4911.67N", "01635.96E"); 70 | delay(500); 71 | 72 | // send a location with message and without timestamp 73 | state |= aprs.sendPosition("N0CALL", 0, "4911.67N", "01635.96E", "I'm here!"); 74 | delay(500); 75 | 76 | // send a location with message and timestamp 77 | state |= aprs.sendPosition("N0CALL", 0, "4911.67N", "01635.96E", "I'm here!", "093045z"); 78 | delay(500); 79 | 80 | if(state == RADIOLIB_ERR_NONE) { 81 | Serial.println(F("success!")); 82 | } else { 83 | Serial.print(F("failed, code ")); 84 | Serial.println(state); 85 | } 86 | 87 | // wait one minute before transmitting again 88 | delay(60000); 89 | } 90 | -------------------------------------------------------------------------------- /src/sdlog.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by FLN1021 on 2023/9/5. 3 | // 4 | 5 | #ifndef PAGER_RECEIVE_SDLOG_HPP 6 | #define PAGER_RECEIVE_SDLOG_HPP 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "utilities.h" 13 | #include "ESPTelnet.h" 14 | #include "boards.hpp" 15 | 16 | #define MAX_LOG_SIZE 500000 // 500000 default 17 | #define MAX_CSV_SIZE 500000 18 | #define LOG_VERBOSITY 0 19 | 20 | class SD_LOG { 21 | public: 22 | // SD_LOG() = default; 23 | SD_LOG(); 24 | 25 | // explicit SD_LOG(fs::FS &fs); 26 | void setFS(fs::FS &fs); 27 | 28 | int begin(const char *path); 29 | 30 | int beginCSV(const char *path); 31 | 32 | int beginCD(const char *path); 33 | 34 | void appendCD(const uint8_t *data, size_t size); 35 | 36 | void endCD(); 37 | 38 | void getFilenameCSV(const char *path); 39 | 40 | void append(const char *format, ...); 41 | 42 | void append(int level, const char *format, ...); 43 | 44 | void appendCSV(const char *format, ...); 45 | 46 | void appendBuffer(const char *format, ...); 47 | 48 | void appendBuffer(int level, const char *format, ...); 49 | 50 | void sendBufferLOG(); 51 | 52 | void appendBufferCSV(const char *format, ...); 53 | 54 | void sendBufferCSV(); 55 | 56 | void printTel(unsigned int chars, ESPTelnet &tel); 57 | 58 | File logFile(char op); 59 | 60 | void reopen(); 61 | 62 | void end(); 63 | 64 | static void reopenSD(); 65 | 66 | void disableSizeCheck(); 67 | 68 | void enableSizeCheck(); 69 | 70 | bool status() const; 71 | 72 | private: 73 | void getFilename(const char *path); 74 | 75 | void writeHeader(); 76 | 77 | void writeHeaderCSV(); 78 | 79 | int createIndex(File cwd, const String& index_path); 80 | 81 | int readIndex(const File& cwd); 82 | 83 | void updateIndex(const String& path, int counter); 84 | 85 | String log_path; 86 | String csv_path; 87 | fs::FS *filesys; 88 | String large_buffer; 89 | String large_buffer_csv; 90 | File log; 91 | File csv; 92 | File cd; 93 | int log_count; // Actual file count - 1, default = 0. 94 | char filename[32]; // ="" 95 | char filename_csv[32]; 96 | bool sd_log; // = false 97 | bool sd_csv; 98 | bool sd_cd; 99 | // bool have_sd = false; 100 | // bool haveNTP = false; 101 | bool is_newfile; // = false 102 | bool is_startline; // = true 103 | bool size_checked; 104 | bool is_newfile_csv; 105 | bool is_startline_csv; 106 | const char *log_directory; 107 | const char *csv_directory; 108 | 109 | struct tm timein{}; 110 | }; 111 | 112 | 113 | #endif //PAGER_RECEIVE_SDLOG_HPP 114 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/Si443x/Si443x_Transmit_Blocking/Si443x_Transmit_Blocking.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib Si443x Blocking Transmit Example 3 | 4 | This example transmits packets using Si4432 FSK radio module. 5 | Each packet contains up to 64 bytes of data, in the form of: 6 | - Arduino String 7 | - null-terminated char array (C-string) 8 | - arbitrary binary data (byte array) 9 | 10 | Other modules from Si443x/RFM2x family can also be used. 11 | 12 | Using blocking transmit is not recommended, as it will lead 13 | to inefficient use of processor time! 14 | Instead, interrupt transmit is recommended. 15 | 16 | For default module settings, see the wiki page 17 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#si443xrfm2x 18 | 19 | For full API reference, see the GitHub Pages 20 | https://jgromes.github.io/RadioLib/ 21 | */ 22 | 23 | // include the library 24 | #include 25 | 26 | // Si4432 has the following connections: 27 | // nSEL pin: 10 28 | // nIRQ pin: 2 29 | // SDN pin: 9 30 | Si4432 radio = new Module(10, 2, 9); 31 | 32 | // or using RadioShield 33 | // https://github.com/jgromes/RadioShield 34 | //Si4432 radio = RadioShield.ModuleA; 35 | 36 | void setup() { 37 | Serial.begin(9600); 38 | 39 | // initialize Si4432 with default settings 40 | Serial.print(F("[Si4432] Initializing ... ")); 41 | int state = radio.begin(); 42 | if (state == RADIOLIB_ERR_NONE) { 43 | Serial.println(F("success!")); 44 | } else { 45 | Serial.print(F("failed, code ")); 46 | Serial.println(state); 47 | while (true); 48 | } 49 | } 50 | 51 | // counter to keep track of transmitted packets 52 | int count = 0; 53 | 54 | void loop() { 55 | Serial.print(F("[Si4432] Transmitting packet ... ")); 56 | 57 | // you can transmit C-string or Arduino string up to 58 | // 64 characters long 59 | String str = "Hello World! #" + String(count++); 60 | int state = radio.transmit(str); 61 | 62 | // you can also transmit byte array up to 64 bytes long 63 | /* 64 | byte byteArr[] = {0x01, 0x23, 0x45, 0x56, 0x78, 0xAB, 0xCD, 0xEF}; 65 | int state = radio.transmit(byteArr, 8); 66 | */ 67 | 68 | if (state == RADIOLIB_ERR_NONE) { 69 | // the packet was successfully transmitted 70 | Serial.println(F(" success!")); 71 | 72 | } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) { 73 | // the supplied packet was longer than 256 bytes 74 | Serial.println(F(" too long!")); 75 | 76 | } else if (state == RADIOLIB_ERR_TX_TIMEOUT) { 77 | // timeout occured while transmitting packet 78 | Serial.println(F(" timeout!")); 79 | 80 | } else { 81 | // some other error occurred 82 | Serial.print(F("failed, code ")); 83 | Serial.println(state); 84 | 85 | } 86 | 87 | // wait for a second before transmitting again 88 | delay(1000); 89 | } 90 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/RF69/RF69_Receive_Blocking/RF69_Receive_Blocking.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib RF69 Blocking Receive Example 3 | 4 | This example receives packets using RF69 FSK radio module. 5 | To successfully receive data, the following settings have to be the same 6 | on both transmitter and receiver: 7 | - carrier frequency 8 | - bit rate 9 | - frequency deviation 10 | - sync word 11 | 12 | Using blocking receive is not recommended, as it will lead 13 | to significant amount of timeouts, inefficient use of processor 14 | time and can miss some packets! 15 | Instead, interrupt receive is recommended. 16 | 17 | For default module settings, see the wiki page 18 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231 19 | 20 | For full API reference, see the GitHub Pages 21 | https://jgromes.github.io/RadioLib/ 22 | */ 23 | 24 | // include the library 25 | #include 26 | 27 | // RF69 has the following connections: 28 | // CS pin: 10 29 | // DIO0 pin: 2 30 | // RESET pin: 3 31 | RF69 radio = new Module(10, 2, 3); 32 | 33 | // or using RadioShield 34 | // https://github.com/jgromes/RadioShield 35 | //RF69 radio = RadioShield.ModuleA; 36 | 37 | void setup() { 38 | Serial.begin(9600); 39 | 40 | // initialize RF69 with default settings 41 | Serial.print(F("[RF69] Initializing ... ")); 42 | int state = radio.begin(); 43 | if (state == RADIOLIB_ERR_NONE) { 44 | Serial.println(F("success!")); 45 | } else { 46 | Serial.print(F("failed, code ")); 47 | Serial.println(state); 48 | while (true); 49 | } 50 | } 51 | 52 | void loop() { 53 | Serial.print(F("[RF69] Waiting for incoming transmission ... ")); 54 | 55 | // you can receive data as an Arduino String 56 | String str; 57 | int state = radio.receive(str); 58 | 59 | // you can also receive data as byte array 60 | /* 61 | byte byteArr[8]; 62 | int state = radio.receive(byteArr, 8); 63 | */ 64 | 65 | if (state == RADIOLIB_ERR_NONE) { 66 | // packet was successfully received 67 | Serial.println(F("success!")); 68 | 69 | // print the data of the packet 70 | Serial.print(F("[RF69] Data:\t\t")); 71 | Serial.println(str); 72 | 73 | // print RSSI (Received Signal Strength Indicator) 74 | // of the last received packet 75 | Serial.print(F("[RF69] RSSI:\t\t")); 76 | Serial.print(radio.getRSSI()); 77 | Serial.println(F(" dBm")); 78 | 79 | } else if (state == RADIOLIB_ERR_RX_TIMEOUT) { 80 | // timeout occurred while waiting for a packet 81 | Serial.println(F("timeout!")); 82 | 83 | } else if (state == RADIOLIB_ERR_CRC_MISMATCH) { 84 | // packet was received, but is malformed 85 | Serial.println(F("CRC error!")); 86 | 87 | } else { 88 | // some other error occurred 89 | Serial.print(F("failed, code ")); 90 | Serial.println(state); 91 | 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /lib/RadioLib/src/ArduinoHal.h: -------------------------------------------------------------------------------- 1 | // make sure this is always compiled 2 | #include "TypeDef.h" 3 | 4 | #if !defined(_RADIOLIB_ARDUINOHAL_H) 5 | #define _RADIOLIB_ARDUINOHAL_H 6 | 7 | // this file only makes sense for Arduino builds 8 | #if defined(RADIOLIB_BUILD_ARDUINO) 9 | 10 | #if defined(RADIOLIB_MBED_TONE_OVERRIDE) 11 | #include "mbed.h" 12 | #endif 13 | 14 | #include "Hal.h" 15 | 16 | #include 17 | 18 | /*! 19 | \class ArduinoHal 20 | \brief Arduino default hardware abstraction library implementation. 21 | This class can be extended to support other Arduino platform or change behaviour of the default implementation. 22 | */ 23 | class ArduinoHal : public RadioLibHal { 24 | public: 25 | /*! 26 | \brief Arduino Hal constructor. Will use the default SPI interface and automatically initialize it. 27 | */ 28 | ArduinoHal(); 29 | 30 | /*! 31 | \brief Arduino Hal constructor. Will not attempt SPI interface initialization. 32 | \param spi SPI interface to be used, can also use software SPI implementations. 33 | \param spiSettings SPI interface settings. 34 | */ 35 | ArduinoHal(SPIClass& spi, SPISettings spiSettings = RADIOLIB_DEFAULT_SPI_SETTINGS); 36 | 37 | // implementations of pure virtual RadioLibHal methods 38 | void pinMode(uint32_t pin, uint32_t mode) override; 39 | void digitalWrite(uint32_t pin, uint32_t value) override; 40 | uint32_t digitalRead(uint32_t pin) override; 41 | void attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) override; 42 | void detachInterrupt(uint32_t interruptNum) override; 43 | void delay(unsigned long ms) override; 44 | void delayMicroseconds(unsigned long us) override; 45 | unsigned long millis() override; 46 | unsigned long micros() override; 47 | long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override; 48 | void spiBegin() override; 49 | void spiBeginTransaction() override; 50 | void spiTransfer(uint8_t* out, size_t len, uint8_t* in) override; 51 | void spiEndTransaction() override; 52 | void spiEnd() override; 53 | 54 | // implementations of virtual RadioLibHal methods 55 | void init() override; 56 | void term() override; 57 | void tone(uint32_t pin, unsigned int frequency, unsigned long duration = 0) override; 58 | void noTone(uint32_t pin) override; 59 | void yield() override; 60 | uint32_t pinToInterrupt(uint32_t pin) override; 61 | 62 | #if !defined(RADIOLIB_GODMODE) 63 | private: 64 | #endif 65 | SPIClass* spi = NULL; 66 | SPISettings spiSettings = RADIOLIB_DEFAULT_SPI_SETTINGS; 67 | bool initInterface = false; 68 | 69 | #if defined(RADIOLIB_MBED_TONE_OVERRIDE) 70 | mbed::PwmOut *pwmPin = NULL; 71 | #endif 72 | 73 | #if defined(ESP32) 74 | int32_t prev = -1; 75 | #endif 76 | }; 77 | 78 | #endif 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /src/BCH3121.md: -------------------------------------------------------------------------------- 1 | # 关于BCH(31,21)纠错码的说明及资料 2 | 3 |   BCH(31,21)纠错码是POCSAG传输协议使用的纠错码算法。除BCH(31,21)外,POCSAG还使用奇偶校验码。以下是一个典型的POCSAG数据帧结构: 4 | 5 | | 位置 | 1位 | 2-21位 | 22-31位 | 32位 | 6 | |----|:----:|:-----:|:------:|:-----:| 7 | | 内容 | 数据类型 | 数据 | BCH纠错码 | 奇偶校验码 | 8 | | 长度 | 1bit | 20bit | 10bit | 1bit | 9 | 10 | 例如同步码**0x7CD215D8**转换成二进制就是 11 | 12 | ```asm 13 | 01111100110100100001010111011000 14 | ``` 15 | 16 | 然后按上面的格式分割就是 17 | 18 | | 1位 | 2-21位 | 22-31位 | 32位 | 19 | |:----:|:--------------------:|:----------:|:-----:| 20 | | 0 | 11111001101001000010 | 1011101100 | 0 | 21 | | 数据类型 | 数据内容 | BCH纠错码 | 奇偶校验码 | 22 | 23 | 可见数据帧为32bit组成的数据包,其中占10bit的BCH纠错码负责校验及纠正前21位的错误,占1bit的奇偶校验码负责校验前31位。 24 | 25 | ## 1. BCH纠错码 26 | 27 |   BCH纠错码的编码规律我并不清楚,在参考了一堆资料后我终于放弃理解了。参考资料我列在下面: 28 | 29 | - [BCH Codes](https://math.mit.edu/~shor/18.310/BCH.pdf) 30 | - [6.0 Decoding BCH and RS Codes](https://pages.jh.edu/bcooper8/sigma_files/ERROR_CONTROL_CODING/06dec.pdf) 31 | - [【举例子详细分析】BCH码(BCH code)](https://zhuanlan.zhihu.com/p/95909150) 32 | - [BCH Codes: Constructing them and finding the Syndrome of a Message](https://math.mit.edu/~djk/18.310/18.310F04/bch_codes.html) 33 | - [bch3121.c](http://www.sxlist.com/techref/method/error/bch3121.c) 34 | - …… 35 | 36 | 总之看得我头疼。反正现在知道BCH(31,21) 37 | 就是使用前面21个bit数据计算出一个10bit的纠错码,总共31bit,可以纠正前21bit中2个随机错误应该就行了。BCH(31,21) 38 | 的解码代码在[BCH3121.cpp](BCH3121.cpp)、[BCH3121A.c](BCH3121A.c)中都有,只是实现方式不一样,后面再说。 39 | 40 | ## 2. 奇偶校验码 41 | 42 |   奇偶校验码原理很简单,就是数1的个数,然后按情况填1。POCSAG协议采用偶校验,即前31位中有偶数个1,奇偶校验位(第32位) 43 | 就填0,不然就填1。比如POCSAG的同步码**0x7CD215D8**展开成二进制就是 44 | 45 | ```asm 46 | 01111100110100100001010111011000 47 | ``` 48 | 49 | 前31位中总共有16个1,为偶数,故最后一位填0。反之,若有奇数个1,则填1。如IDLE码**0x7A89C197**,展开后即 50 | 51 | ```asm 52 | 01111010100010011100000110010111 53 | ``` 54 | 55 | 前31位有15个1,为奇数,最后一位填0。同理可得32位完整的数据帧中,1的个数总为偶数个。 56 | 57 | ## 3. 需要完成的事项 58 | 59 | **已知:**[BCH3121.cpp](BCH3121.cpp)、[BCH3121A.c](BCH3121A.c)中都有以上两种的纠错码的解码代码,其中: 60 | 61 | - [BCH3121.cpp](BCH3121.cpp) 似乎采用了较为标准的解码算法,但是并没有使用奇偶校验码提高准确率/无法应对BCH码本身出错的情况。 62 | - [BCH3121A.c](BCH3121A.c) 似乎使用了两种纠错码,但是原理不明,还需进一步分析。并且由于使用了某种暴力算法解码BCH,BCH的解码效果纯看运气。 63 | - 更详细的还请自己看代码吧。 64 | 65 | **目标:结合BCH纠错码、奇偶校验码以最大程度的检查/修正接收过程中产生的错误。** 66 | 67 | **要求:** 输入的32位数据帧形式为**uint32_t & (unsigned int &)** 68 | ,需要在函数体内改变数据帧的值(通过传入指针的形式,具体实现可以参考上面给的代码文件)来输出修正后的32位数据帧,返回true或false以表示能否完成数据纠错(BCH( 69 | 31,21)码无法修正大于2个错误),可以在给出代码的基础上修改。基本上形式如下: 70 | 71 | ```c++ 72 | bool function(uint32_t &data, .../*别的参数随意*/) { 73 | // 对data进行BCH纠错及奇偶校验 74 | if (/*能纠错*/) { 75 | data = data_corrected; // 通过指针把纠错后的数据赋回给data 76 | return true; 77 | } else { 78 | return false; 79 | } 80 | } 81 | ``` 82 | 83 | 目前思路:在[BCH3121.cpp](BCH3121.cpp) 84 | 的基础上,先纠错,然后如果返回了false就直接返回false,返回true再进行一次奇偶校验,奇偶校验也通过就返回true,不过就返回false。别的暂时没想到,最好看看[BCH3121A.c](BCH3121A.c) 85 | 是怎么结合这两种纠错码的,然后参考一下。 86 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/SX128x/SX128x_Ranging/SX128x_Ranging.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib SX128x Ranging Example 3 | 4 | This example performs ranging exchange between two 5 | SX1280 LoRa radio modules. Ranging allows to measure 6 | distance between the modules using time-of-flight 7 | measurement. 8 | 9 | Only SX1280 and SX1282 without external RF switch support ranging! 10 | 11 | Note that to get accurate ranging results, calibration is needed! 12 | The process is described in Semtech SX1280 Application Note AN1200.29 13 | 14 | For default module settings, see the wiki page 15 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem 16 | 17 | For full API reference, see the GitHub Pages 18 | https://jgromes.github.io/RadioLib/ 19 | */ 20 | 21 | // include the library 22 | #include 23 | 24 | // SX1280 has the following connections: 25 | // NSS pin: 10 26 | // DIO1 pin: 2 27 | // NRST pin: 3 28 | // BUSY pin: 9 29 | SX1280 radio = new Module(10, 2, 3, 9); 30 | 31 | // or using RadioShield 32 | // https://github.com/jgromes/RadioShield 33 | //SX1280 radio = RadioShield.ModuleA; 34 | 35 | void setup() { 36 | Serial.begin(9600); 37 | 38 | // initialize SX1280 with default settings 39 | Serial.print(F("[SX1280] Initializing ... ")); 40 | int state = radio.begin(); 41 | if (state == RADIOLIB_ERR_NONE) { 42 | Serial.println(F("success!")); 43 | } else { 44 | Serial.print(F("failed, code ")); 45 | Serial.println(state); 46 | while (true); 47 | } 48 | } 49 | 50 | void loop() { 51 | Serial.print(F("[SX1280] Ranging ... ")); 52 | 53 | // start ranging exchange 54 | // range as master: true 55 | // slave address: 0x12345678 56 | int state = radio.range(true, 0x12345678); 57 | 58 | // the other module must be configured as slave with the same address 59 | /* 60 | int state = radio.range(false, 0x12345678); 61 | */ 62 | 63 | // if ranging calibration is known, it can be provided 64 | // this should improve the accuracy and precision 65 | /* 66 | uint16_t calibration[3][6] = { 67 | { 10299, 10271, 10244, 10242, 10230, 10246 }, 68 | { 11486, 11474, 11453, 11426, 11417, 11401 }, 69 | { 13308, 13493, 13528, 13515, 13430, 13376 } 70 | }; 71 | 72 | int state = radio.range(true, 0x12345678, calibration); 73 | */ 74 | 75 | if (state == RADIOLIB_ERR_NONE) { 76 | // ranging finished successfully 77 | Serial.println(F("success!")); 78 | Serial.print(F("[SX1280] Distance:\t\t\t")); 79 | Serial.print(radio.getRangingResult()); 80 | Serial.println(F(" meters (raw)")); 81 | 82 | } else if (state == RADIOLIB_ERR_RANGING_TIMEOUT) { 83 | // timed out waiting for ranging packet 84 | Serial.println(F("timed out!")); 85 | 86 | } else { 87 | // some other error occurred 88 | Serial.print(F("failed, code ")); 89 | Serial.println(state); 90 | 91 | } 92 | 93 | // wait for a second before ranging again 94 | delay(1000); 95 | } 96 | -------------------------------------------------------------------------------- /lib/RadioLib/src/protocols/Hellschreiber/Hellschreiber.cpp: -------------------------------------------------------------------------------- 1 | #include "Hellschreiber.h" 2 | 3 | #if !defined(RADIOLIB_EXCLUDE_HELLSCHREIBER) 4 | 5 | HellClient::HellClient(PhysicalLayer* phy) { 6 | phyLayer = phy; 7 | lineFeed = " "; 8 | #if !defined(RADIOLIB_EXCLUDE_AFSK) 9 | audioClient = nullptr; 10 | #endif 11 | } 12 | 13 | #if !defined(RADIOLIB_EXCLUDE_AFSK) 14 | HellClient::HellClient(AFSKClient* audio) { 15 | phyLayer = audio->phyLayer; 16 | lineFeed = " "; 17 | audioClient = audio; 18 | } 19 | #endif 20 | 21 | int16_t HellClient::begin(float base, float rate) { 22 | // calculate 24-bit frequency 23 | baseFreqHz = base; 24 | baseFreq = (base * 1000000.0) / phyLayer->getFreqStep(); 25 | 26 | // calculate "pixel" duration 27 | pixelDuration = 1000000.0/rate; 28 | 29 | // configure for direct mode 30 | return(phyLayer->startDirect()); 31 | } 32 | 33 | size_t HellClient::printGlyph(uint8_t* buff) { 34 | // print the character 35 | Module* mod = phyLayer->getMod(); 36 | bool transmitting = false; 37 | for(uint8_t mask = 0x40; mask >= 0x01; mask >>= 1) { 38 | for(int8_t i = RADIOLIB_HELL_FONT_HEIGHT - 1; i >= 0; i--) { 39 | uint32_t start = mod->hal->micros(); 40 | if((buff[i] & mask) && (!transmitting)) { 41 | transmitting = true; 42 | transmitDirect(baseFreq, baseFreqHz); 43 | } else if((!(buff[i] & mask)) && (transmitting)) { 44 | transmitting = false; 45 | standby(); 46 | } 47 | mod->waitForMicroseconds(start, pixelDuration); 48 | } 49 | } 50 | 51 | // make sure transmitter is off 52 | standby(); 53 | 54 | return(1); 55 | } 56 | 57 | void HellClient::setInversion(bool inv) { 58 | invert = inv; 59 | } 60 | 61 | size_t HellClient::write(uint8_t b) { 62 | // convert to position in font buffer 63 | uint8_t pos = b; 64 | if((pos >= ' ') && (pos <= '_')) { 65 | pos -= ' '; 66 | } else if((pos >= 'a') && (pos <= 'z')) { 67 | pos -= (2*' '); 68 | } else { 69 | return(0); 70 | } 71 | 72 | // fetch character from flash 73 | uint8_t buff[RADIOLIB_HELL_FONT_WIDTH]; 74 | buff[0] = 0x00; 75 | for(uint8_t i = 0; i < RADIOLIB_HELL_FONT_WIDTH - 2; i++) { 76 | buff[i + 1] = RADIOLIB_NONVOLATILE_READ_BYTE(&HellFont[pos][i]); 77 | } 78 | buff[RADIOLIB_HELL_FONT_WIDTH - 1] = 0x00; 79 | 80 | // print the character 81 | return(printGlyph(buff)); 82 | } 83 | 84 | int16_t HellClient::transmitDirect(uint32_t freq, uint32_t freqHz) { 85 | #if !defined(RADIOLIB_EXCLUDE_AFSK) 86 | if(audioClient != nullptr) { 87 | return(audioClient->tone(freqHz)); 88 | } 89 | #endif 90 | return(phyLayer->transmitDirect(freq)); 91 | } 92 | 93 | int16_t HellClient::standby() { 94 | #if !defined(RADIOLIB_EXCLUDE_AFSK) 95 | if(audioClient != nullptr) { 96 | return(audioClient->noTone(invert)); 97 | } 98 | #endif 99 | return(phyLayer->standby(RADIOLIB_STANDBY_WARM)); 100 | } 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/RFM9x/RFM95.cpp: -------------------------------------------------------------------------------- 1 | #include "RFM95.h" 2 | #if !defined(RADIOLIB_EXCLUDE_RFM9X) 3 | 4 | RFM95::RFM95(Module* mod) : SX1278(mod) { 5 | 6 | } 7 | 8 | int16_t RFM95::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, uint8_t gain) { 9 | // execute common part 10 | int16_t state = SX127x::begin(RADIOLIB_RFM9X_CHIP_VERSION_OFFICIAL, syncWord, preambleLength); 11 | if(state == RADIOLIB_ERR_CHIP_NOT_FOUND) { 12 | // SX127X_REG_VERSION might be set 0x12 13 | state = SX127x::begin(RADIOLIB_RFM9X_CHIP_VERSION_UNOFFICIAL, syncWord, preambleLength); 14 | RADIOLIB_ASSERT(state); 15 | } else if(state != RADIOLIB_ERR_NONE) { 16 | // some other error 17 | return(state); 18 | } 19 | RADIOLIB_DEBUG_PRINTLN("M\tSX1278"); 20 | RADIOLIB_DEBUG_PRINTLN("M\tRFM95"); 21 | 22 | // configure publicly accessible settings 23 | state = setBandwidth(bw); 24 | RADIOLIB_ASSERT(state); 25 | 26 | state = setFrequency(freq); 27 | RADIOLIB_ASSERT(state); 28 | 29 | state = setSpreadingFactor(sf); 30 | RADIOLIB_ASSERT(state); 31 | 32 | state = setCodingRate(cr); 33 | RADIOLIB_ASSERT(state); 34 | 35 | state = setOutputPower(power); 36 | RADIOLIB_ASSERT(state); 37 | 38 | state = setGain(gain); 39 | 40 | return(state); 41 | } 42 | 43 | int16_t RFM95::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, bool enableOOK) { 44 | // execute common part 45 | int16_t state = SX127x::beginFSK(RADIOLIB_RFM9X_CHIP_VERSION_OFFICIAL, freqDev, rxBw, preambleLength, enableOOK); 46 | if(state == RADIOLIB_ERR_CHIP_NOT_FOUND) { 47 | // SX127X_REG_VERSION might be set 0x12 48 | state = SX127x::beginFSK(RADIOLIB_RFM9X_CHIP_VERSION_UNOFFICIAL, freqDev, rxBw, preambleLength, enableOOK); 49 | RADIOLIB_ASSERT(state); 50 | } else if(state != RADIOLIB_ERR_NONE) { 51 | // some other error 52 | return(state); 53 | } 54 | RADIOLIB_DEBUG_PRINTLN("M\tSX1278"); 55 | RADIOLIB_DEBUG_PRINTLN("M\tRFM95"); 56 | 57 | // configure settings not accessible by API 58 | state = configFSK(); 59 | RADIOLIB_ASSERT(state); 60 | 61 | // configure publicly accessible settings 62 | state = setFrequency(freq); 63 | RADIOLIB_ASSERT(state); 64 | 65 | state = setBitRate(br); 66 | RADIOLIB_ASSERT(state); 67 | 68 | state = setOutputPower(power); 69 | RADIOLIB_ASSERT(state); 70 | 71 | if(enableOOK) { 72 | state = setDataShapingOOK(RADIOLIB_SHAPING_NONE); 73 | RADIOLIB_ASSERT(state); 74 | } else { 75 | state = setDataShaping(RADIOLIB_SHAPING_NONE); 76 | RADIOLIB_ASSERT(state); 77 | } 78 | 79 | return(state); 80 | } 81 | 82 | int16_t RFM95::setFrequency(float freq) { 83 | RADIOLIB_CHECK_RANGE(freq, 862.0, 1020.0, RADIOLIB_ERR_INVALID_FREQUENCY); 84 | 85 | // set frequency and if successful, save the new setting 86 | int16_t state = SX127x::setFrequencyRaw(freq); 87 | if(state == RADIOLIB_ERR_NONE) { 88 | SX127x::frequency = freq; 89 | } 90 | return(state); 91 | } 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/SX1231/SX1231.cpp: -------------------------------------------------------------------------------- 1 | #include "SX1231.h" 2 | #if !defined(RADIOLIB_EXCLUDE_SX1231) 3 | 4 | SX1231::SX1231(Module* mod) : RF69(mod) { 5 | 6 | } 7 | 8 | int16_t SX1231::begin(float freq, float br, float freqDev, float rxBw, int8_t power, uint8_t preambleLen) { 9 | // set module properties 10 | this->mod->init(); 11 | this->mod->hal->pinMode(this->mod->getIrq(), this->mod->hal->GpioModeInput); 12 | this->mod->hal->pinMode(this->mod->getRst(), this->mod->hal->GpioModeOutput); 13 | 14 | // try to find the SX1231 chip 15 | uint8_t i = 0; 16 | bool flagFound = false; 17 | while((i < 10) && !flagFound) { 18 | int16_t version = getChipVersion(); 19 | if((version == 0x21) || (version == 0x22) || (version == 0x23)) { 20 | flagFound = true; 21 | this->chipRevision = version; 22 | } else { 23 | RADIOLIB_DEBUG_PRINTLN("SX1231 not found! (%d of 10 tries) RF69_REG_VERSION == 0x%04X, expected 0x0021 / 0x0022 / 0x0023", i + 1, version); 24 | this->mod->hal->delay(10); 25 | i++; 26 | } 27 | } 28 | 29 | if(!flagFound) { 30 | RADIOLIB_DEBUG_PRINTLN("No SX1231 found!"); 31 | this->mod->term(); 32 | return(RADIOLIB_ERR_CHIP_NOT_FOUND); 33 | } 34 | RADIOLIB_DEBUG_PRINTLN("M\tSX1231"); 35 | 36 | // configure settings not accessible by API 37 | int16_t state = config(); 38 | RADIOLIB_ASSERT(state); 39 | RADIOLIB_DEBUG_PRINTLN("M\tRF69"); 40 | 41 | // configure publicly accessible settings 42 | state = setFrequency(freq); 43 | RADIOLIB_ASSERT(state); 44 | 45 | // configure bitrate 46 | this->rxBandwidth = 125.0; 47 | state = setBitRate(br); 48 | RADIOLIB_ASSERT(state); 49 | 50 | // configure default RX bandwidth 51 | state = setRxBandwidth(rxBw); 52 | RADIOLIB_ASSERT(state); 53 | 54 | // configure default frequency deviation 55 | state = setFrequencyDeviation(freqDev); 56 | RADIOLIB_ASSERT(state); 57 | 58 | // configure default TX output power 59 | state = setOutputPower(power); 60 | RADIOLIB_ASSERT(state); 61 | 62 | // configure default preamble length 63 | state = setPreambleLength(preambleLen); 64 | RADIOLIB_ASSERT(state); 65 | 66 | // default sync word values 0x2D01 is the same as the default in LowPowerLab RFM69 library 67 | uint8_t syncWord[] = {0x2D, 0x01}; 68 | state = setSyncWord(syncWord, 2); 69 | RADIOLIB_ASSERT(state); 70 | 71 | // set default packet length mode 72 | state = variablePacketLengthMode(); 73 | if (state != RADIOLIB_ERR_NONE) { 74 | return(state); 75 | } 76 | 77 | // SX1231 V2a only 78 | if(this->chipRevision == RADIOLIB_SX1231_CHIP_REVISION_2_A) { 79 | // modify default OOK threshold value 80 | state = this->mod->SPIsetRegValue(RADIOLIB_SX1231_REG_TEST_OOK, RADIOLIB_SX1231_OOK_DELTA_THRESHOLD); 81 | RADIOLIB_ASSERT(state); 82 | 83 | // enable OCP with 95 mA limit 84 | state = this->mod->SPIsetRegValue(RADIOLIB_RF69_REG_OCP, RADIOLIB_RF69_OCP_ON | RADIOLIB_RF69_OCP_TRIM, 4, 0); 85 | RADIOLIB_ASSERT(state); 86 | } 87 | 88 | return(RADIOLIB_ERR_NONE); 89 | } 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/AFSK/AFSK_Tone_AM/AFSK_Tone_AM.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib AM-modulated AFSK Example 3 | 4 | This example shows hot to send AM-modulated 5 | audio FSK tones using SX1278's OOK modem. 6 | 7 | Other modules that can be used for AFSK: 8 | - SX127x/RFM9x 9 | - RF69 10 | - SX1231 11 | - CC1101 12 | 13 | For default module settings, see the wiki page 14 | https://github.com/jgromes/RadioLib/wiki/Default-configuration 15 | 16 | For full API reference, see the GitHub Pages 17 | https://jgromes.github.io/RadioLib/ 18 | */ 19 | 20 | // include the library 21 | #include 22 | 23 | // SX1278 has the following connections: 24 | // NSS pin: 10 25 | // DIO0 pin: 2 26 | // RESET pin: 9 27 | SX1278 radio = new Module(10, 2, 9); 28 | 29 | // create AFSK client instance using the FSK module 30 | // this requires connection to the module direct 31 | // input pin, here connected to Arduino pin 5 32 | // SX127x/RFM9x: DIO2 33 | // RF69: DIO2 34 | // SX1231: DIO2 35 | // CC1101: GDO2 36 | AFSKClient audio(&radio, 5); 37 | 38 | void setup() { 39 | Serial.begin(9600); 40 | 41 | // initialize SX1278 with default settings 42 | Serial.print(F("[SX1278] Initializing ... ")); 43 | int state = radio.beginFSK(); 44 | 45 | // when using one of the non-LoRa modules for AFSK 46 | // (RF69, CC1101, Si4432 etc.), use the basic begin() method 47 | // int state = radio.begin(); 48 | 49 | if(state == RADIOLIB_ERR_NONE) { 50 | Serial.println(F("success!")); 51 | } else { 52 | Serial.print(F("failed, code ")); 53 | Serial.println(state); 54 | while(true); 55 | } 56 | 57 | // initialize AFSK client 58 | Serial.print(F("[AFSK] Initializing ... ")); 59 | state = audio.begin(); 60 | if(state == RADIOLIB_ERR_NONE) { 61 | Serial.println(F("success!")); 62 | } else { 63 | Serial.print(F("failed, code ")); 64 | Serial.println(state); 65 | while(true); 66 | } 67 | 68 | // after that, set mode to OOK 69 | Serial.print(F("[SX1278] Switching to OOK ... ")); 70 | state = radio.setOOK(true); 71 | if(state == RADIOLIB_ERR_NONE) { 72 | Serial.println(F("success!")); 73 | } else { 74 | Serial.print(F("failed, code ")); 75 | Serial.println(state); 76 | while(true); 77 | } 78 | } 79 | 80 | void loop() { 81 | // AFSKClient can be used to transmit tones, 82 | // same as Arduino tone() function 83 | 84 | // 400 Hz tone 85 | Serial.print(F("[AFSK] 400 Hz tone ... ")); 86 | audio.tone(400); 87 | delay(1000); 88 | 89 | // silence 90 | Serial.println(F("done!")); 91 | audio.noTone(); 92 | delay(1000); 93 | 94 | // AFSKClient can also be used to transmit HAM-friendly 95 | // RTTY, Morse code, Hellschreiber, SSTV and AX.25. 96 | // Details on how to use AFSK are in the example 97 | // folders for each of the above modes. 98 | 99 | // CAUTION: Unlike standard AFSK, the result when using OOK 100 | // must be demodulated as AM! 101 | } 102 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/RFM9x/RFM96.cpp: -------------------------------------------------------------------------------- 1 | #include "RFM96.h" 2 | #if !defined(RADIOLIB_EXCLUDE_RFM9X) 3 | 4 | RFM96::RFM96(Module* mod) : SX1278(mod) { 5 | 6 | } 7 | 8 | int16_t RFM96::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, uint8_t gain) { 9 | // execute common part 10 | int16_t state = SX127x::begin(RADIOLIB_RFM9X_CHIP_VERSION_OFFICIAL, syncWord, preambleLength); 11 | if(state == RADIOLIB_ERR_CHIP_NOT_FOUND) { 12 | // SX127X_REG_VERSION might be set 0x12 13 | state = SX127x::begin(RADIOLIB_RFM9X_CHIP_VERSION_UNOFFICIAL, syncWord, preambleLength); 14 | RADIOLIB_ASSERT(state); 15 | } else if(state != RADIOLIB_ERR_NONE) { 16 | // some other error 17 | return(state); 18 | } 19 | RADIOLIB_DEBUG_PRINTLN("M\tSX1278"); 20 | RADIOLIB_DEBUG_PRINTLN("M\tRFM96"); 21 | 22 | // configure publicly accessible settings 23 | state = setBandwidth(bw); 24 | RADIOLIB_ASSERT(state); 25 | 26 | state = setFrequency(freq); 27 | RADIOLIB_ASSERT(state); 28 | 29 | state = setSpreadingFactor(sf); 30 | RADIOLIB_ASSERT(state); 31 | 32 | state = setCodingRate(cr); 33 | RADIOLIB_ASSERT(state); 34 | 35 | state = setOutputPower(power); 36 | RADIOLIB_ASSERT(state); 37 | 38 | state = setGain(gain); 39 | RADIOLIB_ASSERT(state); 40 | 41 | return(state); 42 | } 43 | 44 | int16_t RFM96::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, bool enableOOK) { 45 | // execute common part 46 | int16_t state = SX127x::beginFSK(RADIOLIB_RFM9X_CHIP_VERSION_OFFICIAL, freqDev, rxBw, preambleLength, enableOOK); 47 | if(state == RADIOLIB_ERR_CHIP_NOT_FOUND) { 48 | // SX127X_REG_VERSION might be set 0x12 49 | state = SX127x::beginFSK(RADIOLIB_RFM9X_CHIP_VERSION_UNOFFICIAL, freqDev, rxBw, preambleLength, enableOOK); 50 | RADIOLIB_ASSERT(state); 51 | } else if(state != RADIOLIB_ERR_NONE) { 52 | // some other error 53 | return(state); 54 | } 55 | RADIOLIB_DEBUG_PRINTLN("M\tSX1278"); 56 | RADIOLIB_DEBUG_PRINTLN("M\tRFM96"); 57 | 58 | // configure settings not accessible by API 59 | state = configFSK(); 60 | RADIOLIB_ASSERT(state); 61 | 62 | // configure publicly accessible settings 63 | state = setFrequency(freq); 64 | RADIOLIB_ASSERT(state); 65 | 66 | state = setBitRate(br); 67 | RADIOLIB_ASSERT(state); 68 | 69 | state = setOutputPower(power); 70 | RADIOLIB_ASSERT(state); 71 | 72 | if(enableOOK) { 73 | state = setDataShapingOOK(RADIOLIB_SHAPING_NONE); 74 | RADIOLIB_ASSERT(state); 75 | } else { 76 | state = setDataShaping(RADIOLIB_SHAPING_NONE); 77 | RADIOLIB_ASSERT(state); 78 | } 79 | 80 | return(state); 81 | } 82 | 83 | int16_t RFM96::setFrequency(float freq) { 84 | RADIOLIB_CHECK_RANGE(freq, 410.0, 525.0, RADIOLIB_ERR_INVALID_FREQUENCY); 85 | 86 | // set frequency and if successful, save the new setting 87 | int16_t state = SX127x::setFrequencyRaw(freq); 88 | if(state == RADIOLIB_ERR_NONE) { 89 | SX127x::frequency = freq; 90 | } 91 | return(state); 92 | } 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/Pager/Pager_Transmit/Pager_Transmit.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib Pager (POCSAG) Transmit Example 3 | 4 | This example sends POCSAG messages using SX1278's 5 | FSK modem. 6 | 7 | Other modules that can be used to send POCSAG: 8 | - SX127x/RFM9x 9 | - RF69 10 | - SX1231 11 | - CC1101 12 | - SX126x 13 | - nRF24 14 | - Si443x/RFM2x 15 | - SX128x 16 | 17 | For default module settings, see the wiki page 18 | https://github.com/jgromes/RadioLib/wiki/Default-configuration 19 | 20 | For full API reference, see the GitHub Pages 21 | https://jgromes.github.io/RadioLib/ 22 | */ 23 | 24 | // include the library 25 | #include 26 | 27 | // SX1278 has the following connections: 28 | // NSS pin: 10 29 | // DIO0 pin: 2 30 | // RESET pin: 9 31 | // DIO1 pin: 3 32 | SX1278 radio = new Module(10, 2, 9, 3); 33 | 34 | // or using RadioShield 35 | // https://github.com/jgromes/RadioShield 36 | //SX1278 radio = RadioShield.ModuleA; 37 | 38 | // create Pager client instance using the FSK module 39 | PagerClient pager(&radio); 40 | 41 | void setup() { 42 | Serial.begin(9600); 43 | 44 | // initialize SX1278 with default settings 45 | Serial.print(F("[SX1278] Initializing ... ")); 46 | int state = radio.beginFSK(); 47 | 48 | // when using one of the non-LoRa modules 49 | // (RF69, CC1101, Si4432 etc.), use the basic begin() method 50 | // int state = radio.begin(); 51 | 52 | if(state == RADIOLIB_ERR_NONE) { 53 | Serial.println(F("success!")); 54 | } else { 55 | Serial.print(F("failed, code ")); 56 | Serial.println(state); 57 | while(true); 58 | } 59 | 60 | // initialize Pager client 61 | Serial.print(F("[Pager] Initializing ... ")); 62 | // base (center) frequency: 434.0 MHz 63 | // speed: 1200 bps 64 | state = pager.begin(434.0, 1200); 65 | if(state == RADIOLIB_ERR_NONE) { 66 | Serial.println(F("success!")); 67 | } else { 68 | Serial.print(F("failed, code ")); 69 | Serial.println(state); 70 | while(true); 71 | } 72 | } 73 | 74 | void loop() { 75 | Serial.print(F("[Pager] Transmitting messages ... ")); 76 | 77 | // the simples form of "message" is just a tone on the destination pager 78 | int state = pager.sendTone(1234567); 79 | delay(500); 80 | 81 | // next, transmit numeric (BCD) message to the destination pager 82 | // NOTE: Only characters 0123456789*U-() and space 83 | // can be sent in a BCD message! 84 | state |= pager.transmit("0123456789*U -()", 1234567); 85 | delay(500); 86 | 87 | // finally, let's transmit an ASCII message now 88 | state |= pager.transmit("Hello World!", 1234567, RADIOLIB_PAGER_ASCII); 89 | delay(500); 90 | 91 | // we can also send only a tone 92 | 93 | if(state == RADIOLIB_ERR_NONE) { 94 | Serial.println(F("success!")); 95 | } else { 96 | Serial.print(F("failed, code ")); 97 | Serial.println(state); 98 | } 99 | 100 | // wait for a second before transmitting again 101 | delay(3000); 102 | } 103 | -------------------------------------------------------------------------------- /lib/RadioLib/src/protocols/FSK4/FSK4.h: -------------------------------------------------------------------------------- 1 | #if !defined(_RADIOLIB_FSK4_H) 2 | #define _RADIOLIB_FSK4_H 3 | 4 | #include "../../TypeDef.h" 5 | 6 | #if !defined(RADIOLIB_EXCLUDE_FSK4) 7 | 8 | #include "../PhysicalLayer/PhysicalLayer.h" 9 | #include "../AFSK/AFSK.h" 10 | 11 | /*! 12 | \class FSK4Client 13 | \brief Client for FSK-4 communication. The public interface is the same as Arduino Serial. 14 | */ 15 | class FSK4Client { 16 | public: 17 | /*! 18 | \brief Constructor for FSK-4 mode. 19 | \param phy Pointer to the wireless module providing PhysicalLayer communication. 20 | */ 21 | explicit FSK4Client(PhysicalLayer* phy); 22 | 23 | #if !defined(RADIOLIB_EXCLUDE_AFSK) 24 | /*! 25 | \brief Constructor for AFSK mode. 26 | \param audio Pointer to the AFSK instance providing audio. 27 | */ 28 | explicit FSK4Client(AFSKClient* audio); 29 | #endif 30 | 31 | // basic methods 32 | 33 | /*! 34 | \brief Initialization method. 35 | \param base Base (space) frequency to be used in MHz (in FSK-4 mode), 36 | or the space tone frequency in Hz (in AFSK mode) 37 | \param shift Frequency shift between each tone in Hz. 38 | \param rate Baud rate to be used during transmission. 39 | \returns \ref status_codes 40 | */ 41 | int16_t begin(float base, uint32_t shift, uint16_t rate); 42 | 43 | /*! 44 | \brief Send out idle condition (RF tone at mark frequency). 45 | */ 46 | void idle(); 47 | 48 | /*! 49 | \brief Set correction coefficients for frequencies and tone length. 50 | \param offsets Four positive or negative correction offsets for audio frequencies in Hz. 51 | \param length Tone length modifier, defaults to 1.0. 52 | \returns \ref status_codes 53 | */ 54 | int16_t setCorrection(int16_t offsets[4], float length = 1.0f); 55 | 56 | /*! 57 | \brief Transmit binary data. 58 | \param buff Buffer to transmit. 59 | \param len Number of bytes to transmit. 60 | \returns Number of transmitted bytes. 61 | */ 62 | size_t write(uint8_t* buff, size_t len); 63 | 64 | /*! 65 | \brief Transmit a single byte. 66 | \param b Byte to transmit. 67 | \returns Number of transmitted bytes. 68 | */ 69 | size_t write(uint8_t b); 70 | 71 | /*! 72 | \brief Stop transmitting. 73 | \returns \ref status_codes 74 | */ 75 | int16_t standby(); 76 | 77 | #if !defined(RADIOLIB_GODMODE) 78 | private: 79 | #endif 80 | PhysicalLayer* phyLayer; 81 | #if !defined(RADIOLIB_EXCLUDE_AFSK) 82 | AFSKClient* audioClient; 83 | #endif 84 | 85 | uint32_t baseFreq = 0, baseFreqHz = 0; 86 | uint32_t shiftFreq = 0, shiftFreqHz = 0; 87 | uint32_t bitDuration = 0; 88 | uint32_t tones[4]; 89 | uint32_t tonesHz[4]; 90 | 91 | void tone(uint8_t i); 92 | 93 | int16_t transmitDirect(uint32_t freq = 0, uint32_t freqHz = 0); 94 | int32_t getRawShift(int32_t shift); 95 | }; 96 | 97 | #endif 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/STM32WLx/STM32WLx_Channel_Activity_Detection_Interrupt/STM32WLx_Channel_Activity_Detection_Interrupt.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib STM32WLx Channel Activity Detection Example 3 | 4 | This example uses STM32WLx to scan the current LoRa 5 | channel and detect ongoing LoRa transmissions. 6 | Unlike SX127x CAD, SX126x/STM32WLx can detect any part 7 | of LoRa transmission, not just the preamble. 8 | 9 | For default module settings, see the wiki page 10 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem 11 | 12 | For full API reference, see the GitHub Pages 13 | https://jgromes.github.io/RadioLib/ 14 | */ 15 | 16 | // include the library 17 | #include 18 | 19 | // no need to configure pins, signals are routed to the radio internally 20 | STM32WLx radio = new STM32WLx_Module(); 21 | 22 | 23 | void setup() { 24 | Serial.begin(9600); 25 | 26 | // initialize STM32WLx with default settings 27 | Serial.print(F("[STM32WLx] Initializing ... ")); 28 | int state = radio.begin(868.0); 29 | if (state == RADIOLIB_ERR_NONE) { 30 | Serial.println(F("success!")); 31 | } else { 32 | Serial.print(F("failed, code ")); 33 | Serial.println(state); 34 | while (true); 35 | } 36 | 37 | // set the function that will be called 38 | // when LoRa packet or timeout is detected 39 | radio.setDio1Action(setFlag); 40 | 41 | // start scanning the channel 42 | Serial.print(F("[STM32WLx] Starting scan for LoRa preamble ... ")); 43 | state = radio.startChannelScan(); 44 | if (state == RADIOLIB_ERR_NONE) { 45 | Serial.println(F("success!")); 46 | } else { 47 | Serial.print(F("failed, code ")); 48 | Serial.println(state); 49 | } 50 | } 51 | 52 | // flag to indicate that a packet was detected or CAD timed out 53 | volatile bool scanFlag = false; 54 | 55 | // this function is called when a complete packet 56 | // is received by the module 57 | // IMPORTANT: this function MUST be 'void' type 58 | // and MUST NOT have any arguments! 59 | void setFlag(void) { 60 | // something happened, set the flag 61 | scanFlag = true; 62 | } 63 | 64 | void loop() { 65 | // check if the flag is set 66 | if(scanFlag) { 67 | // reset flag 68 | scanFlag = false; 69 | 70 | // check CAD result 71 | int state = radio.getChannelScanResult(); 72 | 73 | if (state == RADIOLIB_LORA_DETECTED) { 74 | // LoRa packet was detected 75 | Serial.println(F("[STM32WLx] Packet detected!")); 76 | 77 | } else if (state == RADIOLIB_CHANNEL_FREE) { 78 | // channel is free 79 | Serial.println(F("[STM32WLx] Channel is free!")); 80 | 81 | } else { 82 | // some other error occurred 83 | Serial.print(F("[STM32WLx] Failed, code ")); 84 | Serial.println(state); 85 | 86 | } 87 | 88 | // start scanning the channel again 89 | Serial.print(F("[STM32WLx] Starting scan for LoRa preamble ... ")); 90 | state = radio.startChannelScan(); 91 | if (state == RADIOLIB_ERR_NONE) { 92 | Serial.println(F("success!")); 93 | } else { 94 | Serial.print(F("failed, code ")); 95 | Serial.println(state); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/CC1101/CC1101_Receive_Blocking/CC1101_Receive_Blocking.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib CC1101 Blocking Receive Example 3 | 4 | This example receives packets using CC1101 FSK radio module. 5 | To successfully receive data, the following settings have to be the same 6 | on both transmitter and receiver: 7 | - carrier frequency 8 | - bit rate 9 | - frequency deviation 10 | - sync word 11 | 12 | Using blocking receive is not recommended, as it will lead 13 | to significant amount of timeouts, inefficient use of processor 14 | time and can some miss packets! 15 | Instead, interrupt receive is recommended. 16 | 17 | For default module settings, see the wiki page 18 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101 19 | 20 | For full API reference, see the GitHub Pages 21 | https://jgromes.github.io/RadioLib/ 22 | */ 23 | 24 | // include the library 25 | #include 26 | 27 | // CC1101 has the following connections: 28 | // CS pin: 10 29 | // GDO0 pin: 2 30 | // RST pin: unused 31 | // GDO2 pin: 3 (optional) 32 | CC1101 radio = new Module(10, 2, RADIOLIB_NC, 3); 33 | 34 | // or using RadioShield 35 | // https://github.com/jgromes/RadioShield 36 | //CC1101 radio = RadioShield.ModuleA; 37 | 38 | void setup() { 39 | Serial.begin(9600); 40 | 41 | // initialize CC1101 with default settings 42 | Serial.print(F("[CC1101] Initializing ... ")); 43 | int state = radio.begin(); 44 | if (state == RADIOLIB_ERR_NONE) { 45 | Serial.println(F("success!")); 46 | } else { 47 | Serial.print(F("failed, code ")); 48 | Serial.println(state); 49 | while (true); 50 | } 51 | } 52 | 53 | void loop() { 54 | Serial.print(F("[CC1101] Waiting for incoming transmission ... ")); 55 | 56 | // you can receive data as an Arduino String 57 | String str; 58 | int state = radio.receive(str); 59 | 60 | // you can also receive data as byte array 61 | /* 62 | byte byteArr[8]; 63 | int state = radio.receive(byteArr, 8); 64 | */ 65 | 66 | if (state == RADIOLIB_ERR_NONE) { 67 | // packet was successfully received 68 | Serial.println(F("success!")); 69 | 70 | // print the data of the packet 71 | Serial.print(F("[CC1101] Data:\t\t")); 72 | Serial.println(str); 73 | 74 | // print RSSI (Received Signal Strength Indicator) 75 | // of the last received packet 76 | Serial.print(F("[CC1101] RSSI:\t\t")); 77 | Serial.print(radio.getRSSI()); 78 | Serial.println(F(" dBm")); 79 | 80 | // print LQI (Link Quality Indicator) 81 | // of the last received packet, lower is better 82 | Serial.print(F("[CC1101] LQI:\t\t")); 83 | Serial.println(radio.getLQI()); 84 | 85 | } else if (state == RADIOLIB_ERR_RX_TIMEOUT) { 86 | // timeout occurred while waiting for a packet 87 | Serial.println(F("timeout!")); 88 | 89 | } else if (state == RADIOLIB_ERR_CRC_MISMATCH) { 90 | // packet was received, but is malformed 91 | Serial.println(F("CRC error!")); 92 | 93 | } else { 94 | // some other error occurred 95 | Serial.print(F("failed, code ")); 96 | Serial.println(state); 97 | 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/nRF24/nRF24_Transmit_Blocking/nRF24_Transmit_Blocking.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib nRF24 Transmit Example 3 | 4 | This example transmits packets using nRF24 2.4 GHz radio module. 5 | Each packet contains up to 32 bytes of data, in the form of: 6 | - Arduino String 7 | - null-terminated char array (C-string) 8 | - arbitrary binary data (byte array) 9 | 10 | Packet delivery is automatically acknowledged by the receiver. 11 | 12 | For default module settings, see the wiki page 13 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#nrf24 14 | 15 | For full API reference, see the GitHub Pages 16 | https://jgromes.github.io/RadioLib/ 17 | */ 18 | 19 | // include the library 20 | #include 21 | 22 | // nRF24 has the following connections: 23 | // CS pin: 10 24 | // IRQ pin: 2 25 | // CE pin: 3 26 | nRF24 radio = new Module(10, 2, 3); 27 | 28 | // or using RadioShield 29 | // https://github.com/jgromes/RadioShield 30 | //nRF24 radio = RadioShield.ModuleA; 31 | 32 | void setup() { 33 | Serial.begin(9600); 34 | 35 | // initialize nRF24 with default settings 36 | Serial.print(F("[nRF24] Initializing ... ")); 37 | int state = radio.begin(); 38 | if(state == RADIOLIB_ERR_NONE) { 39 | Serial.println(F("success!")); 40 | } else { 41 | Serial.print(F("failed, code ")); 42 | Serial.println(state); 43 | while(true); 44 | } 45 | 46 | // set transmit address 47 | // NOTE: address width in bytes MUST be equal to the 48 | // width set in begin() or setAddressWidth() 49 | // methods (5 by default) 50 | byte addr[] = {0x01, 0x23, 0x45, 0x67, 0x89}; 51 | Serial.print(F("[nRF24] Setting transmit pipe ... ")); 52 | state = radio.setTransmitPipe(addr); 53 | if(state == RADIOLIB_ERR_NONE) { 54 | Serial.println(F("success!")); 55 | } else { 56 | Serial.print(F("failed, code ")); 57 | Serial.println(state); 58 | while(true); 59 | } 60 | } 61 | 62 | // counter to keep track of transmitted packets 63 | int count = 0; 64 | 65 | void loop() { 66 | Serial.print(F("[nRF24] Transmitting packet ... ")); 67 | 68 | // you can transmit C-string or Arduino string up to 69 | // 32 characters long 70 | String str = "Hello World! #" + String(count++); 71 | int state = radio.transmit(str); 72 | 73 | if (state == RADIOLIB_ERR_NONE) { 74 | // the packet was successfully transmitted 75 | Serial.println(F("success!")); 76 | 77 | } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) { 78 | // the supplied packet was longer than 32 bytes 79 | Serial.println(F("too long!")); 80 | 81 | } else if (state == RADIOLIB_ERR_ACK_NOT_RECEIVED) { 82 | // acknowledge from destination module 83 | // was not received within 15 retries 84 | Serial.println(F("ACK not received!")); 85 | 86 | } else if (state == RADIOLIB_ERR_TX_TIMEOUT) { 87 | // timed out while transmitting 88 | Serial.println(F("timeout!")); 89 | 90 | } else { 91 | // some other error occurred 92 | Serial.print(F("failed, code ")); 93 | Serial.println(state); 94 | 95 | } 96 | 97 | // wait for a second before transmitting again 98 | delay(1000); 99 | } 100 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/RF69/RF69_Transmit_Blocking/RF69_Transmit_Blocking.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib RF69 Blocking Transmit Example 3 | 4 | This example transmits packets using RF69 FSK radio module. 5 | Each packet contains up to 64 bytes of data, in the form of: 6 | - Arduino String 7 | - null-terminated char array (C-string) 8 | - arbitrary binary data (byte array) 9 | 10 | Using blocking transmit is not recommended, as it will lead 11 | to inefficient use of processor time! 12 | Instead, interrupt transmit is recommended. 13 | 14 | For default module settings, see the wiki page 15 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#rf69sx1231 16 | 17 | For full API reference, see the GitHub Pages 18 | https://jgromes.github.io/RadioLib/ 19 | */ 20 | 21 | // include the library 22 | #include 23 | 24 | // RF69 has the following connections: 25 | // CS pin: 10 26 | // DIO0 pin: 2 27 | // RESET pin: 3 28 | RF69 radio = new Module(10, 2, 3); 29 | 30 | // or using RadioShield 31 | // https://github.com/jgromes/RadioShield 32 | //RF69 radio = RadioShield.ModuleA; 33 | 34 | void setup() { 35 | Serial.begin(9600); 36 | 37 | // initialize RF69 with default settings 38 | Serial.print(F("[RF69] Initializing ... ")); 39 | int state = radio.begin(); 40 | if (state == RADIOLIB_ERR_NONE) { 41 | Serial.println(F("success!")); 42 | } else { 43 | Serial.print(F("failed, code ")); 44 | Serial.println(state); 45 | while (true); 46 | } 47 | 48 | // NOTE: some RF69 modules use high power output, 49 | // those are usually marked RF69H(C/CW). 50 | // To configure RadioLib for these modules, 51 | // you must call setOutputPower() with 52 | // second argument set to true. 53 | /* 54 | Serial.print(F("[RF69] Setting high power module ... ")); 55 | state = radio.setOutputPower(20, true); 56 | if (state == RADIOLIB_ERR_NONE) { 57 | Serial.println(F("success!")); 58 | } else { 59 | Serial.print(F("failed, code ")); 60 | Serial.println(state); 61 | while (true); 62 | } 63 | */ 64 | } 65 | 66 | // counter to keep track of transmitted packets 67 | int count = 0; 68 | 69 | void loop() { 70 | Serial.print(F("[RF69] Transmitting packet ... ")); 71 | 72 | // you can transmit C-string or Arduino string up to 64 characters long 73 | String str = "Hello World! #" + String(count++); 74 | int state = radio.transmit(str); 75 | 76 | // you can also transmit byte array up to 64 bytes long 77 | /* 78 | byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; 79 | int state = radio.transmit(byteArr, 8); 80 | */ 81 | 82 | if (state == RADIOLIB_ERR_NONE) { 83 | // the packet was successfully transmitted 84 | Serial.println(F("success!")); 85 | 86 | } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) { 87 | // the supplied packet was longer than 64 bytes 88 | Serial.println(F("too long!")); 89 | 90 | } else { 91 | // some other error occurred 92 | Serial.print(F("failed, code ")); 93 | Serial.println(state); 94 | 95 | } 96 | 97 | // wait for a second before transmitting again 98 | delay(1000); 99 | } 100 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/BellModem/BellModem_Transmit/BellModem_Transmit.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib Bell Modem Transmit Example 3 | 4 | This example shows how to transmit binary data 5 | using audio Bell 202 tones. 6 | 7 | Other implemented Bell modems 8 | - Bell 101 9 | - Bell 103 10 | 11 | For default module settings, see the wiki page 12 | https://github.com/jgromes/RadioLib/wiki/Default-configuration 13 | 14 | For full API reference, see the GitHub Pages 15 | https://jgromes.github.io/RadioLib/ 16 | */ 17 | 18 | // include the library 19 | #include 20 | 21 | // SX1278 has the following connections: 22 | // NSS pin: 10 23 | // DIO0 pin: 2 24 | // RESET pin: 9 25 | // DIO1 pin: 3 26 | SX1278 radio = new Module(10, 2, 9, 3); 27 | 28 | // create Bell modem instance using the FSK module 29 | // this requires connection to the module direct 30 | // input pin, here connected to Arduino pin 5 31 | // SX127x/RFM9x: DIO2 32 | // RF69: DIO2 33 | // SX1231: DIO2 34 | // CC1101: GDO2 35 | // Si443x/RFM2x: GPIO 36 | // SX126x/LLCC68: DIO2 (only devices without TCXO!) 37 | BellClient bell(&radio, 5); 38 | 39 | void setup() { 40 | Serial.begin(9600); 41 | 42 | // initialize SX1278 with default settings 43 | Serial.print(F("[SX1278] Initializing ... ")); 44 | int state = radio.beginFSK(); 45 | 46 | // when using one of the non-LoRa modules for AFSK 47 | // (RF69, CC1101, Si4432 etc.), use the basic begin() method 48 | // int state = radio.begin(); 49 | 50 | if(state == RADIOLIB_ERR_NONE) { 51 | Serial.println(F("success!")); 52 | } else { 53 | Serial.print(F("failed, code ")); 54 | Serial.println(state); 55 | while(true); 56 | } 57 | 58 | // initialize Bell 202 modem 59 | Serial.print(F("[Bell 202] Initializing ... ")); 60 | state = bell.begin(Bell202); 61 | if(state == RADIOLIB_ERR_NONE) { 62 | Serial.println(F("success!")); 63 | } else { 64 | Serial.print(F("failed, code ")); 65 | Serial.println(state); 66 | while(true); 67 | } 68 | } 69 | 70 | void loop() { 71 | Serial.print(F("[Bell 202] Sending data ... ")); 72 | 73 | // send out idle condition for 500 ms 74 | bell.idle(); 75 | delay(500); 76 | 77 | // BellClient supports all methods of the Serial class 78 | 79 | // Arduino String class 80 | String aStr = "Arduino String"; 81 | bell.println(aStr); 82 | 83 | // character array (C-String) 84 | bell.println("C-String"); 85 | 86 | // string saved in flash 87 | bell.println(F("Flash String")); 88 | 89 | // character 90 | bell.println('c'); 91 | 92 | // byte 93 | // formatting DEC/HEX/OCT/BIN is supported for 94 | // any integer type (byte/int/long) 95 | bell.println(255, HEX); 96 | 97 | // integer number 98 | int i = 1000; 99 | bell.println(i); 100 | 101 | // floating point number 102 | float f = -3.1415; 103 | bell.println(f, 3); 104 | 105 | // ITA2-encoded string 106 | ITA2String str("HELLO WORLD!"); 107 | bell.print(str); 108 | 109 | // turn the transmitter off 110 | bell.standby(); 111 | 112 | Serial.println(F("done!")); 113 | 114 | // wait for a second before transmitting again 115 | delay(1000); 116 | } 117 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/AFSK/AFSK_Imperial_March/AFSK_Imperial_March.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib AFSK Imperial March Example 3 | 4 | This example shows how to EXECUTE ORDER 66 5 | 6 | Other modules that can be used for AFSK: 7 | - SX127x/RFM9x 8 | - RF69 9 | - SX1231 10 | - CC1101 11 | - Si443x/RFM2x 12 | - SX126x/LLCC68 (only devices without TCXO!) 13 | 14 | For default module settings, see the wiki page 15 | https://github.com/jgromes/RadioLib/wiki/Default-configuration 16 | 17 | For full API reference, see the GitHub Pages 18 | https://jgromes.github.io/RadioLib/ 19 | */ 20 | 21 | // include the library 22 | #include 23 | 24 | // include the melody 25 | #include "melody.h" 26 | 27 | // SX1278 has the following connections: 28 | // NSS pin: 10 29 | // DIO0 pin: 2 30 | // RESET pin: 9 31 | // DIO1 pin: 3 32 | SX1278 radio = new Module(10, 2, 9, 3); 33 | 34 | // create AFSK client instance using the FSK module 35 | // this requires connection to the module direct 36 | // input pin, here connected to Arduino pin 5 37 | // SX127x/RFM9x: DIO2 38 | // RF69: DIO2 39 | // SX1231: DIO2 40 | // CC1101: GDO2 41 | // Si443x/RFM2x: GPIO 42 | // SX126x/LLCC68: DIO2 43 | AFSKClient audio(&radio, 5); 44 | 45 | void setup() { 46 | Serial.begin(9600); 47 | 48 | // initialize SX1278 with default settings 49 | Serial.print(F("[SX1278] Initializing ... ")); 50 | int state = radio.beginFSK(); 51 | 52 | // when using one of the non-LoRa modules for AFSK 53 | // (RF69, CC1101,, Si4432 etc.), use the basic begin() method 54 | // int state = radio.begin(); 55 | 56 | if(state == RADIOLIB_ERR_NONE) { 57 | Serial.println(F("success!")); 58 | } else { 59 | Serial.print(F("failed, code ")); 60 | Serial.println(state); 61 | while(true); 62 | } 63 | 64 | // initialize AFSK client 65 | Serial.print(F("[AFSK] Initializing ... ")); 66 | state = audio.begin(); 67 | if(state == RADIOLIB_ERR_NONE) { 68 | Serial.println(F("success!")); 69 | } else { 70 | Serial.print(F("failed, code ")); 71 | Serial.println(state); 72 | while(true); 73 | } 74 | } 75 | 76 | void loop() { 77 | Serial.print(F("[AFSK] Executing Order 66 ... ")); 78 | 79 | // calculate whole note duration 80 | int wholenote = (60000 * 4) / 120; 81 | 82 | // iterate over the melody 83 | for(unsigned int note = 0; note < sizeof(melody) / sizeof(melody[0]); note += 2) { 84 | // calculate the duration of each note 85 | int noteDuration = 0; 86 | int divider = melody[note + 1]; 87 | if(divider > 0) { 88 | // regular note, just proceed 89 | noteDuration = wholenote / divider; 90 | } else if(divider < 0) { 91 | // dotted notes are represented with negative durations!! 92 | noteDuration = wholenote / abs(divider); 93 | noteDuration *= 1.5; // increases the duration in half for dotted notes 94 | } 95 | 96 | // we only play the note for 90% of the duration, leaving 10% as a pause 97 | audio.tone(melody[note]); 98 | delay(noteDuration*0.9); 99 | audio.noTone(); 100 | delay(noteDuration*0.1); 101 | } 102 | 103 | Serial.println(F("done!")); 104 | 105 | // wait for a second 106 | delay(1000); 107 | } 108 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/nRF24/nRF24_Receive_Blocking/nRF24_Receive_Blocking.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib nRF24 Blocking Receive Example 3 | 4 | This example listens for FSK transmissions using nRF24 2.4 GHz radio module. 5 | To successfully receive data, the following settings have to be the same 6 | on both transmitter and receiver: 7 | - carrier frequency 8 | - data rate 9 | - transmit pipe on transmitter must match receive pipe on receiver 10 | 11 | Using blocking receive is not recommended, as it will lead 12 | to significant amount of timeouts, inefficient use of processor 13 | time and can some miss packets! 14 | Instead, interrupt receive is recommended. 15 | 16 | For default module settings, see the wiki page 17 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#nrf24 18 | 19 | For full API reference, see the GitHub Pages 20 | https://jgromes.github.io/RadioLib/ 21 | */ 22 | 23 | // include the library 24 | #include 25 | 26 | // nRF24 has the following connections: 27 | // CS pin: 10 28 | // IRQ pin: 2 29 | // CE pin: 3 30 | nRF24 radio = new Module(10, 2, 3); 31 | 32 | // or using RadioShield 33 | // https://github.com/jgromes/RadioShield 34 | //nRF24 radio = RadioShield.ModuleA; 35 | 36 | void setup() { 37 | Serial.begin(9600); 38 | 39 | // initialize nRF24 with default settings 40 | Serial.print(F("[nRF24] Initializing ... ")); 41 | int state = radio.begin(); 42 | if(state == RADIOLIB_ERR_NONE) { 43 | Serial.println(F("success!")); 44 | } else { 45 | Serial.print(F("failed, code ")); 46 | Serial.println(state); 47 | while(true); 48 | } 49 | 50 | // set receive pipe 0 address 51 | // NOTE: address width in bytes MUST be equal to the 52 | // width set in begin() or setAddressWidth() 53 | // methods (5 by default) 54 | Serial.print(F("[nRF24] Setting address for receive pipe 0 ... ")); 55 | byte addr[] = {0x01, 0x23, 0x45, 0x67, 0x89}; 56 | state = radio.setReceivePipe(0, addr); 57 | if(state == RADIOLIB_ERR_NONE) { 58 | Serial.println(F("success!")); 59 | } else { 60 | Serial.print(F("failed, code ")); 61 | Serial.println(state); 62 | while(true); 63 | } 64 | } 65 | 66 | void loop() { 67 | Serial.print(F("[nRF24] Waiting for incoming transmission ... ")); 68 | 69 | // you can receive data as an Arduino String 70 | // NOTE: receive() is a blocking method! 71 | // See example ReceiveInterrupt for details 72 | // on non-blocking reception method. 73 | String str; 74 | int state = radio.receive(str); 75 | 76 | // you can also receive data as byte array 77 | /* 78 | byte byteArr[8]; 79 | int state = radio.receive(byteArr, 8); 80 | */ 81 | 82 | if (state == RADIOLIB_ERR_NONE) { 83 | // packet was successfully received 84 | Serial.println(F("success!")); 85 | 86 | // print the data of the packet 87 | Serial.print(F("[nRF24] Data:\t\t")); 88 | Serial.println(str); 89 | 90 | } else if (state == RADIOLIB_ERR_RX_TIMEOUT) { 91 | // timeout occurred while waiting for a packet 92 | Serial.println(F("timeout!")); 93 | 94 | } else { 95 | // some other error occurred 96 | Serial.print(F("failed, code ")); 97 | Serial.println(state); 98 | 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/SX127x/SX1277.cpp: -------------------------------------------------------------------------------- 1 | #include "SX1277.h" 2 | #if !defined(RADIOLIB_EXCLUDE_SX127X) 3 | 4 | SX1277::SX1277(Module* mod) : SX1278(mod) { 5 | 6 | } 7 | 8 | int16_t SX1277::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, uint8_t gain) { 9 | // execute common part 10 | int16_t state = SX127x::begin(RADIOLIB_SX1278_CHIP_VERSION, syncWord, preambleLength); 11 | RADIOLIB_ASSERT(state); 12 | 13 | // configure publicly accessible settings 14 | state = setBandwidth(bw); 15 | RADIOLIB_ASSERT(state); 16 | 17 | state = setFrequency(freq); 18 | RADIOLIB_ASSERT(state); 19 | 20 | state = setSpreadingFactor(sf); 21 | RADIOLIB_ASSERT(state); 22 | 23 | state = setCodingRate(cr); 24 | RADIOLIB_ASSERT(state); 25 | 26 | state = setOutputPower(power); 27 | RADIOLIB_ASSERT(state); 28 | 29 | state = setGain(gain); 30 | RADIOLIB_ASSERT(state); 31 | 32 | // set publicly accessible settings that are not a part of begin method 33 | state = setCRC(true); 34 | RADIOLIB_ASSERT(state); 35 | 36 | return(state); 37 | } 38 | 39 | int16_t SX1277::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, bool enableOOK) { 40 | // execute common part 41 | int16_t state = SX127x::beginFSK(RADIOLIB_SX1278_CHIP_VERSION, freqDev, rxBw, preambleLength, enableOOK); 42 | RADIOLIB_ASSERT(state); 43 | 44 | // configure settings not accessible by API 45 | state = configFSK(); 46 | RADIOLIB_ASSERT(state); 47 | 48 | // configure publicly accessible settings 49 | state = setFrequency(freq); 50 | RADIOLIB_ASSERT(state); 51 | 52 | state = setBitRate(br); 53 | RADIOLIB_ASSERT(state); 54 | 55 | state = setOutputPower(power); 56 | RADIOLIB_ASSERT(state); 57 | 58 | if(enableOOK) { 59 | state = setDataShapingOOK(RADIOLIB_SHAPING_NONE); 60 | RADIOLIB_ASSERT(state); 61 | } else { 62 | state = setDataShaping(RADIOLIB_SHAPING_NONE); 63 | RADIOLIB_ASSERT(state); 64 | } 65 | 66 | return(state); 67 | } 68 | 69 | int16_t SX1277::setFrequency(float freq) { 70 | RADIOLIB_CHECK_RANGE(freq, 137.0, 1020.0, RADIOLIB_ERR_INVALID_FREQUENCY); 71 | 72 | // set frequency and if successful, save the new setting 73 | int16_t state = SX127x::setFrequencyRaw(freq); 74 | if(state == RADIOLIB_ERR_NONE) { 75 | SX127x::frequency = freq; 76 | } 77 | return(state); 78 | } 79 | 80 | int16_t SX1277::setSpreadingFactor(uint8_t sf) { 81 | uint8_t newSpreadingFactor; 82 | 83 | // check allowed spreading factor values 84 | switch(sf) { 85 | case 6: 86 | newSpreadingFactor = RADIOLIB_SX127X_SF_6; 87 | break; 88 | case 7: 89 | newSpreadingFactor = RADIOLIB_SX127X_SF_7; 90 | break; 91 | case 8: 92 | newSpreadingFactor = RADIOLIB_SX127X_SF_8; 93 | break; 94 | case 9: 95 | newSpreadingFactor = RADIOLIB_SX127X_SF_9; 96 | break; 97 | default: 98 | return(RADIOLIB_ERR_INVALID_SPREADING_FACTOR); 99 | } 100 | 101 | // set spreading factor and if successful, save the new setting 102 | int16_t state = SX1278::setSpreadingFactorRaw(newSpreadingFactor); 103 | if(state == RADIOLIB_ERR_NONE) { 104 | SX127x::spreadingFactor = sf; 105 | } 106 | 107 | return(state); 108 | } 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/SX128x/SX128x_Transmit_Blocking/SX128x_Transmit_Blocking.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib SX128x Blocking Transmit Example 3 | 4 | This example transmits packets using SX1280 LoRa radio module. 5 | Each packet contains up to 256 bytes of data, in the form of: 6 | - Arduino String 7 | - null-terminated char array (C-string) 8 | - arbitrary binary data (byte array) 9 | 10 | Other modules from SX128x family can also be used. 11 | 12 | Using blocking transmit is not recommended, as it will lead 13 | to inefficient use of processor time! 14 | Instead, interrupt transmit is recommended. 15 | 16 | For default module settings, see the wiki page 17 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem 18 | 19 | For full API reference, see the GitHub Pages 20 | https://jgromes.github.io/RadioLib/ 21 | */ 22 | 23 | // include the library 24 | #include 25 | 26 | // SX1280 has the following connections: 27 | // NSS pin: 10 28 | // DIO1 pin: 2 29 | // NRST pin: 3 30 | // BUSY pin: 9 31 | SX1280 radio = new Module(10, 2, 3, 9); 32 | 33 | // or using RadioShield 34 | // https://github.com/jgromes/RadioShield 35 | //SX1280 radio = RadioShield.ModuleA; 36 | 37 | void setup() { 38 | Serial.begin(9600); 39 | 40 | // initialize SX1280 with default settings 41 | Serial.print(F("[SX1280] Initializing ... ")); 42 | // carrier frequency: 2400.0 MHz 43 | // bandwidth: 812.5 kHz 44 | // spreading factor: 9 45 | // coding rate: 7 46 | // output power: 10 dBm 47 | // preamble length: 12 symbols 48 | // CRC: enabled 49 | int state = radio.begin(); 50 | if (state == RADIOLIB_ERR_NONE) { 51 | Serial.println(F("success!")); 52 | } else { 53 | Serial.print(F("failed, code ")); 54 | Serial.println(state); 55 | while (true); 56 | } 57 | 58 | // some modules have an external RF switch 59 | // controlled via two pins (RX enable, TX enable) 60 | // to enable automatic control of the switch, 61 | // call the following method 62 | // RX enable: 4 63 | // TX enable: 5 64 | /* 65 | radio.setRfSwitchPins(4, 5); 66 | */ 67 | } 68 | 69 | // counter to keep track of transmitted packets 70 | int count = 0; 71 | 72 | void loop() { 73 | Serial.print(F("[SX1280] Transmitting packet ... ")); 74 | 75 | // you can transmit C-string or Arduino string up to 76 | // 256 characters long 77 | String str = "Hello World! #" + String(count++); 78 | int state = radio.transmit(str); 79 | 80 | // you can also transmit byte array up to 256 bytes long 81 | /* 82 | byte byteArr[] = {0x01, 0x23, 0x45, 0x56, 0x78, 0xAB, 0xCD, 0xEF}; 83 | int state = radio.transmit(byteArr, 8); 84 | */ 85 | 86 | if (state == RADIOLIB_ERR_NONE) { 87 | // the packet was successfully transmitted 88 | Serial.println(F("success!")); 89 | 90 | } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) { 91 | // the supplied packet was longer than 256 bytes 92 | Serial.println(F("too long!")); 93 | 94 | } else { 95 | // some other error occurred 96 | Serial.print(F("failed, code ")); 97 | Serial.println(state); 98 | 99 | } 100 | 101 | // wait for a second before transmitting again 102 | delay(1000); 103 | } 104 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/SX127x/SX127x_Transmit_Blocking/SX127x_Transmit_Blocking.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib SX127x Blocking Transmit Example 3 | 4 | This example transmits packets using SX1278 LoRa radio module. 5 | Each packet contains up to 255 bytes of data, in the form of: 6 | - Arduino String 7 | - null-terminated char array (C-string) 8 | - arbitrary binary data (byte array) 9 | 10 | Other modules from SX127x/RFM9x family can also be used. 11 | 12 | Using blocking transmit is not recommended, as it will lead 13 | to inefficient use of processor time! 14 | Instead, interrupt transmit is recommended. 15 | 16 | For default module settings, see the wiki page 17 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem 18 | 19 | For full API reference, see the GitHub Pages 20 | https://jgromes.github.io/RadioLib/ 21 | */ 22 | 23 | // include the library 24 | #include 25 | 26 | // SX1278 has the following connections: 27 | // NSS pin: 10 28 | // DIO0 pin: 2 29 | // RESET pin: 9 30 | // DIO1 pin: 3 31 | SX1278 radio = new Module(10, 2, 9, 3); 32 | 33 | // or using RadioShield 34 | // https://github.com/jgromes/RadioShield 35 | //SX1278 radio = RadioShield.ModuleA; 36 | 37 | void setup() { 38 | Serial.begin(9600); 39 | 40 | // initialize SX1278 with default settings 41 | Serial.print(F("[SX1278] Initializing ... ")); 42 | int state = radio.begin(); 43 | if (state == RADIOLIB_ERR_NONE) { 44 | Serial.println(F("success!")); 45 | } else { 46 | Serial.print(F("failed, code ")); 47 | Serial.println(state); 48 | while (true); 49 | } 50 | 51 | // some modules have an external RF switch 52 | // controlled via two pins (RX enable, TX enable) 53 | // to enable automatic control of the switch, 54 | // call the following method 55 | // RX enable: 4 56 | // TX enable: 5 57 | /* 58 | radio.setRfSwitchPins(4, 5); 59 | */ 60 | } 61 | 62 | // counter to keep track of transmitted packets 63 | int count = 0; 64 | 65 | void loop() { 66 | Serial.print(F("[SX1278] Transmitting packet ... ")); 67 | 68 | // you can transmit C-string or Arduino string up to 69 | // 255 characters long 70 | String str = "Hello World! #" + String(count++); 71 | int state = radio.transmit(str); 72 | 73 | // you can also transmit byte array up to 256 bytes long 74 | /* 75 | byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; 76 | int state = radio.transmit(byteArr, 8); 77 | */ 78 | 79 | if (state == RADIOLIB_ERR_NONE) { 80 | // the packet was successfully transmitted 81 | Serial.println(F(" success!")); 82 | 83 | // print measured data rate 84 | Serial.print(F("[SX1278] Datarate:\t")); 85 | Serial.print(radio.getDataRate()); 86 | Serial.println(F(" bps")); 87 | 88 | } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) { 89 | // the supplied packet was longer than 256 bytes 90 | Serial.println(F("too long!")); 91 | 92 | } else if (state == RADIOLIB_ERR_TX_TIMEOUT) { 93 | // timeout occurred while transmitting packet 94 | Serial.println(F("timeout!")); 95 | 96 | } else { 97 | // some other error occurred 98 | Serial.print(F("failed, code ")); 99 | Serial.println(state); 100 | 101 | } 102 | 103 | // wait for a second before transmitting again 104 | delay(1000); 105 | } 106 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/SX126x/SX1268.cpp: -------------------------------------------------------------------------------- 1 | #include "SX1268.h" 2 | #if !defined(RADIOLIB_EXCLUDE_SX126X) 3 | 4 | SX1268::SX1268(Module* mod) : SX126x(mod) { 5 | chipType = RADIOLIB_SX1268_CHIP_TYPE; 6 | } 7 | 8 | int16_t SX1268::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, float tcxoVoltage, bool useRegulatorLDO) { 9 | // execute common part 10 | int16_t state = SX126x::begin(cr, syncWord, preambleLength, tcxoVoltage, useRegulatorLDO); 11 | RADIOLIB_ASSERT(state); 12 | 13 | // configure publicly accessible settings 14 | state = setFrequency(freq); 15 | RADIOLIB_ASSERT(state); 16 | 17 | state = setSpreadingFactor(sf); 18 | RADIOLIB_ASSERT(state); 19 | 20 | state = setBandwidth(bw); 21 | RADIOLIB_ASSERT(state); 22 | 23 | state = setOutputPower(power); 24 | RADIOLIB_ASSERT(state); 25 | 26 | state = SX126x::fixPaClamping(); 27 | RADIOLIB_ASSERT(state); 28 | 29 | return(state); 30 | } 31 | 32 | int16_t SX1268::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, float tcxoVoltage, bool useRegulatorLDO) { 33 | // execute common part 34 | int16_t state = SX126x::beginFSK(br, freqDev, rxBw, preambleLength, tcxoVoltage, useRegulatorLDO); 35 | RADIOLIB_ASSERT(state); 36 | 37 | // configure publicly accessible settings 38 | state = setFrequency(freq); 39 | RADIOLIB_ASSERT(state); 40 | 41 | state = setOutputPower(power); 42 | RADIOLIB_ASSERT(state); 43 | 44 | state = SX126x::fixPaClamping(); 45 | RADIOLIB_ASSERT(state); 46 | 47 | return(state); 48 | } 49 | 50 | int16_t SX1268::setFrequency(float freq) { 51 | return(setFrequency(freq, true)); 52 | } 53 | 54 | /// \todo integers only (all modules - frequency, data rate, bandwidth etc.) 55 | int16_t SX1268::setFrequency(float freq, bool calibrate) { 56 | RADIOLIB_CHECK_RANGE(freq, 410.0, 810.0, RADIOLIB_ERR_INVALID_FREQUENCY); 57 | 58 | // calibrate image 59 | if(calibrate) { 60 | uint8_t data[2]; 61 | if(freq > 770.0) { 62 | data[0] = RADIOLIB_SX126X_CAL_IMG_779_MHZ_1; 63 | data[1] = RADIOLIB_SX126X_CAL_IMG_779_MHZ_2; 64 | } else if(freq > 460.0) { 65 | data[0] = RADIOLIB_SX126X_CAL_IMG_470_MHZ_1; 66 | data[1] = RADIOLIB_SX126X_CAL_IMG_470_MHZ_2; 67 | } else { 68 | data[0] = RADIOLIB_SX126X_CAL_IMG_430_MHZ_1; 69 | data[1] = RADIOLIB_SX126X_CAL_IMG_430_MHZ_2; 70 | } 71 | int16_t state = SX126x::calibrateImage(data); 72 | RADIOLIB_ASSERT(state); 73 | } 74 | 75 | // set frequency 76 | return(SX126x::setFrequencyRaw(freq)); 77 | } 78 | 79 | int16_t SX1268::setOutputPower(int8_t power) { 80 | RADIOLIB_CHECK_RANGE(power, -9, 22, RADIOLIB_ERR_INVALID_OUTPUT_POWER); 81 | 82 | // get current OCP configuration 83 | uint8_t ocp = 0; 84 | int16_t state = readRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1); 85 | RADIOLIB_ASSERT(state); 86 | 87 | // set PA config 88 | state = SX126x::setPaConfig(0x04, RADIOLIB_SX126X_PA_CONFIG_SX1268); 89 | RADIOLIB_ASSERT(state); 90 | 91 | // set output power 92 | /// \todo power ramp time configuration 93 | state = SX126x::setTxParams(power); 94 | RADIOLIB_ASSERT(state); 95 | 96 | // restore OCP configuration 97 | return(writeRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1)); 98 | } 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/Morse/Morse_Receive_AM/Morse_Receive_AM.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib SX127x Morse Receive AM Example 3 | 4 | This example receives Morse code message using 5 | SX1278's FSK modem. The signal is expected to be 6 | modulated as OOK, to be demodulated in AM mode. 7 | 8 | Other modules that can be used for Morse Code 9 | with AFSK modulation: 10 | - SX127x/RFM9x 11 | - RF69 12 | - SX1231 13 | - CC1101 14 | - Si443x/RFM2x 15 | 16 | For default module settings, see the wiki page 17 | https://github.com/jgromes/RadioLib/wiki/Default-configuration 18 | 19 | For full API reference, see the GitHub Pages 20 | https://jgromes.github.io/RadioLib/ 21 | */ 22 | 23 | // include the library 24 | #include 25 | 26 | // SX1278 has the following connections: 27 | // NSS pin: 10 28 | // DIO0 pin: 2 29 | // RESET pin: 9 30 | // DIO1 pin: 3 31 | SX1278 radio = new Module(10, 2, 9, 3); 32 | 33 | // or using RadioShield 34 | // https://github.com/jgromes/RadioShield 35 | //SX1278 radio = RadioShield.ModuleA; 36 | 37 | // create AFSK client instance using the FSK module 38 | // pin 5 is connected to SX1278 DIO2 39 | AFSKClient audio(&radio, 5); 40 | 41 | // create Morse client instance using the AFSK instance 42 | MorseClient morse(&audio); 43 | 44 | void setup() { 45 | Serial.begin(9600); 46 | 47 | // initialize SX1278 with default settings 48 | Serial.print(F("[SX1278] Initializing ... ")); 49 | int state = radio.beginFSK(); 50 | if (state == RADIOLIB_ERR_NONE) { 51 | Serial.println(F("success!")); 52 | } else { 53 | Serial.print(F("failed, code ")); 54 | Serial.println(state); 55 | while (true); 56 | } 57 | 58 | // when using one of the non-LoRa modules for Morse code 59 | // (RF69, CC1101, Si4432 etc.), use the basic begin() method 60 | // int state = radio.begin(); 61 | 62 | // initialize Morse client 63 | Serial.print(F("[Morse] Initializing ... ")); 64 | // AFSK tone frequency: 400 Hz 65 | // speed: 20 words per minute 66 | state = morse.begin(400); 67 | if(state == RADIOLIB_ERR_NONE) { 68 | Serial.println(F("success!")); 69 | } else { 70 | Serial.print(F("failed, code ")); 71 | Serial.println(state); 72 | while(true); 73 | } 74 | 75 | // after that, set mode to OOK to emulate AM modulation 76 | Serial.print(F("[SX1278] Switching to OOK ... ")); 77 | state = radio.setOOK(true); 78 | if(state == RADIOLIB_ERR_NONE) { 79 | Serial.println(F("success!")); 80 | } else { 81 | Serial.print(F("failed, code ")); 82 | Serial.println(state); 83 | while(true); 84 | } 85 | 86 | // start direct mode reception 87 | radio.receiveDirect(); 88 | } 89 | 90 | // save symbol and length between loops 91 | byte symbol = 0; 92 | byte len = 0; 93 | 94 | void loop() { 95 | // try to read a new symbol 96 | int state = morse.read(&symbol, &len); 97 | 98 | // check if we have something to decode 99 | if(state != RADIOLIB_MORSE_INTER_SYMBOL) { 100 | // decode and print 101 | Serial.print(MorseClient::decode(symbol, len)); 102 | 103 | // reset the symbol buffer 104 | symbol = 0; 105 | len = 0; 106 | 107 | // check if we have a complete word 108 | if(state == RADIOLIB_MORSE_WORD_COMPLETE) { 109 | // inter-word space, interpret that as a new line 110 | Serial.println(); 111 | } 112 | 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/Hellschreiber/Hellschreiber_Transmit/Hellschreiber_Transmit.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib Hellschreiber Transmit Example 3 | 4 | This example sends Hellschreiber message using 5 | SX1278's FSK modem. 6 | 7 | Other modules that can be used for Hellschreiber: 8 | - SX127x/RFM9x 9 | - RF69 10 | - SX1231 11 | - CC1101 12 | - SX126x 13 | - nRF24 14 | - Si443x/RFM2x 15 | - SX128x 16 | 17 | For default module settings, see the wiki page 18 | https://github.com/jgromes/RadioLib/wiki/Default-configuration 19 | 20 | For full API reference, see the GitHub Pages 21 | https://jgromes.github.io/RadioLib/ 22 | */ 23 | 24 | // include the library 25 | #include 26 | 27 | // SX1278 has the following connections: 28 | // NSS pin: 10 29 | // DIO0 pin: 2 30 | // RESET pin: 9 31 | // DIO1 pin: 3 32 | SX1278 radio = new Module(10, 2, 9, 3); 33 | 34 | // or using RadioShield 35 | // https://github.com/jgromes/RadioShield 36 | //SX1278 radio = RadioShield.ModuleA; 37 | 38 | // create Hellschreiber client instance using the FSK module 39 | HellClient hell(&radio); 40 | 41 | void setup() { 42 | Serial.begin(9600); 43 | 44 | // initialize SX1278 with default settings 45 | Serial.print(F("[SX1278] Initializing ... ")); 46 | int state = radio.beginFSK(); 47 | 48 | // when using one of the non-LoRa modules for Morse code 49 | // (RF69, CC1101, Si4432 etc.), use the basic begin() method 50 | // int state = radio.begin(); 51 | 52 | if(state == RADIOLIB_ERR_NONE) { 53 | Serial.println(F("success!")); 54 | } else { 55 | Serial.print(F("failed, code ")); 56 | Serial.println(state); 57 | while(true); 58 | } 59 | 60 | // initialize Hellschreiber client 61 | Serial.print(F("[Hell] Initializing ... ")); 62 | // base frequency: 434.0 MHz 63 | // speed: 122.5 Baud ("Feld Hell") 64 | state = hell.begin(434.0); 65 | if(state == RADIOLIB_ERR_NONE) { 66 | Serial.println(F("success!")); 67 | } else { 68 | Serial.print(F("failed, code ")); 69 | Serial.println(state); 70 | while(true); 71 | } 72 | } 73 | 74 | void loop() { 75 | Serial.print(F("[Hell] Sending Hellschreiber data ... ")); 76 | 77 | // HellClient supports all methods of the Serial class 78 | // NOTE: Lower case letter will be capitalized. 79 | 80 | // Arduino String class 81 | String aStr = "Arduino String"; 82 | hell.print(aStr); 83 | 84 | // character array (C-String) 85 | hell.print("C-String"); 86 | 87 | // string saved in flash 88 | hell.print(F("Flash String")); 89 | 90 | // character 91 | hell.print('c'); 92 | 93 | // byte 94 | // formatting DEC/HEX/OCT/BIN is supported for 95 | // any integer type (byte/int/long) 96 | hell.print(255, HEX); 97 | 98 | // integer number 99 | int i = 1000; 100 | hell.print(i); 101 | 102 | // floating point number 103 | // NOTE: println() has no effect on the transmission, 104 | // and is only kept for compatibility reasons. 105 | float f = -3.1415; 106 | hell.println(f, 3); 107 | 108 | // custom glyph - must be a 7 byte array of rows 7 pixels long 109 | uint8_t customGlyph[] = { 0b0000000, 0b0010100, 0b0010100, 0b0000000, 0b0100010, 0b0011100, 0b0000000 }; 110 | hell.printGlyph(customGlyph); 111 | 112 | Serial.println(F("done!")); 113 | 114 | // wait for a second before transmitting again 115 | delay(1000); 116 | } 117 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/SX126x/SX126x_Transmit_Blocking/SX126x_Transmit_Blocking.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib SX126x Blocking Transmit Example 3 | 4 | This example transmits packets using SX1262 LoRa radio module. 5 | Each packet contains up to 256 bytes of data, in the form of: 6 | - Arduino String 7 | - null-terminated char array (C-string) 8 | - arbitrary binary data (byte array) 9 | 10 | Other modules from SX126x family can also be used. 11 | 12 | Using blocking transmit is not recommended, as it will lead 13 | to inefficient use of processor time! 14 | Instead, interrupt transmit is recommended. 15 | 16 | For default module settings, see the wiki page 17 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx126x---lora-modem 18 | 19 | For full API reference, see the GitHub Pages 20 | https://jgromes.github.io/RadioLib/ 21 | */ 22 | 23 | // include the library 24 | #include 25 | 26 | // SX1262 has the following connections: 27 | // NSS pin: 10 28 | // DIO1 pin: 2 29 | // NRST pin: 3 30 | // BUSY pin: 9 31 | SX1262 radio = new Module(10, 2, 3, 9); 32 | 33 | // or using RadioShield 34 | // https://github.com/jgromes/RadioShield 35 | //SX1262 radio = RadioShield.ModuleA; 36 | 37 | // or using CubeCell 38 | //SX1262 radio = new Module(RADIOLIB_BUILTIN_MODULE); 39 | 40 | void setup() { 41 | Serial.begin(9600); 42 | 43 | // initialize SX1262 with default settings 44 | Serial.print(F("[SX1262] Initializing ... ")); 45 | int state = radio.begin(); 46 | if (state == RADIOLIB_ERR_NONE) { 47 | Serial.println(F("success!")); 48 | } else { 49 | Serial.print(F("failed, code ")); 50 | Serial.println(state); 51 | while (true); 52 | } 53 | 54 | // some modules have an external RF switch 55 | // controlled via two pins (RX enable, TX enable) 56 | // to enable automatic control of the switch, 57 | // call the following method 58 | // RX enable: 4 59 | // TX enable: 5 60 | /* 61 | radio.setRfSwitchPins(4, 5); 62 | */ 63 | } 64 | 65 | // counter to keep track of transmitted packets 66 | int count = 0; 67 | 68 | void loop() { 69 | Serial.print(F("[SX1262] Transmitting packet ... ")); 70 | 71 | // you can transmit C-string or Arduino string up to 72 | // 256 characters long 73 | String str = "Hello World! #" + String(count++); 74 | int state = radio.transmit(str); 75 | 76 | // you can also transmit byte array up to 256 bytes long 77 | /* 78 | byte byteArr[] = {0x01, 0x23, 0x45, 0x56, 0x78, 0xAB, 0xCD, 0xEF}; 79 | int state = radio.transmit(byteArr, 8); 80 | */ 81 | 82 | if (state == RADIOLIB_ERR_NONE) { 83 | // the packet was successfully transmitted 84 | Serial.println(F("success!")); 85 | 86 | // print measured data rate 87 | Serial.print(F("[SX1262] Datarate:\t")); 88 | Serial.print(radio.getDataRate()); 89 | Serial.println(F(" bps")); 90 | 91 | } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) { 92 | // the supplied packet was longer than 256 bytes 93 | Serial.println(F("too long!")); 94 | 95 | } else if (state == RADIOLIB_ERR_TX_TIMEOUT) { 96 | // timeout occured while transmitting packet 97 | Serial.println(F("timeout!")); 98 | 99 | } else { 100 | // some other error occurred 101 | Serial.print(F("failed, code ")); 102 | Serial.println(state); 103 | 104 | } 105 | 106 | // wait for a second before transmitting again 107 | delay(1000); 108 | } 109 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/Morse/Morse_Transmit_SSB/Morse_Transmit_SSB.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib Morse Transmit SSB Example 3 | 4 | This example sends Morse code message using 5 | SX1278's FSK modem. The signal is an unmodulated 6 | carrier wave, and may be demodulated in SSB mode. 7 | 8 | Other modules that can be used for Morse Code: 9 | - SX127x/RFM9x 10 | - RF69 11 | - SX1231 12 | - CC1101 13 | - SX126x 14 | - nRF24 15 | - Si443x/RFM2x 16 | - SX128x 17 | 18 | For default module settings, see the wiki page 19 | https://github.com/jgromes/RadioLib/wiki/Default-configuration 20 | 21 | For full API reference, see the GitHub Pages 22 | https://jgromes.github.io/RadioLib/ 23 | */ 24 | 25 | // include the library 26 | #include 27 | 28 | // SX1278 has the following connections: 29 | // NSS pin: 10 30 | // DIO0 pin: 2 31 | // RESET pin: 9 32 | // DIO1 pin: 3 33 | SX1278 radio = new Module(10, 2, 9, 3); 34 | 35 | // or using RadioShield 36 | // https://github.com/jgromes/RadioShield 37 | //SX1278 radio = RadioShield.ModuleA; 38 | 39 | // create Morse client instance using the FSK module 40 | MorseClient morse(&radio); 41 | 42 | void setup() { 43 | Serial.begin(9600); 44 | 45 | // initialize SX1278 with default settings 46 | Serial.print(F("[SX1278] Initializing ... ")); 47 | int state = radio.beginFSK(); 48 | 49 | // when using one of the non-LoRa modules for Morse code 50 | // (RF69, CC1101, Si4432 etc.), use the basic begin() method 51 | // int state = radio.begin(); 52 | 53 | if(state == RADIOLIB_ERR_NONE) { 54 | Serial.println(F("success!")); 55 | } else { 56 | Serial.print(F("failed, code ")); 57 | Serial.println(state); 58 | while(true); 59 | } 60 | 61 | // initialize Morse client 62 | Serial.print(F("[Morse] Initializing ... ")); 63 | // carrier wave frequency: 434.0 MHz 64 | // speed: 20 words per minute 65 | state = morse.begin(434.0); 66 | if(state == RADIOLIB_ERR_NONE) { 67 | Serial.println(F("success!")); 68 | } else { 69 | Serial.print(F("failed, code ")); 70 | Serial.println(state); 71 | while(true); 72 | } 73 | } 74 | 75 | void loop() { 76 | Serial.print(F("[Morse] Sending Morse data ... ")); 77 | 78 | // MorseClient supports all methods of the Serial class 79 | // NOTE: Characters that do not have ITU-R M.1677-1 80 | // representation will not be sent! Lower case 81 | // letters will be capitalized. 82 | 83 | // send start signal first 84 | morse.startSignal(); 85 | 86 | // Arduino String class 87 | String aStr = "Arduino String"; 88 | morse.print(aStr); 89 | 90 | // character array (C-String) 91 | morse.print("C-String"); 92 | 93 | // string saved in flash 94 | morse.print(F("Flash String")); 95 | 96 | // character 97 | morse.print('c'); 98 | 99 | // byte 100 | // formatting DEC/HEX/OCT/BIN is supported for 101 | // any integer type (byte/int/long) 102 | morse.print(255, HEX); 103 | 104 | // integer number 105 | int i = 1000; 106 | morse.print(i); 107 | 108 | // floating point number 109 | // NOTE: When using println(), the transmission will be 110 | // terminated with end-of-work signal (...-.-). 111 | float f = -3.1415; 112 | morse.println(f, 3); 113 | 114 | Serial.println(F("done!")); 115 | 116 | // wait for a second before transmitting again 117 | delay(1000); 118 | } 119 | -------------------------------------------------------------------------------- /lib/RadioLib/src/protocols/RTTY/RTTY.cpp: -------------------------------------------------------------------------------- 1 | #include "RTTY.h" 2 | 3 | #include 4 | 5 | #if !defined(RADIOLIB_EXCLUDE_RTTY) 6 | 7 | RTTYClient::RTTYClient(PhysicalLayer* phy) { 8 | phyLayer = phy; 9 | lineFeed = "\r\n"; 10 | #if !defined(RADIOLIB_EXCLUDE_AFSK) 11 | audioClient = nullptr; 12 | #endif 13 | } 14 | 15 | #if !defined(RADIOLIB_EXCLUDE_AFSK) 16 | RTTYClient::RTTYClient(AFSKClient* audio) { 17 | phyLayer = audio->phyLayer; 18 | lineFeed = "\r\n"; 19 | audioClient = audio; 20 | } 21 | #endif 22 | 23 | int16_t RTTYClient::begin(float base, uint32_t shift, uint16_t rate, uint8_t enc, uint8_t stopBits) { 24 | // save configuration 25 | RadioLibPrint::encoding = enc; 26 | stopBitsNum = stopBits; 27 | baseFreqHz = base; 28 | shiftFreqHz = shift; 29 | 30 | // calculate duration of 1 bit 31 | bitDuration = (uint32_t)1000000/rate; 32 | 33 | // calculate module carrier frequency resolution 34 | uint32_t step = round(phyLayer->getFreqStep()); 35 | 36 | // check minimum shift value 37 | if(shift < step / 2) { 38 | return(RADIOLIB_ERR_INVALID_RTTY_SHIFT); 39 | } 40 | 41 | // round shift to multiples of frequency step size 42 | if(shift % step < (step / 2)) { 43 | shiftFreq = shift / step; 44 | } else { 45 | shiftFreq = (shift / step) + 1; 46 | } 47 | 48 | // calculate 24-bit frequency 49 | baseFreq = (base * 1000000.0) / phyLayer->getFreqStep(); 50 | 51 | // configure for direct mode 52 | return(phyLayer->startDirect()); 53 | } 54 | 55 | void RTTYClient::idle() { 56 | mark(); 57 | } 58 | 59 | size_t RTTYClient::write(uint8_t b) { 60 | uint8_t dataBitsNum = 0; 61 | switch(RadioLibPrint::encoding) { 62 | case RADIOLIB_ASCII: 63 | dataBitsNum = 7; 64 | break; 65 | case RADIOLIB_ASCII_EXTENDED: 66 | dataBitsNum = 8; 67 | break; 68 | case RADIOLIB_ITA2: 69 | dataBitsNum = 5; 70 | break; 71 | default: 72 | return(0); 73 | } 74 | space(); 75 | 76 | uint16_t maxDataMask = 0x01 << (dataBitsNum - 1); 77 | for(uint16_t mask = 0x01; mask <= maxDataMask; mask <<= 1) { 78 | if(b & mask) { 79 | mark(); 80 | } else { 81 | space(); 82 | } 83 | } 84 | 85 | for(uint8_t i = 0; i < stopBitsNum; i++) { 86 | mark(); 87 | } 88 | 89 | return(1); 90 | } 91 | 92 | void RTTYClient::mark() { 93 | Module* mod = phyLayer->getMod(); 94 | uint32_t start = mod->hal->micros(); 95 | transmitDirect(baseFreq + shiftFreq, baseFreqHz + shiftFreqHz); 96 | mod->waitForMicroseconds(start, bitDuration); 97 | } 98 | 99 | void RTTYClient::space() { 100 | Module* mod = phyLayer->getMod(); 101 | uint32_t start = mod->hal->micros(); 102 | transmitDirect(baseFreq, baseFreqHz); 103 | mod->waitForMicroseconds(start, bitDuration); 104 | } 105 | 106 | int16_t RTTYClient::transmitDirect(uint32_t freq, uint32_t freqHz) { 107 | #if !defined(RADIOLIB_EXCLUDE_AFSK) 108 | if(audioClient != nullptr) { 109 | return(audioClient->tone(freqHz)); 110 | } 111 | #endif 112 | return(phyLayer->transmitDirect(freq)); 113 | } 114 | 115 | int16_t RTTYClient::standby() { 116 | // ensure everything is stopped in interrupt timing mode 117 | Module* mod = phyLayer->getMod(); 118 | mod->waitForMicroseconds(0, 0); 119 | #if !defined(RADIOLIB_EXCLUDE_AFSK) 120 | if(audioClient != nullptr) { 121 | return(audioClient->noTone()); 122 | } 123 | #endif 124 | return(phyLayer->standby()); 125 | } 126 | 127 | #endif 128 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/SX128x/SX128x_Receive_Blocking/SX128x_Receive_Blocking.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib SX128x Blocking Receive Example 3 | 4 | This example listens for LoRa transmissions using SX126x Lora modules. 5 | To successfully receive data, the following settings have to be the same 6 | on both transmitter and receiver: 7 | - carrier frequency 8 | - bandwidth 9 | - spreading factor 10 | - coding rate 11 | - sync word 12 | - preamble length 13 | 14 | Other modules from SX128x family can also be used. 15 | 16 | Using blocking receive is not recommended, as it will lead 17 | to significant amount of timeouts, inefficient use of processor 18 | time and can some miss packets! 19 | Instead, interrupt receive is recommended. 20 | 21 | For default module settings, see the wiki page 22 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx128x---lora-modem 23 | 24 | For full API reference, see the GitHub Pages 25 | https://jgromes.github.io/RadioLib/ 26 | */ 27 | 28 | // include the library 29 | #include 30 | 31 | // SX1280 has the following connections: 32 | // NSS pin: 10 33 | // DIO1 pin: 2 34 | // NRST pin: 3 35 | // BUSY pin: 9 36 | SX1280 radio = new Module(10, 2, 3, 9); 37 | 38 | // or using RadioShield 39 | // https://github.com/jgromes/RadioShield 40 | //SX1280 radio = RadioShield.ModuleA; 41 | 42 | void setup() { 43 | Serial.begin(9600); 44 | 45 | // initialize SX1280 with default settings 46 | Serial.print(F("[SX1280] Initializing ... ")); 47 | int state = radio.begin(); 48 | if (state == RADIOLIB_ERR_NONE) { 49 | Serial.println(F("success!")); 50 | } else { 51 | Serial.print(F("failed, code ")); 52 | Serial.println(state); 53 | while (true); 54 | } 55 | } 56 | 57 | void loop() { 58 | Serial.print(F("[SX1280] Waiting for incoming transmission ... ")); 59 | 60 | // you can receive data as an Arduino String 61 | String str; 62 | int state = radio.receive(str); 63 | 64 | // you can also receive data as byte array 65 | /* 66 | byte byteArr[8]; 67 | int state = radio.receive(byteArr, 8); 68 | */ 69 | 70 | if (state == RADIOLIB_ERR_NONE) { 71 | // packet was successfully received 72 | Serial.println(F("success!")); 73 | 74 | // print the data of the packet 75 | Serial.print(F("[SX1280] Data:\t\t")); 76 | Serial.println(str); 77 | 78 | // print the RSSI (Received Signal Strength Indicator) 79 | // of the last received packet 80 | Serial.print(F("[SX1280] RSSI:\t\t")); 81 | Serial.print(radio.getRSSI()); 82 | Serial.println(F(" dBm")); 83 | 84 | // print the SNR (Signal-to-Noise Ratio) 85 | // of the last received packet 86 | Serial.print(F("[SX1280] SNR:\t\t")); 87 | Serial.print(radio.getSNR()); 88 | Serial.println(F(" dB")); 89 | 90 | // print the Frequency Error 91 | // of the last received packet 92 | Serial.print(F("[SX1280] Frequency Error:\t")); 93 | Serial.print(radio.getFrequencyError()); 94 | Serial.println(F(" Hz")); 95 | 96 | } else if (state == RADIOLIB_ERR_RX_TIMEOUT) { 97 | // timeout occurred while waiting for a packet 98 | Serial.println(F("timeout!")); 99 | 100 | } else if (state == RADIOLIB_ERR_CRC_MISMATCH) { 101 | // packet was received, but is malformed 102 | Serial.println(F("CRC error!")); 103 | 104 | } else { 105 | // some other error occurred 106 | Serial.print(F("failed, code ")); 107 | Serial.println(state); 108 | 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /lib/RadioLib/examples/SX127x/SX127x_Receive_Blocking/SX127x_Receive_Blocking.ino: -------------------------------------------------------------------------------- 1 | /* 2 | RadioLib SX127x Blocking Receive Example 3 | 4 | This example listens for LoRa transmissions using SX127x Lora modules. 5 | To successfully receive data, the following settings have to be the same 6 | on both transmitter and receiver: 7 | - carrier frequency 8 | - bandwidth 9 | - spreading factor 10 | - coding rate 11 | - sync word 12 | - preamble length 13 | 14 | Other modules from SX127x/RFM9x family can also be used. 15 | 16 | Using blocking receive is not recommended, as it will lead 17 | to significant amount of timeouts, inefficient use of processor 18 | time and can some miss packets! 19 | Instead, interrupt receive is recommended. 20 | 21 | For default module settings, see the wiki page 22 | https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem 23 | 24 | For full API reference, see the GitHub Pages 25 | https://jgromes.github.io/RadioLib/ 26 | */ 27 | 28 | // include the library 29 | #include 30 | 31 | // SX1278 has the following connections: 32 | // NSS pin: 10 33 | // DIO0 pin: 2 34 | // RESET pin: 9 35 | // DIO1 pin: 3 36 | SX1278 radio = new Module(10, 2, 9, 3); 37 | 38 | // or using RadioShield 39 | // https://github.com/jgromes/RadioShield 40 | //SX1278 radio = RadioShield.ModuleA; 41 | 42 | void setup() { 43 | Serial.begin(9600); 44 | 45 | // initialize SX1278 with default settings 46 | Serial.print(F("[SX1278] Initializing ... ")); 47 | int state = radio.begin(); 48 | if (state == RADIOLIB_ERR_NONE) { 49 | Serial.println(F("success!")); 50 | } else { 51 | Serial.print(F("failed, code ")); 52 | Serial.println(state); 53 | while (true); 54 | } 55 | } 56 | 57 | void loop() { 58 | Serial.print(F("[SX1278] Waiting for incoming transmission ... ")); 59 | 60 | // you can receive data as an Arduino String 61 | String str; 62 | int state = radio.receive(str); 63 | 64 | // you can also receive data as byte array 65 | /* 66 | byte byteArr[8]; 67 | int state = radio.receive(byteArr, 8); 68 | */ 69 | 70 | if (state == RADIOLIB_ERR_NONE) { 71 | // packet was successfully received 72 | Serial.println(F("success!")); 73 | 74 | // print the data of the packet 75 | Serial.print(F("[SX1278] Data:\t\t\t")); 76 | Serial.println(str); 77 | 78 | // print the RSSI (Received Signal Strength Indicator) 79 | // of the last received packet 80 | Serial.print(F("[SX1278] RSSI:\t\t\t")); 81 | Serial.print(radio.getRSSI()); 82 | Serial.println(F(" dBm")); 83 | 84 | // print the SNR (Signal-to-Noise Ratio) 85 | // of the last received packet 86 | Serial.print(F("[SX1278] SNR:\t\t\t")); 87 | Serial.print(radio.getSNR()); 88 | Serial.println(F(" dB")); 89 | 90 | // print frequency error 91 | // of the last received packet 92 | Serial.print(F("[SX1278] Frequency error:\t")); 93 | Serial.print(radio.getFrequencyError()); 94 | Serial.println(F(" Hz")); 95 | 96 | } else if (state == RADIOLIB_ERR_RX_TIMEOUT) { 97 | // timeout occurred while waiting for a packet 98 | Serial.println(F("timeout!")); 99 | 100 | } else if (state == RADIOLIB_ERR_CRC_MISMATCH) { 101 | // packet was received, but is malformed 102 | Serial.println(F("CRC error!")); 103 | 104 | } else { 105 | // some other error occurred 106 | Serial.print(F("failed, code ")); 107 | Serial.println(state); 108 | 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /lib/RadioLib/src/protocols/Print/ITA2String.cpp: -------------------------------------------------------------------------------- 1 | #include "ITA2String.h" 2 | 3 | #include 4 | 5 | ITA2String::ITA2String(char c) { 6 | asciiLen = 1; 7 | #if !defined(RADIOLIB_STATIC_ONLY) 8 | strAscii = new char[1]; 9 | #endif 10 | strAscii[0] = c; 11 | ita2Len = 0; 12 | } 13 | 14 | ITA2String::ITA2String(const char* str) { 15 | asciiLen = strlen(str); 16 | #if !defined(RADIOLIB_STATIC_ONLY) 17 | strAscii = new char[asciiLen + 1]; 18 | #endif 19 | strcpy(strAscii, str); 20 | ita2Len = 0; 21 | } 22 | 23 | ITA2String::~ITA2String() { 24 | #if !defined(RADIOLIB_STATIC_ONLY) 25 | delete[] strAscii; 26 | #endif 27 | } 28 | 29 | size_t ITA2String::length() { 30 | // length returned by this method is different than the length of ASCII-encoded strAscii 31 | // ITA2-encoded string length varies based on how many number and characters the string contains 32 | 33 | if(ita2Len == 0) { 34 | // ITA2 length wasn't calculated yet, call byteArr() to calculate it 35 | byteArr(); 36 | } 37 | 38 | return(ita2Len); 39 | } 40 | 41 | uint8_t* ITA2String::byteArr() { 42 | // create temporary array 2x the string length (figures may be 3 bytes) 43 | #if defined(RADIOLIB_STATIC_ONLY) 44 | uint8_t temp[RADIOLIB_STATIC_ARRAY_SIZE*2 + 1]; 45 | #else 46 | uint8_t* temp = new uint8_t[asciiLen*2 + 1]; 47 | #endif 48 | 49 | size_t arrayLen = 0; 50 | bool flagFigure = false; 51 | for(size_t i = 0; i < asciiLen; i++) { 52 | uint16_t code = getBits(strAscii[i]); 53 | uint8_t shift = (code >> 5) & 0b11111; 54 | uint8_t character = code & 0b11111; 55 | // check if the code is letter or figure 56 | if(shift == RADIOLIB_ITA2_FIGS) { 57 | // check if this is the first figure in sequence 58 | if(!flagFigure) { 59 | flagFigure = true; 60 | temp[arrayLen++] = RADIOLIB_ITA2_FIGS; 61 | } 62 | 63 | // add the character code 64 | temp[arrayLen++] = character & 0b11111; 65 | 66 | // check the following character (skip for message end) 67 | if(i < (asciiLen - 1)) { 68 | uint16_t nextCode = getBits(strAscii[i+1]); 69 | uint8_t nextShift = (nextCode >> 5) & 0b11111; 70 | if(nextShift == RADIOLIB_ITA2_LTRS) { 71 | // next character is a letter, terminate figure shift 72 | temp[arrayLen++] = RADIOLIB_ITA2_LTRS; 73 | flagFigure = false; 74 | } 75 | } else { 76 | // reached the end of the message, terminate figure shift 77 | temp[arrayLen++] = RADIOLIB_ITA2_LTRS; 78 | flagFigure = false; 79 | } 80 | } else { 81 | temp[arrayLen++] = character & 0b11111; 82 | } 83 | } 84 | 85 | // save ITA2 string length 86 | ita2Len = arrayLen; 87 | 88 | uint8_t* arr = new uint8_t[arrayLen]; 89 | memcpy(arr, temp, arrayLen); 90 | #if !defined(RADIOLIB_STATIC_ONLY) 91 | delete[] temp; 92 | #endif 93 | 94 | return(arr); 95 | } 96 | 97 | uint16_t ITA2String::getBits(char c) { 98 | // search ITA2 table 99 | uint16_t code = 0x0000; 100 | for(uint8_t i = 0; i < RADIOLIB_ITA2_LENGTH; i++) { 101 | if(RADIOLIB_NONVOLATILE_READ_BYTE(&ITA2Table[i][0]) == c) { 102 | // character is in letter shift 103 | code = (RADIOLIB_ITA2_LTRS << 5) | i; 104 | break; 105 | } else if(RADIOLIB_NONVOLATILE_READ_BYTE(&ITA2Table[i][1]) == c) { 106 | // character is in figures shift 107 | code = (RADIOLIB_ITA2_FIGS << 5) | i; 108 | break; 109 | } 110 | } 111 | 112 | return(code); 113 | } 114 | -------------------------------------------------------------------------------- /lib/RadioLib/src/modules/SX126x/SX1262.cpp: -------------------------------------------------------------------------------- 1 | #include "SX1262.h" 2 | #if !defined(RADIOLIB_EXCLUDE_SX126X) 3 | 4 | SX1262::SX1262(Module* mod) : SX126x(mod) { 5 | chipType = RADIOLIB_SX1262_CHIP_TYPE; 6 | } 7 | 8 | int16_t SX1262::begin(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength, float tcxoVoltage, bool useRegulatorLDO) { 9 | // execute common part 10 | int16_t state = SX126x::begin(cr, syncWord, preambleLength, tcxoVoltage, useRegulatorLDO); 11 | RADIOLIB_ASSERT(state); 12 | 13 | // configure publicly accessible settings 14 | state = setSpreadingFactor(sf); 15 | RADIOLIB_ASSERT(state); 16 | 17 | state = setBandwidth(bw); 18 | RADIOLIB_ASSERT(state); 19 | 20 | state = setFrequency(freq); 21 | RADIOLIB_ASSERT(state); 22 | 23 | state = SX126x::fixPaClamping(); 24 | RADIOLIB_ASSERT(state); 25 | 26 | state = setOutputPower(power); 27 | RADIOLIB_ASSERT(state); 28 | 29 | return(state); 30 | } 31 | 32 | int16_t SX1262::beginFSK(float freq, float br, float freqDev, float rxBw, int8_t power, uint16_t preambleLength, float tcxoVoltage, bool useRegulatorLDO) { 33 | // execute common part 34 | int16_t state = SX126x::beginFSK(br, freqDev, rxBw, preambleLength, tcxoVoltage, useRegulatorLDO); 35 | RADIOLIB_ASSERT(state); 36 | 37 | // configure publicly accessible settings 38 | state = setFrequency(freq); 39 | RADIOLIB_ASSERT(state); 40 | 41 | state = SX126x::fixPaClamping(); 42 | RADIOLIB_ASSERT(state); 43 | 44 | state = setOutputPower(power); 45 | RADIOLIB_ASSERT(state); 46 | 47 | return(state); 48 | } 49 | 50 | int16_t SX1262::setFrequency(float freq) { 51 | return(setFrequency(freq, true)); 52 | } 53 | 54 | int16_t SX1262::setFrequency(float freq, bool calibrate) { 55 | RADIOLIB_CHECK_RANGE(freq, 150.0, 960.0, RADIOLIB_ERR_INVALID_FREQUENCY); 56 | 57 | // calibrate image 58 | if(calibrate) { 59 | uint8_t data[2]; 60 | if(freq > 900.0) { 61 | data[0] = RADIOLIB_SX126X_CAL_IMG_902_MHZ_1; 62 | data[1] = RADIOLIB_SX126X_CAL_IMG_902_MHZ_2; 63 | } else if(freq > 850.0) { 64 | data[0] = RADIOLIB_SX126X_CAL_IMG_863_MHZ_1; 65 | data[1] = RADIOLIB_SX126X_CAL_IMG_863_MHZ_2; 66 | } else if(freq > 770.0) { 67 | data[0] = RADIOLIB_SX126X_CAL_IMG_779_MHZ_1; 68 | data[1] = RADIOLIB_SX126X_CAL_IMG_779_MHZ_2; 69 | } else if(freq > 460.0) { 70 | data[0] = RADIOLIB_SX126X_CAL_IMG_470_MHZ_1; 71 | data[1] = RADIOLIB_SX126X_CAL_IMG_470_MHZ_2; 72 | } else { 73 | data[0] = RADIOLIB_SX126X_CAL_IMG_430_MHZ_1; 74 | data[1] = RADIOLIB_SX126X_CAL_IMG_430_MHZ_2; 75 | } 76 | int16_t state = SX126x::calibrateImage(data); 77 | RADIOLIB_ASSERT(state); 78 | } 79 | 80 | // set frequency 81 | return(SX126x::setFrequencyRaw(freq)); 82 | } 83 | 84 | int16_t SX1262::setOutputPower(int8_t power) { 85 | RADIOLIB_CHECK_RANGE(power, -9, 22, RADIOLIB_ERR_INVALID_OUTPUT_POWER); 86 | 87 | // get current OCP configuration 88 | uint8_t ocp = 0; 89 | int16_t state = readRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1); 90 | RADIOLIB_ASSERT(state); 91 | 92 | // set PA config 93 | state = SX126x::setPaConfig(0x04, RADIOLIB_SX126X_PA_CONFIG_SX1262); 94 | RADIOLIB_ASSERT(state); 95 | 96 | // set output power 97 | /// \todo power ramp time configuration 98 | state = SX126x::setTxParams(power); 99 | RADIOLIB_ASSERT(state); 100 | 101 | // restore OCP configuration 102 | return(writeRegister(RADIOLIB_SX126X_REG_OCP_CONFIGURATION, &ocp, 1)); 103 | } 104 | 105 | #endif 106 | --------------------------------------------------------------------------------