2011年11月25日 星期五

送出按鍵敲擊動作 (Send a keystroke)

承上篇,接著我們來看個很簡單的範例,來學習如何讓 Arduino 送出一個按鍵敲擊動作 (keystroke) 給電腦。

image 

程式碼

這個範例程式放在 Arduino Keyboard 裏。請打開 Arduino IDE, 載入 "File > Sketchbook > Arduino-keyboard > senda" 然後把程式上傳到 Arduino 板子上:

image

程式上傳到 Arduino 板子上後,接著把 Arduino 切到 DFU mode,用 FLIP 把 Arduino-keyboard-0.3.hex 燒錄到 atmega8u2 晶片上,然後重新插拔 Arduino 的電源。

底下是這支程式的 (senda.pde) 的完整程式碼。程式邏輯很簡單,只是每隔 3 秒鐘送出一個小寫英文字母 a 到電腦端:

程式說明

首先,由於寫在 atmega8u2 的 Arduino Uno Keyboard HID 用的通訊速度是 9600,所以程式必須在 setup() 裏將 baud rate 設成 9600 bps:

keyboard firmware 在 Uno 的主控制器 (atmega328p) 跟 atmega8u2 之間定義了一個很簡單的 serial 通訊協定,每當 Uno 想要送出一個按鍵敲擊動作 (keystroke),只要把按鍵的 Keycode 包在一個 8 個位元組的資料結構裏,然後把封包送到 Serial Port 就可以了。這 8 個位元組的資料結構如下:

Byte Description
0 Modifier keys
1 Reserved
2 Keycode 1
3 Keycode 2
4 Keycode 3
5 Keycode 4
6 Keycode 5
7 Keycode 6

標準鍵盤包含 101 個按鍵、8 個組合鍵 (modifiers)、1 個 OEM 保留鍵以及 5 個指示燈 (LED Indicators)。在上述的資料結構中,Byte 0 的組合鍵 (Modifier Keys) 包括了從鍵盤左邊的 Ctrl、Shift、Alt、GUI (WIN 鍵) 到右邊的 Ctrl、Shift、Alt、GUI (WIN 鍵) 總共 8 個按鍵,每個組合鍵以 1 個位元表示,而 Byte 1 是 OEM 保留鍵,一般是填 0。

而從 byte 2 開始,一個 byte 代表一個按鍵敲擊 (keystroke)。根據 HID Usag Tables 文件,標準鍵盤似乎最多可以同時按下 6 個按鍵,但有沒效我想是作業系統說了算。一般來說,大部份只會送一個 keystroke,所以只需用到 byte 2,其它通常填 0。

由於英文字母 a 的小寫的 Key code 是 4,為了送出一個小寫英文字母 a 的 keystroke,所以這個範例在資料結構的 byte 2 裏填上了 4。緊接著程式會立刻送出一個 keyNone 的 keystroke,這會讓電腦認為按鍵已經放開,否則的話電腦會一直收到 a 的按鍵敲擊動作。

如何查詢按鍵的 Key code

標準鍵盤所有按鍵的 key code 都定義在 HID Usag Tables 這份文件中,從第 53 頁開始:image

如果你想知道某個按鍵對應的 key code 為何,就必須查閱 HID Usag Tables 這份文件。例如小寫英文字母 a 對應 key code 是 4,b 是 5,c 是 6,依此類推。而大寫英文字母的 key code 也是一樣的,只是除了填寫正確的 key code 外,你還必須在 Modifier Keys 位元組中設定 Shift 鍵對應的位元。

參考資料

2 意見:

chen wayway 提到...

請教各位先進:
小弟第一次使用dfu模式,練習完後,就文件上是說重新拔插就會回到原本模式,但我遇到了UNO持續送出DFU指令(顯然atmega晶片正常),不過usb中com的介面抓不到了,是uno的工作晶片壞了嗎?還是我少做了什麼呢?

cooper maa 提到...

請問你上傳的是 Arduino-keyboard-0.3.hex 還是 Arduino-usbserial-uno.hex ? 「UNO持續送出DFU指令」是指什麼?