Heltec WiFi LoRa32 (V3) Light sleep - multiple operations

Hello, I’m using Heltec WiFi LoRa32 (V3) boards (ESP32+SX1262).

I have this code that works for waking up from light-sleep mode by receiving any LoRa packet that is subsequently processed. However, I would need to be able to also take measurements and send the measurements at regular intervals. I have already tried something (commented in the code), however it does not work properly.

Could you please advise me how to make the measurements at regular intervals also work together with the above program for the LoRa repeater?

Thank you

#include <Arduino.h>
#include "LoRaWan_APP.h"

#include <Wire.h>
#include "HT_SSD1306Wire.h"
#include "Adafruit_SHT31.h"
#include <RTClib.h>

#include "esp_timer.h"
#include "esp_adc_cal.h"



String packet;
String lastChar;
String payload_string;
String topic;

String id_src;
String id_dst;


esp_sleep_wakeup_cause_t wakeup_reason;


static void oneshot_timer_callback(void* arg);
static void periodic_timer_callback(void* arg);

esp_timer_handle_t oneshot_timer;

volatile bool timerActive = false;



#define RF_FREQUENCY                                868000000 // Hz

#define TX_OUTPUT_POWER                             10        // dBm

#define LORA_BANDWIDTH                              0         // [0: 125 kHz,
                                                              //  1: 250 kHz,
                                                              //  2: 500 kHz,
                                                              //  3: Reserved]
#define LORA_SPREADING_FACTOR                       10         // [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 BUFFER_SIZE                                 100 // Define the payload size here

char txpacket[BUFFER_SIZE];
char rxpacket[BUFFER_SIZE];

static RadioEvents_t RadioEvents;
/** LoRa transmit success */
void OnTxDone(void);
/** LoRa receive success */
void OnRxDone(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr);
/** LoRa transmit timeout */
void OnTxTimeout(void);
/** LoRa receive timeout */
void OnRxTimeout(void);
int16_t txNumber;

int16_t rssi,rxSize;

bool lora_idle = true;



#define uS_TO_S_FACTOR 1000000

uint16_t originalTimeToSleep = 16;
uint16_t timeToSleep = originalTimeToSleep;


RTC_DATA_ATTR uint64_t rtc_counter1 = 0;
uint64_t rtc_offset = 0;


void VextON(void)
{
  pinMode(Vext,OUTPUT);
  digitalWrite(Vext, LOW);
}

void VextOFF(void) //Vext default OFF
{
  pinMode(Vext,OUTPUT);
  digitalWrite(Vext, HIGH);
}


void print_wakeup_reason(){
  

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason){
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}


void goToSleep(void)
{


   // Go back to bed
  Serial.println("Start sleeping");
  Serial.flush();

  pinMode(12, INPUT_PULLUP);

  esp_sleep_enable_ext0_wakeup(GPIO_NUM_14, RISING);
  // Finally set ESP32 into sleep

  //esp_sleep_enable_timer_wakeup(timeToSleep * uS_TO_S_FACTOR);

  digitalWrite(LED, LOW);
	esp_light_sleep_start();
}




void setup() {

  // Begin serial communication
  Serial.begin(115200);

  Mcu.begin();

  pinMode(LED,OUTPUT);

  print_wakeup_reason();
  //rtc_offset = time(NULL) - rtc_counter1;

  Wire.begin(SDA_OLED, SCL_OLED);
  Wire1.begin(19,20);


  RadioEvents.TxDone = OnTxDone;
  RadioEvents.RxDone = OnRxDone;
  RadioEvents.TxTimeout = OnTxTimeout;
  RadioEvents.RxTimeout = OnRxTimeout;

  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, 3000 );

  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 );


  pinMode(12, INPUT_PULLUP);

  esp_sleep_enable_ext0_wakeup(GPIO_NUM_14, RISING);

  //esp_sleep_enable_timer_wakeup(timeToSleep * uS_TO_S_FACTOR);


  Serial.println("into RX mode");
  Radio.Rx(0);

  Radio.IrqProcess( );

}
  
void loop() {
  
  if(lora_idle)
  {
    lora_idle = false;
    Serial.println("into RX mode");
    Radio.Rx(0);
  }
  Radio.IrqProcess( );
  
/*
  if(wakeup_reason == ESP_SLEEP_WAKEUP_TIMER)
  {
    //Serial.println("WAKEUP TIMER!");
    measure();

    Serial.flush();
    goToSleep();
  }*/

}


void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
{
    digitalWrite(LED, HIGH);
    Serial.println ("RECEIVED!");

    rssi=rssi;
    rxSize=size;
    memcpy(rxpacket, payload, size );
    rxpacket[size]='\0';
    //Radio.Sleep( );
    Serial.printf("\r\nreceived packet \"%s\" with rssi %d , length %d\r\n",rxpacket,rssi,rxSize);

    lora_idle = true;

    if(lora_idle == true)
      {   
        Serial.printf("\r\nsending packet \"%s\" , length %d\r\n",rxpacket, strlen(rxpacket));

        Radio.Send( (uint8_t *)rxpacket, strlen(rxpacket) ); //send the package out	
        lora_idle = false;
      }
      Radio.IrqProcess( );
    

    goToSleep();


}

void OnRxTimeout(void)
{
	Serial.println("Receive timeout");
	// LoRa RX failed, go back to bed
}


void OnTxDone( void )
{
  Serial.print("TX done......");
  lora_idle = true;
}

void OnTxTimeout( void )
{
    Radio.Sleep( );
    Serial.print("TX Timeout......");
}

Timer or RTC interrupt can wake up mild sleep. After switching to light sleep, try reinitializing it. This may be helpful for your friend

Yes, I have tried waking from light sleep by RTC timer.
But the question is how to deal with part of code executed after wake.

I tried to check if the ESP was waked by RTC timer in the loop() function like:

void loop() {

  if(wakeup_reason == ESP_SLEEP_WAKEUP_TIMER)
  {
    Serial.println("WAKEUP TIMER!");
    measure();

    Serial.flush();
    goToSleep();
  }
  
  if(lora_idle)
  {
    lora_idle = false;
    Serial.println("into RX mode");
    Radio.Rx(0);
  }
  Radio.IrqProcess( );
  
}

But this doesn’t work properly - the ESP doesn’t wake when it should, when in the code there is simultally the WAKEUP_EXT0 by LoRa chip (GPIO 14).