マイコンのGPIOへボタンやスイッチを接続するときによく登場するのが、プルアップ抵抗とプルダウン抵抗です。
「ボタンを接続するだけなのに、なぜ抵抗が必要なの?」と疑問に思うかもしれません。
プルアップ・プルダウン抵抗には、入力端子の電圧が決まっていないフローティング(浮いた状態)を防ぎ、GPIOの状態をHIGHまたはLOWに安定させる役割があります。
この記事では、フローティングが起こる理由から、プルアップ・プルダウン抵抗の仕組み、抵抗値、マイコン内部のプルアップ機能、ボタンを使った実際の回路まで順番に解説します。
プルアップ・プルダウン抵抗とは?
プルアップ抵抗とプルダウン抵抗は、GPIOなどのデジタル入力端子の電圧を、あらかじめHIGHまたはLOWのどちらかへ安定させるために使用する抵抗です。
基本的な違いは非常にシンプルです。
| 接続先 | 通常時の入力 | |
|---|---|---|
| プルアップ | 電源(VCC)側 | HIGH |
| プルダウン | GND側 | LOW |
なぜこのような抵抗が必要なのかを理解するには、まずフローティングについて知る必要があります。
GPIOを何も接続しないとどうなる?
GPIOを入力として使用しているとき、その端子を電源にもGNDにも接続していない状態を考えてみましょう。
このときGPIOは、HIGHなのかLOWなのかを決めるための安定した電圧が与えられていません。
このような状態をフローティング(Floating)と呼びます。
入力端子は高インピーダンスであるため、周囲の電気的なノイズなどの影響を受け、意図しないHIGHやLOWとして読み取られることがあります。
そのため、デジタル入力では「何も操作していないときの状態」を明確に決めておくことが重要です。
上図のように、GPIO入力をプルアップまたはプルダウンすることで、スイッチがOFFのときにも入力端子の状態をHIGHまたはLOWへ決めることができます。
プルアップ抵抗の仕組み
プルアップ(Pull-up)では、GPIO入力を抵抗を介して電源側へ接続します。
3.3V │ [抵抗] │ ├──── GPIO入力 │ [スイッチ] │ GND
スイッチが押されていないときは、抵抗を介してGPIOが電源側につながっているため、入力はHIGHになります。
スイッチを押すとGPIOがGNDへ接続されるため、入力はLOWになります。
| ボタン | GPIO入力 |
|---|---|
| 押していない | HIGH |
| 押している | LOW |
そのため、プルアップ回路では「ボタンを押したらLOWになる」という動作になります。
なぜプルアップに抵抗が必要なの?
ここで重要なのが、「なぜ電源とGPIOを直接つながず、抵抗を入れるのか」という点です。
もしGPIOを3.3Vへ直接接続し、そのGPIOをスイッチでGNDへ接続すると、スイッチを押した瞬間に3.3VとGNDを直接接続する状態になってしまいます。
3.3V │ ├──── GPIO │ [スイッチ] │ GND
これは電源を短絡させることになるため、行ってはいけません。
そこで抵抗を入れることで、スイッチを押したときに電源からGNDへ流れる電流を制限します。
たとえば3.3V電源に10kΩのプルアップ抵抗を使用した場合、スイッチを押している間に抵抗へ流れる電流は、理想的にはオームの法則から次のように計算できます。
3.3V ÷ 10,000Ω = 0.00033A = 0.33mA
このように、抵抗には入力状態を決めるだけでなく、スイッチON時の電流を制限する役割もあります。
プルダウン抵抗の仕組み
プルダウン(Pull-down)では、GPIO入力を抵抗を介してGNDへ接続します。
3.3V │ [スイッチ] │ ├──── GPIO入力 │ [抵抗] │ GND
スイッチが押されていないときは、GPIOが抵抗を介してGNDへ接続されているためLOWになります。
スイッチを押すとGPIOが電源へ接続されるためHIGHになります。
| ボタン | GPIO入力 |
|---|---|
| 押していない | LOW |
| 押している | HIGH |
プルアップとプルダウンはどちらを使えばいい?
プルアップとプルダウンのどちらを使うかは、回路やシステムで「通常時をHIGHにしたいか、LOWにしたいか」によって決まります。
ボタン入力ではプルアップ構成がよく使われますが、必ずプルアップでなければならないわけではありません。
| 通常時 | ボタンON | |
|---|---|---|
| プルアップ | HIGH | LOW |
| プルダウン | LOW | HIGH |
使用するマイコンの内部プル抵抗の機能や、外部回路の構成なども考慮して選択します。
プルアップ抵抗は何Ωにすればいい?
プルアップ・プルダウン抵抗では、10kΩ前後の抵抗が使われることがあります。
ただし、「プルアップ抵抗は必ず10kΩ」という決まりがあるわけではありません。
抵抗値を小さくすると入力状態を強く固定できますが、スイッチON時などに流れる電流が増えます。
反対に抵抗値を大きくすると消費電流を減らせますが、ノイズや漏れ電流などの影響を受けやすくなる場合があります。
実際の抵抗値は、入力端子の仕様、配線長、ノイズ環境、消費電力などを考えて決めます。
マイコンには内部プルアップ抵抗がある
多くのマイコンには、GPIO内部にプルアップ抵抗やプルダウン抵抗を有効にする機能があります。
これを利用すると、ボタン入力などの簡単な回路では外付けのプルアップ抵抗を省略できる場合があります。
Arduino環境では、たとえば次のように内部プルアップを有効にできます。
pinMode(BUTTON_PIN, INPUT_PULLUP);
この設定ではGPIO内部のプルアップ抵抗が有効になり、何も操作していないときの入力がHIGH側へ保持されます。
対応しているマイコンでは、内部プルダウンを次のように設定できる場合もあります。
pinMode(BUTTON_PIN, INPUT_PULLDOWN);
内部プルアップ・プルダウンの有無や抵抗値、使用可能なGPIOはマイコンによって異なるため、実際に使用するときはデータシートやメーカーのドキュメントを確認しましょう。
INPUTとINPUT_PULLUPの違い
ArduinoでGPIO入力を設定するとき、INPUTとINPUT_PULLUPの違いが分からなくなることがあります。
| 設定 | 動作 |
|---|---|
| INPUT | 通常の入力。内部プルアップ・プルダウンを使用しない |
| INPUT_PULLUP | 入力+内部プルアップを有効にする |
| INPUT_PULLDOWN | 入力+内部プルダウンを有効にする |
INPUTに設定したGPIOへスイッチだけを接続し、スイッチOFF時に端子がどこにも接続されない回路にすると、入力がフローティングする可能性があります。
KUMITATE-C3で内部プルアップを使う
KUMITATE-C3に搭載されているESP32-C3でも、GPIOの内部プルアップ・プルダウン機能を利用できます。
たとえばボタン入力を内部プルアップで読み取る基本的なプログラムは次のようになります。
const int BUTTON_PIN = 21;
void setup() {
Serial.begin(115200);
pinMode(BUTTON_PIN, INPUT_PULLUP);
}
void loop() {
int state = digitalRead(BUTTON_PIN);
if (state == LOW) {
Serial.println("ボタンON");
} else {
Serial.println("ボタンOFF");
}
delay(100);
}
内部プルアップを使用してボタンをGPIOとGNDの間に接続した場合、ボタンを押していないときはHIGH、押したときはLOWになります。
「押したのにLOWになる」という点は最初は少し分かりにくいですが、プルアップ回路では非常によく使われる考え方です。
前回の「割り込み」と組み合わせるとどうなる?
プルアップ・プルダウンは、前回解説したGPIO割り込みとも密接に関係しています。
たとえば内部プルアップを使用したボタンでは、通常時がHIGH、ボタンを押した瞬間にLOWになります。
つまり信号はHIGH → LOWへ変化します。
そのため、ボタンを押した瞬間に割り込みを発生させたい場合は、FALLINGを利用できます。
attachInterrupt(
BUTTON_PIN,
buttonISR,
FALLING
);
このように、GPIO、プルアップ、割り込みはそれぞれ独立した知識ではなく、実際の回路では組み合わせて使用します。
I2Cでもプルアップ抵抗を使う
プルアップ抵抗はボタン入力だけで使用するものではありません。
代表的な例がI2C通信です。
I2CのSDAとSCLは、一般にプルアップ抵抗を使ってHIGH側へ保持する構成になっています。
ただし、I2Cのプルアップ抵抗値は通信速度や配線・バス容量なども考慮して決める必要があり、単純なボタン入力とは設計上の考え方が異なります。
I2Cについては「I2Cとは?SDA・SCL・アドレス・通信の仕組みを初心者向けに解説」で詳しく解説しています。
プルアップしてもボタン入力が不安定になることがある
プルアップ抵抗を入れればフローティングは防げますが、それだけですべての問題が解決するわけではありません。
機械式のボタンやスイッチでは、押した瞬間や離した瞬間に接点が細かくON・OFFを繰り返すことがあります。
この現象をチャタリングと呼びます。
特にGPIO割り込みとボタンを組み合わせた場合、1回ボタンを押しただけなのに複数回の割り込みが発生する原因になります。
プルアップ・プルダウンの次は、このチャタリングとデバウンスについて理解すると、ボタン入力回路をさらに正しく扱えるようになります。
まとめ
プルアップ・プルダウン抵抗は、GPIO入力の状態をHIGHまたはLOWへ安定させるために使用します。
- 入力端子がどこにも接続されていない状態をフローティングと呼ぶ
- フローティングした入力はノイズなどの影響で不安定になることがある
- プルアップでは入力を抵抗を介して電源側へ接続する
- プルダウンでは入力を抵抗を介してGND側へ接続する
- プルアップでは通常HIGH、ボタンを押すとLOWになる構成がよく使われる
- マイコンによっては内部プルアップ・プルダウンを利用できる
- ArduinoではINPUT_PULLUPなどを使って設定できる
- 抵抗値は用途や回路条件によって決める
プルアップ・プルダウンを理解すると、ボタン入力だけでなく、GPIO割り込みやI2Cなど、さまざまな回路で抵抗が使われている理由が理解しやすくなります。

