2017年4月9日日曜日

FPGA(MAX10)でタッチセンサを実装してみる

ずっとFPGAには興味があったのですが、USB-blasterが高価だったり評価ボードが高価だったりしていたので、個人の学生ではなかなか手が出しづらいなぁと感じていました。

学生から社会人になり購買力が高まったところにCQ出版のMAX10の本を発見し、「これは!」と感じてFPGAに入門しました。
通勤電車でVerilogの入門書を読み、帰ってからはロジックを実装するという毎日を過ごすうち、ようやくある程度のものが実装できるようになってきました。

とりあえずFPGAで時計実装などの入門編は一通りやったので、ちょっと応用ということで静電容量型タッチスイッチを実装してみました。

 静電容量型タッチスイッチにもいろいろな方式がありますが、今回は簡単に実装可能な積分方式を採用します。
以前PICにこの方法でタッチスイッチを実装して遊んでいて実装の勘所はわかっているので、比較的簡単に実装することができました。

概要


タッチスイッチの構成

検出原理

FPGAの入出力端子にタッチスイッチとなるパッドを接続し、抵抗でプルアップしておきます。
FPGAの入出力端子はオープンコレクタとして”ハイインピーダンス”と”L”の2状態をとれるようにします。
FPGAの出力をLとしてパッドの浮遊容量に充電されていた電荷を抜き、ハイインピーダンスにしてプルアップ抵抗から充電されるまでの時間を測定することによって静電容量の変化を検出します。
パッドに触れた時には浮遊容量が増加し、電圧が上昇するまでにかかる時間が増加します。
FPGA内部のカウンタで充電開始からFPGA内のコンパレータ(今回は単にディジタル入力)がHになるまでをカウントします。

閾値について

ここまでは簡単に実現できるのですが、
タッチしたと判定するカウント値の閾値の決定方法が悩みどころです。
決め打ちで決めてしまってもいいのですが、今回は汎用性を持たせるため、タッチ時とリリース時の静電容量をそれぞれ測定・キャリブレーションする方法とします。
 キャリブレーションを行うcalibration_enable信号と、キャリブレーションする対象がタッチなのかリリースなのかを示すcalibration_touch信号をモジュールに加えます。
calibration_enable信号がアサートされている間、充放電を繰り返し、FPGA内のコンパレータ出力が1になるカウント値の平均をとります。この平均値をタッチ時およびリリース時の閾値として利用します。
この時、キャリブレーションする対象がタッチ時なのかリリース時なのかはcalibration_touch信号によって選択します。

閾値はヒステリシス特性を持たせ、現出力が”タッチ”状態ならば、リリース時に取得した平均値を閾値としてこの値を下回った場合に出力を”リリース”とします。
反対に現状態が”リリース”状態ならば、タッチ時に取得した平均値を閾値としてこの値を上回った場合に出力を”タッチ”とします。

実装

ひとまず簡単に実装してみました。
クロックは48MHzの水晶発振器からの入力をPLLで100MHzにしたものを使用しています。
タッチスイッチの出力をLEDに、calibration_enable入力とcalibration_touch入力をそれぞれ外部のスイッチに接続しています。
キャリブレーションしたのち、タッチすることでLEDの点灯を制御できました。

充放電の電圧波形

おわり

今回は外部の1MΩの抵抗でプルアップしましたが、FPGA内部のweak-pullupを使用しても実現できるかもしれません。
Avalon-MMスレーブとして実装してnios iiと連携させるのも楽しそうです。
実験用に基板を設計して発注したので、基板が届いたらまた少し遊んでみたいと思います。

0 件のコメント:

コメントを投稿