概要
今回は RTC GPIO に付いての説明です。RTC GPIOの特徴はDeepSleep中も値を保持出来る点です。
GPIO と RTC GPIOの違いは?
ESP32のマニュアル によるとGPIOの一部としてRTC GPIOが有る様です。またRTC GPIOはULPによって管理されるとも有りました。 機能面で一番大きな違いは、通常のGPIOはDeepSleepに入るとリセットされるのに対し、RTC GPIOはDeepSleep中も値を保持出来る点です。
RTC GPIOのピンはどれ
下記はRTC GPIOについてまとめた表。GPIOポート一覧 と比べると、ポート数は 18個。GPIOでアナログ機能を持ったポートが RTC_GPIO の様です
| I/O | GPIOピン |
|---|---|
| Input Only | GPIO 34, 35, 36, 39(要プルアップ・ダウン用の抵抗) 37, 38 |
| Input & Output | GPIO 0, 2, 4, 12, 13, 14, 15, 25, 26, 27, 32, 33 |
使い方
- 初期化
- esp_err_t rtc_gpio_init(gpio_num_t gpio_num)
- 引数: gpio_num(RTC機能を持つピン番号)
- 戻り値:
- ESP_OK: 初期化成功
- ESP_ERR_INVALID_ARG: 指定したピンがRTC GPIOに対応していない場合
- 指定したポートのみ RTC が有効になる。digitalWrite()等は使用出来ない。
- 元に戻すには rtc_gpio_deinit() を使用
- esp_err_t rtc_gpio_init(gpio_num_t gpio_num)
- I/O設定
- esp_err_t rtc_gpio_set_direction(gpio_num_t gpio_num, rtc_gpio_mode_t mode);
- gpio_num: 設定するRTC GPIOの番号。
- mode: 設定したい入出力モード。
モード名 内容 RTC_GPIO_MODE_INPUT_ONLY 入力設定 RTC_GPIO_MODE_OUTPUT_ONLY 出力設定 RTC_GPIO_MODE_INPUT_OUT_HIGH_IMP 入力設定かつ、出力はハイインピーダンス RTC_GPIO_MODE_OUTPUT_OD オープンドレイン出力として設定 RTC_GPIO_MODE_INPUT_OUTPUT 入出力両方を有効にする
- esp_err_t rtc_gpio_set_direction(gpio_num_t gpio_num, rtc_gpio_mode_t mode);
- 出力
- esp_err_t rtc_gpio_set_level(gpio_num_t gpio_num, uint32_t level);
- 引数: gpio_num 設定したいGPIO番号。
- 引数: level 0(Low)または 1(High)。
- esp_err_t rtc_gpio_set_level(gpio_num_t gpio_num, uint32_t level);
- 入力設定
- rtc_gpio_pullup_en(gpio_num): 内部プルアップを有効にする。
- rtc_gpio_pulldown_en(gpio_num): 内部プルダウンを有効にする。
- rtc_gpio_pullup_dis(gpio_num) / rtc_gpio_pulldown_dis(gpio_num): 無効にする。
- 入力
- uint32_t rtc_gpio_get_level(gpio_num_t gpio_num);
- gpio_num ポートを指定
- 戻り値: ピンの状態 0 (Low) か 1 (High) 。
- uint32_t rtc_gpio_get_level(gpio_num_t gpio_num);
Deep Sleepへの対応
- esp_err_t gpio_hold_en(gpio_num_t gpio_num);
- ディープスリープ(Deep Sleep)に入った際、あるいはリセットが発生した際に、 特定のGPIOピンの出力状態やプル設定を物理的に(ラッチ)させる関数。
- gpio_num: RTC_GPIO番号
- ホールドを有効にすると、スリープから復帰して setup() が再び実行されてもそのピンは固定されたまま
- 解除には gpio_hold_dis(gpio_num_t gpio_num); を使う
- esp_err_t esp_deep_sleep_pd_config(esp_sleep_pd_domain_t domain, esp_sleep_pd_option_t option);
- ディープスリープ中における各電源ドメインの動作状態を制御する関数
- 設定オプション
ドメイン名 制御対象 ESP_PD_DOMAIN_RTC_PERIPH RTC GPIO、I2C、Hallsensor, ADC等、ULPコプロセッサ。 ESP_PD_DOMAIN_RTC_SLOW_MEM RTCスローメモリ(ULPプログラムやスリープを跨ぐ変数の保存領域)。 ESP_PD_DOMAIN_RTC_FAST_MEM RTCファストメモリ(ディープスリープ復帰後のスタブプログラム等の保存用)。 ESP_PD_DOMAIN_XTAL 外部水晶発振器 ESP_PD_DOMAIN_VDDSDIO SDIOインターフェース用の電圧レギュレータ 設定 詳細 ESP_PD_OPTION_OFF そのドメインの電源を強制的にOFFにする ESP_PD_OPTION_ON そのドメインの電源を強制的にONに保つ。 ESP_PD_OPTION_AUTO (デフォルト)ウェイクアップソースなどの設定に基づいて、システムが自動で判断する。
RTC_GPIOの出力をDeepsleep中保持したいなら、"esp_err_t gpio_hold_en(gpio_num_t gpio_num);" のみでOKです。esp_err_t esp_deep_sleep_pd_config(esp_sleep_pd_domain_t domain, esp_sleep_pd_option_t option); は保険の感じ。
確認
動作を下記の回路とプログラムで確認しました。
#include "Arduino.h"
#include "driver/rtc_io.h"
#include "esp_sleep.h"
#define uS_TO_S_FACTOR 1000000ULL
void setup() {
Serial.begin(115200);
delay(100);
Serial.println("LED点灯準備");
// RTC GPIOの設定
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);
// 重要:スリープ中も現在の状態(HIGH)を物理的に固定する
gpio_hold_en(GPIO_NUM_2);
// RTC周辺回路の電源を維持 (保険)
esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
esp_sleep_enable_timer_wakeup(5 * uS_TO_S_FACTOR);
Serial.println("5秒間のスリープに入ります(LEDは点灯したままになります)");
Serial.flush(); // 送信完了を待つ
esp_deep_sleep_start();
}
void loop() {
}
5秒間のDeepSleepを繰り返すスケッチです。 DeepSleepの間もちゃんとLEDは点灯していました。
最後に
DeepSleep 時でも出力を保持出来る RTC_GPIO。自作機器では電力消費を抑える為に DeepSleep をよく使用します。 その時、RTC_GPIOが威力を発揮します。