☆youtube更新中☆
▶Youtubeのチャンネル登録で更新頻度がUPするかも!!

Youtubeで文章にするのが難しい内容について
実際にしゃべって解説しています。
ブログでは紹介していない(しにくい)内容も
じゃんじゃん更新中。

▶Youtubeでhobbyhappyを応援する

Arduinoの割り込み(interrupts)を使ってチャタリングが出た話【ソフトで解決】

chattering_eyecatchArduino(マイコンボード)
この記事は約7分で読めます。

今回は、Arduino標準で搭載されている割り込み(interrupts)の機能と、

それを使った時のチャタリングについてお話していきます。

実際チャタリングとはどんなイメージなのかはこちらをご覧ください。↓↓

Arduinoで割り込みさせてチャタリング発生している様子。

イメージとしては、割り込みで反応しているものの、

1回ボタンを押しただけなのに、割り込みが複数回入ってしまう感じです。

割り込みの中でONとOFFを反転させるような仕組みになっていたので、

この場合、ONとOFFが一瞬で2回切り替わって、ONのままのように見える。

という仕組みですね。

一番手前の黒いボタンが調子が悪いのが何となくわかってもらえると思います。

【チャタリング起こしにくいスイッチにすればいいじゃん…】

というのは無しで、今回はソフト側からチャタリングを防止してみました。

自己紹介

東証一部上場企業でサラリーマンしてます。

主に工場(生産現場)で使用する検査装置のアプリケーション開発してます。

ヒトの作業を自動化して簡略化するアプリケーションを日々開発中。

転職に成功して現在は超大手企業でシステム系の開発をしています。

Youtubeチャンネルにさまざまな動画を上げています

↓↓↓こちらからYoutubeチャンネルにアクセス!! ↓↓↓

チャタリングとはなんなのか?実際の回路も紹介。

チャタリングとは何なのかについてですが、

マルツさんが詳細を説明してくれているので

こちらを参考にしてください。

スイッチのチャタリングの概要。チャタリングを防止する方法 | マルツオンライン

簡単に説明すると、

1回の切り替えで接点がバウンドして超高速で2回信号が変わってしまったりする現象です。

機械的なスイッチを使う以上、避けられない現象で、

何かしらの対策を入れる必要がある。というのが一般的な流れです。

対策方法としては、メカ的なものと、ソフト的なものがありますが、

今回はソフト的なアプローチをしてみようと思います。

動画のようなチャタリングが起きる回路

まず、冒頭の動画のようにチャタリングが発生する状態をご紹介します。

配線はこちらです。スイッチ2個とLEDという構成です。

chatterring
チャタリングテスト用のテスト回路。

ArduinoNanoの互換機を動画では使用していますが、

ArduinoUNOでも同じことができますのでご安心ください。

スイッチはD2,D3,LEDはD12につなげています。

LEDの抵抗だけ忘れないように気を付けてくださいね。

割り込み(interrupts)を使用してチャタリングが起きる。

今回は割り込み処理を使用するのが目的だったので、

Interruptsを使用します。

ArduinoのモデルによってInterruptsを使用できるピンは決まっています。

詳しくは公式のこちらに掲載されています。↓↓

attachInterrupt() - Arduino Reference
The Arduino programming language Reference, organized into Functions, Variable and Constant, and Structure keywords.

内容としては、UNOにしてもNanoにしても、

2番ピンと3番ピンのみが割り込み処理のトリガーにできるピンです。

interruptsPins
interruptsが使用可能なピン(公式より)

というわけで実際のスケッチはこちらです。

const byte ledPin = 12;
const byte interruptPinB = 2;
const byte interruptPinG = 3;

volatile byte state = LOW;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPinB, INPUT_PULLUP);
  pinMode(interruptPinG, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPinB), blink, RISING);
  attachInterrupt(digitalPinToInterrupt(interruptPinG), blink, FALLING);
}

void loop() {
  
}

void blink() { 
  state = !state;
  digitalWrite(ledPin, state);
}

上記のスケッチをそのまま書き込むと、1回タクトスイッチを押すと、

何回かに1回消えるはずが消えなかったり、

点くはずが点かなかったりするはずです。

それがチャタリングです。

チャタリングを防ぐ方法(スケッチ紹介)

チャタリングの説明の時に、メカ的な対策とソフト的な対策があると紹介しましたが、

メカ的な対策としては、コンデンサやシュミット・トリガなどを使うのが一般的なようです。

コンデンサは手持ちでありますが、

どうせやるなら書き込むスケッチで何とかならないかチャレンジしてみました。

チャタリング対策したスケッチ。

それではここが知りたかったところだと思いますのでもったいぶらずにご紹介します。

const byte ledPin = 12;
const byte interruptPinB = 2;
const byte interruptPinG = 3;

byte ledState=LOW;
bool switchFlg=false;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPinB, INPUT_PULLUP);
  pinMode(interruptPinG, INPUT_PULLUP);
  
  attachInterrupt(digitalPinToInterrupt(interruptPinB), blink, RISING);
  attachInterrupt(digitalPinToInterrupt(interruptPinG), blink, RISING);
  Serial.begin(9600);   
}

void loop() {  
  if(switchFlg)
  {       
    delay(300);    // チャタリング発生時間だけ待つ。ここは個体差あり。
    ledState=!ledState;
    digitalWrite(ledPin,ledState); 
    switchFlg=false; 
    Serial.println("LEDblink");  
    }    
}

void blink() { 
  switchFlg=true;  
  Serial.println("interrupt!");
}

先ほどに比べてloop関数の中にいろいろ入れているのがわかりますかね。

実は、チャタリングしていたスケッチに対して対策した内容としては、

割り込みで実行される関数の中でLEDのONOFFをさせないようにしています。

割り込み自体はタクトスイッチ=チャタリングが発生するもの。

という構図になるので、割り込み関数の中でLEDの処理の実行部分を入れておくのは危険です。

では、割り込み関数の中でやっていることはなんでしょうか?

void blink() { 
  switchFlg=true;  
  Serial.println("interrupt!");
}

実は、割り込みされましたよ。とフラグをTrueにしているだけです。

これなら、何度Trueになりましたよ。とloopの中に入ってきたとしても、

実際の処理を行うのはloop関数の中なので何度もLEDのONOFFは実行されないということになります。

もう一つ大事なのが、

loop関数内のdelay(300)つまり待ちですね。

void loop() {  
  if(switchFlg)
  {       
    delay(300);    // チャタリング発生時間だけ待つ。ここは個体差あり。
    ledState=!ledState;
    digitalWrite(ledPin,ledState); 
    switchFlg=false; 
    Serial.println("LEDblink");  
    }    
}

この待ちは、チャタリングしている場合、

つぎの割り込みが入ってきたとしても無視するためのものです。

逆に考えると、300mmSec以上の長期間チャタリングを起こす場合は防げません。

300mmSecもdelayを入れると若干押してから反応するまでのタイミングにラグが発生するので、

なるべくなら短くしたいですよね。

ちなみにこの対策版のスケッチを書き込んで動作テストしたのがこちらの動画です。

チャタリングをソフト的に対策。

タイムラグは人間が感じられるレベルですが、

チャタリングするよりはましかな…といった感じですね。

冒頭の動画は光ったり光らなかったりなのでそれよりは全然いいですね。

今回のまとめ。

メカ的なチャタリングの対策方法はネット上にも結構あるのですが、

ソフト的に解決するアプローチに対してもちょっと紹介してみました。

Arduino限定にはなってしまいますが、割り込み処理を入れようとしてチャタリングして

困っている…という場合には参考にしてみてください。

コメント

タイトルとURLをコピーしました