Timer wakeup with Arduino on ESP32-C3

Updated on 13 January 2023
dev board ESP32-C3-DevKitM-1
chip ESP32-C3-MINI-1-N4
features timer wakeup periodic esp32c3
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:

Buy the components

Code

Download code timer-wakeup-arduino-esp32c3.ino
#define uS_TO_S_FACTOR 1000000ULL
#define TIME_TO_SLEEP 5  // in seconds
#define LED 3  // or LED_BUILTIN to use the on-board LED
#define BLINKING_NUMNER 10  // Blink the LED 10 times
RTC_DATA_ATTR int bootCount = 0;

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;
  }
}

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

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

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

  print_wakeup_reason();

  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  Serial.println("Setup ESP32 to sleep for every "
    + String(TIME_TO_SLEEP)
    + " Seconds");

  // Blinking the LED gives a visual indication
  // that the dev board is awake.
  // Also, it gives some time to upload the firmware
  // while the port is available during while awake.
  Serial.println("Blink the LED while awake");
  blink(BLINKING_NUMNER);

  Serial.println("Going to sleep for "
    + String(TIME_TO_SLEEP)
    + " seconds now");
  Serial.flush();
  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, LOW);
    delay(1000);

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

Makefile

BOARD?=esp32:esp32:esp32c3
PORT?=/dev/cu.SLAB_USBtoUART*
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)

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

Prototype

A photo of the actual setup.

Timer wakeup with Arduino on ESP32-C3 prototype

Schematic

Wire up the hardware accordingly

Timer wakeup with Arduino on ESP32-C3 schematic

Serial console

Serial output from the firmware.

Timer wakeup with Arduino on ESP32-C3 serial console

Description

Compile and upload the code to wakeup and sleep periodically.

Troubleshooting: Port not available

While sleeping, the port will not be available via the USB port. Hence, a delay has been added by blinking the LED to make time for uploading firmware in development.

References