LoRaWAN + Deep Sleep , need help

I’m working with my Wireless Stick V3 board, using a simple code to send data via LoRaWAN to ChirpStack. My power source is a 3.7V lithium battery.

I need help integrating deep sleep into my ESP32 code to maximize my battery life. I’ve tried several times, but I always encounter issues when incorporating deep sleep, as it interrupts the LoRaWAN flow. As you can see in my code, it’s simple, and I’m sending data from a vector via LoRaWAN. I’d like the ESP32 to go into deep sleep after sending the data and wake up after a certain period.

I want you to help me by giving ideas on how I can implement deep sleep in my code.

I’m attaching my code:

#include “LoRaWan_APP.h”

#include <Arduino.h>

/* — Configuración LoRaWAN — */

extern uint8_t appData[];

extern uint8_t appDataSize;

/* OTAA */

uint8_t devEui[] = { 0xF0, 0x4A, 0x74, 0xC4, 0x05, 0x20, 0xB7, 0x5F };

uint8_t appEui[] = { 0x36, 0x8F, 0x85, 0x13, 0x16, 0xAF, 0xCA, 0xB9 };

uint8_t appKey[] = { 0x0E, 0xF1, 0x9F, 0x70, 0x02, 0xF8, 0xAB, 0xCA, 0x42, 0x48, 0xC4, 0x5E, 0x87, 0x4A, 0x76, 0x16 };

/* ABP (no se usa si OTAA = true) */

uint8_t nwkSKey[] = { 0x15, 0xB1, 0xD0, 0xEF, 0xA4, 0x63, 0xDF, 0xBE, 0x3D, 0x11, 0x18, 0x1E, 0x1E, 0xC7, 0xDA, 0x85 };

uint8_t appSKey[] = { 0xD7, 0x2C, 0x78, 0x75, 0x8C, 0xDC, 0xCA, 0xBF, 0x55, 0xEE, 0x4A, 0x77, 0x8D, 0x16, 0xEF, 0x67 };

uint32_t devAddr = (uint32_t)0x007E6AE1;

/* Máscara de canales y región */

uint16_t userChannelsMask[6] = { 0xFF00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };

LoRaMacRegion_t loraWanRegion = ACTIVE_REGION;

DeviceClass_t loraWanClass = CLASS_A;

/* Config LoraWAN */

bool overTheAirActivation = true;

bool loraWanAdr = true;

bool isTxConfirmed = false;

uint8_t appPort = 2;

uint8_t confirmedNbTrials = 4;

/* Intervalo de transmisión (2 minutos) */

uint32_t appTxDutyCycle = 10000; // 2 minutos en ms

/* Prepara el payload de la trama */

static void prepareTxFrame(uint8_t port)

{

// Valores estáticos de sensores (int16_t)

int16_t sensorValues[9] = { 1234, 5678, 9101, 1121, 3141, 5161, 7181, 9202, 2232 };

// Preparar el payload

appDataSize = 18; // 9 valores * 2 bytes cada uno

for (int i = 0; i < 9; i++) {

appData[i * 2] = (sensorValues[i] >> 8) & 0xFF; // Byte alto

appData[i * 2 + 1] = sensorValues[i] & 0xFF;    // Byte bajo

}

}

void setup()

{

Serial.begin(9600);

Mcu.begin(HELTEC_BOARD, SLOW_CLK_TPYE);

}

void loop()

{

switch (deviceState)

{

case DEVICE_STATE_INIT:

{

#if (LORAWAN_DEVEUI_AUTO)

  LoRaWAN.generateDeveuiByChipID();

#endif

  LoRaWAN.init(loraWanClass, loraWanRegion);

  // Establecer Data Rate

  LoRaWAN.setDefaultDR(3);

  break;

}

case DEVICE_STATE_JOIN:

{

  Serial.println("Uniéndose a la red...");

  LoRaWAN.join();

  break;

}

case DEVICE_STATE_SEND:

{

  Serial.println("Enviando datos...");

  prepareTxFrame(appPort);

  LoRaWAN.send();

  Serial.println("Datos enviados.");

 

  deviceState = DEVICE_STATE_CYCLE;

  break;

}

case DEVICE_STATE_CYCLE:

{

  // Programar la siguiente transmisión

  txDutyCycleTime = appTxDutyCycle + randr(-APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND);

  LoRaWAN.cycle(txDutyCycleTime);

   

  deviceState = DEVICE_STATE_SLEEP;

  break;

}

case DEVICE_STATE_SLEEP:

{

   

  LoRaWAN.sleep(loraWanClass);

 

  break;

}

default:

{

  deviceState = DEVICE_STATE_INIT;

  break;

}

}

}

DEEP SLEEP EXAMPLE WITH LEDS :

/////////////////////////////////////////////////////////////////

// ESP32 Deep Sleep Example 1 v1.00 //

// Get the latest version of the code here: //

// http://educ8s.tv/esp32-deep-sleep-tutorial //

/////////////////////////////////////////////////////////////////

#define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */

#define TIME_TO_SLEEP 3 /* Time ESP32 will go to sleep (in seconds) */

RTC_DATA_ATTR int bootCount = 0;

int GREEN_LED_PIN = 45;

int YELLOW_LED_PIN = 46;

void setup(){

pinMode(GREEN_LED_PIN,OUTPUT);

pinMode(YELLOW_LED_PIN,OUTPUT);

delay(500);

if(bootCount == 0) //Run this only the first time

{

  digitalWrite(YELLOW_LED_PIN,HIGH);

  bootCount = bootCount+1;

}else

{

  digitalWrite(GREEN_LED_PIN,HIGH);

}

delay(3000);

digitalWrite(GREEN_LED_PIN,LOW);

digitalWrite(YELLOW_LED_PIN,LOW);

esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);

esp_deep_sleep_start();

}

void loop(){

}

You might want to look at Radiolib for ideas. One of their LoraWan samples includes a sleep.

I used Radiolib for a Lora only (not LoraWan) and found it easier to use.

1 Like

Joining on OTAA creates a session that needs to be saved for the next time - otherwise you’ll have to join each time & then send, which will kill the battery almost as fast as putting it in to one of the lesser sleep modes.

So either use ABP that is session-less and read about Frame Counters which you can either have ignored on the LNS or you can save the Fcnt before sleeping in the RTC RAM and then set it when you wake up.

Or, as @dstacer says, use a far more up to date stack linked above that the author & tester of that component of RadioLib are on this forum.

However, as per your PM, you’ve a tough learning curve ahead because LoRaWAN is like Shrek (& onions), they have many layers. As a minimum, DO NOT try to implement your stuff until you have the basic LW code running & sleeping successfully.

A 2 minute send interval is pretty close to the limit - a breach of the FUP on TTN and for certain spreading factors illegal. Sending on 10 second intervals is just illegal and very hard for LW to keep up given that it takes at least 7 seconds to do a Send/Receive. And all you do is flood your brain with “results” that you can’t read fast enough or know enough to interpret. Just have a press to send to wake the device, do the send and go back to sleep.

Most important, get the basic example working, THEN add your own code.

1 Like

Thank you very much for your time.
I’m going to try it.