GoにいればGoに従え(44) ラズパイPico、USB HIDデバイスその1

Joseph Halfmoon

ラズパイ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シリアルに出力されてくる出力をキャプチャしたものが以下に。一発スイッチを押したところ。SerialMonitor

 

一方、まったくラズパイPicoとは無関係のコマンド・プロンプトに標準入力を向けておくとこんな感じ。上記とはほぼほぼ同時に反応。GreatingFromHIDa

挨拶されたな。キーボードとして動作しておるようです。

GoにいればGoに従え(43) ラズパイPico、TIMERアラーム、一部は使われている? へ戻る