Giter VIP home page Giter VIP logo

sx126x-arduino's Introduction

SX126x-Arduino Build StatusDocumentation


Arduino library for LoRa communication with Semtech SX126x chips. It is based on Semtech's SX126x libraries and adapted to the Arduino framework for ESP32, ESP8266, nRF52832 and RP2040. It will not work with other uC's like AVR.
LoRaWAN version: MAC V1.0.2 and Regional Parameters version: PHY V1.0.2 REV B



IMPORTANT:

RAK11300 module (RP2040) support is only tested with the ArduinoCore Mbed BSP. It will not work with other BSP's for the Raspberry RP2040.

NEWS:

Current testing RAK11300/RAK11310 with the Arduino Pico BSP, still experimental, but promising.



IMPORTANT: READ WHAT'S NEW IN V2 Some major changes are made in V2 of the SX126x-Arduino library:
- The library now supports all LoRaWAN regions without re-compiling
- The interrupt handling for SX126x IRQ's are taken into separate tasks for ESP32, nRF52 and RP2040
This requires some code changes in your existing applications. Please read WHAT'S NEW IN V2 to learn how to migrate your application to use SX126x-Arduino V2


Content

General Info LoRa   LoRaWan
  Based on   Basic LoRa communication     LoRaWAN region definitions
  Licenses     HW structure definition   LoRaWan functions
Changelog     GPIO definitions     Initialize
Features     Example HW configuration     Callbacks
Functions     Initialize the LoRa HW     Join
  Module specific setup     Initialization for specific modules     LoRaWan single channel gateway
  Chip selection     Setup the callbacks for LoRa events     Limit frequency hopping to a sub band
  LoRa parameters     Initialize the radio
  SPI definition     Initialize the radio after CPU woke up from deep sleep Examples
  TXCO and antenna control     Start listening for packets Installation

General info

I stumbled over the SX126x LoRa family in a customer project. Most of the existing Arduino libraries for Semtech's SX127x family are unfortunately not working with this new generation LoRa chip. I found a usefull base library from Insight SIP which is based on the original Semtech SX126x library and changed it to work with the ESP32.
For now the library is tested with an eByte E22-900M22S module connected to an ESP32 and an Insight SIP ISP4520 which combines a Nordic nRF52832 and a Semtech SX1262 in one module. It is as well tested with an RAKwireless WisCore RAK4630 module

Check out the example provided with this library to learn the basic functions.

For the deep sleep support on the ESP32 check out the example DeepSleep.

THIS IS WORK IN PROGRESS AND NOT ALL FUNCTIONS ARE INCLUDED NOR TESTED. USE IT AT YOUR OWN RISK!


Based on


Licenses

Library published under MIT license

Semtech revised BSD license for codeparts used from Semtech S.A.

--- Revised BSD License ---
Copyright (c) 2013, SEMTECH S.A.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the Semtech corporation nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL SEMTECH S.A. BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Changelog

Code releases

  • 2024-07-02 Add missing header file
    • Fix compilation error
  • 2024-06-26
    • With ADR enabled, fix the DR reset to default when confirmed/unconfirmed packets are sent.
  • 2024-02-24
    • Fix callbacks for P2P RX and TX timeout not being called
  • 2023-12-14
    • Seems RAK11300 and arduino-pico BSP is working now. still experimental
  • 2023-12-12
    • Added support for the RAK11300 in arduino-pico BSP still experimental
  • 2023-11-22
    • Change behaviour of IRQ_HEADER_ERROR, thanks to @JeromeBriot
  • 2023-10-01
    • Fix public/private network always public
    • Add option to restart MAC stack to change e.g. region without re-init timers
  • 2023-08-27
    • Add function to reset MAC counters
  • 2023-05-16
    • Fix typo in RadioTimeOnAir for FSK
    • Improve RadioTimeOnAir for FSK, thanks to @mikedupi
  • 2023-04-17
    • Fix runtime problem in LoRaMacHelper, thanks to @avillacis
  • 2023-01-28
    • Update examples, thanks to @DanielBustillos
    • Cleanup RAK4630 initialization
    • Add lmh_getConfRetries() to readback the confirmed package retry setting
    • Make RX timeout configurable with #define RXTIMEOUT_LORA_MAX, thanks to @kisChang
    • Add set default RX gain in SX126xSertRx, thanks to @kisChang
    • Allow change of TCXO control with hwConfig structure, thanks to @dberlin
    • Add confirmed failed callback if the degraded datarate becomes insufficient to transmit the payload length, thanks to @avillacis
    • Fix RX window timeouts, thanks to @battosai30
  • 2022-10-11
    • Fix RP2040 timers, thanks to @kisChang
  • 2022-09-01
    • Fix wrong RX2 frequency in AS923-2, AS923-3, AS923-4
  • 2022-07-13
    • Fix crash when library debug is enabled in AS923 region.
  • 2022-03-21
    • Fix RAK11310 timer problem
  • 2022-03-03
    • Fix AS923 CFlist channel assignment bug
  • 2022-02-09
    • Fix EU868 bug that enabled always all 8 channels
  • 2021-12-18
    • Fix bug in lmh_datarate_set. Function did change only ADR, but did not update the datarate setting
  • 2021-12-09
    • Make antenna switch control compatible with different switches
  • 2021-11-26
    • Improve the examples and correct outdated information
  • 2021-11-01
    • Correct handling of TX timeout in Radio callbacks
  • 2021-09-20
    • Add missing declaration for lora_rak13300_init()
  • 2021-08-11:
    • Correct power regulator setting for RAKwireless RAK11300 module from LDO to DCDC
  • 2021-07-22:
    • Add support for RAKwireless RAK11300 module (Raspberry RP2040 + SX1262 module)
  • 2021-06-30:
    • Add callbacks for LoRaWAN TX finished (both confirmed and unconfirmed)
    • Add addional bandwidths for LoRa transmissions. Breaks Radio.TimeOnAir() for bandwidths other than BW 125, 250 and 500
    • Fix minor problem in CF list handling for AS923-x regions
  • 2021-05-15:
    • Implement new regions AS923-2, AS923-3, AS923-4, RU864
    • Test CF list to add additionals channesl on AS923 and RU864
  • 2021-04-10:
    • Add support for all LoRaWAN regions without recompilation of the code
    • Add background handling of SX126x IRQ's for better performance
    • Read WHAT'S NEW IN V2 to migrate your application to V2
  • 2021-03-10:
    • Fix AS923 OTAA join problem
  • 2021-02-26:
    • Fix join bug when first OTAA join fails
    • When OTAA join failed callback was called, following lmh_join() calls fail always
  • 2021-02-11:
    • Add callback for OTAA join failure
  • 2021-02-02:
    • Fix ADR problem
    • Fix Join problem for some Regions
    • Add some debug output
    • Add option to set node class during initialization. Defaults to CLASS_A for backward compatibility: lmh_error_status lmh_init(lmh_callback_t *callbacks, lmh_param_t lora_param, bool otaa, eDeviceClass class = CLASS_A);
  • 2020-09-29:
    • Fix wrong control of antenna switch for RAK4631
    • Add option to control power of antenna switch by the library with _hwConfig.USE_RXEN_ANT_PWR
  • 2020-08-01:
    • Fixed linker error when header files are included from multiple source files
  • 2020-07-09:
    • Duty cycle and adaptive data rate control moved out of Commissioning.h
  • 2020-06-25:
    • Rework the timer functions for nRF52 family. OTAA now working better
    • Add option to select between OTAA and ABP for LoRaWan when calling lmh_init()
    • Reworked SX126x reset function
    • Support for RAKwireless RAK4630/4631 => lora_rak4630_init()
  • 2020-06-14:
    • Fix Travis CI & documentation
    • Add option to select LDO instead of DCDC for SX126x chip in hwConfig struct
  • 2020-05-22:
    • Fix compiler errors when OTAA is selected
  • 2020-05-20:
    • Add compatibility with nRF52840 (experimental)
    • Fix ArduinoIDE compile problems
    • Fix examples
  • 2020-03-28:
    • Fix bug in LoRaWan Class switch
  • 2020-03-10:
    • Added new SetCadParameter function to Radio class
  • 2020-01-16:
    • Fix bug in receive callbacks in case a CRC error is detected.
    • Added Preamble detection callback
    • Added two more examples for a sensor node and a gateway node with deep sleep usage.
  • 2019-12-28:
    • Updated examples
  • 2019-12-12:
    • Added check if SX126x is really connected
    • Fixed second bug in the definition of the sync word
    • Added IRQ settings in RadioSetRxDutyCycle
  • 2019-12-09:
    • Fixed bug in the definition of the sync word
    • Added possibility to re-init connection to SX1261/2 after CPU wakes up from sleep/deep-sleep
      • lora_hardware_re_init() to re-initialize SX1262 connection without resetting the LoRa chip
      • Radio.ReInit() to re-initialize SX1262 connection without resetting the LoRa chip
      • Radio.IrqProcessAfterDeepSleep() to handle IRQ that woke up the CPU (RX_DONE, TX_DONE, ...)
  • 2019-11-09:
    • Added Workarounds for limitations as written in DS_SX1261-2_V1.2 datasheet
    • Tested with both Single Channel (ESP32) and 8 Channel (Dragino LPS8) LoRaWan gateways
    • Added possibility to force use of sub band of region lmh_setSubBandChannels()
  • 2019-10-12:
    • On PlatformIO no more need to edit Commissioning.h. Everything is done with functions and build flags
    • On ArduinoIDE reduced edititing of Commissioning.h. Only the region has to be setup by #define
    • Replaced LoRaWan definitions by function calls lmh_setDevEui, lmh_setAppEui, lmh_setAppKey, lmh_setNwkSKey, lmh_setAppSKey, lmh_setDevAddr, lmh_setSingleChannelGateway
    • Updated LoRaWan examples
    • Added CHANNEL.MD and DATARATE.MD lists
    • Beautify README.MD
  • 2019-10-11: Added support for LoRaWan connection to single channel Gateway (no frequency hopping)
  • 2019-10-09:
    • Tested LoRaWan with a single channel LoRaWan gateway.
    • Added support for single channel gateways
    • Added support for Insight SIP ISP4520 SoC (nRf52832 + SX1261/2 in one package)
  • 2019-08-01: Added Espressif ESP8266 support
  • 2019-07-31: Added LoRaWan support (only partly tested)
  • 2019-07-28: Restructure of folders, added nRF52832 support
  • 2019-07-26: First commit.

Features

  • Support SX1261, SX1262 and SX1268 chips
  • Support of LoRa protocol and FSK protocol (theoretical, I did not test FSK at all)
  • Flexible setup for different modules (antenna control, TCXO control)
  • Support LoRaWan node class A and C tested with single channel LoRaWan gateway

Functions

WORK IN PROGRESS
Check out the example provided with this library to learn the basic functions.
See examples


Module specific setup

To adapt the library to different modules and region specific ISM frequencies some defines are used. The following list is not complete yet and will be extended


Chip selection

#define SX1261_CHIP // if your module has a SX1261 chip    
#define SX1262_CHIP // if your module has a SX1262 or SX1268 chip    

MCU to SX126x SPI definition

The hardware configuration is given to the library by a structure with the following elements

  hwConfig.CHIP_TYPE = SX1262_CHIP;         // SX1261_CHIP for Semtech SX1261 SX1262_CHIP for Semtech SX1262/1268
  hwConfig.PIN_LORA_RESET = PIN_LORA_RESET; // GPIO pin connected to NRESET of the SX126x    
  hwConfig.PIN_LORA_NSS = PIN_LORA_NSS;     // GPIO pin connected to NSS of the SX126x    
  hwConfig.PIN_LORA_SCLK = PIN_LORA_SCLK;   // GPIO pin connected to SCK of the SX126x    
  hwConfig.PIN_LORA_MISO = PIN_LORA_MISO;   // GPIO pin connected to MISO of the SX126x    
  hwConfig.PIN_LORA_DIO_1 = PIN_LORA_DIO_1; // GPIO pin connected to DIO 1 of the SX126x    
  hwConfig.PIN_LORA_BUSY = PIN_LORA_BUSY;   // GPIO pin connected to BUSY of the SX126x    
  hwConfig.PIN_LORA_MOSI = PIN_LORA_MOSI;   // GPIO pin connected to MOSI of the SX126x    
  hwConfig.RADIO_TXEN = RADIO_TXEN;         // GPIO pin used to enable the RX antenna of the SX126x    
  hwConfig.RADIO_RXEN = RADIO_RXEN;         // GPIO pin used to enable the TX antenna of the SX126x    
  hwConfig.USE_DIO2_ANT_SWITCH = false;     // True if DIO2 is used to switch the antenna from RX to TX
  hwConfig.USE_DIO3_TCXO = true;            // True if DIO3 is used to control the voltage of the TXCO oscillator
  hwConfig.USE_DIO3_ANT_SWITCH = false;     // True if DIO3 is used to enable/disable the antenna
  hwConfig.USE_LDO = false;                 // False if SX126x DCDC converter is used, true if SX126x LDO is used
  hwConfig.USE_RXEN_ANT_PWR = false;        // If set to true RADIO_RXEN pin is used to control power of antenna switch

Explanation for LDO and DCDC selection

The hardware of the SX126x chips can be designed to use either an internal LDO or an internal DCDC converter. The DCDC converter provides better current savings and will be used in most modules. If there are problems to get the SX126x to work, check which HW configuration is used and set USE_LDO accordingly.
If USE_LDO is not set in the hwConfig, DCDC is used as default.


Explanation for TXCO and antenna control

  • RADIO_TXEN and RADIO_RXEN are used on eByte E22-900M22S module to switch the antenna between RX and TX
  • DIO2 as antenna switch is used in the example Semtech design as default and might be used by many modules
  • DIO3 as antenna switch is used by e.g. Insight SIP ISP4520 module which integrates a nRF52832 and a SX126x chip
  • Some modules use DIO3 to control the power supply of the TXCO.
  • Some modules use DIO2 to switch the antenna between RX and TX and a separate GPIO to power the antenna switch on or off. Switching the antenna switch off can reduce the power consumption. The GPIO used to control the antenna power is defined as RADIO_RXEN. LOW == power off, HIGH == power on.

Usage

See examples.
There is one example for ArduinoIDE and one example for PlatformIO available.
The PingPong examples show how to define the HW connection between the MCU and the SX126x chip/module.
Another example is for LoRaWan and is tested with a Single Channel (ESP32) and a 8 Channel (Dragino LPS8) LoRaWan gateways. The examples can be found here: ArduinoIDE and one example for PlatformIO


Basic LoRa communication


HW structure definition

Structure to define the connection between the MCU and the SX126x

hw_config hwConfig;

GPIO definitions

GPIO definitions for an ESP32. Change it to the connections between the ESP32 and the SX126x in your specific HW design

// ESP32 - SX126x pin configuration
int PIN_LORA_RESET = 4;  // LORA RESET
int PIN_LORA_NSS = 5;    // LORA SPI CS
int PIN_LORA_SCLK = 18;  // LORA SPI CLK
int PIN_LORA_MISO = 19;  // LORA SPI MISO
int PIN_LORA_DIO_1 = 21; // LORA DIO_1
int PIN_LORA_BUSY = 22;  // LORA SPI BUSY
int PIN_LORA_MOSI = 23;  // LORA SPI MOSI
int RADIO_TXEN = 26;     // LORA ANTENNA TX ENABLE
int RADIO_RXEN = 27;     // LORA ANTENNA RX ENABLE

LoRa definitions

Check the SX126x datasheet for explanations
The bandwidth can be set to any bandwidth supported by the SX126x:

Index Bandwidth Index Bandwidth
0 125 kHz 5 31.25 kHz
1 250 kHz 6 20.83 kHz
2 500 kHz 7 15.63 kHz
3 62.5 kHz 8 10.42 kHz
4 41.67 kHz 9 7.81 kHz
// Define LoRa parameters
#define RF_FREQUENCY 868000000  // Hz
#define TX_OUTPUT_POWER 22      // dBm
#define LORA_BANDWIDTH 0        // [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3 ... 9 see table]
#define LORA_SPREADING_FACTOR 7 // [SF7..SF12]
#define LORA_CODINGRATE 1       // [1: 4/5, 2: 4/6,  3: 4/7,  4: 4/8]
#define LORA_PREAMBLE_LENGTH 8  // Same for Tx and Rx
#define LORA_SYMBOL_TIMEOUT 0   // Symbols
#define LORA_FIX_LENGTH_PAYLOAD_ON false
#define LORA_IQ_INVERSION_ON false
#define RX_TIMEOUT_VALUE 3000
#define TX_TIMEOUT_VALUE 3000

#define BUFFER_SIZE 64 // Define the payload size here

Example HW configuration

Fill the structure with the HW configuration

  // Define the HW configuration between MCU and SX126x
  hwConfig.CHIP_TYPE = SX1262_CHIP;         // Example uses an eByte E22 module with an SX1262
  hwConfig.PIN_LORA_RESET = PIN_LORA_RESET; // LORA RESET
  hwConfig.PIN_LORA_NSS = PIN_LORA_NSS;     // LORA SPI CS
  hwConfig.PIN_LORA_SCLK = PIN_LORA_SCLK;   // LORA SPI CLK
  hwConfig.PIN_LORA_MISO = PIN_LORA_MISO;   // LORA SPI MISO
  hwConfig.PIN_LORA_DIO_1 = PIN_LORA_DIO_1; // LORA DIO_1
  hwConfig.PIN_LORA_BUSY = PIN_LORA_BUSY;   // LORA SPI BUSY
  hwConfig.PIN_LORA_MOSI = PIN_LORA_MOSI;   // LORA SPI MOSI
  hwConfig.RADIO_TXEN = RADIO_TXEN;         // LORA ANTENNA TX ENABLE
  hwConfig.RADIO_RXEN = RADIO_RXEN;         // LORA ANTENNA RX ENABLE
  hwConfig.USE_DIO2_ANT_SWITCH = false;     // Example uses an eByte E22 module which uses RXEN and TXEN pins as antenna control
  hwConfig.USE_DIO3_TCXO = true;            // Example uses an eByte E22 module which uses DIO3 to control oscillator voltage
  hwConfig.USE_DIO3_ANT_SWITCH = false;     // Only Insight ISP4520 module uses DIO3 as antenna control
  hwConfig.USE_LDO = false;                 // Set to true if SX126x uses LDO instead of DCDC converter
  hwConfig.USE_RXEN_ANT_PWR = false;        // Antenna power is not controlled by a GPIO

Module specific initialization


  • If you use a microcontroller and a separate board with the SX126x transceiver you need to define the hwConfig structure to define the GPIO's used to connect the two chips.
  • If you use the Insight SIP4520 or the RAKwireless RAK4630/4631 modules the connections between the chips are fixed. In this case you do not need the hwConfig structure and can instead use simplified initialzation functions as shown below.

Module specific header files


  • If you use a microcontroller and a separate board with the SX126x transceiver use the generic header files SX126x-Arduino.h and LoRaWan-Arduino.h
  • If you use the RAKwireless RAK4630/4631 modules use the module specific header files SX126x-RAK4630.h and LoRaWan-RAK4630.h
  • If you use the Insight SIP4520 modules use the module specific header files SX126x-ISP4520.h and LoRaWan-ISP4520.h

Initialize the LoRa HW

  lora_hardware_init(hwConfig);

Simplified LoRa HW initialization for specific modules

Some modules integrate an MCU and the SX126x LoRa transceiver and have a fixed connection between them. In these cases a simplified initialization can be used.

Simplified LoRa HW initialization for ISP4520 module

The ISP4520 module has the nRF52832 and SX1261 or SX1262 chips integrated in a module. Therefore the hardware configuration is fixed. To initialize the LoRa chip you need only to specify if the module is based on a SX1261 (ISP4520 EU version) or on a SX1262 (ISP4520 US version).

  lora_isp4520_init(SX1262);

Simplified LoRa HW initialization for RAK4630/4631 module

The RAK4630/4631 module has the nRF52840 and SX1262 chips integrated in a module. Therefore the hardware configuration is fixed.

  lora_rak4630_init();

Simplified LoRa HW initialization for RAK11300/11310 module

The RAK11300/11310 module has the RP2040 and SX1262 chips integrated in a module. Therefore the hardware configuration is fixed.

  lora_rak11300_init();

Simplified LoRa HW initialization for RAK13300 module

The RAK13300 module is an IO module that has a LoRa SX1262 LoRa transceiver. It is made for the RAK11200 ESP32 module and the hardware configuration is fixed.

  lora_rak13300_init();

Initialize the LoRa HW after CPU woke up from deep sleep

When you want to use the deep sleep function of the ESP32 with external wake up source, you do not want to reset and reconfigure the SX126x chip after its IRQ woke up the ESP32. This re-init function sets up only the required definitions for the communication without resetting the SX126x

  lora_hardware_re_init(hwConfig);

Setup the callbacks for LoRa events

  RadioEvents.TxDone = OnTxDone;
  RadioEvents.RxDone = OnRxDone;
  RadioEvents.TxTimeout = OnTxTimeout;
  RadioEvents.RxTimeout = OnRxTimeout;
  RadioEvents.RxError = OnRxError;
  RadioEvents.CadDone = OnCadDone;

Initialize the radio

Initialize the radio and set the TX and RX parameters

  Radio.Init(&RadioEvents);

  Radio.SetChannel(RF_FREQUENCY);

  Radio.SetTxConfig(MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
                    LORA_SPREADING_FACTOR, LORA_CODINGRATE,
                    LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
                    true, 0, 0, LORA_IQ_INVERSION_ON, TX_TIMEOUT_VALUE);

  Radio.SetRxConfig(MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
                    LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
                    LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON,
                    0, true, 0, 0, LORA_IQ_INVERSION_ON, true);

Initialize the radio after CPU woke up from deep sleep

When you want to use the deep sleep function of the ESP32 with external wake up source, you do not want to reset and reconfigure the SX126x chip after its IRQ woke up the ESP32. Radio.ReInit() sets up only the required communication without resetting the SX1262. Radio.IrqProcessAfterDeepSleep() is checking the reason for the wake-up IRQ and calls the event handler

  Radio.ReInit(&RadioEvents);

  Radio.IrqProcessAfterDeepSleep();

Start listening for packets

  Radio.Rx(RX_TIMEOUT_VALUE);

LoRaWan

YOU NEED BELOW STEPS ONLY IF YOU WANT TO IMPLEMENT THE LORAWAN FUNCTIONALITY, IT IS NOT REQUIRED FOR BASIC LORA COMMUNICATION
If you want to use LoRaWan communication some additional steps are required.
You need to define a region. The defined region tells the library which frequency and which channels should be used. Valid regions are:

  • LORAMAC_REGION_AS923 -> Asia 923 MHz
  • LORAMAC_REGION_AU915 -> Australia 915 MHz
  • LORAMAC_REGION_CN470 -> China 470 MHz
  • LORAMAC_REGION_CN779 -> China 779 MHz
  • LORAMAC_REGION_EU433 -> Europe 433 MHz
  • LORAMAC_REGION_EU868 -> Europe 868 MHz
  • LORAMAC_REGION_IN865 -> India 865 MHz
  • LORAMAC_REGION_KR920 -> Korea 920 MHz
  • LORAMAC_REGION_US915 -> US 915 MHz
  • LORAMAC_REGION_AS923_2 -> Asia 923 MHz with frequency shift of -1.8MHz (not tested)
  • LORAMAC_REGION_AS923_3 -> Asia 923 MHz with frequency shift of -6.6MHz (e.g. Philippines) (in use)
  • LORAMAC_REGION_AS923_4 -> Asia 923 MHz with frequency shift of -5.9MHz (Israel) (not tested)
  • LORAMAC_REGION_RU864 -> Russia 864 MHz (not tested)

More information:

In addition you need

  • Device EUI if you want to use ABP registration of the device
  • Application EUI
  • Application Key, the AES encryption/decryption cipher application key
  • Device address
  • Network Session Key
  • App Session Key

for your node.

Sparkfun has a nice tutorial how to get these requirements from TheThingsInternet

In addition you must define several LoRaWan parameters.

  • Enable or disable adaptive data rate
  • Set the default or a specific data rate
  • Define if you want to connect to a public or private network
  • Specify the number of join trials in case you use OTAA
  • Specify the TX power
  • Enable or disable the duty cycle transmissions. For EU retion the ETSI mandates duty cycled transmissions.

You can find a lot of information about LoRaWan on the LoRa Alliance website.


LoRaWan region definitions

The LoRaWAN region is set during the lmh_init() call.
See lmh_init() for details.


LoRaWan functions


Set EUIs and keys

To be able to send data over a gateway to an IoT application like TheThingsNetwork you need to set the EUIs and Keys for the device, the application and the sessions. If you are using ABP activation all 6 values need to be set. If you are using OTAA activation, only the device EUI, the application EUI and the application key are required.
For the difference between ABP and OTAA activation read the TheThingsNetwork Wiki.
The EUIs, keys and address should be defined in your code like this:

// Device EUI
uint8_t nodeDeviceEUI[8] = {0x00, 0x95, 0x64, 0x1F, 0xDA, 0x91, 0x19, 0x0B};
// Application EUI
uint8_t nodeAppEUI[8] = {0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x02, 0x01, 0xE1};
// Application key for AES encryption
uint8_t nodeAppKey[16] = {0x07, 0xC0, 0x82, 0x0C, 0x30, 0xB9, 0x08, 0x70, 0x0C, 0x0F, 0x70, 0x06, 0x00, 0xB0, 0xBE, 0x09};
// Device address
uint32_t nodeDevAddr = 0x260116F8;
// Network session key for AES encryption
uint8_t nodeNwsKey[16] = {0x7E, 0xAC, 0xE2, 0x55, 0xB8, 0xA5, 0xE2, 0x69, 0x91, 0x51, 0x96, 0x06, 0x47, 0x56, 0x9D, 0x23};
// Application session key for AES encryption
uint8_t nodeAppsKey[16] = {0xFB, 0xAC, 0xB6, 0x47, 0xF3, 0x58, 0x45, 0xC7, 0x50, 0x7D, 0xBF, 0x16, 0x8B, 0xA8, 0xC1, 0x7C};

Then, just before initializing the library set these values with

// Setup the EUIs and Keys
lmh_setDevEui(nodeDeviceEUI);
lmh_setAppEui(nodeAppEUI);
lmh_setAppKey(nodeAppKey);
lmh_setNwkSKey(nodeNwsKey);
lmh_setAppSKey(nodeAppsKey);
lmh_setDevAddr(nodeDevAddr);

Connection to a single channel gateway

If the node talks to a single channel gateway you can fix the frequency and data rate and avoid frequency hopping. See more info in LoRaWan single channel gateway

 lmh_setSingleChannelGateway(uint8_t userSingleChannel, int8_t userDatarate)

Initialize

Initialize LoRaWan.

/**@brief Lora Initialisation
 *
 * @param callbacks   Pointer to structure containing the callback functions
 * @param lora_param  Pointer to structure containing the parameters
 * @param otaa        Choose OTAA (true) or ABP (false) activation
 * @param nodeClass   Choose node class CLASS_A, CLASS_B or CLASS_C, default to CLASS_A
 * @param region      Choose LoRaWAN region to set correct region parameters, defaults to EU868
 *
 * @retval error status
 */
	lmh_error_status lmh_init(lmh_callback_t *callbacks, lmh_param_t lora_param, bool otaa, 
	                          eDeviceClass nodeClass = CLASS_A, 
	                          LoRaMacRegion_t region = LORAMAC_REGION_EU868);

Valid regions are: LoRaMacRegion_t region This parameter selects the LoRaWAN region for your application. Allowed values for the region are:

  • LORAMAC_REGION_AS923
  • LORAMAC_REGION_AU915
  • LORAMAC_REGION_CN470
  • LORAMAC_REGION_CN779
  • LORAMAC_REGION_EU433
  • LORAMAC_REGION_EU868
  • LORAMAC_REGION_IN865
  • LORAMAC_REGION_KR920
  • LORAMAC_REGION_US915
  • LORAMAC_REGION_AS923_2
  • LORAMAC_REGION_AS923_3
  • LORAMAC_REGION_AS923_4
  • LORAMAC_REGION_RU864

REMARK

CN779-787 devices may not be produced, imported or installed after 2021-01-01; deployed devices may continue to operate through their normal end-of-life.


Specifiy sub bands

For some regions and some gateways you need to specifiy a sub band to be used. See more info in Limit frequency hopping to a sub band

 lmh_setSubBandChannels(uint8_t subBand)

RAKwireless RAK4630/RAK4631
The subbands for each region are automatically preset to match with the RAKwireless gateways default settings. In this case you do not need to define the sub bands.


Callbacks

LoRaWan needs callbacks and parameters defined before initialization

/** Lora user application data buffer. */ 
static uint8_t m_lora_app_data_buffer[LORAWAN_APP_DATA_BUFF_SIZE];
/** Lora user application data structure. */
static lmh_app_data_t m_lora_app_data = {m_lora_app_data_buffer, 0, 0, 0, 0};

/**@brief Structure containing LoRaWan parameters, needed for lmh_init()
 * 
 * Set structure members to
 * LORAWAN_ADR_ON or LORAWAN_ADR_OFF to enable or disable adaptive data rate
 * LORAWAN_DEFAULT_DATARATE OR DR_0 ... DR_5 for default data rate or specific data rate selection
 * LORAWAN_PUBLIC_NETWORK or LORAWAN_PRIVATE_NETWORK to select the use of a public or private network
 * JOINREQ_NBTRIALS or a specific number to set the number of trials to join the network
 * LORAWAN_DEFAULT_TX_POWER or a specific number to set the TX power used
 * LORAWAN_DUTYCYCLE_ON or LORAWAN_DUTYCYCLE_OFF to enable or disable duty cycles
 *                   Please note that ETSI mandates duty cycled transmissions. 
 */
static lmh_param_t lora_param_init = {LORAWAN_ADR_ON, 
			LORAWAN_DEFAULT_DATARATE, LORAWAN_PUBLIC_NETWORK, 
			JOINREQ_NBTRIALS, LORAWAN_DEFAULT_TX_POWER};

/**@brief Structure containing LoRaWan callback functions, needed for lmh_init() */

static lmh_callback_t lora_callbacks = {BoardGetBatteryLevel, BoardGetUniqueId, BoardGetRandomSeed,
			lorawan_rx_handler, lorawan_has_joined_handler, lorawan_confirm_class_handler,
			lorawan_join_failed_handler, lorawan_unconfirmed_finished, lorawan_confirmed_finished};

The following callbacks are implemented in the library, but you can override them in your application code:
BoardGetBatteryLevel is an empty pre-defined callback in the library. Every board has a different method to read the battery level (or none at all). If you want the LoRaWAN node to report it's battery level, you should write your own function to read and return the battery level. Keep in mind that the LoRaWAN server expects the battery level as a value between 0 and 255. 100% battery level equals 255.
BoardGetUniqueId is a pre-defined callback used by the library to get a unique ID of the board. This is used when the device EUI is assigned automatically. In most use cases this is not used.
BoardGetRandomSeed is used together with BoardGetUniqueId. In most use cases this is not used.
The following callbacks have to be implemented in your application code:
lorawan_rx_handler is called when a Downlink was received from the LoRaWAN server. See examples how to implement it.
lorawan_has_joined_handler is called after the node has successfully joined the network. Keep in mind that when ABP join method is used, this callback is called immediately after lmh_join().
lorawan_confirm_class_handler is called if you change the nodes class with lmh_class_request().
lorawan_join_failed_handler is called if the join process failed. Failing te join process can have multiple reasons. A few can be

  • No gateway in range
  • Gateway not connected to a LoRaWAN server
  • Wrong DevEUI, AppEUI or AppKey

lorawan_unconfirmed_finished is called after a unconfirmed packet send is finished. It is called after RX1 window and RX2 window timed out or after a downlink from the LoRaWAN server was received.
lorawan_confirmed_finished is called after a confirmed packet send is finished. It has a paramter that tells if a confirmation (ACK) was received from the LoRaWAN server or not.


Join

Join the LoRaWan network to be able to send and receive data. Default connection type is

void lmh_join(void)

LoRaWan single channel gateway

By default when using LoRaWan communication, the node is using frequency hoping. That means that for each package to be sent a random frequency is chosen out of the predefined frequencies for a region. The frequency (== channels) for each region can be found in the file CHANNELS.MD.
If connecting the node to a single channel gateway this is a problem, because a single channel gateway can receive only on one channel (== frequency). To get around this problem the channel hoping can be disabled and a fixed frequency (channel) and datarate can be set by the function

void lmh_setSingleChannelGateway(uint8_t userSingleChannel, int8_t userDatarate);

The first paramenter is the channel (frequency) to be used to communicate with the single channel gateway.
Check the specification of your single channel gateway to find out on which channel (frequency) it is listening and then get the channel number from the file CHANNELS.MD.
The second parameter selects the datarate for the communication. Again check the specification of your single channel gateway to find out what datarate it is using and use it in the function call. It might be that instead of the datarate the spreading factor SF and bandwidth BW are documented. In this case you need to check the file DATARATE.MD to find out which datarate to choose.
E.g. the things4u ESP-1ch-Gateway-v5.0 single channel gateway when setup to US915 region is listening on 902.30 Mhz with a bandwidth of 125kHz and a spreading factor of 7. In CHANNEL.MD you can find that 902.30 MHz is channel 0 and in DATARATE.MD you can find that SF7 and BW 125 kHz would be for region US915 the data rate DR_3. In this example we fix the communication to the channel 0 with the datarate DR_3 (SF7 and BW125);

// Setup connection to a single channel gateway
lmh_setSingleChannelGateway(0, DR_3);

Limit frequency hopping to a sub band

While testing the LoRaWan functionality I discovered that for some regions and some LoRaWan gateways it is required to limit the frequency hopping to a specific sub band of the region.
E.g. in the settings of the LoRaWan gateway I bought for testing (Dragino LPS8) you have not only to define the region, but as well one of 8 sub bands. The gateway will listen only on the selected sub band.
The problem is that if the LoRa node uses all available frequencies for frequency hopping, then for sure some of the packets will be lost, because they are sent on frequencies outside of the sub band on which the gateway is listening.
Depending on the region, there could be between 2 and 12 sub bands to select from. Each sub band consists of 8 frequencies with a fixed distance between each. The sub bands are selected by numbers starting with 1 for the first sub band of 8 frequencies.
You have to check with your LoRaWan gateway if you need to setup a sub band
Example to limit the frequency hopping to sub band #1

// For some regions we might need to define the sub band the gateway is listening to
/// \todo This is for Dragino LPS8 gateway. How about other gateways???
if (!lmh_setSubBandChannels(1))
{
	Serial.println("lmh_setSubBandChannels failed. Wrong sub band requested?");
}

Installation

In Arduino IDE open Sketch->Include Library->Manage Libraries then search for SX126x-Arduino
In PlatformIO open PlatformIO Home, switch to libraries and search for SX126x-Arduino. Or install the library in the terminal with platformio lib install SX126x-Arduino

For manual installation download the archive, unzip it and place the SX126x-Android folder into the library directory.
In Arduino IDE this is usually <arduinosketchfolder>/libraries/
In PlatformIO this is usually <user/.platformio/lib>


sx126x-arduino's People

Contributors

avillacis avatar beegee-tokyo avatar danielbustillos avatar dberlin avatar inmerso avatar ivankravets avatar kischang avatar mikeplentify avatar robsonos avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sx126x-arduino's Issues

Compatible with Arduino Mbed Core?

Hi @beegee-tokyo

I am trying to test this library with the Arduino Core Mbed and Arduino Nano 33 BLE but I have the next errors

Undefined functions

Arduino/libraries/SX126x-Arduino/src/boards/sx126x/sx126x-board.cpp:165: undefined reference to `BoardDisableIrq'
/Arduino/libraries/SX126x-Arduino/src/boards/sx126x/sx126x-board.cpp:178: undefined reference to `BoardEnableIrq'

and SPI undefined

can you help me?

Thanks

Esp32-c3 chip running PingPong does not respond, request help

ESP32-C3 is a cost-effective, RISC-V-based MCU with Wi-Fi and Bluetooth 5 (LE) connectivity for secure IoT applications. The ESP32-C3 is a chip recently released by Espressif

When I run the following code, only the logs in the setup() and loop() methods have any output. The logs in other methods such as OnRxTimeout() have no output. I tried two C3 development boards and two LLCC68 modules.Can you help me see what's wrong?

#include <Arduino.h>

#include <SX126x-Arduino.h>
#include <SPI.h>

hw_config hwConfig;

// ESP32 - SX126x pin configuration
int PIN_LORA_RESET = 2;  // LORA RESET
int PIN_LORA_DIO_1 = 3; // LORA DIO_1
int PIN_LORA_BUSY = 18;  // LORA SPI BUSY
int PIN_LORA_NSS = SS;	// LORA SPI CS
int PIN_LORA_SCLK = SCK;  // LORA SPI CLK
int PIN_LORA_MISO = MISO;  // LORA SPI MISO
int PIN_LORA_MOSI = MOSI;  // LORA SPI MOSI
int RADIO_TXEN = -1;	 // LORA ANTENNA TX ENABLE
int RADIO_RXEN = -1;	 // LORA ANTENNA RX ENABLE


// Function declarations
void OnTxDone(void);
void OnRxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr);
void OnTxTimeout(void);
void OnRxTimeout(void);
void OnRxError(void);
void OnCadDone(bool cadResult);

// Check if the board has an LED port defined

#define LED_BUILTIN 2

// Define LoRa parameters
#define RF_FREQUENCY 868000000  // Hz
#define TX_OUTPUT_POWER 22		// dBm
#define LORA_BANDWIDTH 0		// [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved]//比特率LLCC68 越小越慢越远
#define LORA_SPREADING_FACTOR 9 // [SF7..SF12]//扩频因子LLCC68 SF5..SF9 越大越慢越远
#define LORA_CODINGRATE 1		// [1: 4/5, 2: 4/6,  3: 4/7,  4: 4/8]//编码率 越大冗余越多,越慢,越远
#define LORA_PREAMBLE_LENGTH 8  // Same for Tx and Rx //前导码,用于睡眠唤醒
#define LORA_SYMBOL_TIMEOUT 0   // Symbols
#define LORA_FIX_LENGTH_PAYLOAD_ON false
#define LORA_IQ_INVERSION_ON false
#define RX_TIMEOUT_VALUE 3000
#define TX_TIMEOUT_VALUE 3000

#define BUFFER_SIZE 64 // Define the payload size here

static RadioEvents_t RadioEvents;
static uint16_t BufferSize = BUFFER_SIZE;
static uint8_t RcvBuffer[BUFFER_SIZE];
static uint8_t TxdBuffer[BUFFER_SIZE];
static bool isMaster = true;
const uint8_t PingMsg[] = "PING";
const uint8_t PongMsg[] = "PONG";

time_t timeToSend;

time_t cadTime;

uint8_t pingCnt = 0;
uint8_t pongCnt = 0;

void setup()
{
	pinMode(LED_BUILTIN, OUTPUT);
	digitalWrite(LED_BUILTIN, LOW);

	// Define the HW configuration between MCU and SX126x
	hwConfig.CHIP_TYPE = SX1262_CHIP;		  // Example uses an eByte E22 module with an SX1262
	hwConfig.PIN_LORA_RESET = PIN_LORA_RESET; // LORA RESET
	hwConfig.PIN_LORA_NSS = PIN_LORA_NSS;	 // LORA SPI CS
	hwConfig.PIN_LORA_SCLK = PIN_LORA_SCLK;   // LORA SPI CLK
	hwConfig.PIN_LORA_MISO = PIN_LORA_MISO;   // LORA SPI MISO
	hwConfig.PIN_LORA_DIO_1 = PIN_LORA_DIO_1; // LORA DIO_1
	hwConfig.PIN_LORA_BUSY = PIN_LORA_BUSY;   // LORA SPI BUSY
	hwConfig.PIN_LORA_MOSI = PIN_LORA_MOSI;   // LORA SPI MOSI
	hwConfig.RADIO_TXEN = RADIO_TXEN;		  // LORA ANTENNA TX ENABLE
	hwConfig.RADIO_RXEN = RADIO_RXEN;		  // LORA ANTENNA RX ENABLE
	hwConfig.USE_DIO2_ANT_SWITCH = true;	  // Example uses an CircuitRocks Alora RFM1262 which uses DIO2 pins as antenna control
	hwConfig.USE_DIO3_TCXO = true;			  // Example uses an CircuitRocks Alora RFM1262 which uses DIO3 to control oscillator voltage
	hwConfig.USE_DIO3_ANT_SWITCH = false;	 // Only Insight ISP4520 module uses DIO3 as antenna control

	// Initialize Serial for debug output
	Serial.begin(115200);

	Serial.println("=====================================");
	Serial.println("SX126x PingPong test");
	Serial.println("=====================================");

	Serial.println("MCU Espressif ESP32");

	uint8_t deviceId[8];

	BoardGetUniqueId(deviceId);
	Serial.printf("BoardId: %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X\n",
				  deviceId[7],
				  deviceId[6],
				  deviceId[5],
				  deviceId[4],
				  deviceId[3],
				  deviceId[2],
				  deviceId[1],
				  deviceId[0]);

	// Initialize the LoRa chip
	Serial.println("Starting lora_hardware_init");
	
	lora_hardware_init(hwConfig);
	
	// Initialize the Radio callbacks
	RadioEvents.TxDone = OnTxDone;
	RadioEvents.RxDone = OnRxDone;
	RadioEvents.TxTimeout = OnTxTimeout;
	RadioEvents.RxTimeout = OnRxTimeout;
	RadioEvents.RxError = OnRxError;
	RadioEvents.CadDone = OnCadDone;

	// Initialize the Radio
	Radio.Init(&RadioEvents);
	
	// Set Radio channel
	Radio.SetChannel(RF_FREQUENCY);

	// Set Radio TX configuration
	Radio.SetTxConfig(MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
					  LORA_SPREADING_FACTOR, LORA_CODINGRATE,
					  LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
					  true, 0, 0, LORA_IQ_INVERSION_ON, TX_TIMEOUT_VALUE);

	// Set Radio RX configuration
	Radio.SetRxConfig(MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
					  LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
					  LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON,
					  0, true, 0, 0, LORA_IQ_INVERSION_ON, true);
	//return;
	// Start LoRa
	Serial.println("Starting Radio.Rx");
	Radio.Rx(RX_TIMEOUT_VALUE);

	timeToSend = millis();
}

uint16_t mCounter =0;
void loop() {
	vTaskDelay(3000);
	Serial.print(String("loop:")+mCounter);
	mCounter++;
}

/**@brief Function to be executed on Radio Tx Done event
 */
void OnTxDone(void){
	Serial.println("OnTxDone");
	Radio.Rx(RX_TIMEOUT_VALUE);
}

void startCAD(){
	// Check if our channel is available for sending
	Radio.Standby();
	Radio.SetCadParams(LORA_CAD_08_SYMBOL, LORA_SPREADING_FACTOR + 13, 10, LORA_CAD_ONLY, 0);
	cadTime = millis();
	Radio.StartCad();
}

/**@brief Function to be executed on Radio Rx Done event
 */
void OnRxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr){
	Serial.println("OnRxDone");
	vTaskDelay(10);
	BufferSize = size;
	memcpy(RcvBuffer, payload, BufferSize);

	Serial.printf("RssiValue=%d dBm, SnrValue=%d\n", rssi, snr);

	for (int idx = 0; idx < size; idx++){
		Serial.printf("%02X ", RcvBuffer[idx]);
	}
	Serial.println("");

	digitalWrite(LED_BUILTIN, HIGH);

	if (isMaster == true) {
		if (BufferSize > 0) {
			if (strncmp((const char *)RcvBuffer, (const char *)PongMsg, 4) == 0) {
				Serial.println("Received a PONG in OnRxDone as Master");
				// Wait 500ms before sending the next package
				vTaskDelay(500);
				startCAD();
			}
			else if (strncmp((const char *)RcvBuffer, (const char *)PingMsg, 4) == 0) { 
				// A master already exists then become a slave
				Serial.println("Received a PING in OnRxDone as Master");
				isMaster = false;
				Radio.Rx(RX_TIMEOUT_VALUE);
			}
			else // valid reception but neither a PING or a PONG message
			{	// Set device as master and start again
				isMaster = true;
				Radio.Rx(RX_TIMEOUT_VALUE);
			}
		}
	}
	else {
		if (BufferSize > 0) {
			if (strncmp((const char *)RcvBuffer, (const char *)PingMsg, 4) == 0) {
				Serial.println("Received a PING in OnRxDone as Slave"); 
				startCAD();
			}
			else // valid reception but not a PING as expected
			{	// Set device as master and start again
				Serial.println("Received something in OnRxDone as Slave");
				isMaster = true;
				Radio.Rx(RX_TIMEOUT_VALUE);
			}
		}
	}
}

/**@brief Function to be executed on Radio Tx Timeout event
 */
void OnTxTimeout(void) {
	// Radio.Sleep();
	Serial.println("OnTxTimeout");
	digitalWrite(LED_BUILTIN, LOW);
	Radio.Rx(RX_TIMEOUT_VALUE);
}

/**@brief Function to be executed on Radio Rx Timeout event
 */
void OnRxTimeout(void) {
	Serial.println("OnRxTimeout");
	digitalWrite(LED_BUILTIN, LOW);

	if (isMaster == true) {
		// Wait 500ms before sending the next package
		vTaskDelay(500);
		startCAD();
	}
	else {
		// No Ping received within timeout, switch to Master
		isMaster = true;
		startCAD();
	}
}

/**@brief Function to be executed on Radio Rx Error event
 */
void OnRxError(void){
	Serial.println("OnRxError");
	digitalWrite(LED_BUILTIN, LOW);

	if (isMaster == true) {
		// Wait 500ms before sending the next package
		vTaskDelay(500); 
		startCAD();
	}
	else {
		Radio.Rx(RX_TIMEOUT_VALUE);
	}
}

/**@brief Function to be executed on Radio Rx Error event
 */
void OnCadDone(bool cadResult) {
	time_t duration = millis() - cadTime;
	if (cadResult) {
		Serial.printf("CAD returned channel busy after %ldms\n", duration);
		Radio.Rx(RX_TIMEOUT_VALUE);
	}
	else {
		Serial.printf("CAD returned channel free after %ldms\n", duration);
		if (isMaster) {
			Serial.println("Sending a PING in OnCadDone as Master");
			// Send the next PING frame
			TxdBuffer[0] = 'P';
			TxdBuffer[1] = 'I';
			TxdBuffer[2] = 'N';
			TxdBuffer[3] = 'G';
		}
		else {
			Serial.println("Sending a PONG in OnCadDone as Slave");
			// Send the reply to the PONG string
			TxdBuffer[0] = 'P';
			TxdBuffer[1] = 'O';
			TxdBuffer[2] = 'N';
			TxdBuffer[3] = 'G';
		}
		// We fill the buffer with numbers for the payload
		for (int i = 4; i < BufferSize; i++) {
			TxdBuffer[i] = i - 4;
		}
		Radio.Send(TxdBuffer, BufferSize);
	}
}

log:


[18:50:04.149]收←◆loop:808
[18:50:07.249]收←◆ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x1 (POWERON),boot:0xd (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd6100,len:0x1428
load:0x403ce000,len:0xc04
load:0x403d0000,len:0x292c
SHA-256 comparison failed:
Calculated: 9f7363434bc7a1a2434ba3062500fa10b9fce5bb859899ee0424321b4ddaf742
Expected: 9b18b42e3e8e407f5e7b13f26c80172eda36d674c584e818f50843c766ebde69
Attempting to boot anyway...
entry 0x403ce000
I (48) boot: ESP-IDF v4.4-dev-2313-gc69f0ec32 2nd stage bootloader
I (49) boot: compile time 12:10:14
I (49) boot: chip revision: 3
I (49) boot_comm: chip revision: 3, min. bootloader chip revision: 0
I (55) qio_mode: Enabling default flash chip QIO
I (59) boot.esp32c3: SPI Speed      : 80MHz
I (63) boot.esp32c3: SPI Mode       : QIO
I (67) boot.esp32c3: SPI Flash Size : 4MB
I (71) boot: Enabling RNG early entropy source...
I (75) boot: Partition Table:
I (78) boot: ## Label            Usage          Type ST Offset   Length
I (84) boot:  0 nvs              WiFi data        01 02 00009000 00005000
I (91) boot:  1 otadata          OTA data         01 00 0000e000 00002000
I (97) boot:  2 app0             OTA app          00 10 00010000 00140000
I (104) boot:  3 app1             OTA app          00 11 00150000 00140000
I (110) boot:  4 spiffs           Unknown data     01 82 00290000 00170000
I (117) boot: End of partition table
I (120) boot_comm: chip revision: 3, min. application chip revision: 0
I (126) esp_image: segment 0: paddr=00010020 vaddr=3c030020 size=08350h ( 33616) map
I (139) esp_image: segment 1: paddr=00018378 vaddr=3fc8a800 size=014dch (  5340) load
I (142) esp_image: segment 2: paddr=0001985c vaddr=40380000 size=067bch ( 26556) load
I (153) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=25570h (152944) map
I (178) esp_image: segment 4: paddr=00045598 vaddr=403867bc size=03ff4h ( 16372) load
I (181) esp_image: segment 5: paddr=00049594 vaddr=50000000 size=00010h (    16) load
I (185) boot: Loaded app from partition at offset 0x10000
I (187) boot: Disabling RNG early entropy source...
=====================================
SX126x PingPong test
=====================================
MCU Espressif ESP32
BoardId: 00-00-E8-1A-C2-A1-DF-7C
Starting lora_hardware_init

[18:50:07.527]收←◆Starting Radio.Rx

[18:50:10.524]收←◆loop:0
[18:50:13.529]收←◆loop:1
[18:50:16.534]收←◆loop:2
[18:50:19.539]收←◆loop:3
[18:50:22.544]收←◆loop:4
[18:50:25.549]收←◆loop:5
[18:50:28.553]收←◆loop:6
[18:50:31.585]收←◆loop:7
[18:50:34.563]收←◆loop:8
[18:50:37.568]收←◆loop:9
[18:50:40.574]收←◆loop:10
[18:50:43.579]收←◆loop:11
[18:50:46.584]收←◆loop:12
[18:50:49.589]收←◆loop:13
[18:50:52.594]收←◆loop:14
[18:50:55.598]收←◆loop:15
[18:50:58.604]收←◆loop:16

Sleep current using DRF1262T and sleep code provided

Using the sleep code example provided, I am testing using a DRF1262T module and I am noticing high current draw in sleep mode. I am getting a 1.6mA draw in sleep. Is that normal? I remove the power to the RF module and get about 70uA in sleep. Still super high but I guess its the pullups being used in the code.

The DRF1262T module has a SW pin, I pull it low and I still get the same current draw.

Also, I tried your library AND radiolib, I am getting the same results.

Arduino IDE: references

The Pingpong sample compiles fine but when i try to compile the LoraWan example:

libraries\SX126x-Arduino-1.0.8\mac\LoRaMacHelper.cpp.o:(.literal.lmh_setSubBandChannels+0x4): undefined reference to `ChannelsDefaultMask'

libraries\SX126x-Arduino-1.0.8\mac\LoRaMacHelper.cpp.o:(.literal.lmh_setSubBandChannels+0x8): undefined reference to `ChannelsMask'

libraries\SX126x-Arduino-1.0.8\mac\LoRaMacHelper.cpp.o:(.literal.lmh_setSubBandChannels+0xc): undefined reference to `ChannelsMaskRemaining'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionGetPhyParam+0x0): undefined reference to `RegionUS915GetPhyParam'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionSetBandTxDone+0x0): undefined reference to `RegionUS915SetBandTxDone'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionInitDefaults+0x0): undefined reference to `RegionUS915InitDefaults'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionVerify+0x0): undefined reference to `RegionUS915Verify'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionApplyCFList+0x0): undefined reference to `RegionUS915ApplyCFList'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionChanMaskSet+0x0): undefined reference to `RegionUS915ChanMaskSet'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionAdrNext+0x0): undefined reference to `RegionUS915AdrNext'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionComputeRxWindowParameters+0x0): undefined reference to `RegionUS915ComputeRxWindowParameters'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionRxConfig+0x0): undefined reference to `RegionUS915RxConfig'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionTxConfig+0x0): undefined reference to `RegionUS915TxConfig'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionLinkAdrReq+0x0): undefined reference to `RegionUS915LinkAdrReq'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionRxParamSetupReq+0x0): undefined reference to `RegionUS915RxParamSetupReq'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionNewChannelReq+0x0): undefined reference to `RegionUS915NewChannelReq'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionTxParamSetupReq+0x0): undefined reference to `RegionUS915TxParamSetupReq'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionDlChannelReq+0x0): undefined reference to `RegionUS915DlChannelReq'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionAlternateDr+0x0): undefined reference to `RegionUS915AlternateDr'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionCalcBackOff+0x0): undefined reference to `RegionUS915CalcBackOff'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionNextChannel+0x0): undefined reference to `RegionUS915NextChannel'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionSetContinuousWave+0x0): undefined reference to `RegionUS915SetContinuousWave'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o:(.literal.RegionApplyDrOffset+0x0): undefined reference to `RegionUS915ApplyDrOffset'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionGetPhyParam':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1464: undefined reference to `RegionUS915GetPhyParam'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionSetBandTxDone':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1464: undefined reference to `RegionUS915SetBandTxDone'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionInitDefaults':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1464: undefined reference to `RegionUS915InitDefaults'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionVerify':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1464: undefined reference to `RegionUS915Verify'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionApplyCFList':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1464: undefined reference to `RegionUS915ApplyCFList'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionChanMaskSet':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1464: undefined reference to `RegionUS915ChanMaskSet'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionAdrNext':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1464: undefined reference to `RegionUS915AdrNext'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionComputeRxWindowParameters':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1464: undefined reference to `RegionUS915ComputeRxWindowParameters'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionRxConfig':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1464: undefined reference to `RegionUS915RxConfig'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionTxConfig':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1464: undefined reference to `RegionUS915TxConfig'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionLinkAdrReq':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1464: undefined reference to `RegionUS915LinkAdrReq'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionRxParamSetupReq':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1464: undefined reference to `RegionUS915RxParamSetupReq'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionNewChannelReq':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1464: undefined reference to `RegionUS915NewChannelReq'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionTxParamSetupReq':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1464: undefined reference to `RegionUS915TxParamSetupReq'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionDlChannelReq':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1464: undefined reference to `RegionUS915DlChannelReq'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionAlternateDr':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1464: undefined reference to `RegionUS915AlternateDr'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionCalcBackOff':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1464: undefined reference to `RegionUS915CalcBackOff'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionNextChannel':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1464: undefined reference to `RegionUS915NextChannel'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionSetContinuousWave':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1478: undefined reference to `RegionUS915SetContinuousWave'

libraries\SX126x-Arduino-1.0.8\mac\region\Region.cpp.o: In function `RegionApplyDrOffset':

C:\Users\HP\Documents\Arduino\libraries\SX126x-Arduino-1.0.8\src\mac\region/Region.cpp:1499: undefined reference to `RegionUS915ApplyDrOffset'

LoRa comunication

Hi @beegee-tokyo, i have been reading your code and implementing it, good job.
I have one question, how i can send the value of a sensor, like a global variable?
The LoRa-WAN example is for create a gateway or to connect the node to a gateway?

Setting Additional Channels

I'm from India and I'm actually confused given the fact that there are only 3 channels configured in TTN and saw the same in docs of this library.

[Q. 1] I just want to know whether I could explicitly increase the number of channels/configure the frequencies with this library.

I want to set additional channels (config.json) to the gateway as well, but I couldn't find anything from Things Stack docs. I already tested with handpicked frequencies. Even though the packets were captured by the gateway (can be seen on the dashboard), it never got transferred to Application Nodes. Once I changed the config, the same one mentioned in Things Network's repository, application nodes on the dashboard started to receive the data.

I assume this was due to the frequency mismatch.

[Q 2] Can I set custom channels on Things Stack, which can also be received application nodes as well (So that I can receive the transmitted data)?

I just need to know whether I could do it, I'm currently running Things Stack locally.

I have been using your library, and it has been working perfectly fine.
Thank You for that.

Radio.SetRxDutyCycle power usage not lower than Radio.Rx(0)

I have a TTGO TBeamV1.1 which I have successfully programmed for low power usage. 0.82mA in deep sleep without power to or using the LoRa radio.

Once I power the LoRa radio via the AXP192 and set in into receive mode, power usage increases, as expected.
I tested the deep sleep of the ESP and it successfully woke up when receiving a message.
Next I tried using the SetRxDutyCycle method configured like the example code that can be found here, this also seems to work and the esp is woken up by the incoming message.

I have however noticed that the power usage between using Radio.Rx(0) and Radio.SetRxDutyCycle is exactly the same, 6.9mA.
I measured the current with a multimeter placed in between (series) the battery and the board.
According to the datasheet in this repo the power saving should be significant.

Am I missing something obvious? Could there be an issue or bug in the library?

#include <Arduino.h>
#include <SPI.h>
#include <rom/rtc.h>
#include <driver/rtc_io.h>
#include <SX126x-Arduino.h>
#include <WiFi.h>
#include <esp_wifi.h>
#include "axp20x.h"
#include "esp_bt.h"
#include "driver/adc.h"

AXP20X_Class PMU;

int PIN_LORA_RESET = 23;
int PIN_LORA_DIO_1 = 33;
int PIN_LORA_BUSY = 32;
int PIN_LORA_NSS = 18;
int PIN_LORA_SCLK = 5;
int PIN_LORA_MISO = 19;
int PIN_LORA_MOSI = 27;

#define RF_FREQUENCY 868000000  // Hz
#define TX_OUTPUT_POWER 17      // dBm
#define LORA_BANDWIDTH 0        // [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved]
#define LORA_SPREADING_FACTOR 7 // [SF7..SF12]
#define LORA_CODINGRATE 1       // [1: 4/5, 2: 4/6,  3: 4/7,  4: 4/8]
#define LORA_PREAMBLE_LENGTH 8  // Same for Tx and Rx
#define LORA_SYMBOL_TIMEOUT 0   // Symbols
#define LORA_FIX_LENGTH_PAYLOAD_ON false
#define LORA_IQ_INVERSION_ON false
#define RX_TIMEOUT_VALUE 3000
#define TX_TIMEOUT_VALUE 3000

static RadioEvents_t RadioEvents;
hw_config hwConfig;
uint8_t cadRepeat;

void OnTxDone(void);
void OnRxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr);
void OnTxTimeout(void);
void OnRxTimeout(void);
void OnRxError(void);
void OnCadDone(bool cadResult);

uint8_t deviceId[8];

const uint8_t i2c_sda = 21;
const uint8_t i2c_scl = 22;

void goToSleep(void) {
  Serial.println("Preparing to sleep!");

  Radio.Standby();
  SX126xSetDioIrqParams(IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT,
                        IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT,
                        IRQ_RADIO_NONE, IRQ_RADIO_NONE);
  // To get maximum power savings we use Radio.SetRxDutyCycle instead of Radio.Rx(0)
  // This function keeps the SX1261/2 chip most of the time in sleep and only wakes up short times
  // to catch incoming data packages
  Radio.SetRxDutyCycle(2 * 1024 * 1000 * 15.625, 10 * 1024 * 15.625);
  //Radio.Rx(0);
  Serial.println("Radio in low power receiver mode!");

  // Make sure the DIO1, RESET and NSS GPIOs are hold on required levels during deep sleep
  rtc_gpio_pullup_en((gpio_num_t)PIN_LORA_RESET);
  rtc_gpio_pullup_en((gpio_num_t)PIN_LORA_NSS);
  rtc_gpio_pulldown_en((gpio_num_t)PIN_LORA_DIO_1);

  esp_sleep_enable_ext1_wakeup(0x200000000, ESP_EXT1_WAKEUP_ANY_HIGH);
  esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
  Serial.println("IO configured for sleep!");

  Serial.println("Going to sleep!");
  Serial.flush();
  esp_deep_sleep_start();
}

void setup() {
  setCpuFrequencyMhz(20);
  Serial.begin(115200);

  RESET_REASON cpu0WakeupReason = rtc_get_reset_reason(0);
  RESET_REASON cpu1WakeupReason = rtc_get_reset_reason(1);

  // Define the HW configuration between MCU and SX126x
  hwConfig.CHIP_TYPE = SX1262_CHIP;         // SX1261_CHIP for Semtech SX1261 SX1262_CHIP for Semtech SX1262/1268
  hwConfig.PIN_LORA_RESET = PIN_LORA_RESET; // GPIO pin connected to NRESET of the SX126x
  hwConfig.PIN_LORA_NSS = PIN_LORA_NSS;     // GPIO pin connected to NSS of the SX126x
  hwConfig.PIN_LORA_SCLK = PIN_LORA_SCLK;   // GPIO pin connected to SCK of the SX126x
  hwConfig.PIN_LORA_MISO = PIN_LORA_MISO;   // GPIO pin connected to MISO of the SX126x
  hwConfig.PIN_LORA_DIO_1 = PIN_LORA_DIO_1; // GPIO pin connected to DIO 1 of the SX126x
  hwConfig.PIN_LORA_BUSY = PIN_LORA_BUSY;   // GPIO pin connected to BUSY of the SX126x
  hwConfig.PIN_LORA_MOSI = PIN_LORA_MOSI;   // GPIO pin connected to MOSI of the SX126x
  hwConfig.RADIO_TXEN = -1;                 // GPIO pin used to enable the TX antenna of the SX126x
  hwConfig.RADIO_RXEN = -1;                 // GPIO pin used to enable the RX antenna of the SX126x
  hwConfig.USE_DIO2_ANT_SWITCH = false;     // True if DIO2 is used to switch the antenna from RX to TX
  hwConfig.USE_DIO3_TCXO = true;           // True if DIO3 is used to control the voltage of the TXCO oscillator
  hwConfig.USE_DIO3_ANT_SWITCH = false;     // True if DIO3 is used to enable/disable the antenna
  hwConfig.USE_LDO = false;                  // False if SX126x DCDC converter is used, true if SX126x LDO is used
  hwConfig.USE_RXEN_ANT_PWR = false;        // If set to true RADIO_RXEN pin is used to control power of antenna switch

  RadioEvents.TxDone = OnTxDone;
  RadioEvents.RxDone = OnRxDone;
  RadioEvents.TxTimeout = OnTxTimeout;
  RadioEvents.RxTimeout = OnRxTimeout;
  RadioEvents.RxError = OnRxError;
  RadioEvents.CadDone = OnCadDone;

  if ((cpu0WakeupReason == DEEPSLEEP_RESET) || (cpu1WakeupReason == DEEPSLEEP_RESET)) {
    lora_hardware_re_init(hwConfig);
    Radio.ReInit(&RadioEvents);
    Radio.IrqProcessAfterDeepSleep();
  } else {
    //Red onboard LED
    pinMode(4, OUTPUT);
    digitalWrite(4, LOW);

    int ret = 0;
    Wire.begin(i2c_sda, i2c_scl);
    PMU.begin(Wire, AXP192_SLAVE_ADDRESS);

    do {
      // In order to ensure that it is set correctly,
      // the loop waits for it to return the correct return value
      Serial.println("Set PMU in sleep mode");
      ret = PMU.setSleep();
      delay(500);
    } while (ret != AXP_PASS);

    //PMU.setTSmode(AXP_TS_PIN_MODE_DISABLE);
    //PMU.enableChargeing(false);
    PMU.setChgLEDMode(AXP20X_LED_OFF);
    PMU.setPowerOutPut(AXP192_DCDC1, AXP202_OFF);
    PMU.setPowerOutPut(AXP192_DCDC2, AXP202_OFF);
    PMU.setPowerOutPut(AXP192_LDO2, AXP202_OFF);
    PMU.setPowerOutPut(AXP192_LDO3, AXP202_OFF);
    PMU.setPowerOutPut(AXP192_EXTEN, AXP202_OFF);

    PMU.setLDO2Voltage(3300);   //LoRa VDD
    PMU.setPowerOutPut(AXP192_LDO2, AXP202_ON);

    WiFi.disconnect(true);
    WiFi.mode(WIFI_OFF);
    esp_wifi_stop();
    btStop();
    esp_bt_controller_disable();
    adc_power_off();

    delay(3000);
    Serial.println("PMU init done!");

    lora_hardware_init(hwConfig);
    Radio.Init(&RadioEvents);
    Radio.SetChannel(RF_FREQUENCY);
    Radio.SetTxConfig(MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
                      LORA_SPREADING_FACTOR, LORA_CODINGRATE,
                      LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
                      false, 0, 0, LORA_IQ_INVERSION_ON, TX_TIMEOUT_VALUE);
    Radio.SetRxConfig(MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
                      LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
                      LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON,
                      0, false, 0, 0, LORA_IQ_INVERSION_ON, true);
  }
  goToSleep();
}

void loop() {
}

void OnTxDone(void) {
  goToSleep();
}

void OnRxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) {
  char debugOutput[1024];
  for (int idx = 0; idx < size; idx++) {
    sprintf(&debugOutput[(idx * 2)], "%02X", payload[idx]);
  }
  Serial.print("Data: ");
  Serial.println(debugOutput);

  // Now its up to YOU to do something with the data

  goToSleep();
}

void OnTxTimeout(void) {
  goToSleep();
}

void OnRxTimeout(void) {
  goToSleep();
}

void OnRxError(void) {
  goToSleep();
}

void OnCadDone(bool cadResult) {
  cadRepeat++;
  Radio.Standby();
  if (cadResult) {
    if (cadRepeat < 6) {
      Radio.Standby();
      SX126xSetCadParams(LORA_CAD_08_SYMBOL, LORA_SPREADING_FACTOR + 13, 10, LORA_CAD_ONLY, 0);
      SX126xSetDioIrqParams(IRQ_CAD_DONE | IRQ_CAD_ACTIVITY_DETECTED,
                            IRQ_CAD_DONE | IRQ_CAD_ACTIVITY_DETECTED,
                            IRQ_RADIO_NONE, IRQ_RADIO_NONE);
      Radio.StartCad();
    } else {
      goToSleep();
    }
  }
}```

Sx1262-Arduino ESP32 node not connected to Gateway(RPI+RHF0M301)

Hi All ,

First of All thank you for SX1262-Arduino library . I am facing an issue while using this library , i need your help in this regard .
i have followed the following steps to test the SX1262-Arduino library .

1)i have connected the Gateway(RPI+RHF0M301) with loriot server .
2)Node which i use to connect with gateway was "Semtech SX1262MB2xAs" and controller Stm32Nucleo board.
3)You can see the data sent from the node to loriot server .

image

4)After that, i changed the node device controller to "ESP32" and kept the Lora device same "Semtech SX1262MB2xAs" as mentioned above in point #2 .

5)Connections i have made are according to the mentioned in the library. These are total 7 connections and 2 more connections are 3.3v and Gnd.

int PIN_LORA_RESET = 4; // LORA RESET
int PIN_LORA_NSS = 5; // LORA SPI CS
int PIN_LORA_SCLK = 18; // LORA SPI CLK
int PIN_LORA_MISO = 19; // LORA SPI MISO
int PIN_LORA_DIO_1 = 21; // LORA DIO_1
int PIN_LORA_BUSY = 22; // LORA SPI BUSY
int PIN_LORA_MOSI = 23; // LORA SPI MOSI

6)Compiled the library in Arduino IDE and as well as in Visual Code Studio (PlatformIO extension).
7)Got two different results with both the IDE's

Results are as Follows

A)When compiled with PlatformIO . Following output i got on docklight terminal

image

B)When compiled with the Arduino IDE then

image

8)To solve the above issues , i have followed the instructions mentioned in this link
#1
regarding the commissioning.h file . But still the same issue

  1. i also changed the LORAWAN_APPLICATION_EUI ,LORAWAN_APPLICATION_KEY and LORAWAN_DEVICE_EUI same when i was able to connect the node to gateway and then to loriot server as mentioned above from Point # 1-3 .

But Still the same issue . Can you please guide me where is the issue ? I will appreciate the help and thank you very much in advance !

Best Regards ,

lmh_send() silently discards MAC commands from previous DLs when payload is too large

From LoRaMacHelper.cpp: lmh_send() :

	if (LoRaMacQueryTxPossible(app_data->buffsize, &txInfo) != LORAMAC_STATUS_OK)
	{
		LOG_LIB("LMH", "lmh_send -> LoRaMacQueryTxPossible failed");

		// Send empty frame in order to flush MAC commands
		mcpsReq.Type = MCPS_UNCONFIRMED;
		mcpsReq.Req.Unconfirmed.fBuffer = NULL;
		mcpsReq.Req.Unconfirmed.fBufferSize = 0;
		mcpsReq.Req.Unconfirmed.Datarate = m_param.tx_data_rate;
		// cannot send
		return LMH_ERROR;
	}

This digresses from Semtech reference behavior, which would go ahead and send the empty frame to flush the MAC commands that make the frame too large to send (assuming fOpts isn't too large later on).

I believe I understand the issue here: the reference stack will return OK, so the calling code will believe it has sent the payload, while the stack will send an empty frame. The calling code has no idea.

My question: this change was intentional so calling code could see the error, attempt to send an empty frame, then send the desired payload?

E22 900 M22s using segger embedded studio

Dear Sir,
As you mention that your base library is ISP4520 module based . And you converted into Arduino Library.
Actually Sir I am interfacing nrf52832 with E22900M22s module and using ISP4520 module Library, my lora communication is working fine for both ping_pong and Tx and Rx temperature example. But when I am using Lorawan library on E22900m22s module so its continuously show this message :

app: Uplink counter : 120
app: Uplink Data rate : DR_0
app: Uplink TX power : 0
app: Uplink frequency: 868500000
app: FDS update success! FileId: 0x3E8 RecKey:0x1
app: FDS update success! FileId: 0x3E8 RecKey:0x2
app: FDS update success! FileId: 0x3E8 RecKey:0x5
app: Data stored on NVM: 224 bytes
app: MCPS-Request: MCPS_UNCONFIRMED, OK

Although when I am using your Arduino Library for LORAWAN then is working fine but I need to work on Segger Embedded Studio for this, can you please helping me out in this. How I run ISP4520 library with NRF52832 + E22900M22S on segger?
Is this possible to easily convert Arduino library to segger? Any tips?
Please also let me know what problem do you face when converting ISP4520 library to Sx126x-Arduino Library.
Thanks

questions

Good morning @beegee-tokyo @ivankravets

First of all, congratulations!

I have some questions

-have you plan to port to STM32 ? I ask you because i have a lot of LoRa modules here and they use the STM32. Today we program it using the Semtech libraries, but with KEIL. I would like to use the ARDUINO and make a lot of blogs.
-will your lib work with 1276 ?

Have a good day!

Print rssi and snr

Hello,
nice job done in this library. Still learning how all that works.
I am trying to print rssi and snr using the example "Sensor-Gateway-Deepsleep/LoRa-Gateway" data is received correctly from node but LoRa-Gateway rssi and snr =0 ?
PinPongPio example the rssi and snr it is ok.
any idea?

SX126x FSK mode

Hello there!
I am continuing to use your library to do some research and development. When I switch to FSK mode, I find that it is not compatible. Do you have plans to continue to improve it?

Class C Support

Hi, I like to use Class C support. In Class A the application works well but at the moment when I switch to Class C , the guru kicks in with the following stack. Any suggestion or any working sample code for Class I can use to debug?

PC: 0x400914f9: uxListRemove at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/list.c line 218
EXCVADDR: 0x00000004

Decoding stack results
0x400914f9: uxListRemove at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/list.c line 218
0x4009082e: xTaskRemoveFromEventList at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c line 3092
0x4008e509: xQueueGenericSend at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/queue.c line 767
0x400ecf85: spiEndTransaction at /Users/christian/Library/Arduino15/packages/esp32/hardware/esp32/1.0.4/cores/esp32/esp32-hal-spi.c line 765
0x400eada6: SPIClass::endTransaction() at /Users/christian/Library/Arduino15/packages/esp32/hardware/esp32/1.0.4/libraries/SPI/src/SPI.cpp line 143
0x400dfecc: SX126xWakeup() at /Users/christian/Documents/Arduino/libraries/SX126x-Arduino/src/boards/sx126x/sx126x-board.cpp line 151
0x400e4bac: SX126xCheckDeviceReady() at /Users/christian/Documents/Arduino/libraries/SX126x-Arduino/src/radio/sx126x/sx126x.cpp line 128
0x400dfee3: SX126xWriteCommand(RadioCommands_t, uint8_t*, uint16_t) at /Users/christian/Documents/Arduino/libraries/SX126x-Arduino/src/boards/sx126x/sx126x-board.cpp line 162
0x400e4ef9: SX126xSetDioIrqParams(uint16_t, uint16_t, uint16_t, uint16_t) at /Users/christian/Documents/Arduino/libraries/SX126x-Arduino/src/radio/sx126x/sx126x.cpp line 403
0x400e4a78: RadioRx(uint32_t) at /Users/christian/Documents/Arduino/libraries/SX126x-Arduino/src/radio/sx126x/radio.cpp line 1021
0x400e0ee6: RxWindowSetup(bool, uint32_t) at /Users/christian/Documents/Arduino/libraries/SX126x-Arduino/src/mac/LoRaMac.cpp line 1503
0x400e0fba: OnRxWindow2TimerEvent() at /Users/christian/Documents/Arduino/libraries/SX126x-Arduino/src/mac/LoRaMac.cpp line 1475
0x400e1f08: LoRaMacMibSetRequestConfirm(MibRequestConfirm_t*) at /Users/christian/Documents/Arduino/libraries/SX126x-Arduino/src/mac/LoRaMac.cpp line 2723
0x400e2f5b: lmh_class_request(DeviceClass_t) at /Users/christian/Documents/Arduino/libraries/SX126x-Arduino/src/mac/LoRaMacHelper.cpp line 1076
0x400d35a9: lorawan_has_joined_handler() at /Users/christian/Documents/Arduino/MC5/lorawan.ino line 213

Wish list item: STM32WL support

According to https://www.st.com/en/microcontrollers-microprocessors/stm32wl-series.html#overview the

STM32WL microcontrollers feature a sub-GHz radio based-on Semtech SX126x

The STM32 Arduino core is adding support for this series too, and I have been able to program a blink example to my Seeed Studio LORA E5 module.
https://github.com/stm32duino/Arduino_Core_STM32

I am wondering if it would be possible, and if it is, how much effort it would be to get this library to work on the STM32WL series of microcontrollers?

Timeout Waiting For BUSY Now

Hi Bernd, I hope you're fine. I try send "Helllo" over LoRaWAN wşth ESP32. But I saw serial "timeout waiting for BUSY now". I defined txen and rxen. And I send picture and LoraWAN settings. What should i change, this is the first time i saw such an error.
ADR : Disabled
Datarate : DR_2
Duty cycles : Enabled
Region : LORAMAC_REGION_EU868
LORAWAN_APP_INTERVAL 20000
LMH_UNCONFIRMED_MSG;

Ekran Alıntısı

MAC and RP version

On the new TTNv3 console one needs to choose the MAC version as well as the Region Parameters version.

Normally I default to LoRaWAN version: MAC V1.0.2 and Regional Parameters version: PHY V1.0.2 REV B. This seems to work, but knowing the exact version implemented by this library would be better.

sx1262 on nucleo-l452re-p

Hi @beegee-tokyo, have you ever try the library from MBED for sx1262 in SX126xMB2CAS board for stm32 https://os.mbed.com/components/SX126xMB2xAS/, I already try that library in my Nucleo board, and it is success to send and receive data from ttn.

My problem is when I try that library for sx1262 from ebyte using my Nucleo board, it didn't work. I try to find that problem, and I found the busy pin didn't off or the ebyte didn't wake up when the NSS pin goes low.

I try your code on my esp32, and it behaves like the datasheet says, its wake up when the NSS pin goes low the same when I try library from MBED for sx1262 in SX126xMB2CAS board for stm32.

Did you know anything about this problem? I know they're so much difference between your library and the MBED library but i think the main problem in LoRaMacInitialization.

e22-900m30s ebyte

Hy @beegee-tokyo, i really enjoy your discussions in radiolib issues about ebyte module.

currently, i try to develop e22-900m30s ebyte module, as far as i know, your library and radiolib can apply in the e22-900m22s module. I already implementation radiolib and your library too in my project for e22-900m30s, and its work and can transmit. The reason why i use e22-900m30s module is i want to reach 30dbm of my signal power transmit and I use this RF Power meter (like this one https://id.aliexpress.com/item/32798899747.html) as a monitor to see how high the e22-900m30s module can transmit with your library and radiolib, and the result of my measurement is just can reach 20 dBm and cannot reach little higher from that number. As far as I know, the e22-900m22s can reach 22dbm because it uses the sx1262 Lora module. do you know how to configure your library so my e22-900m30s module can reach a little higher from that number or maybe can reach 30 dBm?

i already setting the current limitation on sx1262 library and my output in my monitor just reach -3dbm, I try to make the parameter of TX_OUTPUT_POWER 30 dBm and comment some limitation power code in sx1262 library and the result keeps -5 dBm, become so much lower, did you know why this could be happening?

thanks before

DeepSleep enqueue multiple transmissions

Using the RAK4631-DeepSleep-LoRaWan example, I want to wake up periodically (say every 60 minutes) to send multiple LoRaWan messages.

My code looks similar to this:

      /// \todo read sensor or whatever you need to do frequently
      uint8_t dataBuffer[64];
      size_t bufferSize;
      POWER ON SENSORS();
      
      bufferSize = READ_SENSOR_A(dataBuffer);
      if(sendLoRaFrame(1, dataBuffer, bufferSize)) {
        Serial.println("LoRaWan: sent READ_SENSOR_A");
      }
      else
      {
        Serial.println("LoRaWan: packet send failed");
      }
      
      bufferSize = READ_SENSOR_B(dataBuffer);
      if(sendLoRaFrame(2, dataBuffer, bufferSize)) {
        Serial.println("LoRaWan: sent READ_SENSOR_B");
      }
      else
      {
        Serial.println("LoRaWan: packet send failed");
      }
      
      bufferSize = READ_SENSOR_C(dataBuffer);
      if(sendLoRaFrame(3, dataBuffer, bufferSize)) {
        Serial.println("LoRaWan: sent READ_SENSOR_C");
      }
      else
      {
        Serial.println("LoRaWan: packet send failed");
      }
      
      bufferSize = READ_SENSOR_D(dataBuffer);
      if(sendLoRaFrame(4, dataBuffer, bufferSize)) {
        Serial.println("LoRaWan: READ_SENSOR_D");
      }
      else
      {
        Serial.println("LoRaWan: packet send failed");
      }

The problem is that only the the first call to sendLoRaFrame is accepted. The other three calls to this function fails. This is understandable as the TX is likely still in progress, as sendLoRaFrame only enqueues the message for transmission, and does not wait for it to finish.

What would the best solution be to enqueue multiple messages for transmission?

LoRaWAN Change Region

Hi Bernd, I hope you're fine.

I am working on ESP32 Sx1262 LoRaWAN on Arduino Plartform and first of all I has tried to connect EU868 and I have successfully sent the package. Then I changed the region inside the void loop and called the lmh_init and lmh_join functions again. The region has changed, I saw on the serial screen, but normally when I called the lmh_join function, it would enter the lorawan_has_joined_handler function, but in the code, it went into the tx_lora_periodic_handler function and "Did not join network, skip sending frame"

is this normal? What should we do if we want to join another region after joining a region?

LORAMAC_STATUS_BUSY

Hello Guys,
I am using NRF52832 DK with E22900M22S module, I used LORAWAN example, its work fine for initial 20 packet, but after that serial monitor show this below message:
12:15:37.870 -> LoRaMacMcpsRequest LORAMAC_STATUS_BUSY
12:15:37.917 -> lmh_send -> LoRaMacMcpsRequest failed
12:15:37.917 -> lmh_send result -1

Although multiple time I restart my node but still I received this message, someone can helping out why it happening.
I used my own GATEWAY.
Thanks

LoRa Basic Usage

HI beegee.I am using your project, but I found that the basic pingpong communication can't be done. After modifying the pin, the direct download has no feedback, and the sending timeout always occurs when sending.Some solutions are needed.

Bandwidth Selection

Hi,
#define LORA_BANDWIDTH 0 // [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved]

How can I select other bandwidths? Like if I want to use 62.5khz. How to use the 3: Reserved parameter here?

#define LORA_BANDWIDTH 0 // [0: 125 kHz, 1: 250 kHz, 2: 500 kHz, 3: Reserved]

Library dependencies

Hi Bernd,

If I add SX126x-Arduino to the lib_deps in platformio.ini, without including <SX126x-Arduino.h> to main.cpp, the compiler complains about missing the SPI.h and the Adafruit_TinyUSB.h dependencies:

image
image

This can be easily fixed by adding those dependencies to library.json:

"dependencies": [
    {
      "name": "SPI",
      "frameworks": "arduino"
    },
    {
      "name": "Adafruit TinyUSB Library",
      "frameworks": "arduino"
    }
  ]

The motivation for this change is that we may have an #ifdef wrapping #include <SX126x-Arduino.h>, but we may still wan to keep SX126x-Arduino in lib_deps.
I am happy to create a PR if you agree with those changes.

Cheers,
Robson.

DRF1262T support?

DRF1262T module uses 1 pin for Antenna switching using SW pin.

I had a skype conversation with them and they said:

  1. we use the PE4259 as RF switch
    SW pin is used as the power supply for the RF swith the DIO2 is internally used to swtich RX/TX
    for other modules, they might use AS179 when you need the PE4259 to work, you can set SW to high logic when you want to turn off PE4259 in order to reduce the current leak of PE4259, you can set it to logic low for SW pn

Does your library have support for an SW pin or high / low pin for RF switch? (nRF52832)

Thanks

http://www.dorji.com/docs/data/DRF1262T.pdf

SX126x

Hi , @beegee-tokyo I am using your lib, and I get better results in the initial stage. However, in the function of using CAD, and the official document has always been the error of packet loss, do you have time to write a CAD routine? Thank you very much

SX1262-ESP32 Class B testing

@beegee-tokyo

Hi Again !

Thank you for your amazing support for my previous quires. I have a question , i am able to switch to class B as you told me in previous question . Have you tested class B lorawan , is it fulfilling the Class B TX and RX criteria as per the following link

https://www.rfwireless-world.com/Tutorials/LoRaWAN-classes.html

? Can you please guide me how can i test Class B ? Using which server is the best choice to start chirpstack or any other alternative ?

Thanks In advance

Sx1262 waveshare pins

Hi, can you help me with the pinout of sx1262 waveshare board and an arduino nano 33 iot in order for the lorawan example to work ?
I don't know how to find the busy, nss or reset pins on the sx1262
Here is the arduino pinout : https://store.arduino.cc/arduino-nano-33-iot
And here are the shields pins :
Screenshot_20210320-122624_Chrome

Control Downlink

Hello, just start to play with RAK5005-0 v1.0 and RAK 1920 ver. A , successfully upload .ino file, and transmit messages to gateway. Now i wonder what payload i need to send to the node and what port i need to use . In the repo i found this:
static void lorawan_rx_handler(lmh_app_data_t *app_data)
{
Serial.printf("LoRa Packet received on port %d, size:%d, rssi:%d, snr:%d\n",
app_data->port, app_data->buffsize, app_data->rssi, app_data->snr);

switch (app_data->port)
{
case 3:
	// Port 3 switches the class
	if (app_data->buffsize == 1)
	{
		switch (app_data->buffer[0])
		{
		case 0:
			lmh_class_request(CLASS_A);
			break;

		case 1:
			lmh_class_request(CLASS_B);
			break;

		case 2:
			lmh_class_request(CLASS_C);
			break;

		default:
			break;
		}
	}
	break;

case LORAWAN_APP_PORT:
	// YOUR_JOB: Take action on received data
	break;

default:
	break;
}

}
And my other question is , how i can compare the payload , with some value and manage some IO pin of board.
Thanks!!!

Does it support nRF52840?

Hi @beegee-tokyo ,

According to your example and description, this repo can work on nRF52832 + SX126X, right?
If it is, i want to ask two questions please:

  1. I think this repo can support nRF52840 + SX1262 surely, right?
  2. What should i do if i want to run it on nRF52840 + SX1262?
    Looking forward for your reply, thank you!

ESP32+sx1268 compiling error

hi, i'm new to arduino and try to run the sample project LoRaWan and i encountered some problems aout the compiling like:
libraries\SX126x-Arduino\mac\region\Region.cpp.o:(.literal.RegionGetPhyParam+0x0): undefined reference to `RegionEU868GetPhyParam'
i think this should be caused by the link process, but i cant find how the link is done,do you have any suggestions? thanks.
Hardware: ESP32+sx1268

SX126x-Arduino + Ethernet

I have successfully used your library to communicate 2 modules together but seem to have an issue when I try to use Ethernet at the same time.

Here is the Ethernet, ESP32 I am using:
https://www.amazon.com/Olimex-ESP32-POE-ISO-Espressif-Ethernet-Isolation/dp/B07R1ZMSG7/ref=sr_1_2?keywords=esp32+poe&qid=1572020502&sr=8-2

From what I can tell I need to use a different SPI pins, here is my configuration:

// ESP32 - SX126x pin configuration
int PIN_LORA_RESET = 5; // LORA RESET
int PIN_LORA_NSS = 15; // LORA SPI CS
int PIN_LORA_SCLK = 0; // LORA SPI CLK
int PIN_LORA_MISO = 2; // LORA SPI MISO
int PIN_LORA_DIO_1 = 32; //21; // LORA DIO_1
int PIN_LORA_BUSY = 16; //22; // LORA SPI BUSY
int PIN_LORA_MOSI = 4; // LORA SPI MOSI
int RADIO_TXEN = -1; // 26; // LORA ANTENNA TX ENABLE
int RADIO_RXEN = -1; //27; // LORA ANTENNA RX ENABLE

What I would really like to test is to remove somehow all the events / IRQ's and just check for a message coming in manually.

Side note, would be nice if this was ported to AVR also :)

Over-the-air-activation (OTAA) for LoraWAN (TTN) doesn't seem to work

Hello,
i am trying to set up an OTAA activation with LoraWAN on The-Things-Network. but with no success.
I managed to have a successfull running configuration with ABP activation. Therefore hardware configuation an code should be fine.
I tried to switch from ABP to OTAA by setting the application key and set the following definition in "Commissioning.h" of the library.
#define OVER_THE_AIR_ACTIVATION 1
Does anyone managed to run OTAA?
Thanks for your support!

OTAA join request fails forever until WiFi is turned on

I am doing an exercise on a possible use scenario of LoRaWAN: my sketch uses a library that conditionally initializes WiFi so that a configuration interface can be shown to the user. After entering the values for appEUI, deviceEUI and appKey, the LoRaWAN connection should be established, and the WiFi can then be turned off to save energy. The LoRaWAN configuration values are stored in NVRAM so that a reboot can use them immediately.

The problem I am having (using ChirpStack as networkserver and RAK7258 as gateway devices) is that, when starting from a cold boot, with the WiFi turned OFF, and correct LoRaWAN values already stored in NVRAM, the join request keeps failing over and over again, even with the gateway less than one meter from the device:

`
[E][Preferences.cpp:472] getString(): nvs_get_str len fail: net/1/identity NOT_FOUND
[E][Preferences.cpp:472] getString(): nvs_get_str len fail: net/1/password NOT_FOUND
[E][Preferences.cpp:472] getString(): nvs_get_str len fail: net/2/identity NOT_FOUND
[E][Preferences.cpp:472] getString(): nvs_get_str len fail: net/2/password NOT_FOUND
[V][Preferences.cpp:341] getUChar(): nvs_get_u8 fail: net/2/lastsel NOT_FOUND
[E][Preferences.cpp:49] begin(): nvs_open failed: NOT_FOUND
[E][Preferences.cpp:49] begin(): nvs_open failed: NOT_FOUND
INFO: WiFi inicialmente APAGADO
[I][LoRaMacHelper.cpp:734] lmh_init(): OTAA
DevEui=C8-2B-96-9D-3E-9C-00-00
DevAdd=00000000
AppEui=00-00-00-00-00-00-00-00
AppKey=E4-9C-8A-C1-CC-D0-34-9A-BF-75-0C-DA-CA-FB-2E-75
[E][sx126x-board.cpp:149] SX126xWaitOnBusy(): LORA Busy timeout waiting for BUSY low
[E][LoRaMacHelper.cpp:309] lmh_setSubBandChannels(): [LMH] Selected subband 2
[E][LoRaMacHelper.cpp:309] lmh_setSubBandChannels(): [LMH] Selected subband 2
[D][LoRaMac.cpp:610] OnRadioTxDone(): OnRadioTxDone
[D][LoRaMac.cpp:629] OnRadioTxDone(): OnRadioTxDone => RX Windows #1 4991 #2 6002
[D][LoRaMac.cpp:662] OnRadioTxDone(): OnRadioTxDone => TX was Join Request
[D][radio.cpp:1340] RadioIrqProcess(): RadioIrqProcess => IRQ_RX_TX_TIMEOUT
[D][LoRaMac.cpp:1225] OnRadioRxTimeout(): OnRadioRxTimeout
[D][LoRaMac.cpp:1315] OnMacStateCheckTimerEvent(): Join network failed 1 time(s)

[D][LoRaMac.cpp:610] OnRadioTxDone(): OnRadioTxDone
[D][LoRaMac.cpp:629] OnRadioTxDone(): OnRadioTxDone => RX Windows #1 4991 #2 6002
[D][LoRaMac.cpp:662] OnRadioTxDone(): OnRadioTxDone => TX was Join Request
[D][radio.cpp:1340] RadioIrqProcess(): RadioIrqProcess => IRQ_RX_TX_TIMEOUT
[D][LoRaMac.cpp:1225] OnRadioRxTimeout(): OnRadioRxTimeout
[D][LoRaMac.cpp:1315] OnMacStateCheckTimerEvent(): Join network failed 2 time(s)

[D][LoRaMac.cpp:610] OnRadioTxDone(): OnRadioTxDone
[D][LoRaMac.cpp:629] OnRadioTxDone(): OnRadioTxDone => RX Windows #1 4991 #2 6002
[D][LoRaMac.cpp:662] OnRadioTxDone(): OnRadioTxDone => TX was Join Request
[D][radio.cpp:1340] RadioIrqProcess(): RadioIrqProcess => IRQ_RX_TX_TIMEOUT
[D][LoRaMac.cpp:1225] OnRadioRxTimeout(): OnRadioRxTimeout
[D][LoRaMac.cpp:1315] OnMacStateCheckTimerEvent(): Join network failed 3 time(s)

ERR: OVER_THE_AIR_ACTIVATION failed! Retrying...
[D][LoRaMac.cpp:610] OnRadioTxDone(): OnRadioTxDone
[D][LoRaMac.cpp:629] OnRadioTxDone(): OnRadioTxDone => RX Windows #1 4991 #2 6002
[D][LoRaMac.cpp:662] OnRadioTxDone(): OnRadioTxDone => TX was Join Request
[D][radio.cpp:1340] RadioIrqProcess(): RadioIrqProcess => IRQ_RX_TX_TIMEOUT
[D][LoRaMac.cpp:1225] OnRadioRxTimeout(): OnRadioRxTimeout
[D][LoRaMac.cpp:1315] OnMacStateCheckTimerEvent(): Join network failed 1 time(s)

[D][LoRaMac.cpp:610] OnRadioTxDone(): OnRadioTxDone
[D][LoRaMac.cpp:629] OnRadioTxDone(): OnRadioTxDone => RX Windows #1 4991 #2 6002
[D][LoRaMac.cpp:662] OnRadioTxDone(): OnRadioTxDone => TX was Join Request
[D][radio.cpp:1340] RadioIrqProcess(): RadioIrqProcess => IRQ_RX_TX_TIMEOUT
[D][LoRaMac.cpp:1225] OnRadioRxTimeout(): OnRadioRxTimeout
[D][LoRaMac.cpp:1315] OnMacStateCheckTimerEvent(): Join network failed 2 time(s)

[D][LoRaMac.cpp:610] OnRadioTxDone(): OnRadioTxDone
[D][LoRaMac.cpp:629] OnRadioTxDone(): OnRadioTxDone => RX Windows #1 4991 #2 6002
[D][LoRaMac.cpp:662] OnRadioTxDone(): OnRadioTxDone => TX was Join Request
[D][radio.cpp:1340] RadioIrqProcess(): RadioIrqProcess => IRQ_RX_TX_TIMEOUT
[D][LoRaMac.cpp:1225] OnRadioRxTimeout(): OnRadioRxTimeout
[D][LoRaMac.cpp:1315] OnMacStateCheckTimerEvent(): Join network failed 3 time(s)

ERR: OVER_THE_AIR_ACTIVATION failed! Retrying...

`

However, if I then turn the WiFi ON (with an external button), the join request succeeds after a few retries:

`
[D][LoRaMac.cpp:610] OnRadioTxDone(): OnRadioTxDone
[D][LoRaMac.cpp:629] OnRadioTxDone(): OnRadioTxDone => RX Windows #1 4991 #2 6002
[D][LoRaMac.cpp:662] OnRadioTxDone(): OnRadioTxDone => TX was Join Request
[D][radio.cpp:1340] RadioIrqProcess(): RadioIrqProcess => IRQ_RX_TX_TIMEOUT
[D][LoRaMac.cpp:1225] OnRadioRxTimeout(): OnRadioRxTimeout
[D][LoRaMac.cpp:1315] OnMacStateCheckTimerEvent(): Join network failed 2 time(s)

[294487]INFO: YUBOX Framework toma control de WiFi...
[295528][D][WiFiGeneric.cpp:374] _eventCallback(): Event: 0 - WIFI_READY
[D][yubox-lorawan-SX126X.ino:92] WiFiEvent_ledStatus(): [WiFi-event] event: 0

[D][WiFiGeneric.cpp:374] _eventCallback(): Event: 14 - AP_START
[D][yubox-lorawan-SX126X.ino:92] WiFiEvent_ledStatus(): [WiFi-event] event: 14

[D][WiFiGeneric.cpp:374] _eventCallback(): Event: 14 - AP_START
[D][yubox-lorawan-SX126X.ino:92] WiFiEvent_ledStatus(): [WiFi-event] event: 14

[D][WiFiGeneric.cpp:374] _eventCallback(): Event: 1 - SCAN_DONE
[D][yubox-lorawan-SX126X.ino:92] WiFiEvent_ledStatus(): [WiFi-event] event: 1

[D][WiFiGeneric.cpp:374] _eventCallback(): Event: 2 - STA_START
[D][yubox-lorawan-SX126X.ino:92] WiFiEvent_ledStatus(): [WiFi-event] event: 2

[D][WiFiGeneric.cpp:374] _eventCallback(): Event: 2 - STA_START
[D][yubox-lorawan-SX126X.ino:92] WiFiEvent_ledStatus(): [WiFi-event] event: 2

[D][LoRaMac.cpp:610] OnRadioTxDone(): OnRadioTxDone
[D][LoRaMac.cpp:629] OnRadioTxDone(): OnRadioTxDone => RX Windows #1 4991 #2 6002
[D][LoRaMac.cpp:662] OnRadioTxDone(): OnRadioTxDone => TX was Join Request
[D][WiFiGeneric.cpp:374] _eventCallback(): Event: 4 - STA_CONNECTED
[D][yubox-lorawan-SX126X.ino:92] WiFiEvent_ledStatus(): [WiFi-event] event: 4

[D][WiFiGeneric.cpp:374] _eventCallback(): Event: 7 - STA_GOT_IP
[D][WiFiGeneric.cpp:419] _eventCallback(): STA IP: 192.168.0.17, MASK: 255.255.255.0, GW: 192.168.0.1
[D][yubox-lorawan-SX126X.ino:92] WiFiEvent_ledStatus(): [WiFi-event] event: 7

[D][radio.cpp:1340] RadioIrqProcess(): RadioIrqProcess => IRQ_RX_TX_TIMEOUT
[D][LoRaMac.cpp:1225] OnRadioRxTimeout(): OnRadioRxTimeout
[D][LoRaMac.cpp:1315] OnMacStateCheckTimerEvent(): Join network failed 3 time(s)

ERR: OVER_THE_AIR_ACTIVATION failed! Retrying...
[D][LoRaMac.cpp:610] OnRadioTxDone(): OnRadioTxDone
[D][LoRaMac.cpp:629] OnRadioTxDone(): OnRadioTxDone => RX Windows #1 4991 #2 6002
[D][LoRaMac.cpp:662] OnRadioTxDone(): OnRadioTxDone => TX was Join Request
[D][LoRaMac.cpp:712] OnRadioRxDone(): OnRadioRxDone
[D][LoRaMac.cpp:768] OnRadioRxDone(): OnRadioRxDone => FRAME_TYPE_JOIN_ACCEPT
OVER_THE_AIR_ACTIVATION != 0
INFO: enviando payload (10 bytes)... OK
[D][LoRaMac.cpp:610] OnRadioTxDone(): OnRadioTxDone
[D][LoRaMac.cpp:629] OnRadioTxDone(): OnRadioTxDone => RX Windows #1 991 #2 2002
[D][LoRaMac.cpp:712] OnRadioRxDone(): OnRadioRxDone
[D][LoRaMac.cpp:837] OnRadioRxDone(): OnRadioRxDone => FRAME_TYPE_DATA_(UN)CONFIRMED_DOWN
INFO: enviando payload (10 bytes)... OK

`

If I then turn off the WiFi while the device is joined to the network, the device keeps sending and receiving packets as normal.

What can I do to debug this issue?

EBYTE E22-900T30S using UART, can it be plugged into the library?

Hello. I have this project using an Espressif ESP32 with an EBYTE E22-900T30S. I have been skimming over this library, and so far I can see that, unlike the E22-900M22S that has an SPI interface and some pins that directly enable or disable transmission and such, the E22-900T30S is controlled mainly through an UART interface to read and write data over the radio link, and two additional pins (M0 and M1) to switch between data and register-programming modes. My project involves speaking with a LoRaWAN gateway, and since I already know that the E22 does not have any internal LoRaWAN stack, I was considering the possibility of tweaking the abstraction layer to speak through the UART instead of using SPI. However, there exists the possibility that the UART interface does not expose enough of the underlying chip capabilities to actually implement LoRaWAN on top of the UART, or that it implements its own abstraction over the radio link that gets in the way of speaking to the LoRa chipset.

Can LoRaWAN, in principle, be implemented on top of the UART interface? Is it known one way or the other? If not, what should I know about capabilities exposed through the interface in order to make an informed decision?

Stack size for the LORA task

Hi Bernd, I hope you are doing well.

I was wondering if there a reason I am not seeing for stack size of the LORA task to be 4096?:

#ifdef NRF52_SERIES
if (!xTaskCreate(_lora_task, "LORA", 4096, NULL, TASK_PRIO_NORMAL, &_loraTaskHandle))
#else
if (!xTaskCreate(_lora_task, "LORA", 4096, NULL, 1, &_loraTaskHandle))
#endif

From my tests it looks like 200 would be enough for the task to run:
image

Cheers,
Robson.

Disable debug logs

Using the DeepSleep example I am seeing a Serial print:

16:18:30.751 -> <LM> OnRadioRxDone
16:19:25.634 -> <LM> OnRadioRxDone => FRAME_TYPE_JOIN_ACCEPT
16:19:26.197 -> <LM> OnRadioTxDone
16:19:31.178 -> <LM> OnRadioTxDone => RX Windows #1 4989 #2 5995
16:19:35.163 -> <RADIO> RadioIrqProcess => IRQ_RX_TX_TIMEOUT
16:19:35.163 -> <LM> OnRadioRxTimeout

Looking at the source for this library I see logging is enabled by default, and one can disable it by setting LIB_DEBUG to 0.

In the DeepSleep example, in main.h, I have added the following code after the MAX_SAVE define.

// Comment the next line if you want DEBUG output. But the power savings are not as good then!!!!!!!
#define MAX_SAVE

#ifdef MAX_SAVE 
#define LIB_DEBUG 0
#endif

This however does not work.

Also the compiler does not like it:

In file included from /home/jpmeijers/Izinto/Arduino Code/RAK4631-DeepSleep-LoRaWan-GX701P-new/RAK4631-DeepSleep-LoRaWan-GX701P-new.ino:24:
/tmp/arduino_build_880825/sketch/main.h:20: warning: "LIB_DEBUG" redefined
   20 | #define LIB_DEBUG 0
      | 
In file included from /home/jpmeijers/Arduino/libraries/SX126x-Arduino/src/boards/sx126x/sx126x-board.h:42,
                 from /home/jpmeijers/Arduino/libraries/SX126x-Arduino/src/boards/mcu/board.h:50,
                 from /home/jpmeijers/Arduino/libraries/SX126x-Arduino/src/LoRaWan-Arduino.h:15,
                 from /home/jpmeijers/Arduino/libraries/SX126x-Arduino/src/LoRaWan-RAK4630.h:4,
                 from /tmp/arduino_build_880825/sketch/main.h:14,
                 from /home/jpmeijers/Izinto/Arduino Code/RAK4631-DeepSleep-LoRaWan-GX701P-new/RAK4631-DeepSleep-LoRaWan-GX701P-new.ino:24:
/home/jpmeijers/Arduino/libraries/SX126x-Arduino/src/sx126x-debug.h:18: note: this is the location of the previous definition
   18 | #define LIB_DEBUG 1

Changing the code in main.h to read as follows makes the compiler warning go away, but still lets the library print to Serial:

#define MAX_SAVE

#ifdef MAX_SAVE 
#undef LIB_DEBUG
#define LIB_DEBUG 0
#endif

I guess we'll need to have a similar check and define rather in the library than in the user code. I'll test and report back.

Eror "lmh_send result 1"

I am utilizing ESP32_Wrover Module and E22_900M_22S (sx126x) Module. I have tried OTAA with Helium Console. I " #define OVER_THE_AIR_ACTIVATION 1" and " #define STATIC_DEVICE_EUI 1" instead of 0 in "Commissioning.h" . Also I reduced the size of payload.I am sending only "HELLO". And I have eror. I see "lmh_send_result 1" in serial
4ff5333f-48eb-46d0-9181-7f8dcb1e95c9
.
de8f6275-6cb4-44e6-9d5f-de0fdc3fa34c

Low power mode using semaphore in RAK4630

Hi I am working on low power application firmware on RAK4630 by making use of semaphores I am following the examples given. I am using only one semaphore for all the tasks my aim is to hold the execution until some other task got finished and returns success or failure. But I am not getting the expected output.

I have given a sample code from my work

int eventNum = 0;

/* Semaphore used by events to wake up loop task */
SemaphoreHandle_t taskEvent = NULL;

/* Timer to wakeup task frequently and send message */
SoftwareTimer taskWakeupTimer;

void periodicWakeup(TimerHandle_t unused)
{
  eventNum = 1;

  // Give the semaphore, so the loop task will wake up
  xSemaphoreGiveFromISR(taskEvent, pdFALSE);
}

void setup() {
  // Create the LoRaWan event semaphore
  taskEvent = xSemaphoreCreateBinary();

  // Initialize semaphore
  xSemaphoreGive(taskEvent);

  // Initialize timer
  taskWakeupTimer.begin(60000, periodicWakeup);
  taskWakeupTimer.start();

  // Please assume these things are properly done
  // Initialize LoRa chip.
  // Initialize LoRaWAN in OTAA mode
}

void loop() {
    switch (eventNum) {
        case 0:
              lmh_join();
              // Hold here until released from the LoRa handlers
              // <<< It should hold here until lorawan_has_joined_handler or lorawan_has_join_failed should be executed >>>
              // But its not holding here it will continue to execute 
              xSemaphoreTake(taskEvent, 10);

              eventNum = 1;
              break;

         // Other cases that don't use semaphores
         case 1:
             break;
    }

    // Sleep here till wake up by timer or other events
    if (xSemaphoreTake(taskEvent, portMAX_DELAY) == pdTRUE) 
    {
        eventNum = 1;
    }
}

/* I am providing only two handlers here please assume other handlers also present */
void lorawan_has_joined_handler(void)
{
    eventNum = 1;
     // Give the semaphore, so the loop task will continue
     xSemaphoreGiveFromISR(taskEvent, pdFALSE);
}

void lorawan_has_join_failed(void)
{
     eventNum = 1;
     // Give the semaphore, so the loop task will continue
     xSemaphoreGiveFromISR(taskEvent, pdFALSE);
}

Pin assignment to use ebyte sx1262 22 dbm module with ESP32

Thank you for great library for SX126X chips. I am trying to build a PCB using above hardware. I need to have ST7789 TFT display, a MicroSD card socket and SX1262 Ebyte module in my project. I also need to use I2C for BME280 sensor & I2S bus for microphone and speaker. This is for home automation project but there is no need for Lorawan.

Do you think ESP32 can handle all these hardware devices? If So what you suggest should be the optimum pin out ?

Thanks.

Class of Nodes (LoRaWAN)

Hi again @beegee-tokyo I hope you are well.
I have a questions about the class B and C of nodes in lorawan, i try to switch betwen A,B and C, but just work well the class A, for my project is will possible need the class C, do you know how can do that this class of node works correctly.

pingpong example Taking initial time!

Hello Sir, why in pingpong example it is almost take more than 5 minutes to setup tx and rx.
where to reduce this initial time.
12:08:23.947 -> MCU Espressif ESP32
12:08:23.947 -> BoardId: 00-00-2C-A7-58-C4-0A-24
12:08:23.947 -> Starting lora_hardware_init
12:08:23.994 -> SyncWord = 2414
12:08:23.994 -> LoRa Task started
12:08:24.040 -> Starting Radio.Rx
Then it is start on :

12:13:11.248 -> OnRxTimeout
12:13:11.761 -> CAD returned channel free after 13ms
12:13:11.761 -> Sending a PING in OnCadDone as Master
12:13:11.898 -> OnTxDone
12:13:12.457 -> OnRxDone
12:13:12.457 -> RssiValue=-15 dBm, SnrValue=12
12:13:12.457 -> 50 4F 4E 47 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B
12:13:12.457 -> Received a PONG in OnRxDone as Master
12:13:12.967 -> CAD returned channel free after 13ms
12:13:12.967 -> Sending a PING in OnCadDone as Master

Increase SF during join

Hi,

I can't find any example/info : in LORAWAN_OTAA_ABP example, after JOINREQ_NBTRIALS the device just stop to try joining. So it tries 3 times in SF7 and just give up. Is there any way to give another shot using SF8, and if it fails, another using SF9 etc ... until SF12 (like in other Lorawan libraries like lmic).

Regards

Sx1262-Arduino ESP32 Payload Size

Hi Beegee_tokyo!

Hope you are doing well!. I am having issue in understanding that how to increase the payload size .Recently , able to send the "HELLO WORLD!" only when i increase the payload size it gives me error "-1" . In another post you replied me that this error is because of increase in payload size . According to my understanding i changed the default Data rate from DR_0 to DR_1 , DR_2 , DR_3 and DR_4 but same error with no data receive at server side .

Thanks in advance .

Best Regards,

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.