Superb Garbages 2

千野純一(chinorin)のはてなダイアリーの続きです。

電子回路の基礎の基礎③:LOWという名でもエネルギー

  • 前回の補足~
if ( digitalRead(D1) ) {
   digitalWrite(D2,LOW);   // LED OFF
} else {
   digitalWrite(D2,HIGH);   // LED ON
}
  • なんですかねこの体たらくは。自分で読み返していて気づきましたが。このプログラムは、下のように1行で書くことができまぁす。
digitalWrite(D2,!digitalRead(D1));
  • 違うんですよ。可読性の問題です。上の方が何やってるかわかりやすいでしょ? そういうことですよ。
  • ちなみにHIGHとLOWはシステム定数で、中身はそれぞれ1と0です。それからArduino言語はCと違ってbool型なんてものがありまして*1、bool型変数が持ちうる2つの値trueとfalse*2も1と0です。なおbool型変数が1byteなのはご愛敬っちゅーことでね。*3


  • HIGHは5VなのでそれそのものがLEDを光らせる。前回はそれをやりました。
  • 一方、LOWは0Vです。しかし驚くべきことに、マイコンのピンをLOWにすることでもLEDを光らせることができます。NOTゲートを使うとかそういうのじゃありません。それは前回やったし、もっと根本的な、物理現象の話です。

 

  • その前に、プルアッププルダウンの話~。電子回路を始めてまず教わるのがこれなんですけど、何すかねこれ。ボクはこの歳で電子回路をやって初めて聞きました。中学高校の授業でもやらないよね?
  • 曰く。集積回路(ICとかマイコンとか)のデジタル入力ピンは普段HIGHあるいはLOWに固定しておけとのことです。電源にもGNDにも繋がらず浮いている状態を「オープン」と呼ぶのですが、オープン状態のピンにかかる電圧は不安定で、ノイズなどの影響でふらふらとHIGHやLOWを行ったり来たりすることがあり、それによって誤動作を起こしたり耐久性を損ねたりするそうです。なるほど。
  • 例として「ボタンを押したらそれをマイコンで検知する」という回路を設計してみましょう。前提として⋯⋯電源は5Vとして、GNDというのは0Vです。電気は電圧に差があるところ(電位差と言います)に発生し、必ず電圧の高いところから低いところへ向かって流れます。5V電源とGNDを(直結すると理論的には電流が無限大っていうやべーことになるので必ず抵抗を介して)繋ぐと、5Vと0Vという電位差が生まれたことにより、電源からGNDに向かって電気が流れます。これをふまえて。
  • 最初に思いつくのは⋯⋯電源の5Vを引っ張ってきて、ボタンを設置し、その先にマイコンのピンという構造ですかね。このピンの状態を見て、HIGHならボタンが押されていて、そうでなければ押されていないということがわかるでしょう。
  • f:id:chinorin:20210924063423p:plain:w300
  • はい(HIGHだけに)、これが代表的な駄目回路です。ボタンを押していない間、マイコンのピン(PORT)はどうなってますか? オープンですよね。曰く、これではマイコンが誤動作を起こす可能性があるということです。5Vを検知させる回路においてオープン状態を回避するためにはプルダウン抵抗を使ってGNDを繋ぎます。
  • このプルダウン抵抗というのは部品の名前ではなく部品が果たす役割の名前です。部品そのものは普通の抵抗を使います。抵抗値は、10K~47KΩ程度で余ってるのを適当に使えばいいそうです。ボクはいつも10KΩを使ってます。
  • f:id:chinorin:20210924064523p:plain:w300
  • これが正解です。ボタンを押していない状態では、PORT側にノイズが発生したとしても問答無用で0VであるGNDへ落ちていきます。ということでこのあたりは常に0V、つまりPORTはLOWを検知します。
  • 一方ボタンを押している間は⋯⋯プルダウン抵抗とマイコンは並列なので*4どちらも同じ5Vの電圧がかかるはずです。というわけでPORTはHIGHを検知します。
  • この正しいつなぎ方をプルダウンと言います。回路図における位置的にも電位的にも低いところにあるGNDの方向に引っ張って落とすイメージです。
  • ソフト出身だとあんまりこういう考え方がしにくいのですが、電源とGNDを逆に扱うこともできます。どんなんやねんって思いますよね? ボクは思いました。
  • f:id:chinorin:20210924065918p:plain:w300
  • ボクは気持ち悪いんですけど、いかがでしょうか。これも正解だそうです。
  • ボタンを押していない状態では、プルアップ抵抗マイコンが直列に繋がっているので、両者の抵抗の比と同じ割合で分圧されます。こういう問題を考えるときの決まり事がひとつありまして、マイコンが持っている抵抗値はとても大きい(例えば数十MΩとかだそうな)と考えるので、仮に10MΩだとしても10KΩはたかだか1000分の1。前者が0.005V、後者が4.995Vとなり、これはだいたい5VなのでPORTはHIGHを検知します。*5
  • ボタンを押している間は、まず分岐前(プルアップ抵抗)と分岐後(ボタンとマイコンが並列)で分圧するようにも見えるのですが、ボタンのある経路は短絡(0Ωとみなす)なので、そこに並列で接続されているものは計算上は一切無視します。全ての電流はボタン側の経路を流れるため、マイコン側には電圧がかからず0V。よってPORTはLOWを検知します。
  • 既に自明とは思いますがこちらの正しいつなぎ方をプルアップと言います。位置的にも電位的にも高いところにある電源方向に引っ張り上げるイメージです。
  • プルアップの場合、プログラムはHIGHならボタンは押されていない、LOWならボタンが押されているという風に書くわけですが、プログラム的にはHIGHは真、LOWは偽なわけで、ボタンを押さなければ真、ボタンを押したら偽っていうのがなんかやりづらいんだよなあ⋯⋯と思うんですがなんと、電子回路業界ではどちらかというとこちらの方がスタンダードです。常に電気流しとくのってなんか無駄な気がするんだけど、どうやらそういうわけでもないらしいのよね。

 

  • で。ここでちょっと変な実験をしてみましょう。上に挙げたプルダウンの回路とプルアップの回路それぞれにおいて、PORTの近くに発光ダイオード(LED)を繋ぎます。LEDっていうのは原則、一方向にしか電気を通さないので互い違いに2個接続し、どちら方向に電気が流れてもどちらかが光るという状態にしておきます。ついでに、LEDを光らせるには抵抗の値が大きすぎるのでこちらもしれっと差し替えます。ボタンは回路図には残ってますが使いません。(下に挙げる回路のボタンを押すと、場合によっては電源、マイコン、LEDいずれも壊れる可能性があるので押さないでください。実際に組む場合は撤去していいです。)
  • それから、マイコンのピン(PORT)は上の回路では入力モードでしたが、今度は出力モードにして、そのピンをHIGHにしたりLOWにしたりというのをやってみます。まずはプルダウン。
    f:id:chinorin:20211001011039p:plain:w400
  • このPORTをHIGHにしたらどうなるでしょうか。PORTが5V、GNDが0Vということは電位差があるので電気が流れます。電気はPORTから出て、互い違いLEDの下は通れないので上の道を通り、抵抗を通ってGNDへ。ということで、上側のLEDが通電したので光ります。前回やったのと同じ、HIGHそのものが持つエネルギーによってです。
  • では、LOWではどうでしょうか。PORTが0V、GNDが0Vなので電位差がなく、電気が流れません。
  • 次に、同じことをプルアップの方でやってみましょう。
    f:id:chinorin:20211001011055p:plain:w400
  • まずPORTをHIGHにしてみます。電源が5Vで、PORTが5V。電位差がないので電気が流れません。
  • それではPORTをLOWにしてみます。電源が5Vで、PORTが0V。電位差があるので電気が流れます。電源から出てきた電気はまず抵抗を通り、互い違いLED上は通れないので下の道を通り、PORTへ。ということで、通電した下側のLEDが光ります。
  • どうでしょうか。マイコンのピンをLOWにすることで、LEDを光らせることができました。
  • 別にプルアッププルダウンは関係なくて(ついでに説明したかっただけw)、HIGHのピンとGNDを繋ぐとGND方向に電気が流れ、LOWのピンと電源を繋ぐとLOWの方向に電気が流れますよってだけのことです。
  • 言い換えるなら⋯⋯回路というものは通常、電源~GND間を流れる電気によって動かすものなのですが、その一部分を見た場合、マイコン集積回路が出力するHIGHは電源のように振る舞い、LOWはGNDのように振る舞うということですね。
  • なお、HIGHからもらう電気のことをソース電源、LOWが引っ張った電気のことをシンク電源と言います。ソースは普通に発生源みたいな意味のソース、シンクは流し台の排水口が水を吸い込むようなイメージみたいです。集積回路から発生させることができる電気の量にはどうしても限りがあるため、前者に比べると後者で電源からの電気を引っ張ってきた方が安定性が高いとされています。*6
  • 実際、ソース電源とシンク電源どちらも電子回路界隈では基本的な技って感じですが、シンク電源にはなんとなーくとんちみたいなものを感じてしまうのはボクだけでしょうか。出力ピンなのに吸い込むんですよ。

 

  • 今思いついたとんち的回路:ある出力ピンと別の出力ピンを接続すると「片方はHIGH、もう片方はLOW」という条件で電気が流れるので、それを検知することでNAND回路ができるんですね。へー。
  • いや待て、これ検知するの意外と難しいぞ。検知するための仕組みがGNDに繋がってたらHIGH-HIGHでも電気が流れて、NANDではなくORになってしまう。うーん⋯⋯まず思いつくのは双方向にしたフォトカプラ*7かなあ。(リレーは熱とかインピーダンスとかめんどくさいイメージしかないので考えたくない)
    f:id:chinorin:20211001015531p:plain:w600
  • 一番上か一番下のダイオードはなくても大丈夫だな。(10/7追記)いやだめだろ。フォトカプラ内のダイオードの一方通行性を他のダイオードのいずれかの代わりにできないかということなんだけど、おそらくどれも代替できない。こういうちょっとした勘違いがあったとき、ハマって抜け出せなくなるんだよなあ。
  • (11/11追記)これXORだと思うんだけど、NANDって言ってるのはNANDEだ?

*1:bool型:代表的な1ビット変数で、中に入る値は「真」か「偽」のどちらか。Arduino言語ではbooleanって書いても通る。真の型名はboolで、booleanの方が別名。

*2:trueとfalse:内部的にはたぶん定数なんだけど、小文字ってことは定数という理解をしないで欲しいってことだと思う。こういう値の表し方だけはモダンな感じなんだよなあ。

*3:boolなのに1byte(8bit):Arduino言語のベースになってるのはC言語。Cはポインタのアドレスがbyte単位なので、その関係でそうせざるを得ないんじゃないかな?

*4:マイコンは、この回路図に書かれていない別の経路でもともとGNDに繋がっています。GNDは全て電源のマイナス側に繋げるわけで⋯⋯並列に接続されているのが理解できますでしょうか。

*5:AVRのスレッショルド電圧はVH=2.6V、VL=2.1Vだそうな。意外と広いんだなあ。ちなみにAVRは必ずシュミットトリガなので、例えば電圧が一度HIGHの領域に入った後2.2Vくらいまで落ちてもまだHIGHです。2.1まで落ちて初めてLOWになります。逆も然り。

*6:どちらかというとシンク電源の方が安定:これに関する習慣が、プルダウンよりプルアップの方が好まれる理由のひとつだと思われます。いずれPNP型トランジスタとかカソードコモンとかを説明する機会があれば説明できるかも。

*7:フォトカプラ:入力A→出力Aを通電させると密閉された空間にあるLEDが光る。すると同じ空間にあるフォトトランジスタが反応し入力B→出力Bが通電するという部品。A系統とB系統が電気的に絶縁しているスイッチというかリレーの一種。