NOBのArduino日記!

NOBのArduino日記!

趣味は車・バイク・自転車・ラジコン・電子工作です。

ボタンスイッチのチャタリング対策!

イメージ 4
ボタンスイッチのチャタリング対策!
 
 4chのサーミスタ接続用ArduinoUNOシールドに、モノクロディスプレイ(AE-AQM0802)を搭載する事まで決まりましたが、表示できる文字数が8×2と少なく4ch全部の温度を同時に表示できません
 ならばボタンスイッチで表示を順番に切り替えればOK!と思ったのは良かったのですが、チャタリング※1の影響が厄介です
 チャタリング対策はCRローパスフィルター+シュミットトリガインバータの様に回路で対応する方法も有るようですが、コストパフォーマンスがあまりよろしくないです。
 と言う事で、プログラムでチャタリング対策の実験をしてみました
 
※1:チャタリング (英: chattering、Contact bounce、chatter) とは、可動接点などが接触状態になる際に、微細な非常に速い機械的振動を起こす現象のことである。

1. 実験!

 普通にボタン入力をカウントするスイッチ1個と、チャタリング対策プログラムによるボタン入力をカウントするスイッチ1個で回路を作りました!
 
1.1 接続
 回路接続図をFritzingを使って図1の様に書いてみました。 また図2の通り実際に繋げた状態を図2に示します。
イメージ 1
図1:ブレッドボード回路図

イメージ 2
図2:実際に作ったもの

1.2 プログラム
 図2の回路で、ArduinoUNOに書き込んだプログラムを図3に示します。
 チャタリング対策の部分は、「Arduino Button Library」を参考に「ButtonRead」関数として別にまとめてみました。(変数の宣言部分volatile…も必要)
 ButtonRead関数がTrueを返す判断基準は「ボタンを押した時」にしましたが、他にも「ボタンを離した時」や「ボタンが押されている時」「ボタンが離されている時」等も使えます。(/*…*/で囲ってあるグレーの部分)
/*20180828 NOBのArduino日記!(ボタンスイッチのチャタリング対策)*/
int Count = 0, Max = 100;  // Count:ボタンを押した回数、Max:Max到達で1に戻る

void setup() {
  pinMode(7, INPUT_PULLUP);  //7番ピンをプルアップし入力用に設定する
  pinMode(8, INPUT_PULLUP);  //8番ピンをプルアップし入力用に設定する
  Serial.begin(9600);
}

void loop() {
  // ButtonRead関数でカウント(チャタリング発生なし)
  if (ButtonRead(7)) {
    Count++;
    if (Count == Max) {
      Count = 1;
    } Serial.println(Count);
  }
  // 普通にカウント(40~60回チャタリング発生)
  if (digitalRead(8) == LOW) {
    Count++;
    if (Count == Max) {
      Count = 1;
    } Serial.println(Count);
  }
}

uint32_t ms, lastChange = millis(), dbTime = 25, Time = lastChange;
bool lastState = false, state = false, invert = false, changed = false, pinVal = false;
bool ButtonRead(uint8_t pin) {
  ms = millis(); pinVal = digitalRead(pin);
  if (invert) pinVal = !pinVal;
  if (ms - lastChange < dbTime) {
    changed = false;
  } else {
    lastState = state; state = pinVal; changed = (state != lastState);
    if (changed) lastChange = ms;
  }
  Time = ms;
  return !state && changed;//押した時True
  /*return state && changed;//離した時True
    return state;//離されている時True
    return !state;//押されている時True
    return state && Time - lastChange >= ms;//離された時True
    return !state && Time - lastChange >= ms;//押された時True*/
}
イメージ 1
図1:プログラム例

 

1.3 実験!
 図2の回路で図3プログラムを実行して実験してみました。

対策無しボタン(7ピン):1回押すと高橋名人もビックリの50回位連打!
 
対策有りボタン(8ピン):1回押すと安定の1回カウント何度やっても1UP!
 
イメージ 3
図5:Arduino IDE シリアルモニター

2. まとめ

 プログラムでチャタリングキャンセルが出来る様になりました!
 ArduinoUNOプログラム中でプルアップ出来るので、回路構成は「GPIOピン」⇔「ボタン」⇔「GND」だけと超お手軽に済みます
 
イメージ 1 イメージ 3
励みになりますのでよければクリック下さい(^o^)/

↩【NOBのArduino日記!】目次に戻る