XIAO esp32 c3 deep sleep for door sensor

Hello,

I’m currently working on a project involving a door sensor powered by the Xiao ESP32-C3 microcontroller and a normally open magnetic reed switch. I’ve connected the reed switch to the D1 pin of the Xiao ESP32-C3 using a pull-down resistor(10K).

The goal of my project is to have the ESP32-C3 in deep sleep mode at all times unless there is a change in the state of the reed switch, which indicates that the door has been opened. When the door opens, I want the ESP32-C3 to wake up and send an alert to a BLE server, which is an ESP32-S.
It actually works for the first time after uploading the code when the door opens.

However, I’m encountering an issue where the ESP32-C3 wakes up from deep sleep every time the door opens, This results in unnecessary power consumption.

Is there any way to detect the falling value of sensor or any other methods to fix this issue?

I’ve included my code structure below for reference.

#define BUTTON_PIN_BITMASK 0x200000000 // 2^33 in hex
#include "BLEDevice.h"

void setup() 
{
 
  BLE_data_send();
  esp_deep_sleep_enable_gpio_wakeup(BIT(D1), ESP_GPIO_WAKEUP_GPIO_LOW);
  Serial.println("Going to sleep now");
  delay(1000);
  esp_deep_sleep_start();
  Serial.println(" This will be never printed ");
  
} // End of setup.

// This is the Arduino main loop function.
void loop() 
{

 
}

Hi tony,
These two statements seam to contradict each other?
You can set the Interrupt to be HIGH , LOW or EDGE rising or falling.

Looks to be working properly?
HTH
GL :slight_smile:

Hi Glasso,
Sorry for the inconvenience, I will explain the problem clearly.
When the door opens, the ESP32C3 wakes up and alerts the server, then goes to deep sleep. Now the door is in open condition(the magnetic reed status will be low in my case), This thing again wakes up the ESP32c3 and it goes to deep sleep, it becomes a loop until the door closes. How can I avoid this?
This means the MCU will only need to wakeup from deep sleep when the sensor values changes from HIGH to LOW.
If you need more clarification, please tell me!

Hi tony1,
No inconvenience at all , Interesting task. I notice You never define the initial PIN state in your code.
for one, and You may find this link VERY helpful http://www.gammon.com.au/switches be sure you have the correct pin state defined to go with the Pull _down state you are using in your code (WAKEUP_GPIO_LOW);
Your magnetic switch should be configured to make a Creates a PULSE on the GPIO
then you can use the EDGE polarity Rising or Falling and do what you want.
Also ,IMO make a variable the button state is better, my .02
are you trying to debounce the switch in code ?
HTH
GL:-)
PJ

Another method is to check the state of the button in each passing of the loop. If the state changes (ie goes low) you can set a flag. Then when you read that the button is high again and the flag has been set then you execute the appropriate code. For example:

const int buttonPin = 2;     // the number of the pushbutton pin
boolean buttonWasLow = false;         // variable flag for when the pushbutton goes low

void setup() {
    pinMode(buttonPin, INPUT);    // initialize the pushbutton pin as an input:
}

void loop() {
    // read the state of the pushbutton and set a flag if it is low:
    if (digitalRead(buttonPin) == LOW)  {
        buttonWasLow = true;
    }

    // This if statement will only fire on the rising edge of the button input
    if (digitalRead(buttonPin) == HIGH && buttonWasLow)  {
        // reset the button low flag
        buttonWasLow = false;

        // Button event here
    }
}

My favorite way to detect a rising edge of an input is actually much simpler:

void loop() {
    button = digitalRead(buttonPin);

    // If the button is pressed
    if (button && !buttonLast)
    {
        // Button event here
    }

    // Update button flag
    buttonLast = button;
}

Hi PJ_Glasso,
As per your instruction, I have updated the code and it is working fine, this is my new code

#define BUTTON_PIN_BITMASK 0x200000000 // 2^33 in hex

#include "BLEDevice.h"
#include "esp_sleep.h"

const int reedSwitchPin = D1;
boolean door_status = HIGH;
boolean send_flag = HIGH;

void setup() 
{
  BLE_setup();
 }
void loop() 
{
  door_status  = digitalRead(reedSwitchPin);
  if(door_status == LOW)
  {
    // Door open detected
    if(send_flag == HIGH)
    {
      BLE_Data_Send();
    }
    
  }
  else
  {
   //door closed
    esp_deep_sleep_enable_gpio_wakeup(BIT(D1), ESP_GPIO_WAKEUP_GPIO_LOW);
    Serial.println("Going to sleep now");
    Serial.end();
    esp_deep_sleep_start();
    delay(1000);
    Serial.println(" This will be never printed ");
  }
 void BLE_Data_Send()
 {
   send_data();
   send_flag = LOW;
}

This is working fine, But when the door is in the open state for a long time it will ruin my battery because it will be in the loop. (i.e., The ESP 32 will only go to deep sleep if the door is closed). Is there anything I can do in the code to fix it?

Hi there, Nice work !
Looks good, Yes I would use the RTC and set a timer after what you think is suficiant time, either go back to Sleep or Alarm for an action to be taken. either way your’e in the ball park.
You may want to try another approach inspired by msfujino’s System_ON_Sleep of XIAO BLE This is one of the BEST threads on Xiao Sleep as it pertains to nRF52840 how ever some of it can apply to ESP32C3

My logic would be Power up , initialize, send a BLE test message and set time & date., store Epoc Time, Go to sleep. When door is opened Wake up compare epoc time send info, wait for door closed or “door left open” alarm , go to sleep… Rinse and repeat.
something along those lines.
HTH
GL :slight_smile: PJ