uchan が 2021年09月27日11時49分38秒 に編集
共振の説明を若干修正
本文の変更
この記事はタクトスイッチのチャタリングを細かく検証します。 ## チャタリングとは タクトスイッチ(プッシュスイッチ)はこんな見た目のスイッチです。  普段は端子間が絶縁され、ボタンを押すと端子間が導通する仕組みです。ボタンを押したり離したりするときに機械的に接点が動くため、細かく見ると電気的に導通した状態と絶縁した状態を繰り返します。これをチャタリングと呼びます。マルツオンラインの [スイッチのチャタリングの概要。チャタリングを防止する方法](https://www.marutsu.co.jp/pc/static/large_order/1405_311_ph) が詳しいです。 この記事では、チャタリング時の電圧を観測した結果を紹介します。筆者はチャタリングに特に詳しいわけではありませんが、観測結果が何かの役に立てば幸いです。 ## 実験回路 チャタリングの観測に用いた 3 種類の回路を紹介します。  回路 A はタクトスイッチを単にプルアップしただけです。チャタリングの防止は特に意図していない回路です。下図のようにブレッドボードで実装しました。  回路 B は回路 A にチャタリング防止用コンデンサを追加したものです。マルツの記事には出てこない回路ですが、実際に Tang Nano という FPGA ボードで採用されていたりします。参照:[FPGAでスイッチ入力を受けるときにregを使うと安定する](https://elchika.com/article/7adfb60a-2de4-48ae-9103-9340b41d422b/) 回路 C は先のマルツの記事で解説されているものです。回路 B に抵抗 R2 が追加された形です。 ## 回路 A の観測波形 まず、回路 A の動作を観測することで、今回使用したタクトスイッチやブレッドボードに実装した回路の特性を見ておきましょう。チャタリング防止措置を何も行っていませんので、スイッチの生のチャタリングの様子が見られるのではないかと思います。  上図はオシロスコープで回路図の OUT 点の電圧を観測したものです。時間軸(横軸)は 10ms/div で、電圧軸(縦軸)は 1V/div となっています[^1]。トリガは立ち下がりエッジ、閾値 2.02V に設定しました[^2]。トリガ位置は左から 3 目盛りの場所としました(図下側の黄色い「↑」矢印)。 [^1]: 「div」は 1 マス(目盛り)のことを意味します。横軸の 1 マスが 10 ミリ秒、縦軸の 1 マスが 1V ということです。 [^2]: 「トリガ」とは信号を記録するタイミングを指定する機能です。トリガを「立ち下がりエッジ、閾値 2.02V」としたので、電圧が 2.02V より高い状態から 2.02V より低い状態になったときに信号が記録されます。 それにしても綺麗な波形ですね。チャタリングなんてなさそうに見えます。マルツの記事によれば、チャタリングの継続時間は「数100μsec~数10msec程度」だそうですから、ちょっと横軸の設定が粗すぎたかもしれません。今度はより詳細に、1ms/div で観測してみます。  この図はオシロスコープの「パーシステントモード」を使いました。パーシステントモードとは、複数の信号を重ねて表示するモードで、さらに色の違いで頻度が分かるようになっています。青が低頻度、赤が高頻度を表します。左上に「100 swps」とあるのは、100 回トリガがかかった、すなわち 100 個の信号が重なっていることを意味します。「100 回トリガがかかった≒スイッチが 100 回押された」と解釈できます。 上図を見ると、トリガ位置(左から 3 目盛り)までは 5V で、スイッチを押した瞬間に 0V になる、という「5V→0V パターン」が赤で表示されています。20% 以上の頻度の場合に赤になるように設定していますので、この 5V→0V パターンは 100 回中 20 回以上の頻度で出現したということになります。 逆に 0V→5V になるパターンも記録されています。こちらは赤くなっていませんから、20% 未満の頻度ということが分かります。このパターンはスイッチを離したときの電圧変化だろうと思います。実験回路はプルアップですから、スイッチを離すと 0V→5V になりますよね。 でもちょっと待ってください。立ち下がりエッジでトリガをかけているので、立ち上がりエッジ(0V→5V になった瞬間)では信号は記録されないはずです。なぜ 0V→5V パターンの信号が記録されているのでしょうか? これこそがチャタリングなのだろうと思います。ボタンを離すと、機械式の接点が微妙に絶縁したり、導通したりを繰り返し、最終的に絶縁状態に落ち着くと考えられます。このときに、一瞬だけ 5V→0V の変化が起こるので、トリガとして検知されて信号が記録されたのだと思います。  もっと細かく観測した結果が上図です。先ほどの図を単に拡大したものではなく、横軸の設定を変えた後に再測定しました[^3]。 これも先ほどと同様、5V→0V パターンが主流で、たまに 0V→5V パターンが現れています。先ほどの観測結果と合わせて見てみると、「スイッチを押したとき」よりは「スイッチを離したとき」の方がチャタリングが酷いということが分かります。むしろ、押したときはほとんどチャタリングが起きていません。このタクトスイッチ、なかなか優秀なのでは!? [^3]: 今回使ったオシロスコープでは、再測定しないと横軸の設定変更が反映されないためです。 ## 回路 B の観測波形 回路 B でスイッチを押したときの波形を示します。  回路 A に比べ、0V→5V パターンの出現頻度が激減しています。というか、100 回のスイッチ操作では 1 回も 0V→5V パターンが現れていません。これは回路的にも納得できる結果です。回路 B はコンデンサ C1 に抵抗 R1 から充電する回路になっており、スイッチを離したときのチャタリング程度では充放電が全く間に合わず、トリガの閾値を超える電圧にならないということでしょう。 もう少し時間軸を拡大して観察してみます。  0V→5V パターンは依然として観測されないものの、5V→0V パターンの波形がかなり荒れています。見えにくいですが、トリガ前後でノイズのように上下に振動しています。少ないながらも、6V や -2V 付近にも点が打たれています。  さらに時間軸を 0.1μs/div に拡大して観察しました。これは酷い荒れ模様です。コンデンサ C1 を追加することで、スイッチを離すときのチャタリングはある程度防げるようになった反面、押したときの信号が汚くなりました。
この現象は多分、部品のリードや配線によるインダクタンス成分(コイル成分)と、コンデンサ C1 によって共振のようになっているのだと思います。スイッチを押す前は C1 は満充電状態で、回路に流れる電流は 0 です。スイッチを押した瞬間に R1 にいきなり電流が流れるため、このような振動が発生したと考えられます。
この現象は多分、部品のリードや配線によるインダクタンス成分(コイル成分)と、コンデンサ C1 によって共振のようになっているのだと思います。スイッチを押す前は C1 は満充電状態で、回路に流れる電流は 0 です。スイッチを押した瞬間に C1 からスイッチにいきなり電流が流れるため、このような振動が発生したと考えられます。
## Tang Nano の観測波形 実験回路 B と同様、抵抗とコンデンサを 1 つずつ用いたスイッチ回路になっている Tang Nano ボードでも波形を観測してみました。電源電圧が 3.3V である以外は、回路 B と同等の構成です。  回路 B の観測と似て、0V→3.3V パターンは観測されませんでした。しかし、トリガの瞬間に 3.3V を超えたり、0V を下回る現象が見られます。  回路 B より酷い様相を呈しています。チャタリング(あるいは CR 発振)の継続時間もさることながら、電源電圧の超え方も酷いように見えます。  電圧がどこまで高くなるのか気になったので、縦軸を 1/2 に縮小し(2V/div)て観測したのが上図です。最後に観測された信号を黄色の実線で表示しています。 これは酷い……。全体的に汚い波形なのもそうですが、9V を超える電圧になる場合があることが特に悪いです。下限は -3V 付近まで下がるパターンが観測されました。これも良くないです。Tang Nano に搭載されている FPGA チップ GOWIN GW1N-1 の入出力ポートの定格はなぜかデータシートに載っておらず分かりませんでしたが、3.3V で動作する IC チップに 9V、あるいは -3V を印加するのは、通常は許されないと思います。まあこれで良く FPGA が死なずに動いているなあ、という感想です。 ## 回路 C の観測波形 これがチャタリング防止回路の本命です。マルツの記事で紹介されているくらいですから、信頼性がありそうです。回路を見ると、R2 と C1 によりローパスフィルタを構成し、スイッチのチャタリングという高速に変化する信号をカットする構成であることが分かります。  いやはや、綺麗です。時間軸を拡大して観測もしてみたのですが、回路 B のような信号の乱れが観測されることもありませんでした。  時間軸を 10 倍に拡大した図も載せました。特に変な振動が起きることもなく、綺麗なグラフです。 綺麗なグラフになったのは、回路 B に比べ、R2 によりゆっくりと C1 が放電されるようになった影響です。急激に電流が変化すると、配線等によるインダクタンス成分により振動が発生しますが、このようにゆっくりと放電させればその影響も出ないようです。 ただ、その分スイッチを押してから反応するまでにラグが発生するというデメリットはあります。5V から 2V に変化するまでに 0.12ms ほど時間がかかっています。これを長いとみるか、短いとみるかは回路の目的によって違うでしょう。60FPS で動作するゲームなら 1 フレーム 16.6ms 程度ですから、0.12ms 程度の遅延なら許容できるかもしれません。 念のため回路 C における立ち上がりエッジ付近も測定してみました。  こちらも大体綺麗な充電グラフなのですが、でもチャタリングの影響で充放電を繰り返すケースもたまに発生するようです。100 回の観測結果からは、最大で 2.5V 付近まで充電されたのち放電されるケースがあることが分かります。 これは R1 や C1 が小さすぎて、スイッチを離した場合のチャタリングを防ぐ能力が足りないことを示唆しています。R1 や R2、C1 を大きな値にすれば、充電に時間がかかるようになるため、チャタリングをさらに緩和することができるでしょう。 スイッチを押した場合の遅延の観点からは、C1 と R2 はそのままで R1 を大きくするのが良いでしょう。R1 はスイッチ押下時の放電には寄与せず、充電にだけ寄与する部品だからです。C1 や R2 を大きくすると放電時間も延びてしまいます。 マルツの記事ではシュミットトリガインバータ(74HC14)を用いることで、さらに誤動作を下げる工夫が施されています。