Xiao Sense ESP32S3 Wakeup on Motion from AM312 Not Working

I’m been banging my head against the wall trying to get a simple wake up from deep sleep working on the Xiao Sense (ESP32S3). I have the same code working just fine on an ESP32-CAM board (with the addition of the brown-out disable function call). If I switch to the timer version of the deep sleep wake up it works fine. Here’s my non-working code:

NOTE: AM312 PIR sensor output is on GPIO 4 and power/ground comes from 3v3/GND on the Xiao

#define MOTIONPIN GPIO_NUM_4

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(MOTIONPIN, INPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(250);
  digitalWrite(LED_BUILTIN, LOW);
  delay(250);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(250);

  Serial.println("Going to sleep...");
  delay(1000);
  esp_sleep_enable_ext0_wakeup(MOTIONPIN, 1);
  delay(5000);
  esp_deep_sleep_start();
}

void loop() {
}

Hi there,
DOes it work if you use a test lead or jumper, Are you confident in ;

#define MOTIONPIN GPIO_NUM_4 (is this syntax correct ?why not just " MotionPin GPIO 4 " ? or MotionPin 4 " ?
“esp_sleep_enable_ext0_wakeup(MOTIONPIN, 1);” is this correct also?
can you post the timer example you have working?
HTH
GL :slight_smile: PJ :v:

to consider …
Here’s some information about waking up an ESP32-S3:

  • To enable wakeup, call gpio_wakeup_enable for each GPIO used for wakeup. Specify the GPIO number and wakeup level.
  • To wake up from light sleep, use the UART peripheral’s feature. This feature wakes up the chip when a certain number of positive edges on the RX pin are seen.
  • To wake an ESP32 from deep sleep, press the pushbuttons.
  • To wake an ESP32 from deep sleep by touching the wire connected to Touch Pin 3, upload the code to the ESP32 and open the Serial Monitor at a baud rate of 115200.
  • To wake up the chip using multiple GPIO pins, use ext1.
  • To wake up the chip only by a specific GPIO pin, use ext0.
  • The ESP32’s GPIO wakeup source cannot be used together with touch or ULP wakeup sources.
    Sleep Modes - ESP32-S3 - — ESP-IDF Programming Guide latest documentation.

This code works to blink the built-in LED when motion is detected which confirms the wiring:

#define MOTIONPIN GPIO_NUM_4

int value = 0;

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(MOTIONPIN, INPUT);
  digitalWrite(LED_BUILTIN, HIGH);
}

void loop() {
  value = digitalRead(MOTIONPIN);
  Serial.println(value);
  if (value==1) {
    digitalWrite(LED_BUILTIN, LOW);
    delay(250);
    digitalWrite(LED_BUILTIN, HIGH);
  }
  delay(250);
}

Here’s the code for the timer based wakeup that works:

#define MOTIONPIN GPIO_NUM_4
#define uS_TO_S_FACTOR 1000000ULL
#define TIME_TO_SLEEP 5

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(MOTIONPIN, INPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(250);
  digitalWrite(LED_BUILTIN, LOW);
  delay(250);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(250);

  Serial.println("Going to sleep...");
  delay(1000);
  //esp_sleep_enable_ext0_wakeup(MOTIONPIN, 1);
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  delay(5000);
  esp_deep_sleep_start();
}

void loop() {
}

Hi there,
Ok good, wiring is Check…
Does it work if you use Light Sleep? esp_light_sleep_start(void),
What power group is GPIO4 part of in the chip?
EXT1 , or EXT0 , Hmmm
Try this one…
from the Doc’s

esp_sleep_enable_gpio_wakeup()

"Each GPIO supports wakeup function, which can be triggered on either low level or high level. Unlike EXT0 and EXT1 wakeup sources, this method can be used both for all IOs: RTC IOs and digital IOs. It can only be used to wakeup from light sleep though.

To enable wakeup, first call gpio_wakeup_enable, specifying gpio number and wakeup level, for each GPIO which is used for wakeup. Then call this function to enable wakeup feature."
HTH
GL :slight_smile: PJ
Your close, you get it… also what about the pull UP ? Something about if a sleep it won’t HOLD the pull up (or pull down) unless you tell it too.? just a thought?

Also what about the wakeup Return stub code?, I doesn’t just do a system reset does it.

No joy with light sleep either. In both cases, it goes to sleep and never wakes up.

replace it with this…
#define MOTIONPIN RTC_GPIO10
LMK
HTH
:crossed_fingers:

No, that didn’t work either. It’s looking for a type gpio_num_t

what about a different approach
pinMode(MOTIONPIN, INPUT_PULLUP);
and change the other to
esp_sleep_enable_ext0_wakeup(MOTIONPIN, 0);

GL :slight_smile: PJ

Or try this:

#define   TouchPin  GPIO_NUM_3

void setup() {
  pinMode(TouchPin,  INPUT);
}

void gotoSleep() {
  Serial.println("going to sleep in 30 sec....");   
  delay(3000); 
  esp_deep_sleep_enable_gpio_wakeup(1ULL << 3,ESP_GPIO_WAKEUP_GPIO_HIGH);  
  Serial.println("going to sleep now"); 
  delay(1000);
  esp_deep_sleep_start();   

}

LMK
GL :slight_smile: PJ

I figured this one out. The issue ended up being that the AM312 was not providing enough current to drive the input GPIO pin to register the signal. Measuring at the input pin, I got ~3.3V but it still wasn’t triggering.

So, in the end, I added an NPN resistor (S8050 in my case) to act like a switch. However, the signal is inverted in this case. So, you need a pull up resistor on your input GPIO pin and to set the ext0 wake to wake on a 0 instead of a 1.

This provides the solution: ESP32-CAM PIR Motion Detector with Photo Capture | Random Nerd Tutorials

NOTE: The transistor switch is not required with an HC-SR501 PIR Sensor as it can drive enough current to trigger the input pin.