通常使用にはあまり支障は無さそうでしたが、話を総合するとどうやらスイッチのチャタリングが絡んでいるものとみて、この現象をソフトウエア的に回避でいないものか考えてみました。
Keyer Mini-V2のスイッチはすべて1ミリ秒のタイマー割り込みでポートを監視し、1ミリ秒前と現在のポート状態でスイッチ押下を判断していました。(具体的には立下りエッジ(1から0への遷移)を検出してスイッチオンフラグを立てて各処理にまわす)
スイッチが押して離した状態について下の図といっしょに解説します。
上段は立下りを検出してスイッチオンフラグを立てていますが、スイッチを押したときのチャタリングで立下りを誤検出しています。しかしチャタリング持続時間はフラグオンの後の処理時間内にだいたい収まりため実害はほとんど無いと思われます。一方スイッチを離したときのチャタリングはもし立下りと判断された場合フラグを立ててしまう可能性が出てきます(実動作ではほとんど発生しません)。超短押しの場合にはチャタリングの発生している時間が延びて、処理が済んでリセットされたフラグが再立ち上がりしたため誤動作したものと推察されます。
対策としては、立下りを検出した段階で数ミリ秒のタイマーを作動させ、数ミリ秒後のポート状態(1ミリ秒前と現在の状態) で判定しフラグを立たせるというようなコードに書き換えました。押してから数ミリ秒の遅れが出ますが、スイッチを離したときや超短押しのチャタリングによる誤動作はほぼ完全に抑えられると思います。
というわけで報告いただいた現象は回避できたのですが、ロータリーエンコーダについても以前から動作にちょっと不満が残っていたので何とかならないだろうかとついでに考えてみました。
ロータリーエンコーダでは2ミリ秒前、1ミリ秒前、現在のポート状態を監視して2つのポートのうちどちらが先に立ち下がるかで回転方向を判定していました。
しかし、採用したロータリーエンコーダはメカニカル接点なのでスイッチと同じようにチャタリングは避けられません。3つの時相監視をもってしてもチャタリングは完全に取り除くことはできず、つまみを回した瞬間にメニューを1つ飛ばしたりまたはなぜか戻ってみたりという現象が時折起りあまりよろしくありませんでした。
ロータリーエンコーダは回す速度によって立下りのパルス幅が変化するため、スイッチのような一定時間後に再チェックする方法では回転速度によって取りこぼしが出る可能性が考えられたため下図のような方法で対応してみました。
まず対策前と同じように立下りを検出したときにキープフラグを立て(up_keep、down_keep)、そのフラグが真であることを条件にして次の立ち上がりを検出したところでスイッチオンフラグを立て(UP_flag, down_flag)キープフラグをリセットします。
これによってクリックありのエンコーダーのときは、1クリックごとにほぼ確実に読み取ることが可能になると思います。
高速回転の場合はやはり光学式のロータリーエンコーダが必要になりますが、周波数調整などの低速回転の用途なら秋月の安価なエンコーダでもこの方法で十分使えそうです^^
なお、パドルスイッチのポートにはチャタリング対策を施していません。なぜでしょう?
0 件のコメント:
コメントを投稿