在下曾經製作一些模擬鍵盤、滑鼠、遊戲控制器等 USB HID
但通常功能越多便需要連接越多按鈕,或需要在編寫一鍵多功能的程式設計
所以在下打算參考現代的觸控操作產品,製作一個類似 Stream Deck 的輔助工具
電阻式觸控熒幕
現今常見的觸控熒幕主要是: 電阻式(Resistive)觸控熒幕 及 電容式(Capacitive)觸空熒幕
兩者的運作原理在下不在這裡詳說明,在下只測試觸控熒幕作為 USB HID 裝置的可行性
外觀
型號為 MSP2807 的 2.8寸 TFT 電阻式觸控熒幕模組 的正面
其解像度為 240x320
MSP2807 的背面
引腳
編號 | 引腳 | 方向 | 功能 |
---|---|---|---|
1 | VCC | 電源,接受 3.3V 至 5V | |
2 | GND | 接地 | |
3 | CS | 輸入 | LCD 的 CS引腳,低電壓時選取 |
4 | RESET | 輸入 | LCD 的 RESET引腳,從高電壓到低電壓並保持10微秒後回到高電壓,執行重設 |
5 | D/C | 輸入 | LCD 的 D/C引腳,高電壓時寫入資料,低高電時寫入指令 |
6 | SDI(MOSI) | 輸入 | LCD 的 SDI(MOSI)引腳,寫入到暫存器的資料 |
7 | SCK | 輸入 | LCD 的 SCK引腳,時脈從高到低時將資料寫入及讀取 |
8 | LED | 輸入 | LCD 的 LED引腳,高電壓時高著背光燈 |
9 | SDO(MISO) | 輸出 | LCD 的 SDO(MISO)引腳,從暫存器讀寫的資料 |
10 | T_CLK | 輸入 | Touch 的 CLK引腳,時脈從高到低時將資料寫入及讀取 |
11 | T_CS | 輸入 | Touch 的 CS引腳,低電壓時選取 |
12 | T_DIN | 輸入 | Touch 的 DIN引腳,寫入到暫存器的資料 |
13 | T_OUT | 輸出 | Touch 的 OUT引腳,從暫存器讀寫的資料 |
14 | T_IRQ | 輸出 | Touch 的 IRQ引腳,中斷訊號並讓裝置資料 |
15 | SD_SS | 輸入 | SD 的 SS引腳,低電壓時選取 |
16 | SD_MOSI | 輸入 | SD 的 MOSI引腳,寫入到暫存器的資料 |
17 | SD_MISO | 輸出 | SD 的 MISO引腳,從暫存器讀寫的資料 |
18 | SD_SCK | 輸入 | SD 的 SCK引腳,時脈從高到低時將資料寫入及讀取 |
控制晶片
HR2046 是一種與 XPT2046 相同的觸控操作晶片
引腳名稱以 T_ 為前綴都是 與 觸控(Touch) 相關的引腳
SD卡控制
觸控熒幕還提供 SD卡模組 ,可以將容量大的圖片資料保存到 SD卡
引腳名稱以 SD_ 為前綴都是 與 SD控制 相關的引腳
注意:
由於 觸控熒幕模組 沒有提供 電阻 或 3.3V電壓穩定器 到 SD卡模組
另外 熒幕控制晶片 及 觸控晶片 同樣需要使用 3.3V
如果 微控制器 的 GPIO 電壓只能輸出 5V
可能會損壞 SD卡 、 熒幕控制晶片 及 觸控晶片
因此需要使用 電位器(Potentiometer) 、 電壓分配定則(Voltage Divider Rule) 、
電位移轉器(Logic Level Shifter) 讓電壓設定為 3.0V 至 3.3V
因此測試時,建議使用 Raspberry Pi Pico 、
ESP8266 或 ESP32 這些 GPIO 為 3.3V 輸出的 微控制器
控制熒幕
線路原型
Raspberry Pi Pico | MSP2807 |
---|---|
5V | VCC, LED |
GND | GND |
3V3 | RESET |
GP22 | D/C |
GP21 | CS |
GP19 | SDI(MOSI) |
GP18 | SCK |
GP16 | SDO(MISO) |
實際線路
到 Sketch > Include Library > Manage Libraries... 搜尋 ili9341 並下載 Adafruit ILI9341
第一次下載 Adafruit ILI9341 會建議下載相依函式庫,包括:
- Adafruit GFX Library
- Adafruit BusIO
- Adafruit STMPE610
- Adafruit TouchScreen
- Adafruit TSC2007
- Adafruit SH110X
按 Install all 安裝所有相依函式庫
到 File > Examples > Adafruit ILI9341 > graphicstest
將 範例 的 TFT_DC 及 TFT_CS 的引腳分別修改成 L_DC 及 L_SS 對應的 微控制器的引腳
測試影像
觸控回應
線路原型
Raspberry Pi Pico | MSP2807 |
---|---|
5V | VCC |
GND | GND |
GP20 | T_CS |
GP19 | T_DIN |
GP18 | T_CLK |
GP16 | T_OUT |
實際線路
再到 Manage Library 搜尋 xpt2046
(在下使用由 Paul Stoffregen 提供的 XPT2046 Touchscreen)
到 File > Examples > XPT2046_Touchscreen > TouchTest
將 範例 的 CS_PIN 引腳分別修改成 T_SS 對應的 微控制器的引腳
(暫時不使用 TIRQ_PIN 設定)
測試觸控
觸控操作除了能夠偵測相對的 X軸 及 Y軸 ,還能夠偵測 Z軸(按壓)
線路原型
Raspberry Pi Pico | MSP2807 |
---|---|
5V | VCC |
GND | GND |
GP20 | T_CS |
GP19 | T_DIN |
GP18 | T_CLK |
GP17 | T_IRQ |
GP16 | T_OUT |
實際線路
T_IRQ 監察觸控熒幕的狀態,當 觸控熒幕 被按壓 , T_IRQ 會接地
因此可以使用 中斷(Interrupt) 讓 微控制器 監察 T_IRQ 的狀態來執行當 觸控熒幕 被按壓 或 未被按壓 的操作
線路原型
Raspberry Pi Pico | MSP2807 |
---|---|
5V | VCC, LED |
GND | GND |
3V3 | RESET |
GP22 | D/C |
GP21 | CS |
GP20 | T_CS |
GP19 | SDI(MOSI), T_DIN |
GP18 | SCK, T_SCK |
GP17 | T_IRQ |
GP16 | SDO(MISO), T_OUT |
因為 ILI9341 及 XPT2046 都是使用 SPI ,所以能共用相同的 SCK, MOSI, MISO 線路
不過 SS引腳 則需要分開連接,讓 主機 能獨立控制 ILI9341 及 XPT2046
因此 初始化 2塊晶片 前,需要先將 L_SS 及 T_SS 設定為 高電壓 ,確保 2塊晶片 都未被選取
實際線路
最終測試效果
電容式觸控熒幕
外觀
在下還測試另一款電容式的觸控熒幕,解像度同樣是 240x320,型號為 MSP2834
型號為 MSP2834 的 3.2寸 TFT 電容式觸控熒幕模組 的正面
MSP2834 的背面
引腳
編號 | 引腳 | 方向 | 功能 |
---|---|---|---|
1 | VCC | 電源,接受 3.3V 至 5V | |
2 | GND | 接地 | |
3 | LCD_CS | 輸入 | LCD 的 CS引腳,低電壓時選取 |
4 | LCD_RST | 輸入 | LCD 的 RST引腳,從高電壓到低電壓並保持10微秒後回到高電壓,執行重設 |
5 | LCD_RS | 輸入 | LCD 的 RS引腳,高電壓時寫入資料,低高電時寫入指令 |
6 | MOSI | 輸入 | LCD 及 SD 的 MOSI引腳,寫入到暫存器的資料 |
7 | SCK | 輸入 | LCD 及 SD 的 SCK引腳,時脈從高到低時將資料寫入及讀取 |
8 | LED | 輸入 | LCD 的 LED引腳,高電壓時高著背光燈 |
9 | MISO | 輸出 | LCD 及 SD 的 MISO引腳,從暫存器讀寫的資料 |
10 | CTP_SCL | 輸入 | Touch 的 SCL引腳,時脈從高到低時將資料寫入及讀取 |
11 | CTP_RST | 輸入 | Touch 的 RST引腳,從高電壓到低電壓並保持10微秒後回到高電壓,執行重設 |
12 | CTP_SDA | 輸入 | Touch 的 SDA引腳,寫入到暫存器的資料 |
13 | CTP_INT | 輸出 | Touch 的 INT引腳,中斷訊號並讓裝置資料 |
14 | SD_CS | 輸入 | SD 的 CS引腳,低電壓時選取 |
MSP2834 的引腳分佈
需要留意的是 觸控的協定不是 SPI 而是 I2C
MSP2834 還提供 FCP-14 連接器,可以讓 MSP2834 使用 FCP-14 柔性線路 連接到其他裝置
控制晶片
LVC245A晶片,是 74245系列 之一
接收SPI訊號 來 控制熒幕
MSP2834 的 觸控晶片 使用 柔性電路板 連接到 MSP2834 的印刷電路板
柔性電路板 焊接著 FT6336U晶片,常用於 電容式觸控熒幕,使用 I2C 協定
SD卡控制
MSP2834 同樣提供 SD卡槽 讓 MSP2834 能讀取 SD卡 資料,滅省由微控制器儲存圖像資料的空間
但 MSP2834 使用 Micro SD卡 不是 標準SD卡
觸控回應
由於能夠使用同樣的函式庫控制熒幕,因此在下省卻熒幕的測試,直接測試觸控
線路原型
Raspberry Pi Pico | MSP2834 |
---|---|
5V | VCC, LED |
GND | GND |
3V3 | LCD_RST |
GP26 | CTP_INT |
GP22 | LCD_RS |
GP21 | LCD_CS |
GP20 | CTP_RST |
GP19 | MOSI |
GP18 | SCK |
GP17 | CTP_SCL |
GP16 | CTP_SDA |
由於寫入影像到熒幕的訊號只需要使用 SPI 的 LCD_CS引腳 、 SCK引腳 、 MOSI引腳 ,不需要讀取資料,因此可以省卻連接 MISO引腳
不過如果需要讀取 Micro SD卡 的資料,便需要連接 MOSI引腳 及 SD_CS引腳
實際線路
最終測試效果
補充資料
SD 卡
如果閣下打算將比較細緻圖片在熒幕上顯示,將 圖片 保存到 SD卡
並使用 微控制器 讀取 SD卡,則可以節省 微控制器 的儲存空間
不過由於 SD卡模組 的操作方法同樣能夠使用 SPI 來讀寫資料,因此在下不在此測試
熒幕與觸控
Adafruit Ili9341 及 XPT2046 Touchscreen 同樣提供 setRotation 的功能來調整熒幕的方向
令使用者不需要計算圖案的在旋轉後的內容位置
但兩者的 setRotation 的旋轉方向有些分別
ili9341.setRotation(0) 及 xpt2046.setRotation(2) 的情況
ili9341.setRotation(1) 及 xpt2046.setRotation(3) 的情況
ili9341.setRotation(2) 及 xpt2046.setRotation(0) 的情況
ili9341.setRotation(3) 及 xpt2046.setRotation(1) 的情況
由於 MSP2807 的觸控熒幕 由於使用 電阻式觸控(Resistive Touch) 技術,因此只能回應 1個觸控點
如果超過 1個觸控點 在熒幕上按壓,偵測到的 X軸 、 Y軸 、 Z軸 的資料會錯誤
在下製作一個簡單的資料表來比較 3軸 的數值
軸 | 最小值 | 最大值 |
---|---|---|
X | 111 | 3910 |
Y | 231 | 3872 |
Z | 400 | 2550 |
ILI9341 及 XPT2046 的旋轉設定偏差 2
雖然資料指 XPT2046 擁有 12位元 的深度,不過在下實際測試時,3軸 都無法達到 4095
當中 Z軸 表示 按壓力度,在下測試時使用觸控筆,大致上沒有用力按壓,只是讓地心吸力自然按壓
由於 按壓力度越大, Z軸的數值便越大,但在下避免損受模組,因此不敢太用力按壓
而在下亦測試 平均按壓力度 大約是 1154 (1024個樣本) ,因此如果想避免觸控操作太敏感,可以參考平均值
另外 FT6336U 的函式庫則沒有提供旋轉設定,因此必須自行計算觸控範圍
對應方向與 ili9341.setRotation(0) 相同
如果將熒幕上的圖案旋轉成與 ili9341.setRotation(0) 相同的方向,便可以省卻自行計算觸控制位置
除了無法旋轉, FT6336U 亦沒有壓力感應
而在 FT6336U 的函式庫運用上,不是傳回位元資料,而是已經將資料轉換成對應位置的資料
這種設計,好處是使用者不需要自行轉換資料便能夠直接使用
但壞處是當觸控熒幕解像度超過 240x320 便無法傳回正確的位置資料
另外 FT6336U 的電容式觸控制熒幕能夠偵測同時最多2個觸控位置
由於測試的程式碼都是能夠直接使用範本修改,便可以使用
不過要設定觸控範圍是比較麻煩的編程內容,因為需要規劃不同觸控範圍的操作
Column 1 (80 px) |
Column 2 (80 px) |
Column 3 (80 px) |
|
Row 1 (80 px) |
Row 1 Column 1 |
Row 1 Column 2 |
Row 1 Column 3 |
Row 2 (80 px) |
Row 2 Column 1 |
Row 2 Column 2 |
Row 2 Column 3 |
Row 3 (80 px) |
Row 3 Column 1 |
Row 3 Column 2 |
Row 3 Column 3 |
Row 4 (80 px) |
Row 4 Column 1 |
Row 4 Column 2 |
Row 4 Column 3 |
if (0 <= x && x < 80 && 0 <= y && y < 80) { // row 1 column 1 action } else if (80 <= x && x < 160 && 0 <= y && y < 80) { // row 1 column 2 action } else if (160 <= x && x < 240 && 0 <= y && y < 80) { // row 1 column 3 action } else if (0 <= x && x < 80 && 80 <= y && y < 160) { // row 2 column 1 action } else if (80 <= x && x < 160 && 80 <= y && y < 160) { // row 2 column 2 action } else if (160 <= x && x < 240 && 80 <= y && y < 160) { // row 2 column 3 action } else if (0 <= x && x < 80 && 160 <= y && y < 240) { // row 3 column 1 action } else if (80 <= x && x < 160 && 160 <= y && y < 240) { // row 3 column 2 action } else if (160 <= x && x < 240 && 160 <= y && y < 240) { // row 3 column 3 action } else if (0 <= x && x < 80 && 240 <= y && y < 320) { // row 4 column 1 action } else if (80 <= x && x < 160 && 240 <= y && y < 320) { // row 4 column 2 action } else if (160 <= x && x < 240 && 240 <= y && y < 320) { // row 4 column 3 action }
例如要製作上述觸控範圍,假設 闊240像素 及 高320像素
每個觸控範圍都是 闊80像素 及 高80像素,分割成 3列 4欄 ,便需要自訂觸控範圍以觸發觸控操作
程式碼中的 x 及 y 分別是 觸控 的 x軸 及 y軸 位置
I2C 地址
#include <Wire.h> void setup() { pinMode(13, OUTPUT); Serial.begin(115200); Wire.begin(); digitalWrite(13, HIGH); delay(1000); for (byte i = 0; i < 128; i++) { Wire.beginTransmission(i); byte code = Wire.endTransmission(); if (code == 0) { Serial.print("0x"); if (i < 16) { Serial.print("0"); } Serial.print(i, HEX); Serial.println(); } } digitalWrite(13, LOW); } void loop() { delay(1000); }
由於一些使用 I2C 協定的裝置未必有提供 I2C 地址
因此在下製作了一個能偵測已連接的 I2C 裝置的地址的 Sketch
在下使用另一款 I2C 熒幕測試,地址分別為 0x3C 及 0x3D
微控制器會將偵測到的 I2C 地址 顯示在序列輸出
輸出結果與裝置設定的 I2C 地址 相同
測試 MSP2834 便能夠獲取 I2C 地址
總結
在下曾經閱讀過一篇文章,提到 SpaceX 的控制裝置設計採用了觸控熒幕,取代了大量的按鈕、旋鈕及類比操作
這種設計不僅可以降低開發成本,還能加快開發進度和縮短檢查時間
不過,對於涉及安全的操作,仍然使用傳統的控制方式
在這次測試中,在下確實減少了大量的佈線問題
例如如果在下需要製作一個具備熒幕顯示結果並且有 12個功能 的裝置
僅僅是 12個按鈕 就需要 12個GPIO,即使使用矩陣方式佈線,最少仍需 7個GPIO
如果需要增加按鈕,則需額外增加 GPIO 的使用量
然而,觸控熒幕使用序列訊號協定,只需要 4個GPIO(SPI) 甚至 2個GPIO(I2C) 就能完成操作
此外,觸控範圍和數量可以根據需求在更新韌體時進行調整,無需因為增加功能而重新添置按鈕或佈線
即使需要接上 RST引腳 及 INT引腳,最多也只需 6個GPIO
如果觸控熒幕損壞,更換整個觸控模組將會更迅速方便
雖然按鈕的價格相對較低,但在 SpaceX 執行太空任務時發生事故的情況下
能夠即時更換整個觸控模組反而會更快、更安全
但在下仍然覺得按鈕、旋鈕及類比的操作方式有存在的必要
例子某些電子遊戲、手術儀器等需要非常準確的操作要求,觸控操作反而會非常不方便
另外還有如果沒有聲音輔助,盲人是無法使用觸控熒幕操作
沒有留言 :
張貼留言