概要
Arduino IDEでのGPIOまわりを調査しなおしてみました。pinMode()まわりやアナログ入力のときにはどんなGPIOかを意識して利用する必要があります。
GPIO一覧
GPIO | 種類 | アナログ入力 | タッチ入力 | RTC | PULL | pinMode初期値 |
GPIO0 | I/O | ADC2_CH1 | TOUCH1 | RTC_GPIO11 | ○ | PULLUP |
GPIO1 | I/O | ○ | PULLUP | |||
GPIO2 | I/O | ADC2_CH2 | TOUCH2 | RTC_GPIO12 | ○ | PULLDOWN |
GPIO3 | I/O | ○ | PULLUP | |||
GPIO4 | I/O | ADC2_CH0 | TOUCH0 | RTC_GPIO10 | ○ | PULLDOWN |
GPIO5 | I/O | ○ | PULLUP | |||
GPIO6 | I/O | ○ | PULLUP | |||
GPIO7 | I/O | ○ | PULLUP | |||
GPIO8 | I/O | ○ | PULLUP | |||
GPIO9 | I/O | ○ | PULLUP | |||
GPIO10 | I/O | ○ | PULLUP | |||
GPIO11 | I/O | ○ | PULLUP | |||
GPIO12 | I/O | ADC2_CH5 | TOUCH5 | RTC_GPIO15 | ○ | PULLDOWN |
GPIO13 | I/O | ADC2_CH4 | TOUCH4 | RTC_GPIO14 | ○ | INPUT |
GPIO14 | I/O | ADC2_CH6 | TOUCH6 | RTC_GPIO16 | ○ | INPUT |
GPIO15 | I/O | ADC2_CH3 | TOUCH3 | RTC_GPIO13 | ○ | PULLUP |
GPIO16 | I/O | ○ | INPUT | |||
GPIO17 | I/O | ○ | INPUT | |||
GPIO18 | I/O | ○ | INPUT | |||
GPIO19 | I/O | ○ | INPUT | |||
GPIO21 | I/O | ○ | INPUT | |||
GPIO22 | I/O | ○ | INPUT | |||
GPIO23 | I/O | ○ | INPUT | |||
GPIO25 | I/O | ADC2_CH8 | RTC_GPIO6 | ○ | ||
GPIO26 | I/O | ADC2_CH9 | RTC_GPIO7 | ○ | ||
GPIO27 | I/O | ADC2_CH7 | TOUCH7 | RTC_GPIO17 | ○ | INPUT |
GPIO32 | I/O | ADC1_CH4 | TOUCH9 | RTC_GPIO9 | ○ | |
GPIO33 | I/O | ADC1_CH5 | TOUCH8 | RTC_GPIO8 | ○ | |
GPIO34 | I | ADC1_CH6 | RTC_GPIO4 | × | ||
GPIO35 | I | ADC1_CH7 | RTC_GPIO5 | × | ||
GPIO36 | I | ADC1_CH0 | RTC_GPIO0 | × | ||
GPIO37 | I | ADC1_CH1 | RTC_GPIO1 | × | ||
GPIO38 | I | ADC1_CH2 | RTC_GPIO2 | × | ||
GPIO39 | I | ADC1_CH3 | RTC_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出力 |
INPUT | – | 0 – 1 | – | – |
INPUT_PULLUP | 3.3Vに抵抗経由で接続 | 0 – 1 | – | – |
INPUT_PULLDOWN | GNDに抵抗経由で接続 | 0 – 1 | – | – |
ANALOG | – | 0 – 4095 | – | – |
OUTPUT | – | – | 0V(GND) | 3.3V |
OUTPUT_OPEN_DRAIN | – | – | 0V(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
GPIO | ADC | 無線未使用時 | 無線使用時 |
GPIO0 | ADC2_CH1 | ○ | |
GPIO2 | ADC2_CH2 | ○ | |
GPIO4 | ADC2_CH0 | ○ | |
GPIO12 | ADC2_CH5 | ○ | |
GPIO13 | ADC2_CH4 | ○ | |
GPIO14 | ADC2_CH6 | ○ | |
GPIO15 | ADC2_CH3 | ○ | |
GPIO25 | ADC2_CH8 | ○ | |
GPIO26 | ADC2_CH9 | ○ | |
GPIO27 | ADC2_CH7 | ○ | |
GPIO32 | ADC1_CH4 | ○ | ○ |
GPIO33 | ADC1_CH5 | ○ | ○ |
GPIO34 | ADC1_CH6 | ○ | ○ |
GPIO35 | ADC1_CH7 | ○ | ○ |
GPIO36 | ADC1_CH0 | ○ | ○ |
GPIO37 | ADC1_CH1 | ○ | ○ |
GPIO38 | ADC1_CH2 | ○ | ○ |
GPIO39 | ADC1_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が利用できないのもはまりやすいので注意してください。
コメント
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にももしかしたら同じようなデータがあるかもしれません
ありがとうございます。確認できました。参考にします。