### Initialize LoRaWAN Node with Persistence (C++) Source: https://context7.com/radiolib-org/radiolib-persistence/llms.txt Demonstrates the initialization of a LoRaWAN node using RadioLib on an ESP32, including radio hardware configuration, regional settings, and OTAA parameters. It sets up the node for LoRaWAN communication and performs initial radio setup. ```cpp #include #include // Configure radio hardware (ESP32 with SX1262) SX1262 radio = new Module(8, 14, 12, 13); // Regional configuration const LoRaWANBand_t Region = EU868; const uint8_t subBand = 0; // LoRaWAN credentials uint64_t joinEUI = 0x0000000000000000; uint64_t devEUI = 0x70B3D57ED006544E; uint8_t appKey[] = { 0x31, 0x16, 0x6A, 0x22, 0x97, 0x52, 0xB6, 0x34, 0x57, 0x45, 0x1B, 0xC3, 0xC9, 0xD8, 0x83, 0xE8 }; uint8_t nwkKey[] = { 0x45, 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F }; // Create LoRaWAN node LoRaWANNode node(&radio, &Region, subBand); void setup() { Serial.begin(115200); // Initialize radio int16_t state = radio.begin(); if (state != RADIOLIB_ERR_NONE) { Serial.print("Radio init failed: "); Serial.println(state); while (true); } // Setup OTAA parameters node.beginOTAA(joinEUI, devEUI, nwkKey, appKey); Serial.println("Node initialized successfully"); } ``` -------------------------------- ### Configure LoRaWAN Region and Detect Hardware Source: https://context7.com/radiolib-org/radiolib-persistence/llms.txt This C++ code snippet configures LoRaWAN regional parameters (e.g., EU868, US915) and attempts to automatically detect and initialize the radio hardware for popular development boards like Heltec WiFi Kit V3 and TTGO LoRa32 v2.1. It includes LoRaWAN credentials and a fallback for manual hardware configuration. The `setup()` function initializes the serial communication and the radio module, returning an error state if initialization fails. ```cpp #include // Regional configuration // Options: EU868, US915, AU915, AS923, IN865, KR920, CN780, CN500 const LoRaWANBand_t Region = EU868; const uint8_t subBand = 0; // For US915/AU915, set to 2 // LoRaWAN credentials #define RADIOLIB_LORAWAN_JOIN_EUI 0x0000000000000000 #define RADIOLIB_LORAWAN_DEV_EUI 0x70B3D57ED006544E #define RADIOLIB_LORAWAN_APP_KEY 0x31, 0x16, 0x6A, 0x22, 0x97, 0x52, 0xB6, 0x34, 0x57, 0x45, 0x1B, 0xC3, 0xC9, 0xD8, 0x83, 0xE8 #define RADIOLIB_LORAWAN_NWK_KEY 0x45, 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F uint64_t joinEUI = RADIOLIB_LORAWAN_JOIN_EUI; uint64_t devEUI = RADIOLIB_LORAWAN_DEV_EUI; uint8_t appKey[] = { RADIOLIB_LORAWAN_APP_KEY }; uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY }; // Hardware pinmap auto-detection #if defined(ARDUINO_heltec_wifi_kit_32_V3) SX1262 radio = new Module(8, 14, 12, 13); #elif defined(ARDUINO_TTGO_LoRa32_v21new) SX1276 radio = new Module(18, 26, 14, 33); #elif defined(ARDUINO_TBEAM_USE_RADIO_SX1276) SX1276 radio = new Module(18, 26, 23, 33); #else // Manual configuration // SX1262: Module(NSS/CS, DIO1, RESET, BUSY) SX1262 radio = new Module(8, 14, 12, 13); #endif // Create LoRaWAN node LoRaWANNode node(&radio, &Region, subBand); void setup() { Serial.begin(115200); // Initialize and test radio int16_t state = radio.begin(); if (state != RADIOLIB_ERR_NONE) { Serial.print("Radio initialization failed: "); Serial.println(state); while (true); } Serial.println("Radio initialized successfully"); Serial.print("Region: "); Serial.println(Region); Serial.print("SubBand: "); Serial.println(subBand); } ``` -------------------------------- ### ESP32 LoRaWAN Uplink with Persistence and Deep Sleep Source: https://context7.com/radiolib-org/radiolib-persistence/llms.txt This comprehensive C++ example for the ESP32 shows a complete LoRaWAN uplink scenario using the RadioLib library. It incorporates automatic session persistence to RTC memory, sensor data collection, and deep sleep for power management between transmissions. The code initializes the radio, activates the LoRaWAN stack, sends data, and then enters deep sleep for a configurable interval. ```cpp #include #include RTC_DATA_ATTR uint16_t bootCount = 0; RTC_DATA_ATTR uint8_t LWsession[RADIOLIB_LORAWAN_SESSION_BUF_SIZE]; const uint32_t uplinkIntervalSeconds = 5UL * 60UL; // 5 minutes void setup() { Serial.begin(115200); delay(2000); Serial.print("Boot count: "); Serial.println(++bootCount); // Initialize radio int16_t state = radio.begin(); if (state != RADIOLIB_ERR_NONE) { Serial.print("Radio init failed: "); Serial.println(state); while (true); } // Restore or create new session state = lwActivate(); // Gather sensor data uint8_t value1 = radio.random(100); uint16_t value2 = radio.random(2000); // Build payload (3 bytes: 1 byte + 2-byte integer) uint8_t uplinkPayload[3]; uplinkPayload[0] = value1; uplinkPayload[1] = highByte(value2); uplinkPayload[2] = lowByte(value2); // Send uplink Serial.println("Sending uplink"); state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload)); if (state == RADIOLIB_ERR_NONE || state == RADIOLIB_ERR_NONE) { Serial.print("Uplink sent, FCntUp: "); Serial.println(node.getFCntUp()); } else { Serial.print("Uplink failed: "); Serial.println(state); } // Save session to RTC memory uint8_t *persist = node.getBufferSession(); memcpy(LWsession, persist, RADIOLIB_LORAWAN_SESSION_BUF_SIZE); // Enter deep sleep until next uplink gotoSleep(uplinkIntervalSeconds); } void loop() { // ESP32 restarts from setup() after deep sleep // loop() is never called } ``` -------------------------------- ### Configure LoRaWAN Device Identifiers and Keys (C++) Source: https://github.com/radiolib-org/radiolib-persistence/blob/main/examples/LoRaWAN_ESP32/notes.md This C++ code snippet from `config.h` defines the necessary EUIs and Keys for LoRaWAN device registration. It includes placeholders for `joinEUI`, `devEUI`, `appKey`, and `nwkKey` that need to be replaced with actual values obtained from the LoRaWAN Network Server (e.g., TTN). The format for these values is crucial for successful device onboarding. ```c++ // replace-with-your-device-id uint64_t joinEUI = 0x0000000000000000; uint64_t devEUI = 0x0000000000000000; uint8_t appKey[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t nwkKey[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ``` -------------------------------- ### Implement LoRaWAN Join Retry with Exponential Backoff Source: https://context7.com/radiolib-org/radiolib-persistence/llms.txt This C++ function, `performJoinWithRetry`, implements a robust retry mechanism for LoRaWAN join requests using exponential backoff. It respects duty cycle regulations by introducing increasing delays between failed attempts, up to a maximum of 3 minutes. Upon successful join, it saves nonces to persistent storage and resets the failure counter. If the join fails, it calculates the backoff delay, increments a persistent boot counter, and initiates a deep sleep before the next retry. ```cpp #include RTC_DATA_ATTR uint16_t bootCountSinceUnsuccessfulJoin = 0; int16_t performJoinWithRetry() { int16_t state = RADIOLIB_ERR_NETWORK_NOT_JOINED; while (state != RADIOLIB_LORAWAN_NEW_SESSION) { Serial.println("Attempting LoRaWAN join"); state = node.activateOTAA(); if (state == RADIOLIB_LORAWAN_NEW_SESSION) { Serial.println("Join successful"); // Save nonces to flash store.begin("radiolib"); uint8_t buffer[RADIOLIB_LORAWAN_NONCES_BUF_SIZE]; uint8_t *persist = node.getBufferNonces(); memcpy(buffer, persist, RADIOLIB_LORAWAN_NONCES_BUF_SIZE); store.putBytes("nonces", buffer, RADIOLIB_LORAWAN_NONCES_BUF_SIZE); store.end(); // Reset failure counter bootCountSinceUnsuccessfulJoin = 0; } else { Serial.print("Join failed with error: "); Serial.println(state); // Calculate backoff delay (1 min, 2 min, 3 min, max 3 min) uint32_t sleepForSeconds = min((bootCountSinceUnsuccessfulJoin++ + 1UL) * 60UL, 3UL * 60UL); Serial.print("Failed join attempts: "); Serial.println(bootCountSinceUnsuccessfulJoin); Serial.print("Retrying in "); Serial.print(sleepForSeconds); Serial.println(" seconds"); // Enter deep sleep before retry esp_sleep_enable_timer_wakeup(sleepForSeconds * 1000UL * 1000UL); esp_deep_sleep_start(); } } return state; } ``` -------------------------------- ### Save and Restore LoRaWAN Nonces to Flash (C++) Source: https://context7.com/radiolib-org/radiolib-persistence/llms.txt Illustrates how to save and restore LoRaWAN nonces to flash memory using the Preferences library on an ESP32. This function attempts to restore a previous session; if unsuccessful, it performs a new join and saves the updated nonces. ```cpp #include Preferences store; uint8_t LWsession[RADIOLIB_LORAWAN_SESSION_BUF_SIZE]; int16_t lwActivate() { int16_t state; // Setup OTAA session node.beginOTAA(joinEUI, devEUI, nwkKey, appKey); // Open flash storage store.begin("radiolib"); // Check if nonces exist from previous join if (store.isKey("nonces")) { Serial.println("Restoring saved nonces"); // Restore nonces from flash uint8_t buffer[RADIOLIB_LORAWAN_NONCES_BUF_SIZE]; store.getBytes("nonces", buffer, RADIOLIB_LORAWAN_NONCES_BUF_SIZE); state = node.setBufferNonces(buffer); if (state == RADIOLIB_ERR_NONE) { // Restore session from RTC RAM state = node.setBufferSession(LWsession); if (state == RADIOLIB_ERR_NONE) { // Activate with restored credentials state = node.activateOTAA(); if (state == RADIOLIB_LORAWAN_SESSION_RESTORED) { Serial.println("Session restored successfully"); store.end(); return state; } } } } // No saved session - perform fresh join Serial.println("Performing fresh join"); state = node.activateOTAA(); if (state == RADIOLIB_LORAWAN_NEW_SESSION) { // Save nonces to flash for future boots uint8_t buffer[RADIOLIB_LORAWAN_NONCES_BUF_SIZE]; uint8_t *persist = node.getBufferNonces(); memcpy(buffer, persist, RADIOLIB_LORAWAN_NONCES_BUF_SIZE); store.putBytes("nonces", buffer, RADIOLIB_LORAWAN_NONCES_BUF_SIZE); Serial.println("Nonces saved to flash"); } store.end(); return state; } ``` -------------------------------- ### ESP8266 LoRaWAN Persistence with EEPROM and RTC Memory (C++) Source: https://context7.com/radiolib-org/radiolib-persistence/llms.txt This C++ code snippet demonstrates how to use EEPROM for nonce storage and RTC user memory for session data persistence on an ESP8266 using the RadioLib library. It handles boot counters, LoRaWAN session restoration and saving, and sensor data transmission. Dependencies include `` and ``. It reads nonces from EEPROM, restores session data from RTC memory, attempts LoRaWAN joining, saves nonces to EEPROM and session to RTC memory upon successful join, and sends sensor data before entering deep sleep. ```cpp #include #include uint8_t LWsession[RADIOLIB_LORAWAN_SESSION_BUF_SIZE]; uint32_t bootCount = 1; uint32_t bootCountSinceUnsuccessfulJoin = 0; void setup() { Serial.begin(74880); delay(2000); // Restore boot counters from RTC RAM uint32_t address = 0; ESP.rtcUserMemoryRead(address, &bootCount, sizeof(bootCount)); address += sizeof(bootCount); ESP.rtcUserMemoryRead(address, &bootCountSinceUnsuccessfulJoin, sizeof(bootCountSinceUnsuccessfulJoin)); address += sizeof(bootCountSinceUnsuccessfulJoin); Serial.print("Boot count: "); Serial.println(++bootCount); // Initialize radio int16_t state = radio.begin(); if (state != RADIOLIB_ERR_NONE) { Serial.println("Radio init failed"); while (true); } // Read nonces from EEPROM EEPROM.begin(RADIOLIB_LORAWAN_NONCES_BUF_SIZE); uint8_t LWnonces[RADIOLIB_LORAWAN_NONCES_BUF_SIZE]; for (uint8_t i = 0; i < RADIOLIB_LORAWAN_NONCES_BUF_SIZE; i++) { LWnonces[i] = EEPROM.read(i); } // Restore nonces state = node.setBufferNonces(LWnonces); // Restore session from RTC RAM ESP.rtcUserMemoryRead(address, (uint32_t *)&LWsession, RADIOLIB_LORAWAN_SESSION_BUF_SIZE); state = node.setBufferSession(LWsession); // Attempt to restore or create new session state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey, false); if (state != RADIOLIB_ERR_NONE) { // Need fresh join Serial.println("Performing fresh join"); state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey, true); if (state == RADIOLIB_ERR_NONE) { // Save nonces to EEPROM uint8_t *persist = node.getBufferNonces(); memcpy(LWnonces, persist, RADIOLIB_LORAWAN_NONCES_BUF_SIZE); for (uint8_t i = 0; i < RADIOLIB_LORAWAN_NONCES_BUF_SIZE; i++) { EEPROM.write(i, LWnonces[i]); } EEPROM.commit(); bootCountSinceUnsuccessfulJoin = 0; } } EEPROM.end(); // Read sensors uint8_t Digital2 = digitalRead(2); uint16_t Analog1 = analogRead(3); // Build and send payload uint8_t uplinkPayload[3]; uplinkPayload[0] = Digital2; uplinkPayload[1] = highByte(Analog1); uplinkPayload[2] = lowByte(Analog1); state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload)); Serial.print("FCntUp: "); Serial.println(node.getFcntUp()); // Save session to RTC RAM uint8_t *persist = node.getBufferSession(); memcpy(LWsession, persist, RADIOLIB_LORAWAN_SESSION_BUF_SIZE); ESP.rtcUserMemoryWrite(address, (uint32_t *)&LWsession, RADIOLIB_LORAWAN_SESSION_BUF_SIZE); // Sleep before next uplink gotoSleep(uplinkIntervalSeconds); } void gotoSleep(uint32_t seconds) { // Save boot counters to RTC RAM uint32_t address = 0; ESP.rtcUserMemoryWrite(address, &bootCount, sizeof(bootCount)); address += sizeof(bootCount); ESP.rtcUserMemoryWrite(address, &bootCountSinceUnsuccessfulJoin, sizeof(bootCountSinceUnsuccessfulJoin)); Serial.flush(); ESP.deepSleep(seconds * 1000UL * 1000UL); } void loop() {} ``` -------------------------------- ### ESP32 Session Persistence with RTC Memory for LoRaWAN Source: https://context7.com/radiolib-org/radiolib-persistence/llms.txt This C++ code snippet demonstrates how to save and restore LoRaWAN session data using RTC (Real-Time Clock) memory on an ESP32. This is crucial for maintaining the LoRaWAN connection state across deep sleep cycles without requiring a full network rejoin. It utilizes the RTC_DATA_ATTR keyword to ensure variables are preserved during sleep and integrates with the RadioLib library. ```cpp #include // RTC_DATA_ATTR stores variables in RTC RAM (preserved during deep sleep) RTC_DATA_ATTR uint16_t bootCount = 0; RTC_DATA_ATTR uint8_t LWsession[RADIOLIB_LORAWAN_SESSION_BUF_SIZE]; void saveSessionToRTC() { // Get current session from LoRaWAN stack uint8_t *persist = node.getBufferSession(); // Copy to RTC RAM memcpy(LWsession, persist, RADIOLIB_LORAWAN_SESSION_BUF_SIZE); Serial.println("Session saved to RTC RAM"); } void restoreSessionFromRTC() { // Restore session from RTC RAM to LoRaWAN stack int16_t state = node.setBufferSession(LWsession); if (state == RADIOLIB_ERR_NONE) { Serial.println("Session restored from RTC RAM"); } else { Serial.print("Session restore failed: "); Serial.println(state); } } void gotoSleep(uint32_t seconds) { // Save session before sleep saveSessionToRTC(); // Configure wakeup timer esp_sleep_enable_timer_wakeup(seconds * 1000UL * 1000UL); Serial.println("Entering deep sleep"); Serial.flush(); esp_deep_sleep_start(); } ``` -------------------------------- ### Split Integer for LoRaWAN Payload (C++) Source: https://github.com/radiolib-org/radiolib-persistence/blob/main/examples/LoRaWAN_ESP32/notes.md This C++ code demonstrates how to split a two-byte integer (typical for analog readings) into two separate bytes for transmission in a LoRaWAN payload. It utilizes Arduino's `highByte` and `lowByte` functions. The corresponding TTN console decoder will be responsible for reassembling these bytes into the original integer value. ```c++ // Example of splitting an analog reading (assuming 'analogValue' is an integer) byte payload[] = { // ... other data ... highByte(analogValue), lowByte(analogValue) // ... other data ... }; ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.