はじめに
「かんたんUSBホスト」を USBシリアル で PCとつなぎ、USBキーボードのイベントをモニターします。
配線図

Mode(P3.3)ピンを GND に接続し、「イベント」モードで動作させます。
イベントモニター プログラム
Python で書きました。
コードを表示するには ここを クリック
usb_keyboard_event_monitor.py
#!/usr/bin/env python
import sys
import time
import threading
import serial # pySerial https://github.com/pyserial/pyserial
def usage(s: str):
print(s)
print(f"""usage:
{sys.argv[0]} serial-port [ baudrate ]
""")
exit(0)
argc = len(sys.argv)
if 3 < argc or argc < 2: usage("Invalid arguments!")
serial_port = sys.argv[1]
baudrate = int(sys.argv[2]) if argc == 3 else 9600
print(f"serial_port: {serial_port}\nbaudrate: {baudrate}\nStarted!")
start_time = time.time()
modifier = 0
def get_elapsed():
elapsed_time = int(time.time() - start_time)
elapsed_hour = elapsed_time // 3600
elapsed_minute = (elapsed_time % 3600) // 60
elapsed_second = (elapsed_time % 3600 % 60)
return f'{elapsed_hour:02d}:{elapsed_minute:02d}:{elapsed_second:02d}'
def get_modifier():
rightWin = ", RightWin" if modifier & 0x80 else ""
rightAlt = ", RightAlt" if modifier & 0x40 else ""
rightShift = ", RightShift" if modifier & 0x20 else ""
rightCtrl = ", RightCtrl" if modifier & 0x10 else ""
leftWin = ", LeftWin" if modifier & 0x08 else ""
leftAlt = ", LeftAlt" if modifier & 0x04 else ""
leftShift = ", LeftShift" if modifier & 0x02 else ""
leftCtrl = ", LeftCtrl" if modifier & 0x01 else ""
str = f'{rightWin}{rightAlt}{rightShift}{rightCtrl}{leftWin}{leftAlt}{leftShift}{leftCtrl}'
return "-" if len(str) == 0 else str[2:]
def monitor(buf: str):
global modifier
AA = int(buf[0:2], 16)
B = buf[2]
CC = int(buf[3:5], 16)
DD = int(buf[5:7], 16) if len(buf) > 6 else 0
#print(f"{buf}\tAA: 0x{AA:02x}, B: {B}, CC: 0x{CC:02x}, DD: 0x{DD:02x}")
if B == 'A':
print(f'{get_elapsed()} keyboard attached: 0x{AA:02x}')
elif B == 'a':
print(f'{get_elapsed()} keyboard detached: 0x{AA:02x}')
elif B == 'L':
numLock = "NumLock" if CC & 0x01 else ""
capsLock = "CapsLock" if CC & 0x02 else ""
scrollLock = "ScrollLock" if CC & 0x04 else ""
print(f'{get_elapsed()} 0x{AA:02x} Lock keyboard:', numLock, capsLock, scrollLock)
elif B == 'M' or B == 'm':
if B == 'M': modifier = modifier | CC
else: modifier = (modifier & ~CC) & 0xff
#print(hex(modifier))
rightWin = "RightWin" if CC & 0x80 else ""
rightAlt = "RightAlt" if CC & 0x40 else ""
rightShift = "RightShift" if CC & 0x20 else ""
rightCtrl = "RightCtrl" if CC & 0x10 else ""
leftWin = "LeftWin" if CC & 0x08 else ""
leftAlt = "LeftAlt" if CC & 0x04 else ""
leftShift = "LeftShift" if CC & 0x02 else ""
leftCtrl = "LeftCtrl" if CC & 0x01 else ""
downUp = "Down" if B == 'M' else "Up"
print(f'{get_elapsed()} 0x{AA:02x} Modify key {downUp}: {rightWin}{rightAlt}{rightShift}{rightCtrl}{leftWin}{leftAlt}{leftShift}{leftCtrl}')
elif B == 'K' or B == 'k' or B == 'R':
downUp = "Down" if B == 'K' else "Up" if B == 'k' else "Repeat"
if DD == 0:
print(f'{get_elapsed()} 0x{AA:02x} {downUp} keycode: 0x{CC:02x}, modifier: {get_modifier()}')
elif DD >= 0x20:
print(f'{get_elapsed()} 0x{AA:02x} {downUp} keycode: 0x{CC:02x}, ascii: 0x{DD:02x} "{chr(DD)}", modifier: {get_modifier()}')
else:
print(f'{get_elapsed()} 0x{AA:02x} {downUp} keycode: 0x{CC:02x}, ascii: 0x{DD:02x}, modifier: {get_modifier()}')
else:
print(f'{get_elapsed()} Unknown command: {B}')
usb = 0
def recv_thread():
try:
buf = ''
while True:
one = usb.read().decode()
if one[0] == ';':
monitor(buf)
buf = ''
else:
buf += one
except Exception as e:
print(e)
import traceback
#print(traceback.format_exc())
if __name__ == "__main__":
try:
usb = serial.Serial(serial_port, baudrate)
thread1 = threading.Thread(target=recv_thread)
thread1.start()
while True:
usb.write(input().encode())
except Exception as e:
print(e)
import traceback
#print(traceback.format_exc())
finally:
usb.close()
thread1.join()
コマンド送信
「かんたんUSBホスト」の UART コマンドを送信することができます。
コマンドは [AA]BCCDD;
フォーマットで入力して、enterキーで送信します。
当然ですが、コマンド は PCのキーボードからタイプします。
主なコマンドは下表の通り;
コマンド | 意味 |
---|---|
C0490; | US Keyboard |
C0410; | JP Keyboard (default) |
C0300; | Key Repeat Off |
C0344; | Key Repeat On (default) |
C0341; | Key Repeat On (fastest repeating) |
実行例
空行
と#行
は 説明のために記入したもので、プログラムからは出力されません。
% ./usb_keyboard_event_monitor.py `chooserial`
serial_port: /dev/cu.wchusbserial110
baudrate: 9600
Started!
C0490;
C0300;
#connect keyboard
00:00:18 keyboard attached: 0x10
00:00:18 0x10 Lock keyboard: NumLock
#Hello!
00:00:25 0x10 Modify key Down: LeftShift
00:00:25 0x10 Down keycode: 0x0b, ascii: 0x48 "H", modifier: LeftShift
00:00:25 0x10 Up keycode: 0x0b, modifier: LeftShift
00:00:25 0x10 Modify key Up: LeftShift
00:00:25 0x10 Down keycode: 0x08, ascii: 0x65 "e", modifier: -
00:00:26 0x10 Up keycode: 0x08, modifier: -
00:00:26 0x10 Down keycode: 0x0f, ascii: 0x6c "l", modifier: -
00:00:26 0x10 Up keycode: 0x0f, modifier: -
00:00:26 0x10 Down keycode: 0x0f, ascii: 0x6c "l", modifier: -
00:00:26 0x10 Up keycode: 0x0f, modifier: -
00:00:26 0x10 Down keycode: 0x12, ascii: 0x6f "o", modifier: -
00:00:26 0x10 Up keycode: 0x12, modifier: -
00:00:27 0x10 Modify key Down: LeftShift
00:00:27 0x10 Down keycode: 0x1e, ascii: 0x21 "!", modifier: LeftShift
00:00:27 0x10 Up keycode: 0x1e, modifier: LeftShift
00:00:27 0x10 Modify key Up: LeftShift
#Ctrl+C
00:00:39 0x10 Modify key Down: LeftCtrl
00:00:39 0x10 Down keycode: 0x06, ascii: 0x03, modifier: LeftCtrl
00:00:39 0x10 Up keycode: 0x06, modifier: LeftCtrl
00:00:39 0x10 Modify key Up: LeftCtrl
#Alt+Ctrl+DEL
00:00:44 0x10 Modify key Down: LeftAlt
00:00:44 0x10 Modify key Down: LeftCtrl
00:00:44 0x10 Down keycode: 0x4c, modifier: LeftAlt, LeftCtrl
00:00:44 0x10 Up keycode: 0x4c, modifier: LeftAlt, LeftCtrl
00:00:44 0x10 Modify key Up: LeftAlt
00:00:44 0x10 Modify key Up: LeftCtrl
#Air60 FN key
00:01:39 0x10 Down keycode: 0x01, modifier: -
00:01:39 0x10 Up keycode: 0x01, modifier: -
#disconnect keyboard
00:00:49 keyboard detached: 0x10

Air60 の FN
キー単独押し も イベントが発生することが確認できました。
ただし、キーコード が 0x01(Keyboard Error Roll Over)なのが謎です。
以上