工作と競馬2

電子工作、プログラミング、木工といった工作の記録記事、競馬に関する考察記事を掲載するブログ

ESP-WROOM-32 起動直後におけるGPIO出力レベルが、ポートごとに異なることについて調べてみた

概要

ESP-WROOM-32で、起動直後におけるGPIO出力レベルがポートごとに異なることを確認し、対処方法について考察した。


背景と目的

先日、ArduinoでESP-WROOM-32をいじっていたところ、GPIOの起動直後における出力レベルがGPIOポートごとに異なるようにみえる現象に遭遇した。具体的には、以下に示すように、ポートの入出力方向の設定後→出力レベルを設定すると、実際に出力されるまでの間HIGHが出力されるポートと、LOWが出力されるポートがあるように見えた。ポートごとの違いが本当にあるのか、チェックしてみる。

void setup () {
    pinMode(GPIO_NUM, OUTPUT);
    digitalWrite(GPIO_NUM, HIGH);
}


詳細

1. 環境

  • Arudino IDE 1.8.12
  • Arduino-esp バージョン調べ忘れた、2020/05/31時点での最新と思われる
  • ESP-WROOM-32 DevKit-C


2.方法

今回は、現象の確認が主な実施事項なので、あまり細かいところに立ち入らず、以下のように、2つのGPIOポートに対して入出力設定と出力レベル設定を行ったときに、出力レベルがどう遷移するか、オシロスコープによって波形を観測する。時間関係が分かりやすいように、2つのポート間に100msecの時間差をつけて観測しやすくしておく。ここで、

  • IO5: 常に、もう一方に対して100msec後にHIGHを出力する
  • 他のIO: IO5に先行する
  • IO34,35,36,39は入力専用なので除く
  • 負荷は何もつけない
void setup () {
    pinMode(他, OUTPUT);
    pinMode(5, OUTPUT);

    digitalWrite(他, HIGH);
    delay(100);
    digitalWrite(5, HIGH);
}


3. 結果

以下の通り、起動後0.5秒間の出力レベルが、GPIOポートによって異なるということが、明らかになった。 青はIO5の出力、赤はもう一方のGPIOの出力である。横軸0秒の時点でリセットボタンを押し、約0.2秒後にリセットボタンを離し、ESP32が再起動させている。その時点から約0.5秒後、IO5がいったんLOWに落ち、0.1秒後にHIGHになることから、LOWに落ちた時点でpinModeが実行されている。

  • IO5,4,15: HIGHが出力される f:id:dekuo-03:20200816003201p:plain

  • IO0: HIGHが出力される(リセット中) f:id:dekuo-03:20200816003154p:plain

  • それ以外: LOWが出力される f:id:dekuo-03:20200816003157p:plain

なお、リセット前の出力レベルに依存しないか確かめるため、LOWを出力した状態でリセットし、起動後LOWを出力する場合についても調べた(赤=IO15)が、以下のように依存しないことが分かった。

f:id:dekuo-03:20200816003205p:plain


4.考察

Arduino-esp32特有の現象なのか、ESP-IDFでも同じなのかといったところは確認できていないが、ひとまず、ポート設定前の挙動を気にせず、ハードウェアを組むと思わぬ動きをするということが予想できる。実際、私はIO5を出力に設定したプログラムで、起動後勝手にHIGH出力がされて意図しない動きになってしまって困った。 対処方法としては、より望ましいレベルが出力されるポートを選択するべきということだ。具体的には、起動直後LOWであってほしい場合には、IO5,15,4は避けるといった感じに。また、ポートに接続される負荷によって出力電圧が変わる。以下は、10kΩの負荷がGNDとの間にぶら下がっている場合だが、0.7V程度までしか上がらない。細かいことはわからないが出力インピーダンスが大きい状態になっているようだ。負荷を利用してLOWになるようにする手もあるだろう。

f:id:dekuo-03:20200816005409p:plain


まとめと今後の課題

ESP-WROOM-32で、起動直後におけるGPIO出力レベルがポートごとに異なることを確認できた。ハード/ソフトを組む際に参考にしたい。