External wakeup with Arduino on ESP32-S3

Updated on 20 January 2023
dev board ESP32-S3-DevKitC-1
chip ESP32-S3-WROOM-1-N8R2
features external wakeup trigger sleep esp32s3
This tutorial is more than 1 year old. If the steps below do not work, then please check the latest versions and the documentations of the individual tools used.

Before starting

Dependancies

Ensure the following dependancies are downloaded and available:

Pre-requisites

Try these simpler or similar examples:

Code

Download code external-wakeup-arduino-esp32s3.ino
#define BUTTON_PIN_BITMASK 0x200000000  // 2^33 in hex
#define INTERRUPT_PIN GPIO_NUM_2

#define LED 5  // or use LED_BUILTIN for on-board LED
RTC_DATA_ATTR int bootCount = 0;

void setup() {
  Serial.begin(115200);
  delay(1000);

  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW);

  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  print_wakeup_reason();

  Serial.println("Going to blink the LED 10 times");
  blink(10);
  Serial.println("Going to sleep now");

  esp_sleep_enable_ext0_wakeup(INTERRUPT_PIN, 1);  // 1 = High, 0 = Low

  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop() { }

void blink(int times) {
  for (int i = 0; i <= times; i++) {
    digitalWrite(LED, HIGH);
    delay(1000);

    digitalWrite(LED, LOW);
    delay(1000);
  }
}

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;
    default:
      Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason);
      break;
  }
}

Makefile

BOARD?=esp32:esp32:esp32s3:CDCOnBoot=cdc
PORT?=/dev/cu.usbmodem14*
UART_PORT?=/dev/cu.usbserial-1*
BUILD=build
## Pass in V=--verbose to output more information than default

.PHONY: help default lint compile upload clean

default: clean lint compile upload

help: ## Show help message
	@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n  make \033[36m\033[0m\n"} /^[$$()% 0-9a-zA-Z_-]+:.*?##/ { printf "  \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

lint: ## Lint code using cpplint
	cpplint --extensions=ino --filter=-legal/copyright,-runtime/int *.ino

compile: ## Compile code and create the firmware binary
	arduino-cli compile $(V) --fqbn $(BOARD) --output-dir $(BUILD) ./

upload: ## Upload the firmware to the board
	arduino-cli upload $(V) --fqbn $(BOARD) --port $(PORT) --input-dir $(BUILD)

rollback:
	@echo "Ensure you plug into the UART port of ESP32-S3 board"
	esptool.py --port $(UART_PORT) erase_flash
	esptool.py --port $(UART_PORT) erase_flash
	@echo "Ensure flash in the blinky example of ESP-IDF before flashing in Arduino code"

clean: ## Remove all built files
	rm -rf build

Prototype

A photo of the actual setup.

External wakeup with Arduino on ESP32-S3 prototype

Schematic

Wire up the hardware accordingly

External wakeup with Arduino on ESP32-S3 schematic

Serial console

Serial output from the firmware.

External wakeup with Arduino on ESP32-S3 serial console

External wakeup with Arduino on ESP32-S3 browser

Add a push button and an external LED to test wakeup the board

Description

Wire up the hardware according to the schematic. Compile and upload the firmware.

Press the push button to wake up and see the LED Blinking 10 times before going back to sleep again.

References