How to keep ESP32 from resetting on wakeup from deep_sleep
Posted: Mon Aug 29, 2022 1:14 pm
I am using ulp_start() in the code below to hold a PWM signal while the ESP32-WROOM-32UE is in deep sleep. However, when the program exits deep sleep via the timer, it resets the module. I need the program to stay in the loop and increment the PWM duty cycle at each iteration and NOT reset completely. Can you direct me on how to do this?
Code: Select all
#include <Arduino.h>
#include "esp32/ulp.h"
#include "driver/rtc_io.h"
//const int dutyMeter = 100; // (0-255)
//Time-to-Sleep
#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 1 /* Time ESP32 will go to sleep (in microseconds); multiplied by above conversion to achieve seconds*/
RTC_DATA_ATTR int bootCount = 0;
/*
Method to print the reason by which ESP32
has been awaken from sleep
*/
void print_wakeup_reason(){
esp_sleep_wakeup_cause_t 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 ulp_start(int dutyMeter) {
// Slow memory initialization
memset(RTC_SLOW_MEM, 0, 8192);
// if LED is connected to GPIO2 (specify by +14)
const gpio_num_t MeterPWMPin = GPIO_NUM_2;
const int MeterPWMBit = RTCIO_GPIO2_CHANNEL + 14;
// GPIOx initialization (set to output and initial value is 0)
rtc_gpio_init(MeterPWMPin);
rtc_gpio_set_direction(MeterPWMPin, RTC_GPIO_MODE_OUTPUT_ONLY);
rtc_gpio_set_level(MeterPWMPin, 0);
// Define ULP program
const ulp_insn_t ulp_prog[] = {
M_LABEL(1),
I_WR_REG(RTC_GPIO_OUT_REG, MeterPWMBit, MeterPWMBit, 1), // on
I_DELAY(dutyMeter * 100),
I_WR_REG(RTC_GPIO_OUT_REG, MeterPWMBit, MeterPWMBit, 0), // off
I_DELAY(25500 - dutyMeter * 100),
M_BX(1),
};
// Run ULP program
size_t size = sizeof(ulp_prog) / sizeof(ulp_insn_t);
ulp_process_macros_and_load(0, ulp_prog, &size);
ulp_run(0);
}
void setup() {
Serial.begin(115200);
delay(1000); //Take some time to open up the Serial Monitor
//Increment boot number and print it every reboot
++bootCount;
Serial.println("Boot number: " + String(bootCount));
//Print the wakeup reason for ESP32
print_wakeup_reason();
Serial.println("Setup");
//GPIO Outputs
pinMode(32, OUTPUT); //8
digitalWrite(32, LOW);
pinMode(33, OUTPUT); //9
digitalWrite(33, LOW);
pinMode(25, OUTPUT); //10
digitalWrite(25, LOW);
pinMode(26, OUTPUT); //11
digitalWrite(26, LOW);
pinMode(27, OUTPUT); //12
digitalWrite(27, LOW);
pinMode(14, OUTPUT); //13
digitalWrite(14, LOW);
pinMode(12, OUTPUT); //14
digitalWrite(12, LOW);
pinMode(13, OUTPUT); //16
digitalWrite(13, LOW);
pinMode(15, OUTPUT); //23
digitalWrite(15, LOW);
//pinMode(2, OUTPUT); //24
//digitalWrite(2, LOW);
pinMode(0, OUTPUT); //25
digitalWrite(0, LOW);
pinMode(4, OUTPUT); //26
digitalWrite(4, LOW);
pinMode(16, OUTPUT); //27
digitalWrite(16, LOW);
pinMode(17, OUTPUT); //28
digitalWrite(17, LOW);
pinMode(5, OUTPUT); //29
digitalWrite(5, LOW);
pinMode(18, OUTPUT); //30
digitalWrite(18, LOW);
pinMode(19, OUTPUT); //31
digitalWrite(19, LOW);
pinMode(21, OUTPUT); //33 //Switch Input
digitalWrite(21, LOW);
/*
pinMode(3, OUTPUT); //34 //RX
digitalWrite(3, LOW);
pinMode(1, OUTPUT); //35 //TX
digitalWrite(1, LOW);
*/
pinMode(22, OUTPUT); //36 //LinveVADC Input
digitalWrite(22, LOW);
pinMode(23, OUTPUT); //37
digitalWrite(23, LOW);
}
void loop() {
while(1){
int d=0;
int i=0;
for(i=0;i<255;i++){
d=d+10;
ulp_start(d);
Serial.println("Deep Sleep");
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); // time set with variable above
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
esp_deep_sleep_start();
Serial.println("I'm Awake");
}
}
}