【電子工作】プルアップ回路とプルダウン回路とは？（危険回路についても）

## はじめに
　大学で電子工作に触れていた時に、よくでてきた**プルアップ回路**や**プルダウン回路**。おそらく、電子工作を使ってなにか作品を作りたいという熱意を持つMakerならば、必ず一度は耳にしたことがあるのではないでしょうか。マイコンのピンを使った検知をしようとした際に必ず頭の片隅に留めて置かなければならない単語です。私が初めて耳にした時にとても理解に時間がかかってしまったので（非理系というのもあったのですが）、少しでも理解を深めるためにも記事にしました。*こういう分野に詳しいベテランの方の意見も是非聞いてみたいので、少しでも記事内容に疑問点や、こんな面白いことあるよ！というのがありましたら、容赦なくコメントいただければと思います。*

## ダメな回路（オープン回路・ショート回路）

　例えば、以下のような回路で**High**か**Low**を検知したいとします。
![オープン回路.jpg](https://qiita-image-store.s3.amazonaws.com/0/298123/4993b455-506a-ab61-bf0a-0d88f8b0fe9f.jpeg)
　インプットのピンを検知ピンとしたとき、ボタンがOFF（図の状態）のときは、Vccと繋がってないから**Low**、逆にボタンがOFFのときは、Vccと繋がっているから**High**だよね！ということで一見間違った回路ではないように見えます。
　しかし、結論からいうとこの回路はNGです。ボタンがONのときは正しい検知が可能ですが、OFFのときを考えてください。完全にインプットピンが宙ぶらりんになってしまっています。これを**オープン（開放）**と呼び、ここでは**オープン回路**と名付けます。このオープン回路はダメな回路です。

　では、次のパターンの回路はどうでしょうか。
![ショート回路.jpg](https://qiita-image-store.s3.amazonaws.com/0/298123/91eca82a-51b3-dee9-4c06-3a8d3b443ae6.jpeg)
　少しだけ複雑になりましたね。ボタンの配置がインプットピンと並列に並んだようになっています。この場合、インプットのピンを検知ピンとしたとき、ボタンがOFF（図の状態）のときは、Vccと繋がっているから**High**、逆にボタンがONのときは、GNDと繋がっているから**LOW**かな？ということで、これも間違っていなさそうです。
　しかし、この回路には大事故に繋がるトンデモナイ罠が隠されています。ボタンがONのとき、すなわち繋がっている状態を考えてみましょう。Vccからかかる電圧は、図の点部分で並列にインプットピンがある方とボタンがある方にかかっていきます。ここで、**並列回路**時の電圧のきまりを思い出してください。ボタンの方にかかっていく電圧V1とインプットピンの方にかかっていく電圧V2は**等しい**です。
![ショート回路2.jpg](https://qiita-image-store.s3.amazonaws.com/0/298123/d3f2097c-a9c1-9984-812d-17fc90c903d3.jpeg)
つまり、上の図に落とし込むと、

```math
V = V_{1} = V_{2}
```

となります。インプットピンの方は、マイコンのインプットピンがそれなりの大きな抵抗値をもっているため、特に問題はないでしょう。危険なのはボタンの方に流れた電圧にあります。ボタンというのは殆ど抵抗値を持っていません。ということで、**オームの法則**を使って流れる電流量I1を計算してみましょう。（オームの法則については、他サイトを参考にしてください）

```math
I_{1} = \frac{V_{1}}{R_{1}} 
```

上記が電流量I1を求める式で、ボタンの抵抗値R1は極めて0Ωに近い数値です。するとI1はいくつになるでしょうか。分母がほぼ0ということは、**I1→∞（無限大）**になってしまうことがわかると思います。これだけ大きな電流が流れるのが危険というのは、言及しなくてもわかるかと思います。これを**ショート（短絡）**と呼び、ここでは**ショート回路**と名付けます。このショート回路もダメな回路です。まあ実際はマイコンにそこまで大きな電流を流す力はないので、大事故になっちゃうというのはないかと思います。

## OKな回路（プルダウン回路）
　さてここからが記事の本題です。次の回路をみてみましょう。
![プルダウン回路.jpg](https://qiita-image-store.s3.amazonaws.com/0/298123/cd0f7662-f555-655d-c653-bbc1f18deb36.jpeg)
　2つのダメな回路と大きく違うのは、**抵抗がある**ことです。この抵抗が、ショート回路で問題となったショートを防ぐ役割を果たします。インプットのピンを検知ピンとしたとき、ボタンがOFF（図の状態）のときは、GNDと繋がっているから**Low**、逆にボタンがONのときは、Vccと繋がっているから**High**を検知することができます。結論から言えば、この回路はOKです。理由は、抵抗を介したおかげでショートが発生しなくなるからです。この抵抗を**プルダウン抵抗**といい、この回路を**プルダウン回路**といいます。
　またプルダウン抵抗というのはもう一つ大きな役割を担っています。インプットピンとGNDを繋げているこの抵抗は、**フローティング(floating)対策**としても使われます。どこにも繋がれていないピンは静電気等で**High**と**Low**を不安的に行き来するわけですが、これをGND側に引っ張って**Low**に安定させることから引っ張り下げるの意味を込めて**プルダウン抵抗**です。

## OKな回路（プルアップ回路）
　次の回路はプルアップ回路です。プルダウン回路と何が違うかが重要ポイントです。
![プルアップ回路.jpg](https://qiita-image-store.s3.amazonaws.com/0/298123/a94054e1-3330-3839-1075-9c78e89148dc.jpeg)
　抵抗とボタンの位置が入れ替わっただけですが、仕組みが大きく違います。インプットのピンを検知ピンとしたとき、ボタンがOFF（図の状態）のときは、Vccと繋がっているから**High**、逆にボタンがONのときは、GNDと繋がっているから**Low**を検知することができます。この回路も勿論OKです。理由は、この抵抗を**プルアップ抵抗**といい、この回路を**プルアップ回路**といいます。検知がプルダウン回路と正反対であることに注意です。プルダウン回路よりもよく使う印象があります。

## マイコンピンの内部プルアップ
　上記はマイコン外でプルアップ回路を作成していますが、実はマイコンでよく使われているArduinoおよびRaspberryPiにおいては、内部で既にプルアップ回路を形成しているおかげで、上のような組み方をしなくても大丈夫...なようです。

（Arduino）
　いくつか種類がありますが、マイコンチップがATmega328なら可能と書いてあったので、おそらく一般的なUNOでもできるような気がします。ピンの動作を入力か出力に設定する`pinMode(pin, mode)`をセットアップ内で行う時、第2引数のmodeに`INPUT_PULLUP`とすることで、内部プルアップを有効にできるようです。普通に`INPUT`だと有効にならないので要注意です。

（RaspberryPi）
　いろいろと調査してみましたが、できるという記事とできないという記事があるので怪しいです。ただできるという記事に関して言及すると、GPIO2とGPIO3は内部で抵抗が接続されているようです。（1.8kΩとの記述あり）ラズパイのプロセッサは、ソフトウェアの書き方次第でプルアップ設定ができるようなので、なんとな〜くいける気がします。ただ、手違いでダメだった！ということも考えられるので、マイコンに頼らずに自分で回路を作成した方が安全な気がします。


## まとめ
　プルアップ回路とプルダウン回路についてまとめてみました。

| 回路 | ボタンON | ボタンOFF |
|:---:|:---:|:---:|
| プルアップ | Low | High |
| プルダウン | High | Low |

　プルアップ・プルダウン抵抗に用いる抵抗値はおおよそ10kΩくらいが良いとされているみたいです。値によってまた違いがあり、プルアップかプルダウンでの違いもあるので、よく調査して再度記事にしたいと思います。

## 追記

- 12/21「マイコンピンの内部プルアップ」を作成しました。

## 参考(図)

- [Pull-up Resistors(sparkfun)](https://learn.sparkfun.com/tutorials/pull-up-resistors)
- [Arduino 日本語リファレンス](http://www.musashinodenpa.com/arduino/ref/index.php?f=0&pos=2014)
- [第22回 Raspberry PiのGPIO概要(ツール・ラボ)](https://tool-lab.com/make/raspberrypi-startup-22/)