Pico PR

RaspberryPi Pico CircuitPythonでUSB HIDを作る方法【自作マウス・自作キーボード】

記事内に商品プロモーションを含む場合があります

はじめに

RaspberryPi Pico でキーボードやマウスなどのUSBの入力装置( HID:Human Interface Device) を作る方法を解説します。言語はいつも解説しているMicroPythonの発展形である「CircuitPython」を使用します。

回路2にはタクトスイッチを2つ使い、それぞれのタクトスイッチが「キーボードのaキー」「マウスの右クリック」になるようにします。

環境

この記事の回路やプログラムは、以下の環境で作成しています。

環境 バージョンなど 備考
開発用PCのOS Windows11 Windows10でもOKです
言語  CircuitPython Ver1.8
開発環境 MuEditor  Ver.1.2
ボード RaspberryPi Pico

CircuitPythonの設定

PicoでCircuitPythonを使うには、CircuitPython用のファームウェアをPicoに書き込む必要があります。まだの方は、こちらの記事を参考にファームウェアの書き込みを行ってください。

ライブラリのインストール

デフォルトのCircuitPythonには、HIDのライブラリは含まれていないため以下の方法でHIDライブラリを追加します。

① ライブラリのダウンロード

以下のサイトから、複数のライブラリをまとめた圧縮(Zip)ファイルをダウンロードします。

ライブラリ用のZipファイルのダウンロード場所

https://circuitpython.org/libraries

ページの少し下にある「Bundle for Version 8.x」のボタンから、圧縮ファイルをダウンロードしてください。

②ライブラリのインストール

ダウンロードした圧縮(Zip)ファイルを解凍し、フォルダ内の「lib」の中にある「adafruit_hid」フォルダをコピーします。

ライブラリの場所を解説する画像
ライブラリ名称を解説する画像

コピーしたフォルダを、Picoの「lib」フォルダ内に貼り付ければ、ライブラリのインストールは完了です。

ライブラリをPicoのどの位置に保存したらいいかを解説するが画像。

RaspberryPi Picoとの接続

RaspberryPi PicoのGPIOにタクト(タクタイル)スイッチを2個つなげます。

抵抗は1kΩを使用していますが、直結を防止しているだけなので、220Ωなど小さいものでも構いません。

Picoとタクトスイッチのつなげ方を解説する画像

ピン番号 内容 備考
38 GND グラウンド
36 3V3(OUT) 電源(3.3V)
24 GP18 タクトスイッチA(キーボード)用に使います
21 GP16 タクトスイッチB(マウス)用に使います

※ GNDは未使用です。

Picoピンアサイン(Pin-Out)

RaspberryPi Picoのピンアサイン(pinout)の画像

Pico公式サイトより引用

使用する部品

ブレッドボード

サンハヤト性のブレッドボードです。少々堅めの指し心地ですが、などの品質も高く、おすすめの一品です。

プログラム概要

今回のプログラムの概要は以下の通りです。

  • タクトスイッチを設定する
  • タクトスイッチAが押されたら、キーボードの「a」を送信
  • タクトスイッチBが押されたら、マウスの「右クリック」を送信

実行結果

後述するプログラムの実行結果です。

タクトスイッチAを押して「a」キーをメモ帳上に入力。途中手動で「半角/全角]キーを押しているので表示が「あ」になっています。

入力後、タクトスイッチBを押して、メモ帳上に右クリックメニューを表示しています。

プログラムの実行結果を表示した画像

全体コード

全体コードは以下の通りです。詳細な内容は後述する「コードのポイント」で解説します。

import board, digitalio, usb_hid

from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard import Keycode
from adafruit_hid.mouse import Mouse

# GP16,18ピンを入力に設定します
tactA = digitalio.DigitalInOut(board.GP16)
tactA.switch_to_input(pull=digitalio.Pull.DOWN)

tactB = digitalio.DigitalInOut(board.GP18)
tactB.switch_to_input(pull=digitalio.Pull.DOWN)

# キーボード・マウスのオブジェクトを作成します
keyboard = Keyboard(usb_hid.devices)
mouse    = Mouse(usb_hid.devices)

# 前回値用の変数を初期化します。
beforeA = 0
beforeB = 0

print("Loop start ")

while True:

    # タクトスイッチA,Bが押されているか取得
    nowA = tactA.value
    nowB = tactB.value

    # タクトスイッチAが押された(立ち上がり)
    if nowA == 1 and beforeA == 0:
        print("sendA")
        keyboard.send(Keycode.A)

    # タクトスイッチBが押された(立ち上がり)
    if nowB == 1 and beforeB == 0:
        print("sendB")
        mouse.click(Mouse.RIGHT_BUTTON)
    
    # 前回値として現在のスイッチの状態を保存します。
    beforeA = nowA
    beforeB = nowB

※ 2023/05/30 import部分のコード修正しました。
なかちゃんさん、ありがとうございます。

プログラムの自動実行(電源ONで実行)をさせたい場合は、プログラムのファイル名を「code.py」にしてPicoに保存してください。

コードのポイント

入力ピンの設定

タクトスイッチをつなげたGP16・18ピンを入力に設定します。

今回の回路はタクトスイッチが押された場合のみ、電源(3V3)から電気が流れる回路なのでピンの設定を「Pull.DOWN」に設定します。

# GP16,18ピンを入力に設定します
tactA = digitalio.DigitalInOut(board.GP16)
tactA.switch_to_input(pull=digitalio.Pull.DOWN)

tactB = digitalio.DigitalInOut(board.GP18)
tactB.switch_to_input(pull=digitalio.Pull.DOWN)

タクトスイッチの状態取得

valueプロパティでタクトスイッチ(がつながったGP16,18)の状態を取得します。状態はタクトスイッチに応じて以下のように変化します。

タクトスイッチの状態 valueの内容
押された 1
押されていない  0
    # タクトスイッチの状態を取得します
    nowA = tactA.value
    nowB = tactB.value

スイッチが押された時だけ処理をする

以下のコードで、タクトスイッチが「押された時」を確認します。

今回のプログラムでは無限ループで連続的にスイッチを確認します。そのため単純に「タクトスイッチがONか?」を条件にしてしまうと、ゆっくりスイッチが押された場合に
「2回(2ループの間)スイッチが押された」と判定されてしまいます。

そこで、以下のように条件にスイッチの「今回のループの値」と「前回のループの値」を使うことで、「スイッチが押された瞬間(立ち上がり)」1回だけを検知するようにします。

信号の立ち上がりを取得する方法を解説した画像

キーボード操作

タクトスイッチAが押された場合に、send関数を使ってPicoからPCにキーボードの「a」キーを送信します。

    # タクトスイッチAが押された(立ち上がり)
    if nowA == 1 and beforeA == 0:
        print("sendA")
        keyboard.send(Keycode.A)

PCが日本語入力モードの場合は「あ」が入力されます。

Muエディタで実行した場合でも、PCに向けてキーが送信されます。確認の為にPico単体でプログラムを実行する必要はありません。

マウス操作

タクトスイッチBが押された場合に、click関数を使ってPicoからPCにマウスの「右クリック」を送信します。

    # タクトスイッチBが押された(立ち上がり)
    if nowB == 1 and beforeB == 0:
        print("sendB")
        mouse.click(Mouse.RIGHT_BUTTON)

その他の操作方法

前述した関数やキー以外にも、様々な操作をPCに送信することができます。紹介は一部のみになるので、詳細は後述の公式リファレンスをご覧ください。

デバイス 関数 内容
keyboard press 引数で指定したキーを押したままにします。
release 引数で指定したキーを離します。
send 引数で指定したキーを1度押して、離します。

デバイス 関数 内容
mouse click 引数で指定したボタンを1度押して、離します。
move 引数(x,y,wheel)でポインタ移動やスクロールを行います。
press 引数で指定したキーを押したままにします。

公式リファレンス

https://docs.circuitpython.org/projects/hid/en/latest/index.html

まとめ

RaspberryPi Pico CircuitPythonで、キーボードやマウスなどの入力装置(HID)を作る方法を解説しました。

PicoとCircuitPythonの組み合わせは、ボードも低価格で、プログラムも短くてすむため、自作のキーボードや、ショートカットデバイスなどを「安く・簡単に」作るのに、おすすめの組み合わせだと思います。

「マウス・キーボードってどう作るんだろう?」「安くて簡単に作りたい」と考えている方は、ぜひPico+CircuitPythonで作ってみてください。

参考になればうれしいです。

自作する時間のない方は・・・

ここまでの解説をみて「作る時間ないな…」「自分にはちょっと難しそう…」と感じたら、以下のデバイスをおすすめします。

ボタンやダイヤルの動きはカスタマイズ可能。幅広いアプリで使えるので、画像編集から事務作業まで作業効率爆上がりです。Picoを使った自作デバイスは、このツール導入でできた空き時間で、ゆっくりと進めてみてください。

お知らせ

今月号のInterfaceは『RaspberryPi 5』特集

3月25日発売のInterfaceは「RaspberryPi 5」特集!

実験などを通じた性能測定や特徴・変更点の解説。新規に追加されたI/Oボード「RP1」の特徴と謎。Pi5のはじめかたやLinuxコマンド入門などが特集されています。

Pico/Pico W関連のおすすめ本

RaspberryPi Pico / Pico W関連のおすすめ本を独断と偏見で3つ選んでみました。Picoやるならとりあえずこれ買っとけ的な本や、電子工作全般で使える本などを厳選しています。

見た目のいい工具をお探しの方へ

よく使うツールは『見た目』が重要。モチベもあがりますし、仲間との話のネタにもなります。以下のサイトは、デザイン性の高い工具が集めたサイトなので、興味がある方はぜひご覧ください。

質問・要望 大歓迎です

「こんな解説記事作って」「こんなことがしたいけど、〇〇で困ってる」など、コメント欄で教えてください。 質問・要望に、中の人ができる限り対応します。

使えたよ・設定できたよの一言コメントも大歓迎。気軽に足跡を残してみてください。記事を紹介したい方はブログ、SNSにバシバシ貼ってもらってOKです。

ABOUT ME
えす
現役のソフトウェアエンジニアです。 C++ C# Python を使ってます。10年ちょい設計/開発部門にいましたが、今はQAエンジニアっぽいことをしています。

POSTED COMMENT

  1. なかちゃん より:

    とても丁寧な解説で参考にさせていただいております。
    ありがとうございます。

    サンプルコードの5行目のですが、
    from adafruit_hid.keyboard import Mouse
    の個所が、
    from adafruit_hid.mouse import Mouse
    かと思われますがいかがでしょうか?

    • えす より:

      なかちゃんさん

      えすです。

      失礼しました、正しいコードはご指摘の通りです。
      記事内のコードを修正しました。

      参考にしていただき、ありがとうございます。
      また何かありましたら、お気軽にコメントしてください。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

Index