2022-03-13

使用 Arduino Pro Micro 製作 USB鍵盤

最近有人向在下查詢,有否外接的 USB數字鍵盤 是 電話按鈕部局
在下在 Google 上嘗試搜尋 usb telephone layout numpad ,大部分都是 電腦按鈕部局 的 USB數字鍵盤
而 電話按鈕部局 都是工業用途,不鏽鋼外殼、防水、12個按扭 已經需要大約 50美元
50美元 只使用 12個按鈕 又有點貴,在下又要想想方法有否平價方案

Arduino Pro Micro

Arduino Pro Micro 使用 ATmega32U4晶片 ,是一種具備 抽像控制模型 (Abstract Control Model (ACM)) 的晶片
能讓電子訊號轉模擬成 USB訊號

外觀
見下文
見下文
Arduino Pro Micro 的正面

見下文
Arduino Pro Micro 的背面

引腳
引腳 編號 編號 引腳
D1 1 24 RAW
D0 2 23 GND
GND 3 22 RST
GND 4 21 5V
D2 5 20 A3
D3~ 6 19 A2
D4 7 18 A1
D5~ 8 17 A0
D6~ 9 16 D15
D7 10 15 D14
D8 11 14 D16
D9~ 12 13 D10~

編號 引腳 方向 功能
1 D1 輸入/輸出 第1數碼引腳, UART TX引腳
2 D0 輸入/輸出 第0數碼引腳, UART RX引腳
3 GND 接地
4 GND 接地
5 D2 輸入/輸出 第2數碼引腳, I2C SDA引腳
6 D3~ 輸入/輸出 第3數碼引腳, I2C SCL引腳,有 PWM 功能
7 D4 輸入/輸出 第4數碼引腳
8 D5~ 輸入/輸出 第5數碼引腳,有 PWM 功能
9 D6~ 輸入/輸出 第6數碼引腳,有 PWM 功能
10 D7 輸入/輸出 第7數碼引腳
11 D8 輸入/輸出 第8數碼引腳
12 D9~ 輸入/輸出 第9數碼引腳,有 PWM 功能
13 D10~ 輸入/輸出 第10數碼引腳,有 PWM 功能
14 D16 輸入/輸出 第16數碼引腳,SPI MOSI引腳
15 D14 輸入/輸出 第14數碼引腳,SPI MISO引腳
16 D15 輸入/輸出 第15數碼引腳,SPI SCK引腳
17 A0 輸入/輸出 第0類比引腳
18 A1 輸入/輸出 第1類比引腳
19 A2 輸入/輸出 第2類比引腳
20 A3 輸入/輸出 第3類比引腳
21 5V 輸出 5V 電源
22 RST 接地時重新啟動
23 GND 接地
24 RAW 接受 4.8V 至 12V 電源
(沒有穩電器,要注意電壓變化)

線路原型
見下文
其實只是接駁一個按鈕作測試

實際線路
見下文
因為線路簡單,實際線路與線路原型接近相同

見下文
編寫測試的 Sketch 並上載到 Arduino Pro Micro
在下使用 Arduino 預設的 Keyboard.h
#include <Keyboard.h>

const byte SIG = A3;

void setup() {
	Keyboard.begin();
	pinMode(SIG, INPUT);
	pinMode(LED_BUILTIN_TX, OUTPUT);
	pinMode(LED_BUILTIN_RX, OUTPUT);
}

void loop() {
	if (digitalRead(SIG) == HIGH) {
		digitalWrite(LED_BUILTIN_TX, HIGH);
		digitalWrite(LED_BUILTIN_RX, LOW);
		Keyboard.press('A');
	} else {
		digitalWrite(LED_BUILTIN_TX, LOW);
		digitalWrite(LED_BUILTIN_RX, HIGH);
		Keyboard.release('A');
	}
}

Keyboard.h 非常容易使用
語法 功能
Keyboard.begin();
啟動鍵盤模擬
Keyboard.end();
結束鍵盤模擬
Keyboard.print(char);
Keyboard.print(char[]);
Keyboard.print(String);
模擬鍵盤輸入 字元、字元陣列、字串
Keyboard.println();
Keyboard.println(char);
Keyboard.println(char[]);
Keyboard.println(String);
模擬鍵盤輸入 新行、字元、字元陣列、字串
Keyboard.write(char);
模擬鍵盤輸入 字元
Keyboard.press(char);
模擬鍵盤按著 字元
Keyboard.release(char);
模擬鍵盤釋放 字元
Keyboard.releaseAll();
模擬鍵盤釋放 所有字元

自製鍵盤

在下為了能方便安裝及卸除 Arduino Pro Micro 及用盡 16支引腳,設計一塊簡單的電路板測試

見下文
電路板設計圖

見下文
16支引腳 其中 8支引腳 控制列,另外 8支引腳 控制欄

見下文
在下使用 試算表儲存格的命名方式 配置按鈕的名稱

見下文
見下文
連接到 Arduino Pro Micro 的引腳亦配置 欄列名稱

見下文
所有線都配置在電路板背面

見下文
見下文
將 100KΩ電阻器 及 引腳座 焊接到 電路板
下拉電阻可以讓訊號保低電壓,避免訊號不穩定

見下文
由於不需要使用 Arduino Pro Micro 第1引腳 至 第4引腳 ,因此在下「偷工減料」一點,焊少4支引腳

見下文
見下文
見下文
將 Arduino Pro Micro 安裝到 引腳座

見下文
焊接 64個按鈕 到 電路板

見下文
除了 Keyboard.h ,在下還使用 Keypad.h 測試按鍵效果

#include <Keypad.h>
#include <Keyboard.h>
const byte ROW_COUNT = 8;
const byte COL_COUNT = 8;
const byte ROW_PINS[ROW_COUNT] = {A3, A2, A1, A0, 15, 14, 16, 10};
const byte COL_PINS[COL_COUNT] = {2, 3, 4, 5, 6, 7, 8, 9};
const byte KEYS[ROW_COUNT][COL_COUNT] = {
	{0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18},
	{0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28},
	{0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38},
	{0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48},
	{0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58},
	{0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68},
	{0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78},
	{0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88}
};
Keypad keypad = Keypad(makeKeymap(KEYS), ROW_PINS, COL_PINS, ROW_COUNT, COL_COUNT);
void setup() {
	pinMode(LED_BUILTIN_RX, OUTPUT);
	pinMode(LED_BUILTIN_TX, OUTPUT);
	Keyboard.begin();
}
void loop() {
	digitalWrite(LED_BUILTIN_RX, HIGH);
	digitalWrite(LED_BUILTIN_TX, HIGH);
	const byte KEY = keypad.getKey();
	if (KEY > 0) {
		if (KEY == 0x11) {
			// select all
			Keyboard.press(0x84);
			Keyboard.write(0x8C);
			Keyboard.release(0x84);
		} else if (KEY == 0x12) {
			// cut
			Keyboard.press(0x84);
			Keyboard.write(0xA3);
			Keyboard.release(0x84);
		} else if (KEY == 0x13) {
			// copy
			Keyboard.press(0x84);
			Keyboard.write(0x8E);
			Keyboard.release(0x84);
		} else if (KEY == 0x14) {
			// paste
			Keyboard.press(0x84);
			Keyboard.write(0xA1);
			Keyboard.release(0x84);
		} else if (KEY == 0x15) {
		} else if (KEY == 0x16) {
		} else if (KEY == 0x17) {
		} else if (KEY == 0x18) {
		} else if (KEY == 0x21) {
		} else if (KEY == 0x22) {
		} else if (KEY == 0x23) {
		} else if (KEY == 0x24) {
		} else if (KEY == 0x25) {
		} else if (KEY == 0x26) {
		} else if (KEY == 0x27) {
		} else if (KEY == 0x28) {
		} else if (KEY == 0x31) {
		} else if (KEY == 0x32) {
		} else if (KEY == 0x33) {
		} else if (KEY == 0x34) {
		} else if (KEY == 0x35) {
		} else if (KEY == 0x36) {
		} else if (KEY == 0x37) {
		} else if (KEY == 0x38) {
		} else if (KEY == 0x41) {
		} else if (KEY == 0x42) {
		} else if (KEY == 0x43) {
		} else if (KEY == 0x44) {
		} else if (KEY == 0x45) {
		} else if (KEY == 0x46) {
		} else if (KEY == 0x47) {
		} else if (KEY == 0x48) {
		} else if (KEY == 0x51) {
		} else if (KEY == 0x52) {
		} else if (KEY == 0x53) {
		} else if (KEY == 0x54) {
		} else if (KEY == 0x55) {
		} else if (KEY == 0x56) {
		} else if (KEY == 0x57) {
		} else if (KEY == 0x58) {
		} else if (KEY == 0x61) {
		} else if (KEY == 0x62) {
		} else if (KEY == 0x63) {
		} else if (KEY == 0x64) {
		} else if (KEY == 0x65) {
		} else if (KEY == 0x66) {
		} else if (KEY == 0x67) {
		} else if (KEY == 0x68) {
		} else if (KEY == 0x61) {
		} else if (KEY == 0x62) {
		} else if (KEY == 0x63) {
		} else if (KEY == 0x64) {
		} else if (KEY == 0x65) {
		} else if (KEY == 0x66) {
		} else if (KEY == 0x67) {
		} else if (KEY == 0x68) {
		} else if (KEY == 0x71) {
		} else if (KEY == 0x72) {
		} else if (KEY == 0x73) {
		} else if (KEY == 0x74) {
		} else if (KEY == 0x75) {
		} else if (KEY == 0x76) {
		} else if (KEY == 0x77) {
		} else if (KEY == 0x78) {
		} else if (KEY == 0x81) {
		} else if (KEY == 0x82) {
		} else if (KEY == 0x83) {
		} else if (KEY == 0x84) {
		} else if (KEY == 0x85) {
		} else if (KEY == 0x86) {
		} else if (KEY == 0x87) {
		} else if (KEY == 0x88) {
		}
		digitalWrite(LED_BUILTIN_TX, LOW);
	}
	delay(10);
}

示範中在下使用了
  • 向左選取 (Shift + 左)
  • 向右選取 (Shift + 右)
  • 向上選取 (Shift + 上)
  • 向下選取 (Shift + 下)
  • 全選 (Ctrl + A)
  • 剪下 (Ctrl + X)
  • 複製 (Ctrl + C)
  • 貼上 (Ctrl + V)
讓 Arduino Pro Micro 模擬這些組合鍵輸入,變成單鍵操作

8位元 ASCII表

Arduino 的 Keyboard.h 定義了 8位元 ASCII表 ,即是 0x00 至 0xFF 的字元

十進制 十六進制 二進制 用途
ASCII 標準鍵盤 數字鍵盤
0 0x00 B00000000 Null
1 0x01 B00000001 Start of Heading
2 0x02 B00000010 Start of Text
3 0x03 B00000011 End of Text
4 0x04 B00000100 End of Transmission
5 0x05 B00000101 Enquiry
6 0x06 B00000110 Acknowledge
7 0x07 B00000111 Bell
8 0x08 B00001000 Backspace
9 0x09 B00001001 Horizontal Tabulation
10 0xA B00001010 Line Feed
11 0xB B00001011 Vertical Tabulation
12 0xC B00001100 Form Feed
13 0xD B00001101 Carriage Return
14 0xE B00001110 Shift Out
15 0xF B00001111 Shift In
16 0x10 B00010000 Data Link Escape
17 0x11 B00010001 Device Control 1
18 0x12 B00010010 Device Control 2
19 0x13 B00010011 Device Control 3
20 0x14 B00010100 Device Control 4
21 0x15 B00010101 Negative Acknowledgement
22 0x16 B00010110 Synchronous Idle
23 0x17 B00010111 End of Transmission Block
24 0x18 B00011000 Cancel
25 0x19 B00011001 End of Medium
26 0x1A B00011010 Substitute
27 0x1B B00011011
28 0x1C B00011100 File Separator
29 0x1D B00011101 Group Separator
30 0x1E B00011110 Record Separator
31 0x1F B00011111 Unit Separator
32 0x20 B00100000 空格 ( )
33 0x21 B00100001 嘆號 (!)
34 0x22 B00100010 雙引號 (")
35 0x23 B00100011 井號 (#)
36 0x24 B00100100 錢幣號 ($)
37 0x25 B00100101 百分號 (%)
38 0x26 B00100110 及號 (&)
39 0x27 B00100111 單引號 (')
40 0x28 B00101000 開圓括號 (
41 0x29 B00101001 關圓括號 )
42 0x2A B00101010 星號 (*)
43 0x2B B00101011 加號 (+)
44 0x2C B00101100 逗號 (,)
45 0x2D B00101101 減號 (-)
46 0x2E B00101110 點 (.)
47 0x2F B00101111 斜線 (/)
48 0x30 B00110000 數字0
49 0x31 B00110001 數字1
50 0x32 B00110010 數字2
51 0x33 B00110011 數字3
52 0x34 B00110100 數字4
53 0x35 B00110101 數字5
54 0x36 B00110110 數字6
55 0x37 B00110111 數字7
56 0x38 B00111000 數字8
57 0x39 B00111001 數字9
58 0x3A B00111010 冒號 (:)
59 0x3B B00111011 分號 (;)
60 0x3C B00111100 小於號 (<)
61 0x3D B00111101 等於號 (=)
62 0x3E B00111110 大於號 (>)
63 0x3F B00111111 問號 (?)
64 0x40 B01000000 在號 (@)
65 0x41 B01000001 大寫字母A
66 0x42 B01000010 大寫字母B
67 0x43 B01000011 大寫字母C
68 0x44 B01000100 大寫字母D
69 0x45 B01000101 大寫字母E
70 0x46 B01000110 大寫字母F
71 0x47 B01000111 大寫字母G
72 0x48 B01001000 大寫字母H
73 0x49 B01001001 大寫字母I
74 0x4A B01001010 大寫字母J
75 0x4B B01001011 大寫字母K
76 0x4C B01001100 大寫字母L
77 0x4D B01001101 大寫字母M
78 0x4E B01001110 大寫字母N
79 0x4F B01001111 大寫字母O
80 0x50 B01010000 大寫字母P
81 0x51 B01010001 大寫字母Q
82 0x52 B01010010 大寫字母R
83 0x53 B01010011 大寫字母S
84 0x54 B01010100 大寫字母T
85 0x55 B01010101 大寫字母U
86 0x56 B01010110 大寫字母V
87 0x57 B01010111 大寫字母W
88 0x58 B01011000 大寫字母X
89 0x59 B01011001 大寫字母Y
90 0x5A B01011010 大寫字母Z
91 0x5B B01011011 開方括號 ([)
92 0x5C B01011100 反斜線 (\)
93 0x5D B01011101 關方括號 (])
94 0x5E B01011110 上標號 (^)
95 0x5F B01011111 底線 (_)
96 0x60 B01100000 反引號 (`)
97 0x61 B01100001 小寫字母a
98 0x62 B01100010 小寫字母b
99 0x63 B01100011 小寫字母c
100 0x64 B01100100 小寫字母d
101 0x65 B01100101 小寫字母e
102 0x66 B01100110 小寫字母f
103 0x67 B01100111 小寫字母g
104 0x68 B01101000 小寫字母h
105 0x69 B01101001 小寫字母i
106 0x6A B01101010 小寫字母j
107 0x6B B01101011 小寫字母k
108 0x6C B01101100 小寫字母l
109 0x6D B01101101 小寫字母m
110 0x6E B01101110 小寫字母n
111 0x6F B01101111 小寫字母o
112 0x70 B01110000 小寫字母p
113 0x71 B01110001 小寫字母q
114 0x72 B01110010 小寫字母r
115 0x73 B01110011 小寫字母s
116 0x74 B01110100 小寫字母t
117 0x75 B01110101 小寫字母u
118 0x76 B01110110 小寫字母v
119 0x77 B01110111 小寫字母w
120 0x78 B01111000 小寫字母x
121 0x79 B01111001 小寫字母y
122 0x7A B01111010 小寫字母z
123 0x7B B01111011 開曲括號 ({)
124 0x7C B01111100 管線 (|)
125 0x7D B01111101 關曲括號 (})
126 0x7E B01111110 波紋號 (~)
127 0x7F B01111111 Delete
128 0x80 B10000000 左Ctrl鍵
129 0x81 B10000001 左Shift鍵
130 0x82 B10000010 左Alt鍵
131 0x83 B10000011 Meta鍵
132 0x84 B10000100 右Ctrl鍵
133 0x85 B10000101 右Shift鍵
134 0x86 B10000110 右Alt鍵
135 0x87 B10000111 OS鍵
136 0x88 B10001000
137 0x89 B10001001
138 0x8A B10001010
139 0x8B B10001011
140 0x8C B10001100 小寫字母a鍵
141 0x8D B10001101 小寫字母b鍵
142 0x8E B10001110 小寫字母c鍵
143 0x8F B10001111 小寫字母d鍵
144 0x90 B10010000 小寫字母e鍵
145 0x91 B10010001 小寫字母f鍵
146 0x92 B10010010 小寫字母g鍵
147 0x93 B10010011 小寫字母h鍵
148 0x94 B10010100 小寫字母i鍵
149 0x95 B10010101 小寫字母j鍵
150 0x96 B10010110 小寫字母k鍵
151 0x97 B10010111 小寫字母l鍵
152 0x98 B10011000 小寫字母m鍵
153 0x99 B10011001 小寫字母n鍵
154 0x9A B10011010 小寫字母o鍵
155 0x9B B10011011 小寫字母p鍵
156 0x9C B10011100 小寫字母q鍵
157 0x9D B10011101 小寫字母r鍵
158 0x9E B10011110 小寫字母s鍵
159 0x9F B10011111 小寫字母t鍵
160 0xA0 B10100000 小寫字母u鍵
161 0xA1 B10100001 小寫字母v鍵
162 0xA2 B10100010 小寫字母w鍵
163 0xA3 B10100011 小寫字母x鍵
164 0xA4 B10100100 小寫字母y鍵
165 0xA5 B10100101 小寫字母z鍵
166 0xA6 B10100110 數字1
167 0xA7 B10100111 數字2
168 0xA8 B10101000 數字3
169 0xA9 B10101001 數字4
170 0xAA B10101010 數字5
171 0xAB B10101011 數字6
172 0xAC B10101100 數字7
173 0xAD B10101101 數字8
174 0xAE B10101110 數字9
175 0xAF B10101111 數字0
176 0xB0 B10110000 Enter鍵
177 0xB1 B10110001 Escape鍵
178 0xB2 B10110010 Backspace鍵
179 0xB3 B10110011 Tab鍵
180 0xB4 B10110100 Space鍵
181 0xB5 B10110101 減號鍵
182 0xB6 B10110110 等於號鍵
183 0xB7 B10110111 開方括號鍵
184 0xB8 B10111000 關方括號鍵
185 0xB9 B10111001 反斜線鍵
186 0xBA B10111010 反斜線鍵
187 0xBB B10111011 分號鍵
188 0xBC B10111100 單引號鍵
189 0xBD B10111101 反引號鍵
190 0xBE B10111110 逗號鍵
191 0xBF B10111111 點鍵
192 0xC0 B11000000 斜線鍵
193 0xC1 B11000001 大小寫鎖定鍵
194 0xC2 B11000010 F1鍵
195 0xC3 B11000011 F2鍵
196 0xC4 B11000100 F3鍵
197 0xC5 B11000101 F4鍵
198 0xC6 B11000110 F5鍵
199 0xC7 B11000111 F6鍵
200 0xC8 B11001000 F7鍵
201 0xC9 B11001001 F8鍵
202 0xCA B11001010 F9鍵
203 0xCB B11001011 F10鍵
204 0xCC B11001100 F11鍵
205 0xCD B11001101 F12鍵
206 0xCE B11001110 Print Screen鍵
207 0xCF B11001111 Scroll Lock鍵
208 0xD0 B11010000 Pause鍵
209 0xD1 B11010001 Insert鍵
210 0xD2 B11010010 Home鍵
211 0xD3 B11010011 Page Up鍵
212 0xD4 B11010100 Delete鍵
213 0xD5 B11010101 End鍵
214 0xD6 B11010110 Page Down鍵
215 0xD7 B11010111 右箭咀鍵
216 0xD8 B11011000 左箭咀鍵
217 0xD9 B11011001 下箭咀鍵
218 0xDA B11011010 上箭咀鍵
219 0xDB B11011011 Num Lock鍵
220 0xDC B11011100 斜線鍵
221 0xDD B11011101 星號鍵
222 0xDE B11011110 減號鍵
223 0xDF B11011111 加號鍵
224 0xE0 B11100000 Enter鍵
225 0xE1 B11100001 數字1鍵
226 0xE2 B11100010 數字2鍵
227 0xE3 B11100011 數字3鍵
228 0xE4 B11100100 數字4鍵
229 0xE5 B11100101 數字5鍵
230 0xE6 B11100110 數字6鍵
231 0xE7 B11100111 數字7鍵
232 0xE8 B11101000 數字8鍵
233 0xE9 B11101001 數字9鍵
234 0xEA B11101010 數字0鍵
235 0xEB B11101011 點鍵
236 0xEC B11101100 小於號鍵
237 0xED B11101101 Context Menu鍵
238 0xEE B11101110 Halt鍵
239 0xEF B11101111 等號鍵
240 0xF0 B11110000 F13鍵
241 0xF1 B11110001 F14鍵
242 0xF2 B11110010 F15鍵
243 0xF3 B11110011 F16鍵
244 0xF4 B11110100 F17鍵
245 0xF5 B11110101 F18鍵
246 0xF6 B11110110 F19鍵
247 0xF7 B11110111 F20鍵
248 0xF8 B11111000 F21鍵
249 0xF9 B11111001 F22鍵
250 0xFA B11111010 F23鍵
251 0xFB B11111011 F24鍵
252 0xFC B11111100
253 0xFD B11111101
254 0xFE B11111110
255 0xFF B11111111

在下將輸入字元分為 ASCII字元 、 標準鍵盤 、 數字鍵盤
Keyboard.h 由 0x00 至 0x7F 模擬輸入的內容與 ISO646 的 ASCII字元 相同
但 0x80 至 0xFF 則是由 Keyboard.h 定義,讓 Arduino 能模擬出更真實的鍵盤操作
例如 0x80 至 0x87 的 修飾鍵 ,可以模擬如示範影片的 選取、複製、貼上 等複合鍵的功能

模擬鍵盤時,當使用 Keyboard.press 指定的操作後,必須使用 Keyboard.release 指定相對的操作
或使用 Keyboard.releaseAll 所有操作,避免操作被鎖定,即使拔除 USB 仍然生效
需要按下真實鍵盤上相同操作的按鈕或關機才能取消操作

Keyboard.h 提供模擬實體鍵盤的操作
Keyboard.write('1');
Keyboard.write(0xA6);
Keyboard.write(0xE1);

輸出結果都是 數字1
但實際上 Keyboard.write('1') 只是輸出 數字1
Keyboard.write(0xA6) 是模擬按下 105鍵盤 (105 Keyboard) 的 數字1鍵
而 Keyboard.write(0xE1) 是模擬按下 數字鍵盤 (Number Pad) 的 數字1鍵
細節上 Keyboard.write(0xA6) 及 Keyboard.write(0xE1) 是不同
例如很多電腦遊戲的快捷鍵操作,當指明需要按 數字鍵盤 的 數字鍵 時,按 105鍵盤 的 數字鍵 則無法生效,反之亦然

總結

由於向在下查詢此問題的人,並不太熟識科技知識,記憶力亦不太好
因此在下將經常使用的組合鍵,製作成單鍵操,方便該人士使用

這個自製鍵盤,除左解決到一些對鍵盤操作有困難的人的問題
還可以簡化在下使用一些重覆工序的電腦操作,及方便遊玩的電腦遊戲時快速輸入特定按鍵操作
Arduino 除了 Keyboard.h ,還有 Mouse.h 及 Joystick.h 可以自行製作類似 Marco 的操作
希望在下稍後有時間製作

參考資料

沒有留言 :

張貼留言