ESP32 SparkFun Thing Plus Deep Sleep and External Interrupts problem

fe7565
Posts: 3
Joined: Sun Jul 15, 2018 5:52 am

ESP32 SparkFun Thing Plus Deep Sleep and External Interrupts problem

Postby fe7565 » Tue Nov 19, 2019 7:57 am

Would like to ask for assistance. Tried several routes. My knowledge is lacking and unable to progress further. I think I am very close to the solution (maybe couple of lines of codes away), but the answer seems to lie in the memory state of the ESP32 after coming back from “deep sleep”. The code is not that difficult so you may want to skip to “the problem” section below to spare you the details. Thank you!!!

The Arduino program is a marriage of two separate Arduino programs, both work. One program is deep sleep with ext0 (and/or ext1) wake interrupt on which I got off the web. The other program measures the time difference between two separate LOW or FALLING signals on Pin 12 and 27 of the ESP32 SparkFun Thing Plus. The signals come on both pins and drop fast (about 20-40ns) and are about 200-800 micro-seconds apart in duration. They always come in pairs and randomly seconds or minutes apart.

How it supposed to work: The first LOW/FALLING signal is always on pin 12 and the second LOW/FALLING always on pin 27. A single LOW/FALLING signal on pin12 wakes up the ESp32 from deep sleep using the ext0 wake up event and an attach interrupt with ISR. The ISR runs a micros() routine that takes a snapshot of the “time1” when the interrupt happened. It stores that value. Next the second LOW/FALLING signal happens on pin27 within about 200-800 micro-seconds from the first one on pin12. It does another ISR routine and takes a snapshot of the “time2” of the second signal (on pin27). A routine subtracts “time2” – “time1” to arrive to the final value. Once that is done, the ESp32 goes back to sleep.

The problem: Both separate programs work. This combined program works but only for every second set of readings. There is some sort of a deep sleep-wake-up issue which I think is that either not all input pins are usable for a period of time after wake-up from deep sleep. Even if I am using the ext0 which keeps some of the peripherals (pin12 and pin27 included) active during sleep. Or maybe there is a problem with keeping the measured time value(s) in memory after sleep. When I send a LOW signal to pin 12 , I get a wake-up triggered by pin12 via ext0 and the SR records the” time1” timestamp. But then it hangs there as the second incoming signal on pin27 does nothing with or without ext1 and using attachinterrupt with ISR.

After the first pair of external signals with the ESP32 fully wake but hanging on pin27, I run again the pair of LOW signals to pin12 and pin 27 (200-600 micro-seconds apart from each other). At this time both ISRs work and I get a correct final value of “ time2-time1”, AND the Esp32 also goes back to deep sleep. If I repeat the process, the same thing happens with pin12 waking up the ESp32 but pin27 just hangs there until I run the second set of signals again a few seconds later.

What I tried: I used ext0 for pin12 wake up with attachinterrupt. Since ext0 uses the RTC Peripherals, I do not think I need to use a pin definition from RTC Preph to GPOI Digital designation ( esp_err_t rtc_gpio_deinit(GPIO_NUM_12). For the second interrupt singal on pin 27, I cannot use ext0 anymore, so I used ext1. This does not have any power during deep sleep and when it wakes up it has to have its RTC Peripherials statyus changed to GPIO status using esp_err_t rtc_gpio_deinit(GPIO_NUM_27); and then attacheinterrupt to it.

I suspect that somehow the second signal on pin27 does not register after deep sleep. I tried to use these commands in various combinations on pin 12 and pin27and the ISRs to save the data during/after deep sleep, but no avail:

RTC_DATA_ATTR ; IRAM_ATTR ; dettachinterrupt, esp_err_t rtc_gpio_deinit(GPIO_NUM_27);

If I had two ext0 wakeup pin options, I think I would not run into this problem. Or if ext1 could be woken up fast enough (less than 200 micro-seconds) so its usable as an interrupt, it would also work. Ultimately, I may need to use the ULP coprocessor to run the time measurement while the ESP32 deep sleeps. The goal is to be able to run this setup on deep sleep instead of using 80-100 mAh.

/*
Deep Sleep with External Wake Up
=====================================
This code displays how to use deep sleep with
an external trigger as a wake up source and how
to store data in RTC memory to use it over reboots

This code is under Public Domain License.

Hardware Connections
======================
NOT USED: Push Button to GPIO 33 pulled down with a 10K Ohm
resistor

NOTE:
======
Only RTC IO can be used as a source for external wake
source. They are pins: 0,2,4,12-15,25-27,32-39.

Modified code... Original deep sleep code by Author:
Pranav Cherukupalli <cherukupallip@gmail.com>
*/

#include <Arduino.h>
#include <FunctionalInterrupt.h>
#include "esp_deep_sleep.h"
#include <driver/gpio.h>
#include <DeepSleepScheduler.h>


//#define BUTTON_PIN_BITMASK 0x1000 // 2^12 in hex

unsigned long time1=0;
unsigned long time2=0;


RTC_DATA_ATTR int bootCount = 0;

volatile boolean Flag = false; //trigger 1 happened
/////////////////////////////////////////////////////////////////////////////////////////////////////
/*
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;
}
}
/////////////// END OF WAKE UP REASON//////////////////////////////////////////////////////////

void isr(){
time1 = micros();
Flag = true;
Serial.print("Time1 ");Serial.println(time1);
} //////////////////// end of ISR routine pin12 //////////////////////////////

void isr2(){
time2= micros();
if (Flag == true) {
Serial.print("Time2 ");Serial.println(time2);
Serial.print("Time2-Time1 ");Serial.println(time2-time1);
Flag = false;
time1=0;
time2=0;

//Go to sleep now routine ////////////////////////////////////////////////////
Serial.println("Going to sleep now in 10 m-sec");
delay(1);
esp_deep_sleep_start();
Serial.println("This will never be printed");

}
} /////////////////// end of ISR2 routine pin27 including CONDITIONAL DEEP SLEEP ROUTINE//////////////////////


void setup(){
pinMode(12, INPUT_PULLUP);
pinMode(27, INPUT_PULLUP);
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();

/*
First we configure the wake up source
We set our ESP32 to wake up for an external trigger.
There are two types for ESP32, ext0 and ext1 .
ext0 uses RTC_IO to wakeup thus requires RTC peripherals
to be on while ext1 uses RTC Controller so doesnt need
peripherals to be powered on.
Note that using internal pullups/pulldowns also requires
RTC peripherals to be turned on.
*/
esp_sleep_enable_ext0_wakeup(GPIO_NUM_12,0); //1 = High, 0 = Low/ no hardware pull up/down. Feeding ext. HIGH to LOW signal

isr(); // duplicated in attachinterrupt below...?

attachInterrupt(digitalPinToInterrupt(12), isr, FALLING); //rearm interrupt1


esp_sleep_enable_ext1_wakeup(GPIO_SEL_27, ESP_EXT1_WAKEUP_ALL_LOW); // no hardware connections or pull op/down, feeding
//Feeding ext. HIGH to LOW signal
attachInterrupt(digitalPinToInterrupt(27), isr2, FALLING); //rearm interrupt2


} /////////////////////////////// END OF SETUP and TWO EXT INTERRUPTS ////////////////////////////////

void loop(){
//This is not going to be called
}

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: ESP32 SparkFun Thing Plus Deep Sleep and External Interrupts problem

Postby WiFive » Thu Nov 21, 2019 6:42 am

You need to use ulp or wake stub, booting the app takes a long time.

Who is online

Users browsing this forum: No registered users and 299 guests