マイコン・プログラミング・メモ
チャタリング・キャンセル方法
ホームページに戻るトップページに戻る前ページに戻る次ページに進む最終ページに進む
マイコンでよく使用する、チャタリングキャンセルの方法について、これまで製作したものを基に紹介します。
1.チャタリングとは

チャタリングは、機械的なスイッチをON/OFFするときに発生する接点のバウンド現象のようなもので、切り換えのわずかな時間にON/OFFを繰り返す現象です。
照明のスイッチのようなものでは問題は起きないでしょうが、例えば電子機器の操作スイッチや機械的に接点がON/OFFするセンサーなど、ON/OFFの正確さを要求する場合にはチャタリングをキャンセルする、つまり無効化する仕組みが必要です。

2.チャタリングを除去する回路

次の図は、スイッチのチャタリングをキャンセルする回路としてよく見かけるもので、RSフリップ・フロップを使ってチャタリングを除去します。
しかし、スイッチ1つにNANDゲートが2つ必要で、しかもメイクとブレークの2接点(またはC接点)のスイッチでなければなりません。
スイッチが2~3個程度なら良いでしょうが、多くのスイッチあるいは多くの接点信号に対しては現実的ではありません。また、キーボード状の操作スイッチなどでは、C接点が使われることはほとんどありません。
チャタリングキャンセル回路

3.マイコンとスイッチの接続

次の図は、マイコンの入力ポートに機械的スイッチを接続する場合の回路例です。
チャタリングキャンセルをソフトウェアで行うとすれば、このように単に入力ポートにスイッチを接続するだけです。ただし、スイッチの数だけ入力ポートが必要です。
キーボードのようにスイッチの数が多い場合は、キー・マトリクスつまりキーを格子状配線の交点に配置して、ソフトウェアで順次スキャンする方法で入力します( こちら を参照)。
マイコンとスイッチの接続

4.チャタリングキャンセルの方法

次の図は、入力ポートで読み込んだスイッチのON/OFF状態から、ソフトウェアでチャタリングを除去する方法例を説明するものです。
チャタリングキャンセル方法説明図

(A) スイッチのON/OFF状態(“H”でOFF,“L”でONとする)
このようにON/OFF変化点でON/OFFが定まらない瞬間があり、これがチャタリングです。図はわかりやすく描いていますが、実際は接点の種類や構造、あるいは経年劣化などで幅(時間)や形状は異なります。
(B) マイコンが入力ポートでスイッチの状態を読み込むタイミング
一定周期の読み込みタイミングで、ON/OFFの幅(時間)を測定することにも使うので、1mS~10mSくらいの速度が必要です。チャタリングキャンセルは、この一定周期を作る割り込み処理の中で行われます。
(C) マイコンが認識したスイッチのON/OFF状態
この中の、幅の狭いONおよびOFFを無視する処理がチャタリングキャンセルとなります。
(D) チャタリングキャンセルの結果

「ON/OFF状態を示す」とあるのが、チャタリングを除去した現在のON/OFF状態です。チャタリングキャンセルした結果は、フラグとしてメモリ内に保持します。

チャタリングキャンセルは、あらかじめ決めておいた時間Tと、認識したスイッチのON/OFF幅を比較することで行われます。つまり、ONまたはOFFが時間Tに達する前に変化した場合は無視し、時間T以上になった場合は有効としてその時の状態(ONまたはOFF)を保持することにより行われます。
時間Tは、筆者の場合10~50mS程度としていますが、時間Tが長すぎるとスイッチの実際のON/OFFに対して反応が鈍くなります。この方法は幅の狭いON/OFFを除去する一種のノイズ除去であるため、機器外部からのON/OFF信号入力などにも使用できます。

上の図で"Tlong"とあるのは、長押しを認識する必要があるキースイッチなどのために、あらかじめ決めておいた時間です。Tlong時間(例えば2~3秒)以上押し続けたとき有効となるスイッチにすることができます。長押しキーが不要の場合、時間Tlongに伴う処理は必要ありません。
上の図で、(D)の「ONしたことを示す」というのは、チャタリングキャンセル済みのスイッチONを示すフラグで、スイッチ入力を使用するプログラムが監視し、確認後に“0”(OFF)に戻すことで、1度のスイッチONを1回だけ認識することができます。
また、「長押ししたことを示す」というのは文字通り長押しを認識したフラグで、同様に1度の長押しを1回だけ認識させるためのものです。


5.プログラム例

下記に、H8/3694Fの場合の、チャタリングキャンセルの処理フロー図例と、チャタリングキャンセルおよびキー入力のプログラム例を示します。
インターバルタイマによる定周期割り込みと、スイッチを接続した入力ポートがあれば、わずかな修正で他のマイコンでも利用できます。
備考:下記の例には、定周期割り込み発生に関する部分やI/Oポートの初期化などは含まれていません。

キー入力チャタリングキャンセルのフロー図例

キー入力チャタリングキャンセルのプログラム例

これらは、次に示す前提の下で作成されています。

1) 関数KeyChatCancelは、10mS 周期の割り込み処理関数から呼ばれるものとします。
    ただし、フロー図およびプログラム例に割り込み処理関数は書かれていません。
2) 6個のキースイッチがPORTB のb5~b0 に接続されているものとします。
3) キースイッチはON するとPORTB の該当ビットが“0”(LOW)になるものとします。
4) 読み込んだキー情報はKEYDAT_T型変数に格納され、関数GetKeyState,WaitKey,GetKeyで読み出すものとします。
    KEYDAT_T型の構造は、プログラム例を見てください。
5) オートリピート機能が有効なのはb1~b0に接続されたキースイッチで、長押しが有効なのはb3~b2に接続されたキースイッチです。

このプログラム例では、長押しとして認識する時間とオートリピートを開始する時間を同じにして簡略化しています。
オートリピート機能は、スイッチのON/OFFの幅(時間)を測定するタイマをリセットすることで、スイッチONを繰り返し認識させて実現しています。
また、このプログラム例では、下記のマクロ定義がそれぞれの処理に関する時間を示しています。
CHAT_TIME = チャタリングキャンセル時間(10mS単位) ←プログラム例では50mS
RPT_STTIM = 長押しおよびオートリピート開始時間(10mS単位) ←プログラム例では1000mS
RPT_INTTM = オートリピート繰り返し時間(10mS単位) ←プログラム例では100mS

6.もう少し簡単な考え方

前出の説明図およびプログラム例では、スイッチのON/OFF時間(つまりパルス幅)を測って時間が少ない状態をチャタリングとみなして除外するというものですが、カウンタで時間を測るというのも少しわかりにくく面倒なものでもあります。
ここで紹介するのは、ON/OFF時間を測るという少々面倒なところを、カウンタなど使わずにわかりやすく行う考え方(アルゴリズム)です。

次の図のように、入力ポートから読み込んだスイッチnのON/OFF状態を、1バイトの変数Knの下位ビットから順に入れて、全ビットが"0"か"1"に揃ったかどうか判定することでチャタリングをキャンセルするものです。
"0""1"が揃ったかどうかは、if ( 変数Kn == 0xFF ) のように簡単に知ることができます。
図にあるように5mSごとに行えば、5mS×8ビットで40mSのチャタリングキャンセルになります。つまり、判定するビット数(下図では8)がカウンタに代わってパルス幅を測っているといえます。
キャンセル時間を変えたい場合は、5mSの時間を変えるか、揃ったかチェックするビット数を減らすまたは増やすことで変えられます。ただ、ビット数を変える場合は、不要なビットを除外するマスクが必要になる場合があります。
より簡単は方法
下図は少し詳しく説明した図です。
スイッチから入力したON/OFFを、左シフトした変数Kのb0にON=1,OFF=0として5mSごとに順に加えていき、全ビットが0のときOFF、全ビットが1のときONとみなすものです。
手順は、
(1) 変数Kを左にシフトする。
(2) スイッチのON/OFF状態を読み込み、ON=1,OFF=0として変数Kのb0に加える。
(3) 変数Kが0x00ならOFF、0xFFならONしているとみなす。
(4) (1)~(3)を5mSごとに繰り返す。

(3)のチャタリングキャンセルが完了した後のON/OFFの扱いは、「4.チャタリングキャンセルの方法」で説明したように結果を示すフラグを用意して格納します。
もし、変数Kが0x00でも0xFFでもないときは、前回の認識で判定したON/OFFを保持したままです、つまり無視します。
ここでは、ひとつのスイッチを例に説明しましたが、スイッチが複数ある場合は変数Kも同数用意して、それぞれ独立してチャタリングキャンセルを行います。
また、入力ポートから読み込んだ状態を反転してON=1,OFF=0としていますが、反転せずにON=0,OFF=1としても判定も逆にすれば問題ありません。
簡単方法の動作説明図

7.安定動作のためのノイズ除去

前に述べたように、スイッチのチャタリングキャンセルはノイズ除去技術の一つです。
チャタリングキャンセルを改めて確認してみると、下図(a)のようにON/OFFが「一定時間安定している」とき有効とみなすものです。スイッチのチャタリングキャンセルなら、これで十分だと思います。
しかし現実には、見た目は明らかにONあるいはOFFなのに、下図(b)のように一瞬のノイズが入っただけで「一定時間安定していない」と判断されてしまい、不都合が起きることがあります。
重要なスイッチや遠隔にあるスイッチ、またはデータ信号や通信データなどを受信する場面でこのようなことが起きると、データの取りこぼしとか動作不良につながるので、対応しておきたい事象であると思います。

その対応策の一つとして“多数決方式”を説明します。
前項で説明した、一定周期で左シフトする変数Knのb0に入力のON/OFF(1/0)状態を加えていき、変数Knが0x00のときOFF,0xFFのときONとみなす方法を利用します。
といっても話は簡単で、変数Knの"1"のビット数を数え、その数でON/OFFを判定します。(高速にビット数を数えるテクニックは必要かも)
例えば下図(c)に示すように、8ビットのうち"1"が7ビット以上あればON,1ビット以下ならOFFとします。これにより、ノイズに相当する"0"あるいは"1"が1ビット含まれていてもON/OFFを認識できます。
これは8ビットの変数Knを使った場合の例なので、1÷8ビットで12.5%のノイズを許容することになります。実行周期や変数のビット数、そしてON/OFFを判定するビット数を変えれば、いろいろの状況に対応できます。
ノイズも除去できるチャタリングキャンセル
ホームページに戻るトップページに戻る前ページに戻る次ページに進む最終ページに進む
■■■ 注 意 ■■■
1.ここに掲載された内容(写真,図,表などを含む)の、全てまたは一部を無断で使用しないでください。
2.ここで紹介した手法(構造や仕組み,回路,プログラムなどを含む)を使用したことにより、問題や不利益が発生したとしても一切関知しません。
3.ここで紹介したプログラム例は、正常なコンパイルおよび正常な動作を保証するものではありません。