espressif / arduino-esp32

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

Turning on LED immediately after Deep Sleep w/ ESP32-C3 #8537

Closed abhi-sachdeva closed 1 year ago

abhi-sachdeva commented 1 year ago

Board

ESP32-C3-DevKit-M1

Device Description

The dev kit is mounted on a breadboard. there is one push button wired to gpio2 such that pressing it would initiate ble pairing. Once paired the device goes to sleep. The second push button is wired to gpio3 and is the interrupt button to wake up the esp (esp_gpio_wakeup_gpio_low). This button also controls 2 different LEDs.

Hardware Configuration

The blue LED for ble is connected to gpio7 and the green/red LEDs are connected to gpio 5 & 6 respectively. Each push button has a pull down resistor of 10kohms and each led has a resistor of 220ohms.

Version

latest master (checkout manually)

IDE Name

Arduino IDE

Operating System

Windows 10

Flash frequency

80Mhz

PSRAM enabled

yes

Upload speed

921600

Description

I have a slight problem in my code such that my LED does not illuminate immediately after deep sleep. The wakeup reason is GPIO go low so that when a button is depressed, the esp will wake up. That same button is also supposed to turn the LED on which is why I have implemented a counter so that it can turn on on the first depress. However, what happens is that the depress wakes up the esp and does not increment the counter so it needs an additional press/depress for the led to turn on. Is there a way I can make the led turn on at the same time as the esp waking up without using an additional button? Perhaps a way to increment the counter at the same time that the esp wakes up? Thanks for the help!

Expected Behavior: BLE connects and blue LED turns off and the esp goes to sleep. Second button is depressed and the esp wakes up and turns on a green led at the same time, a second push of that button turns off the green led and illuminates the red one.

Sketch

#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <Wire.h>
#include <Preferences.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;
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;

bool deviceConnected = false;
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
      Serial.println("True");
      delay(3000);
      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->startAdvertising(); 
    }
};

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");
      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);
  gpio_set_direction((gpio_num_t)buttonPin, GPIO_MODE_INPUT);  // <<<=== Add this line

  //Set up preferences for led state
 // preferences.begin("led-state", false);
  //counter = preferences.getInt("counter", 1);

  //preferences.putInt("counter", counter);
  //preferences.end();

}

void loop(){

  // read the state of the BLE pushbutton
  buttonState2 = digitalRead(buttonPin2);
  if (lastButtonState2 == HIGH && buttonState2 == LOW) {
    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) {
      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, ledState);

    if(pCharacteristic != NULL){
      pCharacteristic->setValue("device_state_1_ready"); //add code for device 1 state 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 1 state ready once buttonPin1 is pushed/released
      pCharacteristic->notify();
    }
  }
  else if (counter >= 4){
    digitalWrite(ledPin, LOW);
    digitalWrite(ledPin2, LOW);
  }

  delay(50);
  }

Debug Message

Wakeup was not caused by deep sleep: 0
Going to Sleep
ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x5 (DSLEEP),boot:0xc (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
Wakeup caused by a GPIO
Wakeup caused by a GPIO
Number of button pushes:  1

Other Steps to Reproduce

I have also tried to use the preferences.h library to store the counter, but I think I may have implemented that wrong as well. Any help on getting the LED to turn on at the same time as the board wakes up from deep sleep is really appreciated!

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

lbernstone commented 1 year ago

This forum is for issues with the code in this repo. Please ask general programming questions at https://esp32.com

abhi-sachdeva commented 1 year ago

This forum is for issues with the code in this repo. Please ask general programming questions at https://esp32.com

Posted it there too, but I have posted other times as well and nobody replies with any help

SuGlider commented 1 year ago

This is not an issue.

But, I'll suggest a few things for your application:

Good Luck!

VojtechBartoska commented 1 year ago

Closing as answered, if needed you can reopen.