From 82b8db196f72d2d1691ef6de00c4741af46ee8d0 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Tue, 4 Sep 2018 13:53:26 +0800 Subject: [PATCH] examples: add light sleep example --- examples/system/light_sleep/CMakeLists.txt | 8 ++ examples/system/light_sleep/Makefile | 9 ++ examples/system/light_sleep/README.md | 67 +++++++++++++ examples/system/light_sleep/example_test.py | 62 ++++++++++++ .../light_sleep/image/light_sleep_scope.png | Bin 0 -> 17183 bytes .../image/light_sleep_scope_zoom.png | Bin 0 -> 26388 bytes examples/system/light_sleep/main/component.mk | 3 + .../main/light_sleep_example_main.c | 90 ++++++++++++++++++ .../system/light_sleep/sdkconfig.defaults | 1 + 9 files changed, 240 insertions(+) create mode 100644 examples/system/light_sleep/CMakeLists.txt create mode 100644 examples/system/light_sleep/Makefile create mode 100644 examples/system/light_sleep/README.md create mode 100644 examples/system/light_sleep/example_test.py create mode 100644 examples/system/light_sleep/image/light_sleep_scope.png create mode 100644 examples/system/light_sleep/image/light_sleep_scope_zoom.png create mode 100644 examples/system/light_sleep/main/component.mk create mode 100644 examples/system/light_sleep/main/light_sleep_example_main.c create mode 100644 examples/system/light_sleep/sdkconfig.defaults diff --git a/examples/system/light_sleep/CMakeLists.txt b/examples/system/light_sleep/CMakeLists.txt new file mode 100644 index 000000000..33b3fec26 --- /dev/null +++ b/examples/system/light_sleep/CMakeLists.txt @@ -0,0 +1,8 @@ +# The following four lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +set(MAIN_SRCS main/light_sleep_example_main.c) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(light_sleep_example) diff --git a/examples/system/light_sleep/Makefile b/examples/system/light_sleep/Makefile new file mode 100644 index 000000000..0477dbfa0 --- /dev/null +++ b/examples/system/light_sleep/Makefile @@ -0,0 +1,9 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := light_sleep_example + +include $(IDF_PATH)/make/project.mk + diff --git a/examples/system/light_sleep/README.md b/examples/system/light_sleep/README.md new file mode 100644 index 000000000..2fa545dae --- /dev/null +++ b/examples/system/light_sleep/README.md @@ -0,0 +1,67 @@ +# Light Sleep Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +This example illustrates usage of light sleep mode. Unlike deep sleep mode, light sleep preserves the state of the memory, CPU, and peripherals. Execution of code on both CPUs is stopped when `esp_light_sleep_start` function is called. When the chip exits light sleep mode, execution continues at the point where it was stopped, and `esp_light_sleep_start` function returns. + +The example enables the following wakeup sources: + +- Timer: wake up the chip in 2 seconds +- EXT0: wake up the chip if a button attached to GPIO0 is pressed (i.e. if GPIO0 goes low) + +The example also prints time spent in light sleep mode to illustrate that timekeeping continues while the chip is in light sleep. + +## How to Use Example + +### Hardware Required + +This example can be used with any ESP32 development board. Most boards have a button attached to GPIO0, often labelled "BOOT". If the board does not have such button, an external button can be connected, along with a 10k pull-up resistor, and a 100nF capacitor to ground for debouncing. + +### Configure the Project + +Run `make menuconfig` and set serial port under Serial Flasher Options. + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +make -j4 flash monitor +``` + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +## Example Output + +``` +Entering light sleep +Returned from light sleep, reason: timer, t=2014 ms, slept for 2000 ms +Entering light sleep +Returned from light sleep, reason: timer, t=4023 ms, slept for 2000 ms +Entering light sleep +Returned from light sleep, reason: pin, t=5297 ms, slept for 1266 ms +Waiting for GPIO0 to go high... +Entering light sleep +Returned from light sleep, reason: timer, t=10072 ms, slept for 2000 ms +Entering light sleep +Returned from light sleep, reason: timer, t=12080 ms, slept for 2000 ms +Entering light sleep +``` + +In the scenario above, the button attached to GPIO0 was pressed and held for about 3 seconds, after the 2nd wakeup from light sleep. The program has indicated the wakeup reason after each sleep iteration. + +## Current Consumption + +In this example, current consumption in light sleep mode is in the range of 0.8 — 1.1 mA. Current consumption in active mode is 28 — 32 mA. Average current consumption is 1.1 - 1.3 mA. + +![Current consumption overview graph](image/light_sleep_scope.png) + +![Current consumption in active mode](image/light_sleep_scope_zoom.png) + + +## Troubleshooting + +If pressing the button attached to GPIO0 does not affect program behavior, check DTR/RTS configuration in the serial monitor. This is not necessary for IDF monitor, but for other tools it might be necessary to set DTR and RTS line state to "disabled" or "de-asserted". + diff --git a/examples/system/light_sleep/example_test.py b/examples/system/light_sleep/example_test.py new file mode 100644 index 000000000..b0f9c650b --- /dev/null +++ b/examples/system/light_sleep/example_test.py @@ -0,0 +1,62 @@ +from __future__ import print_function +import re +import os +import sys +import time + +test_fw_path = os.getenv('TEST_FW_PATH') +if test_fw_path and test_fw_path not in sys.path: + sys.path.insert(0, test_fw_path) + +import TinyFW +import IDF + +ENTERING_SLEEP_STR = 'Entering light sleep' +EXIT_SLEEP_REGEX = re.compile(r'Returned from light sleep, reason: (\w+), t=(\d+) ms, slept for (\d+) ms') +WAITING_FOR_GPIO_STR = 'Waiting for GPIO0 to go high...' + +WAKEUP_INTERVAL_MS = 2000 + +@IDF.idf_example_test(env_tag='Example_WIFI') +def test_examples_system_light_sleep(env, extra_data): + dut = env.get_dut('light_sleep_example', 'examples/system/light_sleep') + dut.start_app() + + # Ensure DTR and RTS are de-asserted for proper control of GPIO0 + dut.port_inst.setDTR(False) + dut.port_inst.setRTS(False) + + # enter sleep first time + dut.expect(ENTERING_SLEEP_STR, timeout=30) + # don't check timing here, might be cache dependent + dut.expect(EXIT_SLEEP_REGEX) + print('Got first sleep period') + + # enter sleep second time + dut.expect(ENTERING_SLEEP_STR) + groups = dut.expect(EXIT_SLEEP_REGEX) + print('Got second sleep period, wakeup from {}, slept for {}'.format(groups[0], groups[2])) + # sleep time error should be less than 1ms + assert(groups[0] == 'timer' and int(groups[2]) == WAKEUP_INTERVAL_MS) + + # this time we'll test gpio wakeup + dut.expect(ENTERING_SLEEP_STR) + print('Pulling GPIO0 low using DTR') + dut.port_inst.setDTR(True) + time.sleep(1) + groups = dut.expect(EXIT_SLEEP_REGEX) + print('Got third sleep period, wakeup from {}, slept for {}'.format(groups[0], groups[2])) + assert(groups[0] == 'pin' and int(groups[2]) < WAKEUP_INTERVAL_MS) + + dut.expect(WAITING_FOR_GPIO_STR) + print('Is waiting for GPIO...') + + dut.port_inst.setDTR(False) + dut.expect(ENTERING_SLEEP_STR) + print('Went to sleep again') + groups = dut.expect(EXIT_SLEEP_REGEX) + assert(groups[0] == 'timer' and int(groups[2]) == WAKEUP_INTERVAL_MS) + print('Woke up from timer again') + +if __name__ == '__main__': + test_examples_system_light_sleep() diff --git a/examples/system/light_sleep/image/light_sleep_scope.png b/examples/system/light_sleep/image/light_sleep_scope.png new file mode 100644 index 0000000000000000000000000000000000000000..78f8407931052e6cdba955196ba70505aadd4ad2 GIT binary patch literal 17183 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 literal 0 HcmV?d00001 diff --git a/examples/system/light_sleep/image/light_sleep_scope_zoom.png b/examples/system/light_sleep/image/light_sleep_scope_zoom.png new file mode 100644 index 0000000000000000000000000000000000000000..fa57ba0279571baf3e4a58bc6689003b6885b730 GIT binary patch literal 26388 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μ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 literal 0 HcmV?d00001 diff --git a/examples/system/light_sleep/main/component.mk b/examples/system/light_sleep/main/component.mk new file mode 100644 index 000000000..44bd2b527 --- /dev/null +++ b/examples/system/light_sleep/main/component.mk @@ -0,0 +1,3 @@ +# +# Main Makefile. This is basically the same as a component makefile. +# diff --git a/examples/system/light_sleep/main/light_sleep_example_main.c b/examples/system/light_sleep/main/light_sleep_example_main.c new file mode 100644 index 000000000..79436ba3d --- /dev/null +++ b/examples/system/light_sleep/main/light_sleep_example_main.c @@ -0,0 +1,90 @@ +/* Light sleep example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +#include +#include +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_sleep.h" +#include "esp_log.h" +#include "rom/uart.h" +#include "driver/rtc_io.h" + +/* Most development boards have "boot" button attached to GPIO0. + * You can also change this to another pin. + */ +#define BUTTON_GPIO_NUM_DEFAULT 0 + +/* "Boot" button on GPIO0 is active low */ +#define BUTTON_WAKEUP_LEVEL_DEFAULT 0 + +void app_main() +{ + /* Configure the button GPIO as input, enable wakeup */ + const int button_gpio_num = BUTTON_GPIO_NUM_DEFAULT; + const int wakeup_level = BUTTON_WAKEUP_LEVEL_DEFAULT; + gpio_config_t config = { + .pin_bit_mask = BIT64(button_gpio_num), + .mode = GPIO_MODE_INPUT + }; + ESP_ERROR_CHECK(gpio_config(&config)); + gpio_wakeup_enable(button_gpio_num, + wakeup_level == 0 ? GPIO_INTR_LOW_LEVEL : GPIO_INTR_HIGH_LEVEL); + + while (true) { + /* Wake up in 2 seconds, or when button is pressed */ + esp_sleep_enable_timer_wakeup(2000000); + esp_sleep_enable_gpio_wakeup(); + + /* Wait until GPIO goes high */ + if (rtc_gpio_get_level(button_gpio_num) == wakeup_level) { + printf("Waiting for GPIO%d to go high...\n", button_gpio_num); + do { + vTaskDelay(pdMS_TO_TICKS(10)); + } while (rtc_gpio_get_level(button_gpio_num) == wakeup_level); + } + + printf("Entering light sleep\n"); + /* To make sure the complete line is printed before entering sleep mode, + * need to wait until UART TX FIFO is empty: + */ + uart_tx_wait_idle(CONFIG_CONSOLE_UART_NUM); + + /* Get timestamp before entering sleep */ + int64_t t_before_us = esp_timer_get_time(); + + /* Enter sleep mode */ + esp_light_sleep_start(); + /* Execution continues here after wakeup */ + + /* Get timestamp after waking up from sleep */ + int64_t t_after_us = esp_timer_get_time(); + + /* Determine wake up reason */ + const char* wakeup_reason; + switch (esp_sleep_get_wakeup_cause()) { + case ESP_SLEEP_WAKEUP_TIMER: + wakeup_reason = "timer"; + break; + case ESP_SLEEP_WAKEUP_GPIO: + wakeup_reason = "pin"; + break; + default: + wakeup_reason = "other"; + break; + } + + printf("Returned from light sleep, reason: %s, t=%lld ms, slept for %lld ms\n", + wakeup_reason, t_after_us / 1000, (t_after_us - t_before_us) / 1000); + } + +} diff --git a/examples/system/light_sleep/sdkconfig.defaults b/examples/system/light_sleep/sdkconfig.defaults new file mode 100644 index 000000000..8e2af8cd2 --- /dev/null +++ b/examples/system/light_sleep/sdkconfig.defaults @@ -0,0 +1 @@ +CONFIG_ESP32_DEFAULT_CPU_FREQ_80=y