ラズパイPicoのTinyGoはUSBのデバイス側に対応。いつもUSBシリアルにはお世話になっておるので、別なクラスということでHIDキーボード・クラスを使ってみることにいたしました。キーボードそのものを作ろうというのではなく、別途データ転送にちょろまし使用の目論見。今回はPCへ文字を送信できるところを確認。
※「GoにいればGoに従え」Go関連記事の総Index
※実機動作確認は Arm Cortex-M0+コアのRP2040チップ搭載、Raspberry Pi Pico機にTinyGoのオブジェクトを書き込んで行っています。ビルドはWindows11上です。
※RP2040のデータシート(PDF)はこちら
HID(Human Interface Device)
TinyGoのインストールホルダをみると、HIDはキーボードとマウスの2つのクラスがサポートされておるようです。HIDが良さげなのはホスト側のデバイスドライバは既存のものが使えるハズなので用意する必要が無いということ。これはPCだけでなく、スマホやタブレットでも多分同様かと。お楽が一番。まあ、遅いちゃ遅いのだろうけど、そんなクリティカルな用途に使おうというのではなし。
実験に使用したTinyGoソース
継ぎ足し、取り去りしている「伝統の」ソースに今回はUSB HID用のコード若干を加えたものが以下に。いつものように USBシリアルも生きているので、fmt.printはホストのシリアルモニタに接続。同じUSBでも、それとは論理的に別の経路でホストからはキーボードにも見えるハズです。PCに接続している本物のキーボードと「並列」な第2(いや第3か、ノートPCに外付けキーボード接続しているから)のキーボード。よってラズパイPicoのHIDから文字を送ると、そのとき標準入力が向いているウインドウに表示されるハズ。なお、キーボードとしてデータを送る切っ掛けにはGPIO15番にとりつけたプッシュスイッチ(立下り)を使ってます。ソースが以下に。
package main import ( "fmt" "machine" "machine/usb/hid/keyboard" "time" ) var pat int var oldpat int func main() { pat = 0 oldpat = 0 keyA := machine.GPIO15 keyA.Configure(machine.PinConfig{Mode: machine.PinInput}) keyA.SetInterrupt(machine.PinFalling, func(machine.Pin) { pat += 1 }) kbd := keyboard.New() for { if pat > oldpat { fmt.Printf("KEY INT: %d\n", pat) kbd.Write([]byte("HELLO!")) oldpat = pat } time.Sleep(time.Second * 2) } }
実機動作確認
上記のソースをビルドして走らせ、通例どおりUSBシリアルに出力されてくる出力をキャプチャしたものが以下に。一発スイッチを押したところ。
一方、まったくラズパイPicoとは無関係のコマンド・プロンプトに標準入力を向けておくとこんな感じ。上記とはほぼほぼ同時に反応。
挨拶されたな。キーボードとして動作しておるようです。