ウィリアムのいたずらの、まちあるき、たべあるき

ウィリアムのいたずらが、街歩き、食べ物、音楽等の個人的見解を主に書くブログです(たま~にコンピューター関係も)

GPIOの電圧変換(5V⇔3.3V)について:プルアップ、オープンドレイン等

2016-12-26 12:02:09 | Weblog
以前のエントリ

PCより値段が高い?小型ボードコンピュータIntel Joule(じゅーる)の話を聞いてきた!
http://blog.goo.ne.jp/xmldtp/e/8b7c95dc006a91c80316f9dab50b5471


GPIOの電圧変換(5V⇔3.3V)をしなけりゃいけないところで、
抵抗を入れるとか、オープンドレインとか、プルアップとか、かなり怪しげ
に使っていたので、どういうときに、何をするかについて、まとめておきます。

それをしないと、どういう羽目になるかということも含めて・・・




■まずは、GPIOの入出力と、電圧の関係を考える

たとえば、
 Raspberry PiはGPIO 3.3V
 Arduinoでは、GPIO 5V
なので、Raspberry Pi,Arduinoをつないで、GPIOを使う場合、
電圧の関係は、3とおりある

(1)出力電圧が高く、入力電圧が低い(OUTがArduino,INがRaspberry Pi等)
→高い電圧のものを、電圧を下げて入力したいとき
(2)出力電圧が低く、入力電圧が高い(OUTがRaspberry Pi,INがArduino等)
 →低い電圧のものを、電圧を上げて入力したいとき
(3)出力電圧と入力電圧が同じ(OUTがRaspberry Pi,INもRaspberry Pi等)

さらに、Raspberry Piに、スイッチ等(マイコン等のGPIO以外)をつないで、GPIOを使う場合
(4)入力に、なにかをつなぐ場合(SWなど)
(5)出力に、なにかを使う場合(LEDなど)

このうち、
 (3)は、つなげばよい(GNDもつながないといけないケースもあるけど、
    とりあえず、この後述べるような、プルアップ等の話とは関係ない)
 (5)は、つなぐ先のものが、高いものを要求していれば(1)、
    低いものを要求していたら(2)なので、そこで書く。

ということで、(1)、(2)、(4)について説明する。これらは全部、対応が違う




■(1)出力電圧が高く、入力電圧が低い→抵抗分圧を使う

 OUTがArduino 5V,INがRaspberry Pi3.3Vのようなケース。
 これは、抵抗分圧という方法を使う。

 以下のサイトに例がある
5Vから3.3Vに分圧する
http://make.bcde.jp/circuit/5v%E3%81%8B%E3%82%893-3v%E3%81%AB%E5%A4%89%E6%8F%9B%E3%81%99%E3%82%8B/


【方法】

・抵抗を2本以上用意する。
  →ここでは1KΩと2KΩとする。
・それらを直列につなぐ(3本以上あるなら直列+並列、並列+直列にしても可)
  → --1KΩ--2KΩ--
・GPIOの出力(=高電圧)の端子を抵抗の一端に、他方をGNDに接続する
  →   *--1KΩ--2KΩ--*
      |            |
   Arduino OUT          I N
・GPIOの入力(=低電圧)の端子を、抵抗間のところに、他方をGNDに接続する
  →
         RasPi I N     OUT
             |      |    
      *--1KΩ-*-2KΩ--*
      |             |
   Arduino OUT           I N

→この方法を、抵抗分圧といいます。
 
【なぜ、これでOKなのか】
 オームの法則E=IRなので、抵抗に比例した電圧が流れます。
   いま、Arduinoは、3KΩ(1+2)の抵抗なので、ここに5Vを流すと、
 Raspberry Piは、2KΩ=Arduinoの3分の2の抵抗がつながっているので、
   電圧も、3分の2つまり、3.333333・・Vの電圧が流れます。
 これがほしかった電圧です。めでたしめでたし。

【変形-(5)の場合】
 上記のケースは、ただしく電圧がほしいときで、LEDをつなげるように、適当に
下がった電圧が欲しい&つなげるものもある程度の抵抗値というときには、2本の抵抗ではなく、
1本の抵抗と、1本のLEDを直列につないで、上記のような抵抗分圧をさせます。

【これをしないと】
 高い電圧が流れることになり、低い入力電圧側のプロセッサを壊す可能性が
ないとはいえません。




■(2)出力電圧が低く、入力電圧が高い→オープンドレイン+プルアップを使う

【戦略】
 直流電流で、低い電圧をそのまま高くするという方法は、簡単ではないです。
(交流にしてしまえば(=インバーターを入れる)、トランスで簡単に出来る)
 そこで、高電圧のものを持ってきて、それを低電圧で制御(SW-ON/OFF)
すると言う方法を取ります。

 実は、このケース、いろいろやり方があるのですが、一番オーソドックス
 と思われる、オープンドレイン+プルアップを使う方法を書きます。


【方法】
・汎用ICには、NAND,ORなどいろいろありますが、「なにもしない」という
 バッファというものがあります。74HC07等がそれです。これを秋葉原か
 通販で買ってください。ついでに、ブレッドボードやジャンパ線、抵抗(10KΩ位)も
 →74HC07は、バッファなのですが、「オープンドレイン」と呼ばれます。
  それを買ってください。以下、これをICと書きます。

・低電圧(Raspberry Pi)を、以下のようにつなぎます。ブレッドボード上でやってね!

    Ras PiのGNDピン- ICのGND
    Ras Piの3.3V - ICのVCC(VDD)
    RasPiの出力端子  - ICの1番(3番、5番・・でもいい)

    ICのGND-ブレッドボードのGND(端の青のライン)

・高電圧を、以下のようにつなげます。 
ArduinoのGNDピン-ブレッドボードのGND(端の青のライン)    
    Arduinoの5Vピン-ブレッドボードのVCC(VDD)(端の赤のライン)
    ICの2番(1番を使った場合)-抵抗の一つの足
    抵抗の他方の足-ブレッドボードのVCC(VDD)(端の赤のライン)
    Arduinoの入力ピン-ICの2番と、抵抗の一つの足の間

つまり、
 →ブレッドボードのVCC→プルアップ抵抗ー*→Arduino→GND
                      |
                      * ICの2番ピン *→GND
                               |
                      * ICの1番ピン | 
                      |
                     RasPi 出力     →GND

・・・なんですけど、通じてます?ごめん、いま回路図をかける環境にないので・・・
(気が向いたら、後日、ここに回路図が入る)

 このときの抵抗(買ってきた10KΩ)を、プルアップ抵抗と呼びます。

【なぜ、これでOKなのか】
 オープンドレインは、
・信号がLOWのとき、LOW信号を出します。
 なので、RasPiから1番ピンでLOWを受け取ると、
     ICの2番ピンにLOW信号を出します。
     ICの2番ピンとArduinoの入力は並列なので(抵抗の並列つなぎ=同じ電圧)、
     Arduinoの入力もLOWになります・・・OK!

・信号がHighのとき、High(3.3)でなく
   「ハイインピーダンス」Zを返します。
 こうすると、2番ピンが電気的に切れることになり、ICに電流は流れません。
 →ブレッドボードのVCC→プルアップ抵抗→Arduino→GNDの
  流れだけになります。

  もともとArduinoの入力ポートには、
    そんなに電流が流れない=(オームの法則より)抵抗値がめちゃくちゃ大きい
  ものになっています。

  入力ポートの抵抗値はプルアップ抵抗10KΩより、はるかに大きいので、
    抵抗分圧により、はるかに大きいAduinoの入力ポートに、5Vほとんどの電圧が
    かかります(そしてちょっと電流が流れる)・・・OK


 この場合、プルアップ抵抗がなければいけません。
 ただし、Raspberry Piでは、ソフトウェア的にプルアップ抵抗をかけることが出来ます。
 (というか、設定されています)※


【これをしないと】
 規定電圧に達しない場合、Highになったことが、高電圧側で、認知できません。
 したがって、つないで信号をHighにしても、LOWが続いていると思って、
 なにもおこりません。




■(4)入力に、なにかをつなぐ場合→プルダウン抵抗

【戦略】

 実は
   Ras Pi3.3Vにスイッチのいったん
   Ras Pi入力にスイッチの他端
 で、うごきます。動くのですが、おかしな動きをすることがあります。

 GNDに繋がっていないので、電位が確定していないし、
 スイッチが切れているときにアンテナ代わりになって、
   ほかの回路に流れた電流から生じた電磁波を拾ってしまい
   ノイズがでたりするかもしれません。
→ノイズが出る:
  ソフト的にいうと、イベントが2回上がったり、上がり続けたりして、
  正しくイベントが取得できなくなる。

 そこで、GND、スイッチの他端間に抵抗を置いて、これを防ぐことがあります・・
 ・・ってか、たいていこうします。
 これを、プルダウン抵抗といいます。

・・・なんですけど、通じてます?ごめん、いま回路図をかける環境にないので・・・
(気が向いたら、後日、ここに回路図が入る)

 プルダウン抵抗を小さくしてしまうと、抵抗側に電流・電圧が流れてしまうので、
 大きくします。

 ただし、Raspberry Piでは、プルダウン抵抗も自動的に設定することが出来ます
 (というか、設定されています)※

【方法】
・Ras Pi3.3Vにスイッチのいったん
・Ras Pi入力にスイッチの他端
 ここまでは上述
・RasPi入力=スイッチの他端に抵抗(10KΩとか)をつけて
・もう一方の抵抗の端をGNDにつけます

【なぜ、これでOKなのか】
・スイッチから、RasPiのところを書くと、こうなりますよね

3.3V--SW-*ー10KΩーーGND
       |        |
       Ras Pi 入力  RasPiGND

つまり、 SWは直列、RasPiとプルダウン抵抗(10KΩ)は並列です。
SWはほとんど抵抗が無いので、抵抗値が大きい、プルダウン抵抗+RasPi入力に
3.3Vほとんどの電圧が流れます(抵抗分圧)

そして、プルダウン抵抗とRasPiは並列なので、同じ電圧が流れます(ほぼ3.3V)
電流は小さくなっちゃうけど、大丈夫、入力ポートへの電流は、小さくてもOKです。

【これをしないと】
・しなくても大丈夫なことも結構あるんだけど、
 しないと、不可解な動きをすることも、結構ある。




■まとめ

(1)出力電圧が高く、入力電圧が低い→抵抗分圧
(2)出力電圧が低く、入力電圧が高い→プルアップ+オープンドレイン
(3)出力電圧と入力電圧が同じ   →そのままつなぐ
(4)入力に、なにかをつなぐ場合  →プルダウン抵抗
(5)出力に、なにかを使う場合   →相手先の電圧による

と対策が違います。そして、ArduinoとRaspberry Piをつなぐ場合、
 Arduinoが出力なら(1)、Arduinoが入力なら(2)
(RasPiはその逆)
 と、入出力によってやることが違うので、一概に、抵抗を入れるとか、
オープンドレインとかいえないのです・・・ここに注意が必要です。

※Raspberry Piのプルアップ、プルダウンは

Raspberry PiのGPIOは起動直後から内部プルダウンされている
http://d.hatena.ne.jp/hnw/20150607

を参照


この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« ドミノピザ、サーバーのシス... | トップ | PDFの読み解き方 »
最新の画像もっと見る

Weblog」カテゴリの最新記事