ボタンスイッチのチャタリング対策!
4chのサーミスタ接続用ArduinoUNOシールドに、モノクロディスプレイ(AE-AQM0802)を搭載する事まで決まりましたが、表示できる文字数が8×2と少なく4ch全部の温度を同時に表示できません
チャタリング対策はCRローパスフィルター+シュミットトリガインバータの様に回路で対応する方法も有るようですが、コストパフォーマンスがあまりよろしくないです。
と言う事で、プログラムでチャタリング対策の実験をしてみました!
1. 実験!
普通にボタン入力をカウントするスイッチ1個と、チャタリング対策プログラムによるボタン入力をカウントするスイッチ1個で回路を作りました!
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.3 実験!
図2の回路で図3プログラムを実行して実験してみました。
〇対策無しボタン(7ピン):1回押すと高橋名人もビックリの50回位連打!
〇対策有りボタン(8ピン):1回押すと安定の1回カウント何度やっても1UP!
2. まとめ
プログラムでチャタリングキャンセルが出来る様になりました!