Armadilloフォーラム

Armadillo4x0 チャタリング対策について

sankyo_takada

2015年7月15日 17時23分

お世話になります。
高田と申します。

Armadillo-410+QtでGUIを作成しております。
タッチパネル入力時のチャタリングについて質問があります。

以下の記事を拝見しましたが、Armadillo400でもソフト的にチャタリング対策が
実装されているのでしょうか?
http://armadillo.atmark-techno.com/howto/armadillo-500-fx-hardware-cust…

また、QtのQPushButtonクラスでLCD上にボタンを作成しているのですが、
タッチパネルを押して→離すまでの間隔が短い場合に、
mousePressEvent/mouseReleaseEventが発生しないことはあるのでしょうか?
(ドライバーにチャタ対策があるとして、チャタではないと判断した場合は必ずイベントが発生する?)

初歩的な質問で申し訳ありませんが、ご教示いただけると助かります。

コメント

at_ohsawa

2015年7月17日 14時30分

Armadillo-400のタッチパネルはソフトウェアではなく、
SoCのADコンバータの機能でデバウンス(チャタリング除去)しています。

設定している箇所はkernelの下記のデバイスドライバの実装です。

linux-2.6.26-at/drivers/mxc/adc/imx_adc.c :: imx_tsc_init()

        /* Debounce time = dbtime*8 adc clock cycles */
        reg = __raw_readl(tsc_base + TGCR);
        dbtime = 3;
        reg &= ~TGCR_PDBTIME_MASK;
        reg |= dbtime << TGCR_PDBTIME_SHIFT;
        __raw_writel(reg, tsc_base + TGCR);

上記 dbtime を大きくするとタッチパネルの取り込み周期を延す
ことができます。dbtime は 0 から127 まで取る事ができます。

当該のレジスタはi.mx25 の refirence manual v2だと
44.4.3.1 TSC General Configuration Register (TGCR)
になります。

> タッチパネルを押して→離すまでの間隔が短い場合

下記の箇所で、タッチパネルからの読取周期が決ります。
linux-2.6.26-at/drivers/input/touchscreen/imx_adc_ts.c :: ts_thread()

                input_sync(drvdata->inputdev);
 
                msleep(10);
        } while (!kthread_should_stop());

上記msleepによって周期が10msになっているので、
10ms以内に 非接触 -> 接触 -> 非接触 が完了した場合は
input event が発生しません。

sankyo_takada

2015年7月22日 16時39分

お世話になります。
高田です。
早々のご回答ありがとうございました。

> 上記 dbtime を大きくするとタッチパネルの取り込み周期を延す
> ことができます。dbtime は 0 から127 まで取る事ができます。

dbtimeはTGCRレジスタのPDBTIMEビットになるかと思います。
この設定値を変更するとどのような変化があるのでしょうか?
(タッチ検出後、A/D値を取り込むまでのディレイを長くしている?
 =A/D値が安定してから取り込む?)

また、SoCで行っているチャタリング除去のロジックや、A/D値取り込み後に
ソフトウェアで行っている処理をご教示いただくことは可能でしょうか?

現在開発中の製品で以下のような現象が発生しており、これを改善したいために
質問させていただいております。
・タッチした位置とは違う位置のキーを押下してしまう
・タッチ/リリース時に座標が飛んでしまう

データシート、ソースの読み込みが不十分な状態での質問で
申し訳ないのですが、よろしくお願いいたします。

at_ohsawa

2015年7月23日 12時09分

> この設定値を変更するとどのような変化があるのでしょうか?
PenDownから、実際に「A/D変換を行ってconversion queueに結果
を書きみはじめる」までの時間を遅延させています。

SoCで行っているチャタリング除去のロジックは上記以外は
データシートに記載されていないので、分りかねます。

A/D変換結果はPen Downを契機(TCQCRレジスタのQSMビットを変更すると
FQSを契機にするように設定することもできます)にTCQFIFOというリング
バッファにに逐次格納されます。

ソフトウェアの処理は、imx_adc_ts.cドライバがデバイスにアタッチされた
以降に、ts_thread()関数がkthreadとして常時ループ実行されており、
その中で、
imx_adc_get_touch_sample()でinput eventとして出力する座標の取り込み
を行います。

imx_adc_get_touch_sample()の中身は
1, imx_adc_read_ts()
によって上記TCQFIFOの読み取りを行い、

2, imx_adc_filter()
によって閾値(TS_DETECT_WM)以下の弱い押下がFIFOから取れる内は
input eventを出さない処理 と calc_optimum4()によるジッタ除去を実装しています。

calc_optimum4()は直近4サンプルについて平均を求める事でジッタした値を
最終的な結果としています。
(実際には、平均から逸脱した飛び値が1つだけの場合は除去して平均値を取っています。)

> ・タッチした位置とは違う位置のキーを押下してしまう

こちらは常に同じ方向にズレた座標を取るのでしょうか?
もしそうであれば、単純にキャリブレーションの問題になると思います。

GUIの挙動ではなく、input eventの値をそのまま evtest で確認してみて
ズレの状況を確認することはできるでしょうか。

[Armadillo]$ evtest /dev/input/event1

> ・タッチ/リリース時に座標が飛んでしまう

この現象については、TS_DETECT_WM の値を小さくした場合は飛ばなくなるでしょうか。
LCD開発セットのパネルでは無いタッチパネルをご利用とのことですが、抵抗膜の個体差も鑑みて、
TS_DETECT_WMの値を上げすぎないように調整してみる事は可能でしょうか。

at_ohsawa

2015年7月23日 18時54分

誤字訂正いたします。
> calc_optimum4()は直近4サンプルについて平均を求める事でジッタした値を
calc_optimum4()は直近4サンプルについて平均を求める事でジッタを除去した値を

失礼いたしました。

sankyo_takada

2015年7月24日 19時20分

お世話になります。
高田です。

ソフトウェアの処理について、詳細なご説明ありがとうございます。
承知いたしました。

>> ・タッチした位置とは違う位置のキーを押下してしまう
>
>こちらは常に同じ方向にズレた座標を取るのでしょうか?
>もしそうであれば、単純にキャリブレーションの問題になると思います。

上記については常に同じ方向にズレるわけではなく、
たまにタッチ位置を誤検知して意図しないキーを押してしまうという現象です。
下記現象に関連した動作となります。

>> ・タッチ/リリース時に座標が飛んでしまう
>
>この現象については、TS_DETECT_WM
>の値を小さくした場合は飛ばなくなるでしょうか。
>LCD開発セットのパネルでは無いタッチパネルをご利用とのことですが、抵抗膜の個体差も鑑みて、
>TS_DETECT_WMの値を上げすぎないように調整してみる事は可能でしょうか。

ご指摘の通り、TS_DETECT_WMを0x80→0xFFに上げており、
これを戻すことで座標の飛び、誤押下はなくなりました。
また、TS_DETECT_WMを0xFFにした場合でもdbtimeを3→100にすることで
誤押下は少なくなったので、座標取得用ADが落ち着いたところで
FIFOに取り込みを開始しているのではないかと考えています。
操作感改善のために感度を上げてみたのですが誤押下はNGなので、
TS_DETECT_WM、dbtimeを調整しながら着地点を見つけたいと思います。

evtestも試してみましたが、まだデータを整理できていない状況なので
引き続き確認してみます。
ご協力ありがとうございました。