備忘録的に書く。
跳ねるのを無視
Arduinoのサンプルに「debounce」というわけのわからないサンプルコードがあった。
bounce は「跳ねる」って意味。
de-bounce は「跳ねを防ぐ」もしくは「跳ねるのを無視する」みたいな意味。
なんのこっちゃと思ってじっくり読んで、実験して分かったこと。
スイッチって一瞬で変わるわけじゃない
ポチっと押すと、ONになったりOFFになったりする「スイッチ」って部品は、ミリ秒単位の世界で見ると「ONからOFF!」もしくは「OFFからON!」みたいにスパっと変わるものではないそうな・・・
電子工作の世界でのONとOFF
ONは電圧がかかっている状態。HIGHともいう。電圧は5Vとか3.3Vとか
OFFは電圧がかかっていない状態。LOWともいう。電圧は0Vに近い状態。
数ミリ秒(以下?)の世界
例えばONの状態のスイッチをポチっと押してOFFにして消したいとする。
すると実際には、数ミリ秒の間に、ONとOFFの間・・・つまり電圧でいうと例えば5Vと0Vの間を行ったり来たりするんだそうな。
これはスイッチが物理的なもので、押すといっても電気的に繋がる(切れる)のは「一瞬で一度」ではなくて一定の時間内に両方の状態がある不安定な状態を経て、繋がる(切れる)の状態に推移するから、なんだそうな。
これは部品ごとに違ったり、同じ部品でも年数が行くと変わってきたりするんだと。
ボールが跳ねる
この状態が、まるでボールが「ポンポンポン・・・ポン・・・ポン・・・」みたいに5Vになったり0Vになったりして、ボールが跳ねる状態に似ているからバウンドする(バウンス)と表現する。
そして、そういうバウンド状態を「無視」出来るようにプログラムを組むことを「debounce」というそうな。
YouTubeで「debounce」で検索するといくつか実際に跳ねてる状態をオシロスコープで見せてくれる。
どうやるか
具体的にどういう風にバウンスしている状態を無視するかというと、要は5ミリ秒とか10ミリ秒とか一定の時間のあいだ、ONもしくはOFFの状態が変わらなかったらそれは間違いない、っという判定をするやり方、が一般的らしい。
Arduinoのサンプルコードはその一例。
勉強になりました。
ライブラリあります
ところでサンプルコードだと一つのインプットピンに対していつかの変数を設けてLoopで処理してるけど、複数のインプットを使うとややこしいコードになるだろうな、と心配してたら、ちゃんとライブラリがありました。
クラスとして扱えるんで、インプットピンにつきそれぞれインスタンスを作成してやれば、すっきりしたコードでdebounce出来る(実験済)
ちなみに、旧バージョンのBounceと新バージョンのBounce2というのがあるけど、どちらでもいいらしい。作者は旧バージョンの方が好きだとWikiに書いてた。
引っ張り上げる
ところで、debounceのコードサンプルはスイッチを使った回路なわけだけど、その回路が「Pulldown回路」 というものだった。
これもなんのこっちゃっだったんで調べてみたらワンサと記事が出てきた。とても一般的な良くある問題(と解決)らしい。
Pulldownは「引き下げる」って意味かな。
逆に
Pullupだと「引っ張り上げる」
Pullupの方が一般的だ、という意見があったんでそうなのかもしれないけど、原理としてはどちらも同じ。
何を引っ張り上げるのか
ArduinoとかRaspberryPiなんかにはインプット端子がいっぱいついてる。
Arduinoの場合は特定の端子を「お前、インプットな」って指定するとそうなるんだけど、まぁどちらにしろインプットってことで、HIGHかLOW、つまり5Vか0Vかどちらが流れているかでその端子がONなのかOFFなのかを決める(5Vは例。他の電圧もある)
Pullupの時はインプットが無い状態(例えばスイッチが押されていない状態)では常にHIGHの状態にしておく、ということ。
Pulldownは逆に、常にLOWの状態にしておくこと。
やり方の前に・・・根本的な問題。
ふわふわ状態だと困る
この「引っ張り上げ」とか「引き下げ」が必要な理由は、Arduinoの場合、インプット端子は「なんだかよく分からない状態」になっている。おそらく静電気だとかノイズなどの環境の影響で、電圧がふわふわと浮いてる状態になってたりするらしい。そうなると、LOWになったりHIGHになったりして困ったことになる。
そういうのが気持ち悪い!好きなのか嫌いなのかはっきりしてよ!みたいなノリでHIGHなのかLOWなのかはっきりして、って言いたい。それがPullupしたりPulldownしたりする理由。
YouTubeで探した結果いちばん分かりやすかったのがこれ。
英語ではこのふわふわ状態を "floaging" というそうです。
Pullupする方法
要はインプットの端子に電源電圧の5Vだとかの電圧を掛ければいい。そうすると、インプットの端子を読んだらいつもHIGHになってる。Arduinoでいえば5Vって書いてある端子から出発して、目的のインプット端子(たとえば2番)につなぐ。
ただし!直接電源電圧5Vをインプットにつないだら大変なことになる可能性がある。いわゆるショート状態と同じで、なんの抵抗もなく5Vが流れるとなるとヤバイことになる。
なので、電源とインプット端子のあいだに抵抗器をおいてやる。この抵抗のオームの値を算出する方法とかいろいろ記事やブログがある。あるけど読んでない。10K オームを挟めとArduinoのサンプルに書いてあるんでそのまま鵜呑みで行った。
Pulldownする方法
これはちょうど対照的なやりかたで、Groundの0V(理論的に)をインプットにつないでやればインプットはスイッチが入って電源電圧がかからない限りはLOWになってる。
やはり同じように抵抗器をいれる。これって0Vだから要らないんじゃないのって気もするけど、Arduinoのサンプルでは使ってるので、これも理屈を理解してない状態だけど挟んだ。
このあたりはまぁそのうち追いついて理解できればいいか、ぐらいの気持ち。
まとめ
ということで「デバウンス」と「プルアップ回路」、「プルダウン回路」、それから「プルアップ抵抗」などというちょっとかっこいい言葉が分かるようになってきて自己満足にひたることが出来た。