GPIO と RTC GPIOの違いは?
ESP32のIOポートでGPIO と RTC GPIOで何が違うのか調べて見ました。
ESP32のマニュアルによるとGPIOの一部としてRTC GPIOが有る様です。またRTC GPIOはULPによって管理されるとも有りました。機能面で一番大きな違いは、RTC GPIOはDeepSleep中も値を保持出来る点だと思います。通常のGPIOはDeepSleepに入るとリセットされますが、RTC GPIOは値を保持出来るのです。
RTC GPIOのピンはどれ?
下記はRTC GPIOについてまとめた表。GPIOポート一覧と比べると、
- RTC GPIOポートは全部で18個。
- RTC GPIOはGPIOでアナログ機能を持ったポート。
DeepSleep時に有効にするには?
Deep SleepとM5StickCの資料ですが参考になります。ESP32ではDeepSleep時の内部周辺機器の電源管理をesp_deep_sleep_pd_config();で行います。
esp_err_t esp_deep_sleep_pd_config(esp_deep_sleep_pd_domain_t domain, esp_deep_sleep_pd_option_t option)
- 第一引数: enum esp_deep_sleep_pd_domain_t型
- ESP_PD_DOMAIN_RTC_PERIPH RTC IOsensors and ULP co-processor.
- ESP_PD_DOMAIN_RTC_SLOW_MEM RTC slow memory.
- ESP_PD_DOMAIN_RTC_FAST_MEM RTC fast memory.
- ESP_PD_DOMAIN_MAX Number of domains.
- 第二引数: esp_deep_sleep_pd_option_t型
- ESP_PD_OPTION_OFF Power down the power domain in deep sleep.
- ESP_PD_OPTION_ON Keep power domain enabled during deep sleep.
- ESP_PD_OPTION_AUTO Keep power domain enabled in deep sleep,if it is needed by one of the wakeup options.Otherwise power it down.
DeepSleep時ポートの値を保持したいならPERIPHをONをDeepSleepに入る前に実行します。。
esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH , ESP_PD_OPTION_ON);
各機器の初期状態は下記の様になっています。PERIPH は初期値としてAUTOが設定されいます。
EXT0とGPIOがONにそれ以外はOFFになっています。GPIOがONなら上記の関数でESP_PD_OPTION_ON 設定を行わなくでも値が保持される様に思いますが、ESP_PD_OPTION_ON 設定にしなければ値は保持されませんでした。
初期値ではULPがOFFになっています。RTC GPIOはULPが管理するのでULPをONする必要が有るのでしょうか。
RTC GPIOの管理はどの様にやるの
RTC GPIOの管理は以下の関数で行います。
- esp_err_t rtc_gpio_init(gpio_num_t gpio_num) ポートの初期化
- 引数 : gpio_num_t型の GPIO number (e.g. GPIO_NUM_12)
- 戻り値: ESP_OK (success) ESP_ERR_INVALID_ARG (GPIO is not an RTC IO)
- uint32_t rtc_gpio_get_level(gpio_num_t gpio_num) ポートの読み込み
- 引数 : gpio_num_t型の GPIO number (e.g. GPIO_NUM_12)
- 戻り値: 0、 1、 ESP_ERR_INVALID_ARG (GPIO is not an RTC IO)
- esp_err_t rtc_gpio_set_level(gpio_num_t gpio_num, uint32_t level)
- 第一引数:gpio_num_t型の GPIO number (e.g. GPIO_NUM_12)
- 第二引数:Level 0/1
- 戻り値: ESP_OK (success) ESP_ERR_INVALID_ARG (GPIO is not an RTC IO)
確認
動作を下記の回路とプログラムで確認しました。
#include "Arduino.h"
#include "driver/rtc_io.h"
#include "esp_deep_sleep.h"
#define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */
void setup()
{
Serial.begin(115200);
delay(100);
Serial.println("Set LED" );
rtc_gpio_init(GPIO_NUM_2);
rtc_gpio_set_direction(GPIO_NUM_2,RTC_GPIO_MODE_OUTPUT_ONLY);
rtc_gpio_set_level(GPIO_NUM_2,1);
delay(3000);
esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
esp_sleep_enable_timer_wakeup(5 * uS_TO_S_FACTOR);
//Go to sleep now
Serial.println("Go interval" );
esp_deep_sleep_start();
}
void loop()
{
}
- プログラムは下記の様に動きます。
- 立ち上がり
- ポートの初期化
- ポートを出力設定
- 1を出力
- 3秒待ち
- PERIPHをONに設定
- タイマーを5秒に設定
- DeepSleepへ
- 5秒のDeepSleep後、”1”へ
- プログラムではDeepSleep中もLEDは点灯しています。
- 18行をコメントアウトするとDeelSleep中GPIO2はリセットされ消灯します。
最後に
これでポートの制限は有りますが、DeepSleep時にポートの値を保持出来るようになりました。