When Deep Sleep Starts LED Turns Off

Hi all,

I am using the "Deep Sleep" function for the first time.

When I wake the ESP32 from a deep sleep it runs the correct function and turns on the LED, but for some reason when it goes back to sleep it turns the LED off!

Code:

/*LIBRARIES FOR LORA*/
#include <SPI.h>
#include <LoRa.h>

/*DEFINE THE PINS USED BY LORA TRANSCEIVER MODULE*/
#define SCK 5
#define MISO 19
#define MOSI 27
#define SS 18
#define RST 14
#define DIO0 26

/*SET THE CHANNEL AND FREQUENCY OF LORA TRANSCEIVER*/
#define BAND 915E6 //915MHz, E6 channel

/*INITIALIZE SOME PINS AND CREATE SOME VARIABLES*/
int buttonState; //this variable is used to store whether the button was pressed or not
const int ledPin = 2; //set the pin for the LED to pin 5
const int buttonPin = 33; //set the pin for the button to pin 33
bool mailStatus = false; //this variable is used to store whether there is mail in the letter box or not

void setup() {
  Serial.begin(115200); //start serial connection
  delay(1000); //Take some time to open up the Serial Monitor

  pinMode(buttonPin, INPUT); //buttonPin assigned as a input
  pinMode(ledPin, OUTPUT); //defines the ledPin as a output

  /*DEFINE SOME PINS FOR OLED AND LORA MODULE*/
  SPI.begin(SCK, MISO, MOSI, SS);  //SPI LoRa pins
  LoRa.setPins(SS, RST, DIO0);   //setup LoRa transceiver module
  LoRa.setSyncWord(0x45); //Set the "group" ID

  if (!LoRa.begin(BAND)) { //if LoRa does not begin 915E6
    Serial.println("Starting LoRa failed!");
    while (1); //freeze while the above if statement is true
  }

  /*SET THE LORA MODULES SPREADING FACTOR, SYNC WORD*/
  LoRa.setSpreadingFactor(12); //LoRa spreading factor can range from 7 to 12 (Minimize bandwidth and maximize spreading factor to boost link budget. Maximize coding rate to boost reliability)
}

void loop() {
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 1); //1 = High, 0 = Low

  buttonState = digitalRead(buttonPin); //read the current state of the button
  if (buttonState == HIGH) { //if the button is pressed
    if (mailStatus == false) { //and there is no mail in the letterbox
      MailDelivered(); //goto the function "Mail Delivered" which will send an alert that mail has been delivered
      mailStatus = true; //store that there is now mail in the letterbox
    }
  }

  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) { //if the button is pressed
    if (mailStatus == true) { //and there is mail in the letterbox
      MailCleared(); //goto the function "Mail Cleared" which will send an alert that mail has been cleared
      mailStatus = false; //store that there is now no mail in the letterbox
    }
  }
  Serial.println ("I have woken up!");

  Serial.print ("Going to sleep....");
  esp_deep_sleep_start();

}

void MailDelivered() {
  digitalWrite(ledPin, HIGH); // turn the LED on
  LoRa.beginPacket(); //begin the LoRa packet
  LoRa.print("Mail Delivered"); //include words "Mail Delivered" in the LoRa packet
  LoRa.endPacket(); //end and send the LoRa packet
  delay (200);
  Serial.println ("Mail Delivered");
}

void MailCleared() {
  digitalWrite(ledPin, LOW); // turn the LED off
  LoRa.beginPacket(); //begin the LoRa packet
  LoRa.print("Mail Cleared"); //include words "Mail Cleared" in the LoRa packet
  LoRa.endPacket(); //end and send the LoRa packet
  delay (200);
  Serial.println ("Mail Cleared");
}

Why might this be? Can you not have a LED turned on when it's in deep sleep?

Thanks,

Zeb

The ESP32 has 2 processors, one processor has 2 cores and the other processor, ULP, is used to run things in low power deep sleep modes.

Under the Arduino IDE, current version, the ULP processor is programmed as per https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/ulp_macros.html

Here is an example of blinking the onboard LED using the ULP

#include "sdkconfig.h"
#include "esp_system.h"
#include "esp32/ulp.h"
#include "driver/rtc_io.h"

void ULP_BLINK_RUN(uint32_t us);

setup()
{
// microseconds to delay between halt and wake states
  ULP_BLINK_RUN(1000000);
}



void ULP_BLINK_RUN(uint32_t us)
{
  size_t load_addr = 0;
  int rtcAddress2047 = 2047; // rtc address to store state R0
  RTC_SLOW_MEM[rtcAddress2047] = 0; // set initial state to address location
  ulp_set_wakeup_period(0, us);
  const ulp_insn_t  ulp_blink[] =
  {
    I_MOVI(R3, rtcAddress2047),             // #rtcAddress2047 -> R3
    I_LD(R0, R3, 0),                        // R0 = RTC_SLOW_MEM[R3(#rtcAddress2047)]
    M_BL(1, 1),                             // GOTO M_LABEL(1) IF R0 < 1
    I_WR_REG(RTC_GPIO_OUT_REG, 26, 27, 1),  // RTC_GPIO2 = 1
    I_SUBI(R0, R0, 1),                      // R0 = R0 - 1, R0 = 1, R0 = 0
    I_ST(R0, R3, 0),                        // RTC_SLOW_MEM[R3(#rtcAddress2047)] = R0
    M_BX(2),                                // GOTO M_LABEL(2)
    M_LABEL(1),                             // M_LABEL(1)
    I_WR_REG(RTC_GPIO_OUT_REG, 26, 27, 0),// RTC_GPIO2 = 0
    I_ADDI(R0, R0, 1),                    // R0 = R0 + 1, R0 = 0, R0 = 1
    I_ST(R0, R3, 0),                      // RTC_SLOW_MEM[R3(#rtcAddress2047)] = R0
    M_LABEL(2),                             // M_LABEL(2)
    I_HALT()                                // HALT COPROCESSOR
  };
  const gpio_num_t led_gpios[] =
  {
    GPIO_NUM_2,
    // GPIO_NUM_0,
    // GPIO_NUM_4
  };
  for (size_t i = 0; i < sizeof(led_gpios) / sizeof(led_gpios[0]); ++i) {
    rtc_gpio_init(led_gpios[i]);
    rtc_gpio_set_direction(led_gpios[i], RTC_GPIO_MODE_OUTPUT_ONLY);
    rtc_gpio_set_level(led_gpios[i], 0);
  }
  size_t size = sizeof(ulp_blink) / sizeof(ulp_insn_t);
  ulp_process_macros_and_load( load_addr, ulp_blink, &size);
  ulp_run( load_addr );
} // void ULP_BLINK_RUN(uint32_t us)

As you can see, from reading the API of the ESP32, the GPIO pins, tuning off under deep sleep, with the ESP32, is normal operation.

Excellent, thank you idahowalker!

Thanks again,

Zeb