Deep sleep act as restart on ESP32, how sleep and continue the sketch?

Hi

I tested this code on my ESP32 Liligo TTGO LoRa32 OLED:

esp_sleep_enable_timer_wakeup(10 * 1000000); // Set wake-up time to 10 seconds
esp_deep_sleep_start(); // Enter deep sleep mode

What happened was that after this 10 sec the esp restarted and did run code from top, it did not continue the void() loop()

Q:
Is there a a way to make it sleep but continue where it stopped?

Use light sleep ?

The Espressif guide suggests that CPU and RAM is not preserved during deep sleep.

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/sleep_modes.html

1 Like

depending on how precise you want to continue after waking up from a deepsleep you could use variables that are stored in RTC-RAM to branch to a certain function in your code.

Variables in RTC-RAM keep their value through a deepsleep.
so as a pseudo-code
you would check in in loop() with a switch-case-break-statement

switch (modeBeforeDeepSleep) {
  case mode1:
   // execute certain code

  case mode2:
   // execute certain code

if you describe in detail what your code is doing and give an overview about your project and especially at which points you go into deepsleep with listing up or giving a very precise description at which lines of code you go into deep-sleep
much better suggestions can be made to achieve this

best regards Stefan

1 Like

Hi, thanks for helping me

I don't have a code for ESP per today, the prototype (today) is built on an ESP8266.
In a week or 4 I will have a ESP32 WROOM U32 protype running.

Maine code 8266 added, functions not included.
In bottom of code is where I imagine the sleep/deep sleep starts

// system reads a scale, 2 temperatures, and 1 humidity
// ESP8266-compile NodeMCU

int LoRaIntervall = 10;          // Tid mellom hver LoRa pakke i sekund

#include <SPI.h>
#include <Wire.h>               // for å lese I2C, muligens for LoRa
#include <math.h>
#include <EEPROM.h>             // store cal factor + hive no
#include <algorithm>            // Allows sort function
#include <LoRa.h>
#include "HX711.h"              // This library can be obtained here http://librarymanager/All#Avia_HX711 https://github.com/bogde/HX711
#include <DHT.h>                // DHT11  aidafruit
//#include <DHT_U.h>            // DHT11  aidafruit  latil denne selv
#include <ESP8266WiFi.h>        // for å slå av wifi
#include <OneWire.h>            //DS18B20
#include <DallasTemperature.h>  //DS18B20

#define ONE_WIRE_BUS D9                //   pin D2 er fra eksempel DS18B20. I2C eller serial, hva er riktig pin? DS18B20 Define to which pin of the Arduino the 1-Wire bus is connected:
OneWire oneWire(ONE_WIRE_BUS);         //Create a new instance of the oneWire class to communicate with any OneWire device:
DallasTemperature sensors(&oneWire);   // Pass the oneWire reference to DallasTemperature library:

int piezoPin = 8;

#define DHTPIN D2                   // Digital pin connected to the DHT sensor Pin 15 can work but DHT must be disconnected during program upload.
#define DHTTYPE DHT11               // DHT 11
#define LB2KG  0.45352              // omregningsfaktor
#define CALWEIGHT 25.3              // kjent vekt i kg
#define DEFAULT_CALIFACTOR -9000    // tilfeldig valgt, min vekt single load ca -15000, liten 4celle ca -9000
#define EEPROM_SIZE 12
#define number_of_digits 3          // Desimaler for vektavlesing

DHT dht(DHTPIN, DHTTYPE);

//Measuring runtime for when if mills kick in, this to delay sending of packets
unsigned long previousTime = 0;
// Define timeout time in milliseconds (example: 2000ms = 2s)
const long timeoutTime = 2000;  //slett?

// Function calls
// float medianFilter(float input)   // bør denne også med i calls?
void sendReadings();
void functionTare();
void functionAlarm();
void functionCalibrate();
void functionBoot();
void sort();                  // med sort i median så kan nok denne slettes
void readMem();
void buttonWait();

// hx711 pins:
#define LOADCELL_DOUT_PIN D3
#define LOADCELL_SCK_PIN D4

HX711 scale;
float currentOffset;
float calibration_factor;

//define the pins used by the LoRa transceiver module
#define SCK 14    //D5
#define MISO 12   //D6
#define MOSI 13   //D7
#define SS 15     //D8
#define RST 16    //RST
#define DIO0 D0   //D0 

//433E6 for Asia, 866E6 for Europe,915E6 for North America // 868 ref https://www.lastmile.no/teknologi/teknologibeskrivelser/lora
#define BAND 433E6

int packetID = 0; //packet counter, reset after boot

//Variables to store temperature, humidity, weight and tare switch status, hive name
float temperatureHive = 0;
float temperatureOut = 0;
float humidity = 0;
float weight = 0;
float tareValue = 0;
float alarmValue = 0;           // Nullstilles kun ved å boot senderen
float hiveNr = 1;               // Kube nr UNIK verdi

// Define Switches
const int buttonPressTime = 5000;     // wait time in milliseconds
const int alarmPressTime  = 5000;

unsigned long tareStartTime = 0;  // variable to store the start time
const int tareThreshold = 512;  // analogue value threshold

const int switchTare            = A0;    //   ALARM SWITCH select the input pin for the switch
int previousState = LOW;
unsigned long debounceTime = 50; // debounce time in milliseconds
unsigned long lastDebounceTime = 0;

int switchTareValue       = 0;     // A0 variable to store the value coming from the sensor
int switchCalibrate       = D1;
/*int switchBoot            = 1;    //
  int switchBootValue       = 2;
  int switchAlarm           = 3;    // select the input pin for the switch
*/

//Median filtering of weight
float window[5];             // array to hold the sorted values in the window
int indeks = 0;              // indeks of the current value
int medianCount = 0;
float weight_median = 0;

void setup() {
  Serial.begin(57600); delay(500);
  Serial.println();
  Serial.println(" starter...");
  tone(piezoPin, 2000, 500);
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  scale.set_scale();  delay(500);
  EEPROM.begin(512);
  //EEPROM.write(0x00, 0xFF);         // REKALIBRERING ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤  sett til 0xff for å restarte kalibrering
  sensors.begin();  //DS18B20

  Serial.println();
  Serial.println("Kalibrering eller ikke?");
  Serial.print("Minne 0x00 Om = 1 så er den kalibrert  :  ");
  Serial.println(EEPROM.read(0x00));
  Serial.printf("Verdi fra minne 0x01 currentOffset     : %0.2f", EEPROM.get(0x01, currentOffset ));      //Serial print lagret verdi?
  Serial.println();
  Serial.printf("Verdi fra minne 0x01 calibration_factor: %0.2f", EEPROM.get(0xAA, calibration_factor));  //Serial print lagret verdi
  Serial.println();
  readMem(); // function Les lagrede verdier inn i variablene

  // Sjekker om vekten er kalibrert via minneplass 0x00, dersom ulik 1  må den kalibreres
  if (EEPROM.read(0x00) != 0x01) { //test if stored value mem 0x00 <> 1
    functionCalibrate();  // function calibrate
  }

  //Setup for temperature and humidity functionality
  dht.begin();

  //Setup for LoRa
  Serial.println("LoRa transivertest utføres");
  SPI.begin();
  LoRa.setPins(SS, RST, DIO0);
  if (!LoRa.begin(BAND)) {
    Serial.println("LoRa transivertest feila!");
    while (1);
  }
  Serial.println("LoRa initisiert!");

  Serial.println(calibration_factor);
  scale.set_scale(calibration_factor / LB2KG);    // denne omregningen tror jeg er unødig om en kalibrerer uten denne
  delay(1500);

  // setup for avlesing av knapper
  pinMode(switchTare, INPUT);            // NO
  pinMode(switchCalibrate, INPUT);       // NO
}

void loop() {
 
  // Send readings og les switch med mills timer -  Sender må sende skjeldnere, mottager må lese det den får.Fewer = power save
  unsigned long currentTime = millis();
  if (currentTime - previousTime >= 10000) {   //Change this value to publish at a different interval. 4 pkg pr loop, 60sec/4 pkg = 15 sec
    previousTime = currentTime;
    humidity = dht.readHumidity();
    Serial.println("if mills");
    Serial.println(humidity);
    temperatureHive = dht.readTemperature();
    Serial.println(temperatureHive);
    //Serial.println(temperatureOut);

    // Median calculus + serial print values
    double data = sqrt(pow(scale.get_units(), 2));  // data er avlest vekt, make abs value
    Serial.print("Avlest vekt før median (data): ");
    Serial.println(data, 3);  // 3 desimaler
    weight_median = medianFilter(data);   // data er avlest vekt, hva med = double weight_median = medianFilter(data);
    Serial.print("Variable weigth_median: ");
    Serial.println(weight_median);
    for (int i = 0; i < 5; i++) {
      Serial.print(" | ");
      Serial.print(window[i]);
    }
    Serial.println(" |");
    sendReadings();                              // dersom tare eller alarm er aktivert sendes verdien 1 over lora, resettes i linjene under

    // ##############################################################################################
    // after sendReadings() 
    //
    // hx711 + AI thinker LoRa SX1276 deep sleep for 15 min (use the moste efficient power save option
    // 
    // 
  }
}

so the overview is
do readings and after sending the readings go into deepsleep.

What shall your code do as the first thing if the device wakes up from deepsleep?

1 Like

Thanks again

This was a tricky question on a Sunday morning :wink:

My initial Idea is that before sleep all is "good", then after sleep the void loop continues based on that all is also "good" after sleep.

By "good" I mean that all hw/variables/other are in same state before and after sleep and void loop just continue, like a blink of an eye. Maybe better described as a hibernation state.

But maybe something changes in sleep and then a simple continue is not possible...

a real hibernation can only be done with lightsleep.

1 Like

You need light sleep for that, as mentioned in post #2.

Its more the case that all the hardware stuff you have setup, SPI, I2C, DHT11, DS18B20, Scale etc is shut down before going into deep sleep.

So you cannot wake from deep sleep and use LoRa (without setup) for instance, you need to start up SPI again, etc, etc.

Without giving the overview about your project
we could go on for weeks to guess around in the fog.

The reason for requesting to give an overview about your real project is to be able to find a good solution for it all instead of

  • making a detail-suggestion that turns out to be not possible
  • making a detail-suggestion that turns out to be not possible
    ...
1 Like

Thanks @srnet , after @StefanL38 asked the magic question this is what I somhow realized

My code is made robust, that means that after a power loss the system wakes up and contiues the job (scale calibration is stored in eeprom)

So my Q:

Can I deep sleep my devise and restart all setup?

Frequency for LoRa pakages is like each 15 min.
My plan is also to add a switch (reed relay) that changes send frequency to each 5 sec to make debug possible without waiting 15 min for a LoRa pakage. In this if statement I must disable sleep after sendReadings(); witch I assume is not a big task, but not done yet.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.