Bắt đầu từ đây: đối chiếu hiện tượng
Hiện tượng | Nguyên nhân nhiều khả năng nhất | Xem mục |
|---|---|---|
Không thấy gì tại 0x5D hay 0x14 khi quét I2C | Bộ điều khiển không được cấp nguồn, thiếu điện trở kéo lên, hoặc chip đang bị giữ ở trạng thái reset | Bước 1 |
Phát hiện tại 0x14 trong khi driver kỳ vọng 0x5D (hoặc ngược lại), hoặc địa chỉ thay đổi giữa các lần khởi động | Mức chân INT trong lúc reset | Bước 2 |
Được phát hiện, đọc product ID chính xác, nhưng không có điểm chạm nào | Thanh ghi trạng thái chưa được xóa, cạnh ngắt sai, hoặc INT chưa được nối dây | Bước 3 |
Có điểm chạm nhưng bị sai vị trí, bị đảo chiều hoặc xoay | Độ phân giải trong cấu hình GT911 không khớp với tấm panel, hoặc cần hoán đổi các trục | Bước 4 |
Đang định viết lại khối cấu hình mới | Hãy đọc phần này trước | Bước 5 |
Thực hiện lần lượt theo các bước. Các địa chỉ thanh ghi và thông số thời điểm dưới đây lấy từ driver goodix của Linux, component esp_lcd_touch_gt911 của Espressif và tài liệu ESPHome; các liên kết nằm trong phần Sources.
1. Xác nhận GT911 đã có nguồn và phản hồi trên I2C
Nguồn và điện trở kéo lên
Device-tree binding của Linux cho các bộ điều khiển Goodix nêu tên hai nguồn cấp: AVDD28 (analog) và VDDIO (đường nguồn I/O logic). Trên module hoặc FPC, cả hai thường được cấp từ connector của máy chủ, vì vậy hãy đo ngay tại connector trước khi nghi ngờ firmware. SDA và SCL cũng cần có điện trở kéo lên ở đâu đó trên bus; nhiều module hiển thị không tích hợp sẵn chúng.
Quét bus
Chạy một sketch quét I2C hoặc i2cdetect. GT911 phản hồi tại một trong hai địa chỉ 7-bit:
Địa chỉ 7-bit | Byte ghi / đọc 8-bit (như một số datasheet liệt kê) |
|---|---|
| |
| |
Các cặp 8-bit xuất phát từ một chú thích trong mã reset của driver Linux. Nếu tài liệu của nhà cung cấp ghi "địa chỉ 0xBA", đó chính là thiết bị với địa chỉ 7-bit 0x5D; hãy nhập 0x5D trong Arduino, ESP-IDF và Linux.
Đọc product ID
Các thanh ghi trên GT911 dùng địa chỉ 16-bit. Driver Linux đọc 6 byte từ 0x8140: 4 byte đầu là product ID ở dạng văn bản ASCII và 2 byte sau là phiên bản firmware (little-endian). GT911 báo chuỗi 911. Nếu bạn nhận được 911, thì bus, nguồn và địa chỉ đều ổn và vấn đề nằm ở phần sau của danh sách này.
Nếu không có gì phản hồi tại cả hai địa chỉ, hãy kiểm tra xem đường reset có đang bị giữ mức thấp hay không. Trên nhiều module, RST là chân input của GT911 và phải được máy chủ đưa lên mức cao (hoặc kéo lên trên bo mạch) trước khi bộ điều khiển hoạt động.
2. Thực hiện đúng trình tự reset và chọn địa chỉ
GT911 chọn địa chỉ I2C dựa trên mức tín hiệu trên chân INT tại thời điểm reset được nhả. Theo nguyên văn của binding Linux, đường INT "được thiết bị lấy mẫu khi reset được nhả để chọn địa chỉ I2C client".
Mức INT khi RST lên mức cao | Địa chỉ I2C |
|---|---|
Thấp | |
Cao | |
Trình tự mà driver Linux sử dụng
- Kéo RST xuống mức thấp và chờ hơn 10 ms (driver chờ 20 ms).
- Đưa INT về mức tương ứng với địa chỉ mong muốn: cao để chọn
0x14, thấp để chọn0x5D. - Chờ hơn 100 µs.
- Đưa RST lên mức cao và chờ hơn 5 ms (driver chờ 6–10 ms).
- Kéo INT xuống mức thấp trong 50 ms, sau đó chuyển INT sang chế độ đầu vào.
Nếu INT ở trạng thái thả nổi (float) trong bước 4, địa chỉ có thể khác nhau giữa các lần cấp nguồn. Đây chính là hiện tượng quen thuộc theo dạng "nạp xong thì chạy, khởi động nguội lại thì lỗi".
ESP-IDF: esp_lcd_touch_gt911
Component của Espressif định nghĩa ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS là 0x5D và ESP_LCD_TOUCH_IO_I2C_GT911_ADDRESS_BACKUP là 0x14. Nó chỉ chạy trình tự chọn địa chỉ khi cả ba điều kiện sau được thỏa mãn:
rst_gpio_numlà một GPIO thực (không phảiGPIO_NUM_NC),int_gpio_numlà một GPIO thực,driver_datatrỏ tới một cấu trúcesp_lcd_touch_io_gt911_config_twhosedev_addrlà địa chỉ bạn muốn.
Ngược lại, nó ghi log I2C address initialization procedure skipped - using default GT9xx setup và chỉ thực hiện reset thông thường. Khi đó, địa chỉ phụ thuộc vào cách đi dây của bo mạch, và địa chỉ I2C của panel-IO bạn truyền vào phải khớp với kết quả quét I2C. Xung clock I2C mặc định của component trong ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG() là 100 kHz.
Các bo mạch mà host không điều khiển chân INT
Nếu INT không được nối với host, host không thể chọn địa chỉ, vì vậy hãy quét cả hai địa chỉ và dùng địa chỉ có phản hồi. Ví dụ, trên bo Sunton ESP32-8048S043C, ngắt của GT911 mặc định không được nối tới GPIO nào (xem trang bo mạch của chúng tôi). Trang GT911 của ESPHome lưu ý rằng khi INT đi qua một IO expander, chân này vẫn được dùng để thiết lập địa chỉ khi khởi động, nhưng cảm ứng sẽ được polled thay vì dùng ngắt.
3. Được phát hiện nhưng không có sự kiện chạm
Đọc và xóa thanh ghi trạng thái
Dữ liệu cảm ứng bắt đầu tại 0x814E. Byte đầu tiên là byte trạng thái:
- Bit 7 (
0x80): buffer sẵn sàng. Dữ liệu mới chỉ có hiệu lực khi bit này được set. - Bit 0–3: số điểm chạm. Driver Linux loại bỏ các giá trị vượt quá số điểm tối đa đã cấu hình.
- Bit 4: có một phím (button) đang được nhấn.
Mỗi điểm chạm tiếp theo gồm 8 byte: một track ID, sau đó là X, Y và size dưới dạng giá trị 16-bit little-endian.
Sau khi đọc, cả driver Linux lẫn esp_lcd_touch_gt911 đều ghi 0 vào 0x814E. Nếu bạn tự viết driver, hãy làm tương tự; bỏ qua bước ghi này là lý do phổ biến khiến driver tự viết chỉ nhận được lần chạm đầu tiên.
Khớp cạnh ngắt
Kiểu trigger nằm trong cấu hình của chính GT911: bit 0–1 của byte cấu hình tại 0x804D (offset 6 tính từ vị trí bắt đầu cấu hình tại 0x8047). Driver Linux ánh xạ như sau:
Giá trị | Kiểu ngắt |
|---|---|
0 | Cạnh lên |
1 | Cạnh xuống |
2 | Mức thấp |
3 | Mức cao |
Hãy đặt ngắt GPIO tương ứng. Trong esp_lcd_touch_gt911, levels.interrupt = 1 chọn ngắt cạnh lên và 0 là cạnh xuống.
Không có đường INT? Dùng polling
Polling hoạt động tốt cho ứng dụng HMI. ESPHome poll mặc định mỗi 50 ms (update_interval) khi không đặt interrupt_pin. Driver Linux, khi có ngắt, sẽ chờ tối đa 20 ms cho bit ready trước khi bỏ qua một khung cảm ứng.
4. Tọa độ cảm ứng bị sai vị trí
Kiểm tra độ phân giải lưu trong GT911
GT911 báo tọa độ theo độ phân giải ghi trong cấu hình của nó, chứ không theo độ phân giải của màn hình bạn. Theo driver Linux, giá trị X maximum là số 16-bit little-endian tại 0x8048 và Y maximum tại 0x804A. Hãy đọc hai giá trị này. Nếu controller được cấu hình cho 1024×600 trong khi panel của bạn là 800×480, điểm chạm sẽ nằm lệch sang phải và xuống dưới so với ngón tay, và các cạnh xa bị rơi ra ngoài màn hình. Cách khắc phục là scale (hoặc đặt giới hạn của driver theo giá trị của controller).
Nguồn giới hạn độ phân giải của từng stack:
Stack | Nguồn độ phân giải | Hoán vị và lật gương |
|---|---|---|
Linux | Đọc từ cấu hình GT911; fallback về 4095 × 4095 khi cấu hình không có | Device-tree |
ESP-IDF | | |
ESPHome | Touchscreen | |
Hiệu chuẩn từ giá trị raw
Trang touchscreen của ESPHome gợi ý log touch.x_raw và touch.y_raw trong một lambda on_touch, chạm vào các góc ở sát pixel biên vài lần, rồi nhập giá trị raw nhỏ nhất và lớn nhất làm calibration. Cách này dùng được trên mọi platform: in ra X và Y raw, chạm bốn góc, và ánh xạ khoảng giá trị đó lên màn hình.
Sửa hướng theo thứ tự này: trước hết đưa X và Y về đúng trục (swap_xy), sau đó lật trục nào chạy ngược (mirror_x / mirror_y). Điểm logic (0, 0) của màn hình phải là góc trên bên trái.
5. Ghi lại cấu hình GT911: giải pháp cuối cùng
Khối cấu hình bắt đầu tại 0x8047. Với GT911, driver Linux coi nó dài 186 byte:
- Byte 0 (
0x8047): phiên bản cấu hình. - Byte 1–4: độ phân giải X và Y (xem bước 4).
- Byte 5 (
0x804C): số điểm cảm ứng tối đa, 4 bit thấp. - Byte 6 (
0x804D): kiểu kích hoạt ngắt, 2 bit thấp. - Byte 184 (
0x80FF): checksum, phần bù hai của 8 bit của tổng các byte 0–183. - Byte 185 (
0x8100):config_fresh, phải bằng1.
Bản thân driver Linux chỉ ghi cấu hình khi nó có cả GPIO INT và RST và tìm thấy file firmware (tên mặc định goodix_911_cfg.bin, hoặc tên trong thuộc tính goodix,config-name). Không có file đó, nó dùng cấu hình đã lưu sẵn trong chip.
Trước khi ghi bất cứ thứ gì, hãy đọc đủ 186 byte và lưu lại. Hãy sửa độ phân giải và hướng trong phần mềm khi có thể. Một khối cấu hình làm cho panel cảm ứng khác có thể làm mất cảm ứng trên panel của bạn, nên nếu thực sự cần thay đổi, hãy lấy file từ nhà cung cấp panel.
Chọn module cảm ứng điện dung
Nếu bạn đang chọn màn hình CTP cho một thiết kế mới, hãy hỏi nhà cung cấp ba điều trước khi đặt mẫu: bộ điều khiển cảm ứng sử dụng chip nào, địa chỉ I2C xuất xưởng là bao nhiêu, và chân INT và RST có được dẫn tới đầu nối hay không. Gửi thông tin về kích thước, giao diện và vi xử lý chủ của bạn qua Ask an Engineer, chúng tôi sẽ cung cấp cả ba câu trả lời đó cùng với các module mà chúng tôi đề xuất.
Câu hỏi thường gặp
Địa chỉ I2C của GT911 là gì?
Một trong hai địa chỉ 0x5D hoặc 0x14 (7-bit). Bộ điều khiển lấy mẫu chân INT khi reset được nhả: INT mức thấp chọn 0x5D, INT mức cao chọn 0x14. Các datasheet liệt kê 0xBA/0xBB hoặc 0x28/0x29 thực chất là cùng địa chỉ đó ở dạng byte ghi/đọc 8-bit.
Tại sao GT911 của tôi đổi địa chỉ sau khi khởi động lại?
Chân INT đang thả nổi hoặc do thành phần khác điều khiển khi reset được nhả, nên bộ điều khiển lấy mẫu mức khác nhau mỗi lần. Kéo INT xuống mức thấp (cho 0x5D) hoặc mức cao (cho 0x14) trước khi nhả RST, đợi hơn 5 ms, giữ INT ở mức thấp trong 50 ms, sau đó chuyển chân này thành đầu vào. Nếu host không điều khiển được INT, hãy quét cả hai địa chỉ.
Tại sao GT911 của tôi chỉ nhận được một điểm chạm?
Sau khi đọc dữ liệu cảm ứng tại 0x814E, ghi 0 vào 0x814E. Driver goodix của Linux và esp_lcd_touch_gt911 của Espressif đều làm điều này sau mỗi lần đọc; driver bỏ qua bước này thường sẽ không còn nhận được các lần chạm mới.
Tại sao tọa độ cảm ứng GT911 bị scale hoặc lệch offset?
GT911 báo tọa độ theo độ phân giải được lưu trong cấu hình của chính nó (X tại 0x8048, Y tại 0x804A). Nếu giá trị này khác với panel của bạn, hãy scale các giá trị hoặc đặt x_max/y_max của driver theo độ phân giải của bộ điều khiển, sau đó dùng swap_xy và mirror_x/mirror_y để chỉnh hướng.
GT911 có hoạt động khi không có chân INT không?
Có. Hãy polling thanh ghi trạng thái 0x814E thay vì dùng ngắt. ESPHome mặc định polling mỗi 50 ms khi không đặt interrupt_pin. Không có INT, host cũng không thể chọn địa chỉ, nên hãy dùng địa chỉ trong hai địa chỉ 0x5D hoặc 0x14 nào phản hồi.
Tôi có nên ghi lại cấu hình GT911 không?
Chỉ dùng như giải pháp cuối cùng. Trước tiên hãy đọc và lưu khối 186 byte hiện có từ 0x8047, ưu tiên sửa độ phân giải và hướng trong phần mềm, và nếu bắt buộc phải ghi cấu hình thì dùng file config từ nhà cung cấp touch panel. Khối này kết thúc bằng checksum 8-bit tại 0x80FF và byte config_fresh tại 0x8100 phải bằng 1.
Nguồn
- Linux kernel: drivers/input/touchscreen/goodix.c
- Linux kernel: drivers/input/touchscreen/goodix.h (địa chỉ thanh ghi)
- Linux kernel: Goodix touchscreen device-tree binding (goodix.yaml)
- Espressif ESP-BSP: mã nguồn driver esp_lcd_touch_gt911
- Espressif ESP-BSP: header esp_lcd_touch_gt911 (địa chỉ I2C)
- ESPHome: GT911 touchscreen
- ESPHome: Touchscreen components (transform, calibration)