WiFi LoRa 32 Deep Sleep, LoRa radio leaves continuous recieve mode (assuming)

I’ve gone a day and a half at this one so far. I managed to make things work with light sleep, but not deep sleep. What i am trying to do is to put the ESP32 into deep sleep mode and have it wake on GPIO26 (LoRa rx,tx complete). First i’ll share the code that is working (with light sleep):

#include "Arduino.h"
#include "heltec.h" 

#define BAND    915E6  //you can set band here directly,e.g. 868E6,915E6
String packSize = "--";
String packet;

void cbk(int packetSize) {
  packet = "";
  
  packSize = String(packetSize,DEC);
  
  for (int i = 0; i < packetSize; i++) { 
    packet += (char) LoRa.read(); 
    }
  
    Serial.println(packet);
}


void setup() { 
  Heltec.begin(false /*DisplayEnable Enable*/, true /*Heltec.Heltec.Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/);
  LoRa.receive();
  delay(10);
  gpio_wakeup_enable(GPIO_NUM_26, GPIO_INTR_HIGH_LEVEL);
  esp_sleep_enable_gpio_wakeup();
}

void loop() {
  
  esp_light_sleep_start();
  Serial.println("Incoming Message");

  int packetSize = LoRa.parsePacket();
  if (packetSize) { 
    cbk(packetSize);
  }
  
  

  LoRa.receive(); // Evidently the LoRa radio has to be put back into continuous recieve mode \
                     after waking up the ESP32 from sleep, otherwise it will not raise DIO0 to \
                     which indicates RX is done (new message has arived).
}


And here is my attempt (failed) with deep sleep:

#include "Arduino.h"
#include "heltec.h" 

#define BAND    915E6  //you can set band here directly,e.g. 868E6,915E6
String packSize = "--";
String packet;

void cbk(int packetSize) {
  packet ="";
  
  packSize = String(packetSize,DEC);
  
  for (int i = 0; i < packetSize; i++) { 
    packet += (char) LoRa.read(); 
    }
  
  Serial.println(packet);
}

void setup() { 
  Heltec.begin(false /*DisplayEnable Enable*/, true /*Heltec.Heltec.Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/);
  LoRa.receive();
  
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_26, 1);
  delay(10);

  int packetSize = LoRa.parsePacket();
  if (packetSize) { 
    cbk(packetSize);
    Serial.println("Message Processed");
  }

  Serial.println("Starting deep sleep");
  //rtc_gpio_hold_en(GPIO_NUM_26);
  
  esp_deep_sleep_start();
}



void loop() {
}

The LoRa radio is not sending DIO0 high to indicate a new message is “in”, i am assuming it is leaving continuous receive mode but not sure how to keep this from happening.

Print it to see if it wakes up.

I’m not sure what exactly you mean by “print it” If you mean apply 3.3v to DIO0 and see if the ESP32 wakes up, then yes it does.

Esp32 deep sleep wake-up is a reset wake-up. After wake-up, when you re initialize Lora, it may clear the data.

I understand that may be the next issue, but I’m not getting that far. The problem is that the LoRa transceiver is not signaling that it has a new message (raising DIO0 which is connected to GPIO 26 on the ESP32) after the ESP32 is put into deep sleep. The LoRa transceiver is always powered on so I’m assuming when esp_deep_sleep_start() is called, something in that function is calling LoRa.sleep() but I cannot find in the ESP32 library(?) where this is happening.

I hooked up a logic analyzer to the SPI bus and am trying to analyze it and make certain that is what is happening. I have a bit to learn about SPI before I can make sense of what I’m seeing but hopefully before long I’ll figure it out.

Or you can use the oscilloscope to capture DIO and see if there is any level change. This scheme is simpler than looking at SPI directly.

I have already verified that DIO0 is not changing with a high speed meter and the logic analyzer. I’m learning quite a bit about the LoRa chip as far as its registers, but so far no smoking gun… I can say for sure that it is not being put into sleep/standby mode be the ESP32 like i had assumed it was.

I’ve verified that there is no change on the SPI bus between light & deep sleep modes. The only thing that has come to light is that for some reason when i started looking at pin 14 (to pin 7 on LoRa NRESET) something strange happened. I hooked my logic analyzer to it then all the sudden everything that wasn’t working started working (DIO0 was going high while the ESP32 was in deep sleep mode). So i though this must be some kind of pull up/down issue here that shows when the uC goes to sleep, but after going down that path, that does not appear to be the issue. Trying to pull it up/down has no effect, the only thing that seems to have the effect is having a decently long wire hooked to the pin just floating in air, or a short wire that i am grabbing the end of with my hand. Someone please enlighten me on this one.

Have you tried an external pull-up?

I did find that pinMode(14, INPUT_PULLUP) did the trick. Now it will sleep for however long until a message is received and wake up. Now i just have to figure out how to not re-init LoRa to keep from clearing the message out upon wakeup. I’ve tried a few different ways but each having their own problems, but that is another story. It looks like for now the initial problem has been solved, unfortunately the power consumption is higher than i was hoping for (~11mA with ESP32 in deep sleep and LoRa in rxcontinuous).

#include "Arduino.h"
#include "heltec.h"

#define BAND    915E6  //you can set band here directly,e.g. 868E6,915E6
String packSize = "--";
String packet;

void cbk(int packetSize) {
  packet = "";
  
  packSize = String(packetSize,DEC);
  
  for (int i = 0; i < packetSize; i++) { 
    packet += (char) LoRa.read(); 
    }
  
    Serial.println("");
    Serial.println("Packet: " + String(packet));
    Serial.println("");
}

void setup() { 
  
  Heltec.begin(false /*DisplayEnable Enable*/, true /*Heltec.Heltec.Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/);

  int packetSize = LoRa.parsePacket();
  if (packetSize) { 
    cbk(packetSize);
  }

  pinMode(14, INPUT_PULLUP);
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_26, HIGH);
  LoRa.receive();
  esp_deep_sleep_start();
}

void loop() {
}

If lora is always in the receiving state, then the power consumption increase is inevitable.

Hello, jds8086, I thank you for your post, it was very useful for me.
I have two modules WiFiLoRa 32(v3) and I succeeded in awakening a module in deep sleep by means of a LORA reception, the same you did. I used GPIO 14, that is connected to the DIO of the LORA chip SX1262 used in WiFiLoRa 32(v3).
Now my problem is “how to not re-init LoRa to keep from clearing the message out upon wakeup”, as I read in your post. Is it possible ? do you succeeded in reading the payload of the LORA message that caused the wakup ? I’m working at this problem, but without success for now, I will be grateful to anyone who can me an advice

I’m glad what i did sort out was useful for someone :slight_smile:

Unfortunately I haven’t visited this project in several months and i cannot recall if I did work this out. When i have time i’ll do a little digging and see where i ended up (if anywhere).

Thanks in advance …

1 Like

Unfortunately I did not resolve this issue. I’m peeking back into it but I’m not feeling optimistic. I’ll update if I do get it going. Let me know if you figure something out.

Well surprisingly it appears that i did manage to get it to work (how reliable or “correct” it is i don’t know). I did have to hack up the Heltec library just a tad to make it work. Once i figured out how to tell if the mcu was just powered up, or if it was waking up from deep sleep, it was a matter of combing through the LoRa initialization and figuring out what to toss and what to keep after waking.

Apologies for the way the code is pasting in here, not sure what is causing that (haven’t looked into it).

main

#include "Arduino.h"
#include "heltec.h"
#include "rom/rtc.h"
#define BAND    915E6  //you can set band here directly,e.g. 868E6,915E6
String packSize = "--";
String packet;

void cbk(int packetSize) {
  packet = "";
  packSize = String(packetSize,DEC);

 

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

    packet += (char) LoRa.read();

    }

 

    Serial.println("");

    Serial.println("Packet: " + String(packet));

    Serial.println("");

}

void setup() {

   

  if(rtc_get_reset_reason(0) == DEEPSLEEP_RESET){

    Heltec.begin(false /*DisplayEnable Enable*/, true /*Heltec.Heltec.Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/, 1 /*Wake*/);

    Serial.println("Woke From Deep Sleep");

  }

  else{

    Heltec.begin(false /*DisplayEnable Enable*/, true /*Heltec.Heltec.Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/, 0 /*Wake*/);

  }

  int packetSize = LoRa.parsePacket();

  if (packetSize) {

    cbk(packetSize);

  }

  else{

    Serial.println("****NO DATA****");

  }

  pinMode(14, INPUT_PULLUP);

  esp_sleep_enable_ext0_wakeup(GPIO_NUM_26, HIGH);

  LoRa.receive();

  esp_deep_sleep_start();

}

void loop() {

}

The rest of this i’ll just paste in sections that i modified

heltec.h

class Heltec_ESP32 {

 public:

    Heltec_ESP32();

    ~Heltec_ESP32();

    void begin(bool DisplayEnable=true, bool LoRaEnable=true, bool SerialEnable=true, bool PABOOST=true, long BAND=470E6, bool WAKE=false);

heltec.cpp

Heltec_ESP32::~Heltec_ESP32(){

#if defined( WIFI_Kit_32 ) || defined( WIFI_LoRa_32 ) || defined( WIFI_LoRa_32_V2 ) || defined( Wireless_Stick )

    delete display;

#endif

}

void Heltec_ESP32::begin(bool DisplayEnable, bool LoRaEnable, bool SerialEnable, bool PABOOST, long BAND, bool WAKE) {

LoRa.h

class LoRaClass : public Stream {

public:

  LoRaClass();

  int begin(long frequency,bool PABOOST, bool WAKE);

  void end();

LoRa.cpp

int LoRaClass::begin(long frequency,bool PABOOST, bool WAKE)

{

  // setup pins

  pinMode(_ss, OUTPUT);

  pinMode(_dio0, INPUT);

  // perform reset (if not waking from deep sleep)

  if(!WAKE) {

    pinMode(_reset, OUTPUT);

    digitalWrite(_reset, LOW);

    delay(20);

    digitalWrite(_reset, HIGH);

    delay(50);

  }

  // set SS high

  digitalWrite(_ss, HIGH);

  // start SPI

  SPI.begin();

  // check version

  uint8_t version = readRegister(REG_VERSION);

  if (version != 0x12) {

    return 0;

  }

  if(!WAKE) {               // none of the following is needed after waking from deep sleep (radio is already initialized)

    // put in sleep mode

    sleep();

    // set frequency

    setFrequency(frequency);

    // set base addresses

    writeRegister(REG_FIFO_TX_BASE_ADDR, 0);

    writeRegister(REG_FIFO_RX_BASE_ADDR, 0);

    // set LNA boost

    writeRegister(REG_LNA, readRegister(REG_LNA) | 0x03);

    // set auto AGC

    writeRegister(REG_MODEM_CONFIG_3, 0x04);

    // set output power to 14 dBm

    if(PABOOST == true)

      setTxPower(14, RF_PACONFIG_PASELECT_PABOOST);

    else

      setTxPower(14, RF_PACONFIG_PASELECT_RFO);

    setSpreadingFactor(11);

    // put in standby mode

    setSignalBandwidth(125E3);

    //setCodingRate4(5);

    setSyncWord(0x34);

    disableCrc();

    crc();

    idle();

  }

  return 1;

}

many, many thanks for having the trouble to digging into your old code and posting into the forum !
I will study this code and will try to export it into the new Heltec library 0.0.7.
I will let you know about it …

1 Like

Thank you for prompting me to look back into this. I remember giving up on making it work, and to re-visit it later and get it figured out was very enjoyable.

Here is a working example that does not require altering the library.

#define BAND    915E6  //you can set band here directly,e.g. 868E6,915E6
String packSize = "--";
String packet;

void cbk(int packetSize) {
  packet = "";
  
  packSize = String(packetSize,DEC);
  
  for (int i = 0; i < packetSize; i++) { 
    packet += (char) LoRa.read(); 
    }
  
    Serial.println("");
    Serial.println("Packet: " + String(packet));
    Serial.println("");
}

void setup() {
  
  

  if(rtc_get_reset_reason(0) == DEEPSLEEP_RESET){
    Heltec.begin(false /*DisplayEnable Enable*/, false /*Heltec.Heltec.Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/, 1 /*Wake*/);
    Serial.println("Woke From Deep Sleep");
    pinMode(LORA_DEFAULT_SS_PIN , OUTPUT);
    pinMode(LORA_DEFAULT_DIO0_PIN, INPUT);
    digitalWrite(LORA_DEFAULT_SS_PIN, HIGH);
    SPI.begin();
    uint8_t version = LoRa.readRegister(0x42);
    if (version != 0x12) {
      Serial.println("Failed to re-connect to LoRa device"); 
    }
  }
  else{
    Heltec.begin(false /*DisplayEnable Enable*/, true /*Heltec.Heltec.Heltec.LoRa Disable*/, true /*Serial Enable*/, true /*PABOOST Enable*/, BAND /*long BAND*/, 0 /*Wake*/);
  }

  int packetSize = LoRa.parsePacket();
  if (packetSize) { 
    cbk(packetSize);
  }
  else{
    Serial.println("****NO DATA****");
  }

  pinMode(14, INPUT_PULLUP);
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_26, HIGH);
  LoRa.receive();
  esp_deep_sleep_start();
}

void loop() {
}