2022-05-12

使用 Mini D1 ESP32 製作 藍牙HID鍵盤

上次使用 Arduino Pro Micro 模擬 鍵盤按鍵操作,但 iOS 無法簡單地透過 USB連接 鍵盤及電腦
需要透過藍牙裝置才能將鍵盤按鍵的效果傳送給 iOS ,因此在下又要測試新零件

Mini D1 ESP32

外觀
見下文
Mini D1 ESP32 正面

見下文
Mini D1 ESP32 使用 ESP-WROOM-32 晶片
是一種具備 WiFiBluetooth Low Energy (BLE) 的混合型微控制器模組

見下文
CH9102X 是一種 能將電子訊號轉換成 USB訊號 的晶片

見下文
Mini D1 ESP32 背面,印有引腳功能
(由於不需要用盡所有引腳,因此在下只焊接需要使用的引腳)

見下文
Mini D1 ESP32 使用 Micro USB Type-B 插口

見下文
Micro USB Type-B 插口 旁邊有重新啟動按鈕

引腳
Mini D1 ESP32 共有 40支引腳,其中38支引腳是由 ESP32-WROOM-32 轉接的引腳
但經 Mini D1 ESP32 轉接的引腳並非傳統的 雙列直插封裝 (Dual Inline Package (DIP))
無法簡單地安裝到麵包板上(除非不焊接其中一排引腳)
另外由於 Mini D1 ESP32 的引腳文字印刷到底部,但使用時通常是正面向上,因此無法看到文字
因此在下以正面的方式將排列列出,方便查看引腳用途

Micro USB Type-B (正面)
1 20 21 40
2 19 22 39
3 18 23 38
4 17 24 37
5 16 25 36
6 15 26 35
7 14 27 34
8 13 28 33
9 12 29 32
10 11 30 31

印刷的引腳名稱比較難明白用途,因此在下使用官方說明文件的用途來命名
編號 引腳 方向 功能
1 S6 特殊 GP6引腳,韌體SPI整合SCK引腳,不能獨立使用
2 S8 特殊 GP8引腳,韌體SPI整合MISO引腳,不能獨立使用
3 IO2 輸入/輸出 GP2數碼引腳,提供接觸訊號,電路板LED
4 IO0 輸入/輸出 GP0數碼引腳,提供接觸訊號
5 IO4 輸入/輸出 GP4數碼引腳,提供接觸訊號
6 IO12 輸入/輸出 GP12數碼引腳,提供接觸訊號
7 IO32 輸入/輸出 GP33數碼引腳,提供接觸訊號
8 IO25 輸入/輸出 GP25數碼引腳
9 IO27 輸入/輸出 GP27數碼引腳,提供接觸訊號
10 GND 接地
11 U1 特殊 GP1引腳,UART整合TXD引腳,不能獨立使用
12 U3 特殊 GP3引腳,UART整合RXD引腳,不能獨立使用
13 IO22 輸入/輸出 GP22數碼引腳,硬件SPI的WP引腳,硬件I2C的SCL引腳
14 IO21 輸入/輸出 GP21數碼引腳,硬件SPI的HOLD引腳,硬件I2C的SDA引腳
15 IO17 輸入/輸出 GP17數碼引腳
16 IO16 輸入/輸出 GP16數碼引腳
17 GND 接地
18 5V 輸出 5V 電壓
19 IO15 輸入/輸出 GP15數碼引腳,提供接觸訊號
20 S7 特殊 GP7引腳,韌體SPI整合MOSI引腳,不能獨立使用
21 S10 特殊 GP10引腳,韌體SPI整合WP引腳,不能獨立使用
22 IO13 輸入/輸出 GP13數碼引腳,提供接觸訊號
23 3V3 輸出 3.3V 電壓
24 IO5 輸入/輸出 GP5數碼引腳,硬件SPI的SS引腳
25 IO23 輸入/輸出 GP23數碼引腳,硬件SPI的MOSI引腳
26 IO19 輸入/輸出 GP18數碼引腳,硬件SPI的MISO引腳
27 IO18 輸入/輸出 GP18數碼引腳,硬件SPI的SCK引腳
28 IO26 輸入/輸出 GP26數碼引腳
29 I36 輸入 GP36引腳,只接受數碼輸入用途
30 RST
31 GND 接地
32 NC 無效引腳
33 I39 輸入 GP39引腳,只接受數碼輸入用途
34 I35 輸入 GP35引腳,只接受數碼輸入用途
35 IO33 輸入/輸出 GP33數碼引腳,提供接觸訊號
36 I34 輸入 GP34引腳,只接受數碼輸入用途
37 IO14 輸入/輸出 GP14數碼引腳,提供接觸訊號
38 NC 無效引腳
39 S9 特殊 GP9引腳,韌體SPI整合HOLD引腳,不能獨立使用
40 S11 特殊 GP11引腳,韌體SPI整合SS引腳,不能獨立使用

Arduino IDE

Mini D1 ESP32 可以透過 Arduino IDE 上載 Sketch
但需要先安裝及設定一些資料

見下文
到 Arduino IDE 的 File > Preferences

見下文
Additional Boards Managers URLs 輸入
https://dl.espressif.com/dl/package_esp32_index.json

然後按 OK

見下文
Tools > Board: > Boards Manager...

見下文
在搜尋欄位尋找 esp32
找到由 Espressif Systems 提供的 ESP32

見下文
見下文
Install 並等待下載及安裝

見下文
安裝支援 ESP32 後,到 Tools > Board: > ESP32 Arduino > WEMOS D1 MINI ESP32

見下文
Tools > Upload Speed: > 115200
其實不一定使用 115200 ,只是 115200 是比較見用的鮑率
使用最高速度的 921600 同樣能夠上載 Sketch

見下文
在下編寫一個讓 Mini D1 ESP32 的 LED 閃動的 Sketch
void setup() {
        pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
        digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
        delay(500);
}

但編譯 Sketch 出現
exec: "python": executable file not found in $PATH
Error compiling for board WEMOS D1 MINI ESP32.


見下文
在 Terminal 輪入
sudo apt install python-is-python3

或按此下載 python-is-python3

見下文
安裝 python-is-python3 雖然修正 PATH 的錯誤,但出現另一個錯誤
Traceback (most recent call last):
    File "${HOME}/.arduino15/packages/esp32/tools/esptool_py/3.0.0/esptool.py", line 38, in <module>
        import serial
moduleNotFoundError: No module named 'serial'
exit status 1
Error compiling for board WEMOS D1 MINI ESP32.

見下文
既然顯示 esptool 找不到 serial ,因此在下在 Terminal 輪入
pip install esptool

嘗試讓 pip 自動安裝需要使用的 python 套件
但原來在下一直都未安裝 pip

見下文
見下文
因此先在 Terminal 輸入
sudo apt install python3-pip
或按此下載 python3-pip

見下文
安裝 pip 後,再次輸入
pip install esptool

便可以下載及安裝 esptool 及相關套件
(注意:不需要使用 sudo 來執行 pip)

見下文
編譯沒有出現錯誤

見下文
將 Sketch 上載到 Mini D1 ESP32

見下文
電路板上的LED 每500毫秒 閃動

BLE Keyboard

BLE Keyboard 函式庫提供與 Keyboard.h 相似的語法及供能,更加容易編寫模擬藍牙鍵盤的功能
但 BLE Keyboard 沒有在 Arduino 函式庫列表上登記,因此需要自行下載及安裝
見下文

見下文
到 Releases 頁面,下載最新版本的 ESP32-BLE-Keyboard.zip
(如果擔心函式庫被移除,請自行保存)

見下文
開啟 Arduino IDE ,到 Include Library > Add .ZIP Library...

見下文
選擇需要匯入的 函式庫zip檔案

見下文
編寫 BLE Keyboard 的 Sketch 並上載到 Mini D1 ESP32
#include <BleKeyboard.h>

BleKeyboard myKeyboard = BleKeyboard("My BLE Keyboard");
// Use any valid pin
const byte SIGNAL_PIN = 26;

void setup() {
        pinMode(SIGNAL_PIN, INPUT);
        pinMode(LED_BUILTIN, OUTPUT);
        digitalWrite(LED_BUILTIN, HIGH);
        myKeyboard.begin();
        digitalWrite(LED_BUILTIN, LOW);
}

void loop() {
        if (myKeyboard.isConnected() && digitalRead(SIGNAL_PIN) == HIGH) {
                myKeyboard.write('1');
        }
}

見下文
當 Mini D1 ESP32 運作時,會發現其藍牙名稱

見下文
點選連接並配對

見下文
見下文
數秒後便可以使用

見下文
見下文
Android 連接時,不需要確認配對

見下文
見下文
見下文
iOS需要 藍牙4.0或以上 及 具備BLE功能 才能辨認及連接

見下文
測試按鍵效果
(閣下應該會發現在下只按一次按鈕,熒幕卻出現多次按鍵效果
是因為在真實環境下,當金屬接觸時,有機會有微少分離並再次接觸的情況,這個情況還會在極短時間內連續發生
這個情況稱為 接觸彈跳(Contact Bouncing)
人不會感覺到這些微少彈跳,但電子裝置卻能夠偵測這些微少彈跳,因此按一次卻出現多次按鍵效果
移除彈跳 (Debouncing) 是非常複雜的操作,因此在下不在此仔細說明
在下使用 下拉電阻 (Pull-Down Resistor) 來處理,但種做法並非最佳方法
如果只是製作測試、實驗性的電子工具,並非精密儀器,這種方法仍然可以解決大部分彈跳的問題

見下文
測試起動、等待配對、已連接效果

在下將之前 Arduino Pro Micro 的程式改為適合 Mini D1 ESP32 使用
在下增加:
  • 起動狀態(Booting)(訊號燈亮著)
  • 等待配對狀態(Waiting for Pairing)(訊號燈每500毫秒閃動)
  • 已配對狀態(Paired)(訊號燈熄滅)
方便辨認 Mini D1 ESP32 的狀態

製作轉接器

由於之前在下曾製作匹配 Arduino Pro Micro 引腳的鍵盤電路板
但不相容 Mini D1 ESP32 的引腳,但重新製作鍵盤電路板,又有點浪費
因此使用萬用電路板,手動方法焊接線路
製作適合 Mini D1 ESP32 至 Arduino Pro Micro 的轉接器

線路原型
見下文
在下使用 Fritzing 並自製 Mini D1 ESP32 元件,方便設計線路

實際線路
見下文
由於實際情況元件能夠向上堆疊,因此可以將萬用電路板剪裁至最小但適合的使用範圍

見下文
見下文
見下文
轉接器的正面

見下文
轉接器的後面

由設計至動手焊接,在下大約使用2小時

見下文
見下文
見下文
見下文
將 Mini D1 ESP32 安裝到 轉接器

見下文
將 轉接器 安裝到 Arduino Pro Micro 鍵盤

見下文
由於在下的朋友使用 iPhone ,因此設計的功能主要是以 iOS 的 VoiceOver 為主要功能:
  • 項目選擇
  • 捲動
  • 轉輪
  • 執行
  • 返回
  • 桌面
  • 切換器
  • 通知中心
  • 控制中心
  • 熒幕開關效果

重新設計

由於之前設計的鍵盤佈局只是為了用盡 Arduino Pro Micro 所有數碼引腳
並沒有考慮按鈕之間空位很少,沒有佈局區分,反而無法達到方便、易用的效果
最後還是要重新設計另一塊電路板,將功能相關的按鈕編排成一個群組,方便記憶及操作

見下文
電路板原型設計圖
綠色線路為正面,紅色線路為背面
按鈕右邊焊墊為列(Row),按鈕左邊焊墊為欄(Column)

見下文
電路板製成器
電路板 正面
其實與之前設計的 8x8按鈕電路板 相同,只是按鈕位置稍微調整及分類
及改用 Mini D1 ESP32 的引腳佈局

見下文
電路板 背面

見下文
在下的名稱 及 Open Hardware 圖案

見下文
安裝 Mini D1 ESP32 (及 8粒 100KΩ 電阻) 的位置

見下文
焊接 64粒 按鈕 及 8粒 120KΩ電阻 及 連接Mini D1 ESP32 的引腳座
(恰巧在下沒有 100KΩ電阻 改用 120KΩ電阻 亦可行)

見下文
焊接 6mm按壓按鈕

見下文
焊接 電阻 及 引腳座
使用 引腳座 可以方便安裝及卸除 Mini D1 ESP32 ,但會比較佔用空間
直接將 Mini D1 ESP32 比較不佔用空間,亦比較美觀,但如果 Mini D1 ESP32 損壞,則很難替換
在下考慮維修或替換問題,因此使用 引腳座 方便事後處理

見下文
焊接後的背面,拿住使用時,非常刺手

見下文
將 Mini D1 ESP32 安裝到新設計的鍵盤電路板

見下文
安裝到鍵盤電路板的 Mini D1 ESP32 的正面

見下文
見下文
安裝到鍵盤電路板的 Mini D1 ESP32 的側面

見下文
安裝到鍵盤電路板的 Mini D1 ESP32 的 Micro USB Type-B 插口方向

欄列按鈕配對
雖然新設計的鍵盤電路板印上按鈕符號,但焊接後會覆蓋符號,因此製作圖表方便記憶按鈕對應程式碼

A B C D E F G H
1 Back Dktp AppS Mute Crtn Notf Ctrl Stts
2 C⇤ C↥ C⇥ Say1 SayC SayS
3 C↤ C↧ C↦ 1 2 3
4 S⇤ S↧ S⇥ 4 5 6
5 S↤ S↧ S↦ 7 8 9
6 Undo Redo SA * 0 #
7 Cut Copy Paste DelR Call DelL
8 Dict SpCp ScCp ! SpTp Run

對應功能
符號 鍵盤1 手勢 功能
Back ESC 2指畫Z 返回上一層目錄
Dktp VO + h 按Home 或 1指由熒幕底部滑動至熒幕下半部 回到桌面
AppS VO + h + h 按2次Home 或 1指由熒幕底部滑動至熒幕上半部 開啟應用程式切換器
Mute VO + s 3指點擊2次 開啟或關閉靜音
Crtn VO + F11 3指點擊3次 開啟或關閉熒幕
Notf VO + PageUp 在狀態列 3指向下滑動 前往通知中心
Ctrl VO + PageDown 在狀態列 3指向上滑動 前往控制中心
Stts VO + m 前往狀態列
C⇤ Cmd + 左箭咀 游標移到最前
C↥ 上箭咀 游標向上移動
C⇥ Cmd + 右箭咀 游標移到最後
Say1 VO + b 2指向上滑動 由第一項目朗讀到最後
SayC VO + a 2指向下滑動 由當前項目朗讀到最後
SayS Control 2指點擊1次 停止朗讀
VO + Cmd + 上箭咀 1指向上滑動 轉輪項目數值增加
VO + Cmd + 下箭咀 1指向下滑動 轉輪項目數值減少
C↤ 左箭咀 遊標向左移動
C↧ 下箭咀 遊標向下移動
C↦ 右箭咀 遊標向右移動
1 數字1 數字鍵盤1
2 數字2 數字鍵盤2
3 數字3 數字鍵盤3
VO + Cmd + 左箭咀 1指在熒幕左邊向下滑動 另1指在熒幕右邊向上滑動 轉輪向左移動
VO + Cmd + 右箭咀 1指在熒幕左邊向上滑動 另1指在熒幕右邊向下滑動 轉輪向右移動
S↤ Cmd + Shift + 左箭咀 選取文字至最前
S↧ Shift + 上箭咀 向上選取文字
S↦ Cmd + Shift + 右箭咀 選取文字至最後
4 數字4 數字鍵盤4
5 數字5 數字鍵盤5
6 數字6 數字鍵盤6
Option + 上箭咀 3指向上滑動 向上捲動
Option + 下箭咀 3指向下滑動 向下捲動
S↤ Shift + 左箭咀 向左取選文字
S↧ Shift + 下箭咀 向下取選文字
S↦ Shift + 右箭咀 向右取選文字
7 數字7 數字鍵盤7
8 數字8 數字鍵盤8
9 數字9 數字鍵盤9
Option + 左箭咀 3指向左滑動 向左捲動
Option + 右箭咀 3指向右滑動 向右捲動
Undo Cmd + z 回復上一步
Redo Cmd + Shift + z 重做下一步
SA Cmd + a 選取所有文字
* 星號 數字鍵盤星號
0 數字0 數字鍵盤0
# 井號 數字鍵盤井號
Control + 上箭咀 3指在熒幕上半部點擊1次 選取最前項目
Control + 下箭咀 3指在熒幕下半部點擊1次 選取最後項目
Cut Cmd + x 將選取的文字複製到剪貼簿,並刪除選取文字
Copy Cmd + c 將選取的文字複製到剪貼簿
Paste Cmd + v 將剪貼簿在遊標位置貼上
DelR Shift + Delete 刪除遊標右側文字
Call Return 電話撥號
DelL Delete 刪除遊標左側文字
左箭咀 1指向左滑動 選取上一個項目
右箭咀 1指向右滑動 選取下一個項目
Dict 文字編輯時2指點擊2次 使用聽寫
SpCp VO + Shift + c 3指點擊4次 將朗讀的文字複製到剪貼簿
ScCp Cmd + Shift + 3 音量減 + Home 或 音量加 + 開關鍵 擷取熒幕截圖
! Control + space 切換輸入法
上箭咀 1指向上滑動 選擇已選取項目的上一個功能
下箭咀 1指向下滑動 選擇已選取項目的下一個功能
SpTp VO + - 2指點擊2次 使用精妙點擊
Run VO + space 2指點擊1次 執行已選取項目
1. 鍵盤 以 Mac鍵盤 為基礎
Mac鍵盤 的 Control 預設為 一般鍵盤 的 Ctrl
Mac鍵盤 的 Option 預設為 一般鍵盤 的 Alt
Mac鍵盤 的 Command 預設為 一般鍵盤 的 Win
VO 為 VoiceOver修飾鍵 預設為 Control + Option

見下文
測試:
  • 數字鍵盤
  • 刪除文字
  • 撥號效果
(在下電話因為只作測試用途,沒有安裝電話卡,因此沒有正式通話)

見下文
測試:
  • 複製朗讀文字
  • 遊標移動
  • 文字選取
  • 文字處理
  • 輸入法切換
  • 熒幕擷取

補充資料

見下文
除了 iOS 的 VoiceOver ,在下還測試 Android 的 TalkBack
TalkBack 都能夠支援類似的無障礙操,但功能比較少
而且主要是 Android 原生鍵盤功能或效果,而 TalkBack 的功能則比較少
不同牌子、型號的 Android 支援鍵盤操作的程度各有不同

由於 Apple 將大量手勢申請專利 (WO2011088134),導致其他公司在未經授權下不能使用特定手勢
因此 TalkBack 有部分手勢無法使用,亦沒有加入鍵盤功能
亦有部分原因是不同的 Android ,沒有整合手勢,導致無法使用鍵盤操作
例如某些 Android 的電話功能能夠使用數字鍵盤輸入,某些不能
某些 Android 可以使用 Page Up 或 Page Down 捲動頁面,某些不能
由於太多不同公司的 Android ,在下都無法全部測試

總結

要讓 iPhone 能使用文字輸入以外的鍵盤操作,需要啟動 全面鍵盤操控 (Full Keyboard Access) 功能
或啟動 VoiceOver 並配合 VoiceOver 專用的快捷鍵
由於一些特別原因,認識到一些有心人捐贈或以非常便宜的二手價轉讓電腦、電話、電子工具給在下
因此在下不同型號的 iPhone 可以測試這個專案

見下文
在下發現,當 主要語言 使用中文(或非英文?)時,VO + 字母 的 VoiceOver 操作有時會無法使用
要到 設定 > 一般 > 語言與地區 > 偏好的語言順序英文 設定為主要語言,便能正常操作,不過 VoiceOver 便會朗讀英語
(切換語言時會中斷熒幕錄影,因此在下直接拍攝電話畫面)

而 Android 由於原生設計已經可以使用鍵盤操作,只需要透過 USB OTG (USB On-The-Go) 連接便可以使用
並非只能使用 藍牙HID鍵盤

製作這個鍵盤的主要原因是因為在下的朋友有視力障礙問題
由於現在的智能電話主要都是觸控熒幕,視力障礙人士容易有錯誤操作情況
但一般藍牙鍵盤的佈局都是傳統佈局,而且要記下大量組合鍵並不容易
因此設計這個鍵盤給朋友使用
而在下只是簡單說明按鈕佈局,朋友只需要5分鐘便熟習操作,至今亦有使用

在下將組合鍵操作設計成單鍵操作,可以方便使用者不需要記下大量組合鍵,甚至可以單手操作
如果懂得自改修改程式碼,可以將按鍵修改成自己需要的按鍵操作或組合鍵,如同 Macro Keyboard 一般使用

在下將資料分享到 https://bitbucket.org/hkgoldenmra/wemos-mini-d1-keyboard ,包括:
  • 相容 WeMos Mini D1 的 Arduino 的 ino 原始碼
  • SVG 及 PNG 電路原型設計預覽圖
  • Fritzing 電路原型設計圖
  • Gerber 印刷電路檔案
有興趣亦可以自行下載使用及修改

參考資料

沒有留言 :

張貼留言