続き(USBキーボード限定オブジェクト化とRAWデータ取得)
前回は、Raspberry Pi Picoや、RP2040 ZEROマイコンで CircuitPython を使い、デバイスの認識までできました。
前回のリンク > https://qiita.com/yniizawa/items/95084981fe768c7a9b35
今回は、キーボードに決め打ちですがオブジェクト化して、キー入力したらRAWデータを受け取り表示するコードを示します。
回路構成
- マイコン: Raspberry Pi Pico / RP2040 ZERO
- USB-Aコネクタ接続ピン:
DP = GP6
DM = GP7
コード
import usb.core
import usb_host
import board
import time
import sys
import busio
import digitalio
# データプラスとデータマイナスピンの指定
dp = board.GP6
dm = board.GP7
# USBホストポートの初期化
host_port = usb_host.Port(dp, dm)
print("USBホストポートが初期化されました。")
time.sleep(1.5)
# キー入力を保存する配列
input_data = []
def find_keyboard():
# USBデバイスを探す
devices = list(usb.core.find(find_all=True)) # ジェネレーターなので、一度list化すると保持される
for device in devices:
print(f"デバイス: {device.idVendor:04x}:{device.idProduct:04x} - {device.product} - {device.manufacturer}")
if not devices:
print("USBデバイスが見つかりませんでした (1)")
return None
else:
keyboard = usb.core.find(idVendor=device.idVendor, idProduct=device.idProduct)
if keyboard is None:
print("USBデバイスが見つかりませんでした (2) 再試行します。")
time.sleep(0.5)
else:
print("USBデバイスが見つかりました。")
keyboard.set_configuration()
return keyboard # キーボードを返す
# キー入力ループ
keyboard = None
while True:
if keyboard is None:
print("キーボードを探しています... (3)")
keyboard = find_keyboard()
continue
try:
buffer = bytearray(8)
endpoint = 0x81 # IN方向のエンドポイント
num_bytes = keyboard.read(endpoint, buffer)
print(f"RAWデータ: {list(buffer)}") # とりあえず生データを表示
except Exception as e:
print(f"エラー: {e}")
keyboard = None
time.sleep(1)
キーボードを接続してa,b,c,dキーを押すと、次のようにRAWデータが表示されます。
キーを押したときに1行、離したときに1行、返ってきます。
USBホストポートが初期化されました。
キーボードを探しています... (3)
デバイス: 0603:00f2 - USB Keyboard - NOVATEK
USBデバイスが見つかりました。
RAWデータ: [0, 0, 4, 0, 0, 0, 0, 0]
RAWデータ: [0, 0, 0, 0, 0, 0, 0, 0]
RAWデータ: [0, 0, 5, 0, 0, 0, 0, 0]
RAWデータ: [0, 0, 0, 0, 0, 0, 0, 0]
RAWデータ: [0, 0, 6, 0, 0, 0, 0, 0]
RAWデータ: [0, 0, 0, 0, 0, 0, 0, 0]
RAWデータ: [0, 0, 7, 0, 0, 0, 0, 0]
RAWデータ: [0, 0, 0, 0, 0, 0, 0, 0]
RAWデータの意味は、次の通りです。
[0] 修飾キー (Modifier keys)
[1] 予約領域 (常に0)
[2] 通常キー1
[3] 通常キー2
[4] 通常キー3
[5] 通常キー4
[6] 通常キー5
[7] 通常キー6
[0] : 修飾キーについて、
0x01 = 左Ctrl
0x02 = 左Shift
0x04 = 左Alt
0x08 = 左GUI
0x10 = 右Ctrl
0x20 = 右Shift
0x40 = 右Alt
0x80 = 右GUI
[2]~[7]:押されたキーコード
これで、キーマップを作ると、文字数字が表示されるようになります。
<追伸>
Curcuitpythonのバージョン10になると、sys.stdinとして、シンプルに扱える?ようです。
ここの情報によると、今回のコードはCurcuitpython APIを使用する方法のようですが「import adafruit_usb_host_descriptors」をしなくともキーコードは返ってきています。
USキーボード配列なら、リンク先にキーマップがあります。
Using a Keyboard with USB Host by Tim C