まずはここから:症状を照合する
症状 | 最も可能性の高い原因 | 対処方法 |
|---|---|---|
I2Cスキャンで0x5Dにも0x14にも応答がない | コントローラーに電源が供給されていない、プルアップ抵抗がない、またはチップがリセット状態で固定されている | ステップ1 |
ドライバーが0x5Dを期待しているのに0x14で見つかる(またはその逆)、あるいは起動するたびにアドレスが変わる | リセット中のINTピンのレベル | ステップ2 |
認識され、プロダクトIDも正しく読めるのに、タッチイベントが届かない | ステータスレジスタがクリアされていない、割り込みエッジの設定が誤っている、またはINTピンが配線されていない | ステップ3 |
タッチは検出されるが、位置がずれる、左右反転する、または回転する | GT911のコンフィグ内の解像度がパネルと一致していない、または軸の入れ替えが必要 | ステップ4 |
新しいコンフィグブロックを書き込みたいとき | まずこちらをお読みください | ステップ5 |
手順には順番に従って取り組んでください。以下のレジスタアドレスとタイミングは、Linuxの goodix ドライバー、Espressifの esp_lcd_touch_gt911 コンポーネント、およびESPHomeのドキュメントに基づいています。リンクはSourcesセクションにあります。
1. GT911の電源確認とI2C応答の確認
電源とプルアップ
GoodixコントローラーのLinuxデバイスツリーバインディングでは、2つの電源、すなわち AVDD28(アナログ)と VDDIO(ロジックI/Oレール)が定義されています。モジュールやFPCでは、通常どちらもホスト側コネクタから供給されるため、ファームウェアを疑う前にコネクタで電圧を計測してください。また、SDAとSCLにはバス上のどこかにプルアップ抵抗が必要です。多くのディスプレイモジュールにはこれが実装されていません。
バスのスキャン
I2Cスキャナーのスケッチまたは i2cdetect を実行してください。GT911は2つの7ビットアドレスのいずれかで応答します:
7ビットアドレス | 8ビット読み書きバイト(一部のデータシートでの表記) |
|---|---|
| |
| |
8ビット表記のペアは、Linuxドライバーのリセットコード内のコメントに由来します。ベンダーの資料に「アドレス0xBA」と記載されていても、それは7ビットの 0x5D と同じデバイスです。Arduino、ESP-IDF、Linuxでは 0x5D を指定してください。
プロダクトIDの読み取り
GT911のレジスタは16ビットアドレスです。Linuxドライバーは 0x8140 から6バイトを読み取ります。先頭の4バイトがASCIIテキストとしてのプロダクトID、残りの2バイトがファームウェアバージョン(リトルエンディアン)です。GT911は文字列 911 を返します。 911 が読めた場合は、バス・電源・アドレスのいずれも正常であり、問題はこのリストの先にあります。
いずれのアドレスでも応答がない場合は、リセットラインがLowに固定されていないか確認してください。多くのモジュールでは、RSTはGT911への入力ピンであり、コントローラーが動作する前にホスト側からHighに駆動する(またはボード上でプルアップする)必要があります。
2. リセットとアドレス選択シーケンスを正しく行う
GT911は、リセットが解除される瞬間のINTピンのレベルによってI2Cアドレスを決定します。Linuxバインディングの説明によれば、INTラインは「リセットの解除時にデバイスによってサンプリングされ、I2Cクライアントアドレスを選択します」。
RSTがHighになったときのINTレベル | I2Cアドレス |
|---|---|
Low | |
High | |
Linuxドライバが使用するシーケンス
- RSTをLowにして10 ms以上待つ(ドライバは20 ms待ちます)。
- INTを希望するアドレスに対応するレベルに設定します:
0x14ならHigh、0x5DならLowです。 - 100 µs以上待ちます。
- RSTをHighにして5 ms以上待つ(ドライバは6〜10 ms待ちます)。
- INTを50 ms間Lowにした後、INTを入力に切り替えます。
ステップ4の間にINTがフロートすると、電源投入のたびにアドレスが変わることがあります。これが「書き込み後は動くがコールドブートでは動かない」という典型報告の原因です。
ESP-IDF: esp_lcd_touch_gt911
Espressifのコンポーネントは、ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESSを0x5D、ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS_BACKUPを0x14と定義しています。アドレス選択シーケンスが実行されるのは、次の3つがすべて設定されている場合のみです:
rst_gpio_numが実GPIOである(GPIO_NUM_NCではない)こと、int_gpio_numが実GPIOであること、driver_dataが、dev_addrに希望するアドレスを設定したesp_lcd_touch_io_gt911_config_tを指していること。
いずれも満たさない場合は、I2C address initialization procedure skipped - using default GT9xx setupというログを出力し、通常のリセットのみを行います。この場合、アドレスはボードの配線によって決まるため、渡すI2CパネルIOのアドレスをスキャン結果と一致させる必要があります。コンポーネントのESP_LCD_TOUCH_IO_I2C_GT911_CONFIG()におけるデフォルトのI2Cクロックは100 kHzです。
ホストがINTを制御しないボード
INTがホストに接続されていない場合、ホストはアドレスを選択できないため、両方のアドレスをスキャンして応答する方を使用します。たとえばSunton ESP32-8048S043Cでは、GT911の割り込みはデフォルトではGPIOに配線されていません(当社のボードページを参照)。ESPHomeのGT911ページには、INTがIOエキスパンダ経由の場合でも、起動時にアドレス設定のためピンが使用される一方、タッチは割り込み駆動ではなくポーリングで取得される旨の記載があります。
3. 検出されるがタッチイベントが発生しない
ステータスレジスタの読み出しとクリア
タッチデータは0x814Eから始まります。先頭バイトはステータスバイトです:
- ビット7(
0x80):バッファ準備完了。このビットがセットされている場合のみ、新規データが有効です。 - ビット0〜3:タッチポイント数。Linuxドライバは設定された最大数を超える数を拒否します。
- ビット4:キー(ボタン)が押されています。
続く各タッチポイントは8バイトで、トラックID、X、Y、サイズがリトルエンディアンの16ビット値で格納されます。
読み出し後、Linuxドライバとesp_lcd_touch_gt911の両方とも、0x814Eに0を書き込みます。自作ドライバの場合も同様にしてください。この書き込みを省略すると、最初のタッチしか検出できない自作ドライバになる典型的な原因となります。
割り込みエッジの一致
トリガタイプはGT911自身のコンフィギュレーションに含まれています:0x804Dにあるコンフィグバイトのビット0〜1です(コンフィグ開始アドレス0x8047からのオフセット6)。Linuxドライバは次のようにマッピングします:
値 | 割り込みタイプ |
|---|---|
0 | 立ち上がりエッジ |
1 | 立ち下がりエッジ |
2 | Lowレベル |
3 | Highレベル |
GPIO割り込みの設定も合わせてください。esp_lcd_touch_gt911では、levels.interrupt = 1で立ち上がりエッジ割り込み、0で立ち下がりエッジ割り込みを選択します。
INTラインがない場合はポーリングで対応
HMI用途であればポーリングで十分機能します。ESPHomeはinterrupt_pinを設定しない場合、デフォルトで50 ms間隔(update_interval)でポーリングします。Linuxドライバーは割り込みを使用する場合、1フレームの処理を諦めるまで最大20 ms、レディービットを待ちます。
4. タッチ位置がずれる
GT911に保存されている解像度を確認する
GT911は、ディスプレイの解像度ではなく、コントローラーのコンフィグレーションに書き込まれた解像度で座標を報告します。Linuxドライバーによれば、X最大値は0x8048、Y最大値は0x804Aにあるリトルエンディアン16ビット値です。まずこれらを読み取ってください。コントローラーが1024×600に設定されていてパネルが800×480の場合、タッチ位置は指の右下にずれ、遠い側の端は画面外に出てしまいます。対処としては、スケーリングするか、ドライバーのリミットをコントローラーの値に合わせてください。
各スタックがリミット値を取得する場所:
スタック | 解像度の取得元 | 入れ替え・ミラー |
|---|---|---|
Linux | GT911のコンフィグから読み取る。コンフィグに値がない場合は4095 × 4095にフォールバック | デバイスツリーの |
ESP-IDF | | |
ESPHome | タッチスクリーンの | |
生値からキャリブレーションする
ESPHomeのタッチスクリーンのページでは、on_touchラムダでtouch.x_rawとtouch.y_rawをログ出力し、画面端のピクセル位置で四隅を数回タッチし、その生値の最小値と最大値をキャリブレーション値として入力する方法が推奨されています。この手法はどのプラットフォームでも使えます。生のXとYを出力し、四隅をタッチして、その範囲を画面にマッピングしてください。
向きは次の順序で修正します。まずXとYを正しい軸に合わせ(swap_xy)、次に逆方向に動く軸を反転させます(mirror_x / mirror_y)。ディスプレイの論座標(0, 0)は左上でなければなりません。
5. GT911コンフィグの書き換え:最終手段
コンフィグレーションブロックは0x8047から始まります。GT911の場合、Linuxドライバーはこれを186バイトとして扱います。
- バイト0(
0x8047):コンフィグバージョン。 - バイト1〜4:XおよびY解像度(ステップ4を参照)。
- バイト5(
0x804C):最大タッチ点数、下位4ビット。 - バイト6(
0x804D):割り込みトリガタイプ、下位2ビット。 - バイト184(
0x80FF):チェックサム。バイト0〜183の合計の8ビット2の補数。 - バイト185(
0x8100):config_fresh。1でなければなりません。
Linuxドライバー自体がコンフィグを書き込むのは、INTとRSTの両GPIOを保持し、かつファームウェアファイル(デフォルト名はgoodix_911_cfg.bin、またはgoodix,config-nameプロパティで指定した名前)を見つけた場合のみです。ファイルがなければ、チップに既に保存されているコンフィグを使用します。
書き込む前に、必ず186バイトすべてを読み出して保存してください。解像度と向きは、可能な限りソフトウェア側で修正してください。別のタッチパネル向けに作られたコンフィグブロックは、お使いのパネルでタッチが動作しなくなる原因になり得るため、どうしても変更が必要な場合はパネルのサプライヤーからファイルを入手してください。
静電容量式タッチモジュールの選び方
新しい設計にCTPディスプレイを選定する場合は、サンプルを発注する前にサプライヤーに3つの点を確認してください。どのタッチコントローラーを使用しているか、出荷時のI2Cアドレスは何か、そしてINTとRSTがコネクタまで配線されているかです。サイズ、インターフェース、ホストプロセッサの情報をAsk an Engineerからお送りいただければ、ご提案するモジュールとともにこの3つの回答をお届けします。
よくある質問
GT911のI2Cアドレスは何ですか?
0x5D または 0x14(7ビット)のどちらかです。コントローラはリセット解除時に INT ピンのレベルをサンプリングします。INT が Low なら 0x5D、High なら 0x14 が選択されます。0xBA/0xBB または 0x28/0x29 と記載されているデータシートは、同じアドレスを 8 ビットの書き込み/読み出しバイトで表記したものです。
再起動後にGT911のアドレスが変わるのはなぜですか?
リセット解除時に INT がフローティング状態か他の回路に駆動されているため、コントローラがサンプリングするたびにレベルが変わるのが原因です。RST を解除する前に INT を Low(0x5D の場合)または High(0x14 の場合)に駆動し、5 ms 以上待ってから 50 ms 間 INT を Low に保持し、その後入力に戻してください。ホスト側で INT を制御できない場合は、両方のアドレスをスキャンしてください。
GT911でタッチが1回しか検出されないのはなぜですか?
0x814E のタッチデータを読み出した後、0x814E に 0 を書き戻してください。Linux の goodix ドライバおよび Espressif の esp_lcd_touch_gt911 はどちらも読み出しごとにこの処理を行っており、これを省略したドライバは新しいタッチを検出できなくなるのが典型的です。
GT911のタッチ座標がスケールされたりずれたりするのはなぜですか?
GT911 は自身のコンフィグに保存された解像度(X は 0x8048、Y は 0x804A)で座標を報告します。パネルの解像度と異なる場合は、値をスケーリングするか、ドライバの x_max/y_max をコントローラの解像度に設定し、向きの調整は swap_xy および mirror_x/mirror_y を使用してください。
GT911はINTピンなしで動作しますか?
可能です。割り込みの代わりに 0x814E のステータスレジスタをポーリングしてください。ESPHome では interrupt_pin を設定しない場合、デフォルトで 50 ms 間隔のポーリングになります。INT を使用しない場合、ホストはアドレスを選択することもできないため、0x5D と 0x14 のうち応答した方のアドレスを使用してください。
GT911のコンフィグレーションを書き換えるべきですか?
最終手段としてのみ行ってください。まず 0x8047 から既存の 186 バイトのブロックを読み出して保存し、解像度と向きはソフトウェアで修正することを優先してください。どうしても書き込む場合は、タッチパネルサプライヤーのコンフィグファイルを使用してください。ブロックの末尾には 0x80FF に 8 ビットチェックサム、0x8100 に config_fresh バイトがあり、この値は 1 である必要があります。
出典
- Linux カーネル:drivers/input/touchscreen/goodix.c
- Linux カーネル:drivers/input/touchscreen/goodix.h(レジスタアドレス)
- Linux カーネル:Goodix タッチスクリーンデバイスツリー バインディング(goodix.yaml)
- Espressif ESP-BSP:esp_lcd_touch_gt911 ドライバソース
- Espressif ESP-BSP:esp_lcd_touch_gt911 ヘッダ(I2C アドレス)
- ESPHome:GT911 タッチスクリーン
- ESPHome:タッチスクリーンコンポーネント(transform、キャリブレーション)