ESP32のGPIO研究

概要

Arduino IDEでのGPIOまわりを調査しなおしてみました。pinMode()まわりやアナログ入力のときにはどんなGPIOかを意識して利用する必要があります。

GPIO一覧

GPIO種類アナログ入力タッチ入力RTCPULLpinMode初期値
GPIO0I/OADC2_CH1TOUCH1RTC_GPIO11PULLUP
GPIO1I/OPULLUP
GPIO2I/OADC2_CH2TOUCH2RTC_GPIO12PULLDOWN
GPIO3I/OPULLUP
GPIO4I/OADC2_CH0TOUCH0RTC_GPIO10PULLDOWN
GPIO5I/OPULLUP
GPIO6I/OPULLUP
GPIO7I/OPULLUP
GPIO8I/OPULLUP
GPIO9I/OPULLUP
GPIO10I/OPULLUP
GPIO11I/OPULLUP
GPIO12I/OADC2_CH5TOUCH5RTC_GPIO15PULLDOWN
GPIO13I/OADC2_CH4TOUCH4RTC_GPIO14INPUT
GPIO14I/OADC2_CH6TOUCH6RTC_GPIO16INPUT
GPIO15I/OADC2_CH3TOUCH3RTC_GPIO13PULLUP
GPIO16I/OINPUT
GPIO17I/OINPUT
GPIO18I/OINPUT
GPIO19I/OINPUT
GPIO21I/OINPUT
GPIO22I/OINPUT
GPIO23I/OINPUT
GPIO25I/OADC2_CH8RTC_GPIO6
GPIO26I/OADC2_CH9RTC_GPIO7
GPIO27I/OADC2_CH7TOUCH7RTC_GPIO17INPUT
GPIO32I/OADC1_CH4TOUCH9RTC_GPIO9
GPIO33I/OADC1_CH5TOUCH8RTC_GPIO8
GPIO34IADC1_CH6RTC_GPIO4×
GPIO35IADC1_CH7RTC_GPIO5×
GPIO36IADC1_CH0RTC_GPIO0×
GPIO37IADC1_CH1RTC_GPIO1×
GPIO38IADC1_CH2RTC_GPIO2×
GPIO39IADC1_CH3RTC_GPIO3×

種類

GPIO34以降は入力専用です。PULLUPやPULLDOWNもできません。

アナログ入力

アナログ入力する場合にはADCに接続されているGPIOを利用する必要があります。ただしWi-Fiなどの無線を利用する場合にはADC2が利用できなくなります。一度でも無線を利用すると、再起動するか内部レジスタを書き換えない限りADC2は利用できないので、注意してください。

タッチ入力

タッチセンサーを利用できるGPIOです。タッチセンサーは無線を利用しても、利用できるGPIOが制限されません。

ただし、実際に使ってみるとGPIO32とGPIO33が逆なようですが、おそらく修正されないので実験してから使ってみてください。

RTC

RTCは内部的なGPIOへのアクセス方法で、ULPからアクセスする場合に利用します。ADCが使えるGPIOは、RTCでも接続できます。つまり、ULPからアクセスする場合にはアナログ入力が可能であるGPIOである必要があります。

RTCの端子番号の並びがGPIOとも、ADCとも違うので注意してください。

PULL

ESP32はGPIOに対して、PULLUPとPULLDOWNを設定することができます。細かい設定はpinMode()で解説を行いますが、入力専用端子のGPIO34以降はPULL系の機能も使えないので注意してください。

pinMode初期値

GPIOの起動直後のピンモード設定です。ただしArduinoや、その他ライブラリなどにて再初期化されている場合があるので注意してください。

pinMode()一覧

モード入力接続入力値範囲LOW出力HIGH出力
INPUT0 – 1
INPUT_PULLUP3.3Vに抵抗経由で接続0 – 1
INPUT_PULLDOWNGNDに抵抗経由で接続0 – 1
ANALOG0 – 4095
OUTPUT0V(GND)3.3V
OUTPUT_OPEN_DRAIN0V(GND)Hi-Z

INPUT

デジタル入力としてLOW(0)かHIGH(1)を入力します。すべてのGPIOで利用可能です。ESP32は3.3V動作ですので、25%の0.825Vより低い電圧の場合LOWになり、75%の2.475Vより高いとHIGHになります。26%から74%までの間はどちらになるかわかりません。ただし、実測では大体50%の電圧で判定しています。

閾値に近い電圧の場合には、ノイズなので入力値が変わったりするのでなるべくGNDか3.3Vかを入力されるようにしてください。

未接続(フローティング)のGPIOに対して入力を行うと、端子の残っている静電気のようなものを入力してしまうので、値が信用できなくなりますので注意してください。

INPUT_PULLUP

INPUTと同じく、デジタル入力としてLOW(0)かHIGH(1)を入力します。入力専用のGPIO34以降のGPIOだと利用できないので注意してください。

電源の3.3Vに抵抗経由で接続されている端子で、通常はHIGHの入力になりますが、スイッチなどでGNDに落とすことでLOWに変化します。

未接続のGPIOでもHIGHが安定して入力することができます。通常がHIGHなので、ノイズの影響を受けにくいために利用されることがあります。

INPUT_PULLDOWN

INPUTと同じく、デジタル入力としてLOW(0)かHIGH(1)を入力します。入力専用のGPIO34以降のGPIOだと利用できないので注意してください。

GNDに抵抗経由で接続されている端子で、通常はLOWの入力になりますが、スイッチなどで電源に接続することでHIGHに変化します。

未接続のGPIOでもLOWが安定して入力することができます。通常のINPUTに比べるとノイズの影響は受けにくいです。

ANALOG

GPIOADC無線未使用時無線使用時
GPIO0ADC2_CH1
GPIO2ADC2_CH2
GPIO4ADC2_CH0
GPIO12ADC2_CH5
GPIO13ADC2_CH4
GPIO14ADC2_CH6
GPIO15ADC2_CH3
GPIO25ADC2_CH8
GPIO26ADC2_CH9
GPIO27ADC2_CH7
GPIO32ADC1_CH4
GPIO33ADC1_CH5
GPIO34ADC1_CH6
GPIO35ADC1_CH7
GPIO36ADC1_CH0
GPIO37ADC1_CH1
GPIO38ADC1_CH2
GPIO39ADC1_CH3

アナログ入力として0 – 4095の値を入力します。入力範囲はanalogReadResolution()にてADC取得解像度設定で、より荒い値に変更することができます。

0は0V、4095は3.3Vに対応していますが、精度はそれほど高くないので注意して利用してください。

ADCに接続されているGPIOでのみアナログ入力が可能です。GPIO32以降であればどんな状況でも利用可能です。無線を利用しない場合にはADC2に接続されている端子でも利用が可能です。

OUTPUT

デジタル出力としてLOW(0V, GND)かHIGH(3.3V)を出力します。入力専用を除き、GPIO0からGPIO33までのGPIOで利用可能です。

LOWの0Vに出力は、GPIOに接続されている端子をGNDとつなげることを意味します。外部からの電圧をそのGPIOに吸い込む方向になります。LEDなどのマイナス側をGPIOに接続して、LOWにすることでLEDを点灯させることが可能です。

OUTPUT_OPEN_DRAIN

デジタル出力としてLOW(0V, GND)かHIGH(Hi-Z, 未接続)を出力します。入力専用を除き、GPIO0からGPIO33までのGPIOで利用可能です。

HIGHのHi-Z(ハイインピーダンス)は未接続の状態です。I2Cなどで別の回路からPULLUPされている場合などにLOWを出力することでGNDに接続し、HIGHを出力した場合にはなにもしません。これは、PULLUPされている場合に3.3V出力をしても電源の無駄になるので、未接続にします。

未接続GPIOに注意

GPIOに何も接続していない場合に入力値が不安定になります。これはADCに静電気のような電荷が残っており、その値を取得しているため正しい値ではありません。

この値は不安定で、変わることもありますし、直前に入力したGPIOの値に引きづられることもあります。接続されていないGPIOの値は読み取らないか、INPUT_PULLUPかINPUT_PULLDOWNなどで内部的に接続することで、値が安定します。

また、ESP32のタッチセンサーは電荷をチャージして、その後入力値を取得することで、触っている場合には電荷が人に移動してLOWになったことを確認していたりします。

pinMode()の未設定に注意

アナログ入力の場合、pinMode()を設定していない場合、内部でアナログ入力モードに切り替わっておらず、デジタル入力相当の0か4095しか戻ってこないGPIOがあります。

起動時にアナログ入力に初期化されているGPIOもあるのですが、安全のためすべてのGPIOを利用前にpinMode()の設定をすることを心がけてください。

参考になるかもしれないページ

外部参考ページ

ハードウエア解説

関数解説

まとめ

あまり日本語でESP32のpinMode()に関する資料がありません。とくに未設定の場合にアナログ入力が動いているように見えて、おかしな数値が戻ってくるので注意してください。

また、GPIO34以降の入力専用GPIOはPULLUPやPULLDOWNが利用できないのもはまりやすいので注意してください。

コメント

  1. hk より:

    GPIO一覧
    https://lang-ship.com/blog/work/esp32-gpio/#toc2
    の表のうち特に「pinMode初期値」について、espressifの技術文書から探していますが見つかりません。(esp32_datasheet_en.pdf、esp32_technical_reference_manual_en.pdf等)
    差し支えなければ引用元をお教えくださいますか。

    • たなかまさゆき より:

      esp32_datasheet_en.pdf
      P63
      Appendix A
      IO_MUX

      上記の横になっている表のAter Resetの

      • wpu: weak pull-up;
      • wpd: weak pull-down;

      ここを拾ってきた気がしますがesp32_technical_reference_manual_enにももしかしたら同じようなデータがあるかもしれません

  2. hk より:

    ありがとうございます。確認できました。参考にします。