espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.61k stars 7.41k forks source link

Deep Sleep Reset Problem #8578

Closed abhi-sachdeva closed 1 year ago

abhi-sachdeva commented 1 year ago

Board

ESP32-C3-DevKit-M1

Device Description

The Dev kit is on a breadboard. buttonPin is wired to GPIO2 and buttonPin2 to GPIO3. buttonPin controls a blue LED through GPIO7. buttonPin2 controls a green and red LED through GPIO5 & 6 respectively.

Hardware Configuration

10kohm pulldown resistors for the buttons and 220ohm resistors for the LED

Version

latest master (checkout manually)

IDE Name

Arduino IDE

Operating System

Windows 10

Flash frequency

80Mhz

PSRAM enabled

yes

Upload speed

921600

Description

buttonPin starts from a pressed state initially. Thus when the code is uploaded with the button pressed at the start, the esp32-c3 goes to sleep. The other button (buttonPin2) wakes the esp up from deep sleep when the gpio goes high. Upon wake up, the esp runs a BLE script and connects to a phone (using a ble scanner for testing). The deviceConnected callback puts the esp back to sleep once a successful connection has been made (after some delay). Now when the device goes back to sleep, the wake-up should occur via the first button (buttonPin). The code contains the lines for waking up the esp upon a gpio going low. However, once the button is released, the esp is reset (it takes an additional press of the button to print the wake-up reason and toggle the LEDs). Why is the ESP reset and not woken up from the button? How can I fix this?

Sketch

#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <Wire.h>
#include <Preferences.h>
#include <WiFi.h>
#include <WiFiMulti.h>

const int buttonPin = 3;  // # for button pin for States/Interrupt
const int buttonPin2 = 2; // # for button pin for BLE
const int ledPin =  5;   // # for the Green LED pin
const int ledPin2 = 6;   // # for the Red LED pin
const int ledPin3 = 7;    // # for the Blue LED pin

// variables will change:
int buttonState = 0;     
int lastButtonState = 0;
int buttonState2 = 0;
int lastButtonState2 = 0;  
int ledState = 0;
int state = 0;
RTC_DATA_ATTR int counter = 0; 

#define SERVICE_UUID        "f0e279fc-a979-4ffd-924c-59ced5392948"
#define CHARACTERISTIC_UUID "7f98738e-382d-43d9-b256-3cf8bd3120b7"

BLEServer *pServer = NULL;
BLEService *pService = NULL;
BLECharacteristic *pCharacteristic = NULL;

Preferences preferences;
WiFiMulti wifimulti;

bool deviceConnected = false;
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
      Serial.println("True");
      state = preferences.getInt("state", 0);
      Serial.print("State: ");
      Serial.println(counter);
      delay(5000);
      Serial.println("Going to Sleep");
      digitalWrite(ledPin3, LOW);  // Turn off LED
      esp_deep_sleep_start();  // Enter deep sleep mode
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
      Serial.println("Disconnected!");
      Serial.println("Advertising...");
      pServer->getAdvertising()->start();
    }
};

class MyCallbacks: public BLECharacteristicCallbacks
{
  void onWrite(BLECharacteristic *pCharacteristic)
  {
    std::string value = pCharacteristic->getValue();

    if (value.length() > 0)
    {
      Serial.println("*********");
      Serial.print("New value: ");
      for (int i = 0; i < value.length(); i++)
      {
        Serial.print(value[i]);
      }

      Serial.println();
      Serial.println("*********");
    }
  }
};

void setupBLEServer(void) {

  Serial.println("Starting BLE Server!");
  BLEDevice::init("Pirouette-IoT-Device");
  pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  pService = pServer->createService(SERVICE_UUID);

  pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_NOTIFY);

  pCharacteristic->setCallbacks(new MyCallbacks());

  pCharacteristic->setValue("device_state_0_stored");
  pService->start();
  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
  pAdvertising->setMinPreferred(0x12);
  pAdvertising->start();
}

void pairing(){

  digitalWrite(ledPin3, HIGH);
  setupBLEServer();
}

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;
    case ESP_SLEEP_WAKEUP_GPIO: //New wakeup reason <-- 
      Serial.println("Wakeup caused by a GPIO");
      if(lastButtonState == HIGH && buttonState == LOW){
        counter++;
        Serial.print("Counter: ");
        Serial.println(counter);
      }
      if(counter == 1){
        digitalWrite(ledPin, HIGH);
      }
      //digitalWrite(ledPin, HIGH);
      if(deviceConnected){
        if(pCharacteristic != NULL){
          pCharacteristic->setValue("device_state_1_ready"); //add code for device state 1 ready once buttonPin1 is pushed/released
          pCharacteristic->notify();
        }
      }
      break;
    default:
      Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason);
      break;
  }
}

void setup() {

  Serial.begin(115200);

  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);

  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  pinMode(buttonPin2, INPUT_PULLUP);

  //Enable GPIO Wakeup from buttonPin
  esp_deep_sleep_enable_gpio_wakeup(1 << buttonPin, ESP_GPIO_WAKEUP_GPIO_LOW);
  esp_deep_sleep_enable_gpio_wakeup(1 << buttonPin2, ESP_GPIO_WAKEUP_GPIO_HIGH);
  gpio_set_direction((gpio_num_t)buttonPin, GPIO_MODE_INPUT);  // <<<=== Add this line
  gpio_set_direction((gpio_num_t)buttonPin2, GPIO_MODE_INPUT);  // <<<=== Add this line

  preferences.begin("dev-states", false);

  state = preferences.getInt("state", 0);
  Serial.print("State: ");
  Serial.println(counter);

  buttonState2 = digitalRead(buttonPin2);
  if(buttonState2 == HIGH && lastButtonState2 == LOW){
    print_wakeup_reason();
    pairing();
  }

    buttonState = digitalRead(buttonPin);
    buttonState2 = digitalRead(buttonPin2);
    if(buttonState == HIGH && buttonState2 == LOW){
      Serial.println("Going to Sleep");
      esp_deep_sleep_start();
  }
}

void loop() {
  // read the state of the BLE pushbutton
  buttonState2 = digitalRead(buttonPin2);
  if (lastButtonState2 == HIGH && buttonState2 == LOW) {
    print_wakeup_reason();
    Serial.println("The button is pressed");
    pairing();
  }
  lastButtonState2 = buttonState2;

  //Wake-up ESP from deep sleep
  //print_wakeup_reason();

  // read the state of the internal pushbutton:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (lastButtonState == HIGH && buttonState == LOW) {
      print_wakeup_reason();
      //counter++;
      Serial.print("Number of button pushes:  ");
      Serial.println(counter);
      // if the current state is HIGH then the button went from off to on:
      ledState = !ledState;
    }
    if(counter == 2){
      buttonState = lastButtonState;
    }
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

  // sets the LED to the button's state
  if(counter == 1){
    digitalWrite(ledPin, HIGH);
    digitalWrite(ledPin2, LOW);

    if(pCharacteristic != NULL){
      pCharacteristic->setValue("device_state_3_locked"); //add code for device state 1 ready once buttonPin1 is pushed/released
      pCharacteristic->notify();
    }
  }

  if(counter == 3){
    digitalWrite(ledPin2, HIGH);
    digitalWrite(ledPin, LOW);

    if(pCharacteristic != NULL){
      pCharacteristic->setValue("device_state_3_locked"); //add code for device state 3 used once buttonPin1 is pushed/released
      pCharacteristic->notify();
    }
  }

  if(counter >= 4){
    digitalWrite(ledPin, LOW);
    digitalWrite(ledPin2, LOW);
  }

  delay(50);

}

Debug Message

ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x5 (DSLEEP),boot:0xe (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5810,len:0x438
load:0x403cc710,len:0x918
load:0x403ce710,len:0x25f4
entry 0x403cc710
State: 0
Wakeup caused by a GPIO
Starting BLE Server!
Wakeup caused by a GPIO
The button is pressed
Starting BLE Server!
True
State: 0
Going to Sleep
ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x5 (DSLEEP),boot:0xe (SPI_FAST_FLASH_BOOT)
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fcd5810,len:0x438
load:0x403cc710,len:0x918
load:0x403ce710,len:0x25f4
entry 0x403cc710
State: 0
Wakeup caused by a GPIO
Counter: 1
Number of button pushes:  1

Other Steps to Reproduce

I press down on button 1 (buttonPin) and reset the esp to put it to sleep in order to test the rest of the code

I have checked existing issues, online documentation and the Troubleshooting Guide

VojtechBartoska commented 1 year ago

Hello, I'm closing this issue as expired due to no answer, if needed you can reopen it. Thanks for understanding.