Blinkから始まるArduino入門 その7 でかいスイッチ

 Blinkのスケッチは、勝手にLEDのON/OFFを繰り返しました。現実は、何かの指示でONしたりOFFするというのが一般的です。ここでは、スイッチを押すと、LEDが光るという動作を想定します。

 筆者は最初に就職した会社で高周波溶解炉を仕事で使っていました。約1kgのニッケル合金が溶けると、でっかくて赤い色をしたストップ・スイッチをグーでたたきます。絶対に止まってくれないと困ります。スイッチの内部は、銀合金の接点で構成されています。リレーも銀合金の接点が使われています。数mAぐらいの大きな電流をON/OFFさせる回路では確実に動作しますが、電流が少ないと、正しく動かないことがあります。

 接点を見ると、カチッとスイッチが入ったとき、OFFからONに、もしくはONからOFFに遷移するように思えますが、約10msの間、ON/OFFが繰り返すという現象が頻繁に起こります。チャタリングという現象です。

 電子デバイスの入力回路は、何もつながれないとき、電波などのノイズを拾ってしまい、かってにON/OFFすることがあります。なので、使用していない端子はGNDにつないだり電源にプルアップして中途半端な電圧を避けます。入力に使う場合は、通常プルアップ抵抗を入れ、常に電源電圧レベルにしておき、スイッチをGNDとの間に入れ、確実にスイッチONで入力端子が0Vになるように設計します。

 まとめると、次の3項目になりますが、対応しなくても動く場合があります。Arduinoの場合は、3番目の対応だけは忘れずにします。

  • 接点には少し電流が流れるようにする
  • ON/OFFが繰り返すチャタリング現象は避けられない
  • プルアップは必須

タクト・スイッチ

 電子機器のあらゆるところで使われるのが、押しボタン・スイッチの「タクト・スイッチ」です。ふつうは下の図の押すところの上に、「電源」とか▼の名前の印刷された薄い板がのっかっているので、直接見ることはありません。電源スイッチも、最近では直接電池やACラインをON/OFFすることはなくなっています。タクト・スイッチが押されると、プログラムで必要な終了処理をしてから、リレーなどで電源を切ります。

 

 タクト・スイッチは、タクタイル・スイッチ、タクティール・スイッチ、プッシュ・モーメンタリ・スイッチとも呼ばれます。プッシュ・スイッチに分類され、押したときだけ接点がつながるので、モーメンタリ・スイッチの分類でもあります。

 接点は一組ですが、リード線は4本あります(2本脚の製品もある)。安定で配線しやすいです。外見を正方形に見てしまうと、どちら側がつながっているかが判別できません。じっくりと見ると長方形です。長辺側がつながっています。

 ブレッドボード(正式にはソルダーレス・ブレッドボード)に挿して配線します。Arduinoの2番ピンに接点の一方を、もう一つの接点はGNDへつなぎました。タクト・スイッチの見えている側は短辺です。

 ルール「プルアップは必須」を無視してスケッチを動かします。

#define inputSwitch 2
#define outputLED 13

void setup() {
pinMode(inputSwitch, INPUT);
pinMode(outputLED, OUTPUT);
}

void loop() {
digitalWrite(outputLED,HIGH);
if (digitalRead(inputSwitch) == LOW ) {
digitalWrite(outputLED,LOW);
}
delay(1000);
}

 タクト・スイッチを少し長押し0.5秒ほど押します。LEDは消えますが、消えたままになります。もう一度押すと点灯します。どうも思ったような動作になっていません。

pinMode(inputSwitch, INPUT_PULLUP );

 スケッチをプルアップ抵抗ありに変更します。今度は、長押しすればLEDはいったん消え、約1秒後に点灯し、想定通りの動きをします。

でかいスイッチ

 タクト・スイッチは現代の電子機器には欠かせない部品になりました。しかし、押しずらいです。そこで、アマゾンで大きめのスイッチを探しました。

digitalRead()の実行時間

 digitalWrite()の実行時間は連続して実行したときの差から約3.8usでした。入力の関数digitalRead()はどのくらいの時間で読み取るのでしょうか。次のスケッチで推測しました。

#define inputSwitch 2
#define outputLED 13

void setup() {
pinMode(inputSwitch, INPUT);
pinMode(outputLED, OUTPUT);
}

void loop() {
digitalWrite(outputLED,HIGH);
digitalRead(inputSwitch) ;
digitalWrite(outputLED,LOW);
}

 上の波形が入力なしの場合です。約3.4usのパルス幅です。下の波形はリードを追加した上記のスケッチです。約7.4usなので、リードにかかる時間は約4.0usです。

タクト・スイッチのチャタリング

 何度かタクト・スイッチを押してみたのですが、チャタリングの現象をほとんど観測できませんでした。

 ほかのスナップ・スイッチや大きな押しボタンは、ほぼすべてのタイミングでチャタリングが起きています。次の図はスナップ・スイッチの観測例です。

 上記のように明確にON/OFFが発生する場合以外に、中途半端な電圧が発生することもあります。次の観測例は、大きな押しボタンの例です。マイコンの入力がLOWとHIGHを判断する電圧はデータシートに書かれています。ATMega328を電源電圧5Vで利用するときは、LOWは1.5V以下、HIGHは3.0V以上です。

大きな押しボタンのチャタリング対策

 チャタリングの対策には、ハードウェアとソフトウェアのどちらか、もしくは併用があります。一番簡単なハードはコンデンサをGND間につなげます。

 次の積分回路で、コンデンサC1が0.1uFと0.01uFでの差を観測しました。

 スケッチです。

void setup() {
pinMode(3, INPUT);
}

void loop() {
digitalRead(3);
delayMicroseconds(10);
}

 0.1uFです。

 0.01uFです。

 シュミット・トリガ回路を入れて、ヒステリシス機能で中途半端な電圧のひげ状のノイズを取り去る回路もありますが、ATMega328のディジタル入力にはすでに入っているので、外部につける必要性は低いです。0.1uFのように時定数が大きいとチャタリングは除去できても電圧がms単位でゆっくり変化するのは望ましくありませんが、シュミット・トリガがあれば、HIGH/LOWはきっちりと判断できます。

 ソフトウェアの対策は、一度読んだ数ms後に再度読み、同じレベルであれば、そのレベルは正しいと判断します。しかし、スイッチを押したこと以外でLOWになることはあり得ません。人のスイッチを押すスピードは連続で100ms前後です。そうすると、スイッチが押されたかの判定、押された回数をカウントするようなスケッチでは、チャタリングを考慮する必要はないと思われます。

 しかし、OFF時、つまり、LOWからHIGHになるときにもチャタリングは生じるので、HIGHになったらLEDを消灯するスケッチであれば、5から10msのタイムラグを置いたのちにスイッチを読みに行きHIGHであれば、間違ってLEDが点灯することを避けられます。

前へ

Blinkから始まるArduino入門 その6 リレー