17
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Raspberry Pi Picoでマクロパッドを作る

Last updated at Posted at 2021-05-24

#作った目的
身内でDiscordを使ってAmong Usをやってるんですが、
マイクミュート等をコマンド入力で対応しており、毎回打つのめんどくせぇな?

って事でマクロパッドを作ることにしました。
(諸事情により自動ミュートbotは使ってない)

#元記事
https://www.tomshardware.com/how-to/raspberry-pi-pico-powered-stream-deck

当初はProMicroとQMK Firmwareでやろうと思ってたんですが、
なんかRaspberry Pi Picoでお手軽に出来るっぽかったのでやってみました。

#部品調達

  • Raspberry Pi Pico x1(遊舎工房で購入)
  • Cherry MX互換キースイッチ x6 (余ってたGateron赤軸)
  • キーキャップ x6 (余ってたry
  • 適当な電子工作用ワイヤー (あm
  • ケース(3Dプリンターで出力)

仕事用にもう一つ作りたかったんですが、Picoが1回の購入で1枚のみという購入制限があったので、とりあえず一つだけ作ることに。

#Raspberry Pi Picoのセットアップ
CircuitPythonのHIDライブラリを使用してるらしく、CircuitPythonが使えるようにセットアップします。
##UF2ファイルのダウンロード
CircuitPython公式サイトからPico用のUF2ファイルをダウンロードします。
image.png
で、ここで注意点が一つ。
親切に言語がJAPANESEになってるかもしれませんが、ENGLISH(US)を選びましょう。(ここで躓いた)
image.png
理由はよく分かりませんがJAPANESEだと動きません。

##UF2ファイルの書き込み
Pico本体に付いている白いボタンがBOOTSELボタンです。(画像右上)
image.png
BOOTSELボタンを押しながらUSBケーブルでパソコンと接続すると書き込みモードで起動します。
接続されたらBOOTSELボタンから指を放して大丈夫です。
無事接続されるとPicoが「RPI-RP2」というストレージとして出ているはずなので、
RPI-RP2の直下に先ほどダウンロードしたUF2ファイルをコピーします。
するとPicoが勝手に再起動して「CIRCUITPY」という名前のストレージが出てきます。
image.png

これでCircuitPythonの導入は完了です。

##カスタムコードの追加
Picoをマクロパッドとして動作させるためのカスタムコードを追加しています。
まずはGitHubのPiPicoMacroKeysからZipファイルをダウンロード。
image.png
Zipファイルの中身をコピー&上書きします。
Picoを接続しなおすとマクロパッドとして動作します。

#マクロの設定方法
マクロの設定は「CIRCUITPY」直下のcode.pyにあります。
デフォルトは以下の通り。
whileの中に記述してあり、それぞれCtrl+F7~F12に相当します。

while True:
    if btn1.value:
        keyboard.send(Keycode.CONTROL, Keycode.F7)
        time.sleep(0.1)
    if btn2.value:
        keyboard.send(Keycode.CONTROL, Keycode.F8)
        time.sleep(0.1)
    if btn3.value:
        keyboard.send(Keycode.CONTROL, Keycode.F9)
        time.sleep(0.1)
    if btn4.value:
        keyboard.send(Keycode.CONTROL, Keycode.F10)
        time.sleep(0.1)
    if btn5.value:
        keyboard.send(Keycode.CONTROL, Keycode.F11)
        time.sleep(0.1)
    if btn6.value:
        keyboard.send(Keycode.CONTROL, Keycode.F12)
        time.sleep(0.1)
    time.sleep(0.1)

これを好みの内容に書き換えていくわけですが、
各キーの定義は/lib/adafruit_hid/keycode.pyの中にあるので参考にします。

keycode.py
class Keycode:
    """USB HID Keycode constants.
    This list is modeled after the names for USB keycodes defined in
    https://usb.org/sites/default/files/hut1_21_0.pdf#page=83.
    This list does not include every single code, but does include all the keys on
    a regular PC or Mac keyboard.
    Remember that keycodes are the names for key *positions* on a US keyboard, and may
    not correspond to the character that you mean to send if you want to emulate non-US keyboard.
    For instance, on a French keyboard (AZERTY instead of QWERTY),
    the keycode for 'q' is used to indicate an 'a'. Likewise, 'y' represents 'z' on
    a German keyboard. This is historical: the idea was that the keycaps could be changed
    without changing the keycodes sent, so that different firmware was not needed for
    different variations of a keyboard.
    """

    # pylint: disable-msg=invalid-name
    A = 0x04
    """``a`` and ``A``"""
    B = 0x05
    """``b`` and ``B``"""
    C = 0x06
    """``c`` and ``C``"""
    D = 0x07
    """``d`` and ``D``"""
    E = 0x08
    """``e`` and ``E``"""
    F = 0x09
    """``f`` and ``F``"""
    G = 0x0A
    """``g`` and ``G``"""
    H = 0x0B
    """``h`` and ``H``"""
    I = 0x0C
    """``i`` and ``I``"""
    J = 0x0D
    """``j`` and ``J``"""
    K = 0x0E
    """``k`` and ``K``"""
    L = 0x0F
    """``l`` and ``L``"""
    M = 0x10
    """``m`` and ``M``"""
    N = 0x11
    """``n`` and ``N``"""
    O = 0x12
    """``o`` and ``O``"""
    P = 0x13
    """``p`` and ``P``"""
    Q = 0x14
    """``q`` and ``Q``"""
    R = 0x15
    """``r`` and ``R``"""
    S = 0x16
    """``s`` and ``S``"""
    T = 0x17
    """``t`` and ``T``"""
    U = 0x18
    """``u`` and ``U``"""
    V = 0x19
    """``v`` and ``V``"""
    W = 0x1A
    """``w`` and ``W``"""
    X = 0x1B
    """``x`` and ``X``"""
    Y = 0x1C
    """``y`` and ``Y``"""
    Z = 0x1D
    """``z`` and ``Z``"""

    ONE = 0x1E
    """``1`` and ``!``"""
    TWO = 0x1F
    """``2`` and ``@``"""
    THREE = 0x20
    """``3`` and ``#``"""
    FOUR = 0x21
    """``4`` and ``$``"""
    FIVE = 0x22
    """``5`` and ``%``"""
    SIX = 0x23
    """``6`` and ``^``"""
    SEVEN = 0x24
    """``7`` and ``&``"""
    EIGHT = 0x25
    """``8`` and ``*``"""
    NINE = 0x26
    """``9`` and ``(``"""
    ZERO = 0x27
    """``0`` and ``)``"""
    ENTER = 0x28
    """Enter (Return)"""
    RETURN = ENTER
    """Alias for ``ENTER``"""
    ESCAPE = 0x29
    """Escape"""
    BACKSPACE = 0x2A
    """Delete backward (Backspace)"""
    TAB = 0x2B
    """Tab and Backtab"""
    SPACEBAR = 0x2C
    """Spacebar"""
    SPACE = SPACEBAR
    """Alias for SPACEBAR"""
    MINUS = 0x2D
    """``-` and ``_``"""
    EQUALS = 0x2E
    """``=` and ``+``"""
    LEFT_BRACKET = 0x2F
    """``[`` and ``{``"""
    RIGHT_BRACKET = 0x30
    """``]`` and ``}``"""
    BACKSLASH = 0x31
    r"""``\`` and ``|``"""
    POUND = 0x32
    """``#`` and ``~`` (Non-US keyboard)"""
    SEMICOLON = 0x33
    """``;`` and ``:``"""
    QUOTE = 0x34
    """``'`` and ``"``"""
    GRAVE_ACCENT = 0x35
    r""":literal:`\`` and ``~``"""
    COMMA = 0x36
    """``,`` and ``<``"""
    PERIOD = 0x37
    """``.`` and ``>``"""
    FORWARD_SLASH = 0x38
    """``/`` and ``?``"""

    CAPS_LOCK = 0x39
    """Caps Lock"""

    F1 = 0x3A
    """Function key F1"""
    F2 = 0x3B
    """Function key F2"""
    F3 = 0x3C
    """Function key F3"""
    F4 = 0x3D
    """Function key F4"""
    F5 = 0x3E
    """Function key F5"""
    F6 = 0x3F
    """Function key F6"""
    F7 = 0x40
    """Function key F7"""
    F8 = 0x41
    """Function key F8"""
    F9 = 0x42
    """Function key F9"""
    F10 = 0x43
    """Function key F10"""
    F11 = 0x44
    """Function key F11"""
    F12 = 0x45
    """Function key F12"""

    PRINT_SCREEN = 0x46
    """Print Screen (SysRq)"""
    SCROLL_LOCK = 0x47
    """Scroll Lock"""
    PAUSE = 0x48
    """Pause (Break)"""

    INSERT = 0x49
    """Insert"""
    HOME = 0x4A
    """Home (often moves to beginning of line)"""
    PAGE_UP = 0x4B
    """Go back one page"""
    DELETE = 0x4C
    """Delete forward"""
    END = 0x4D
    """End (often moves to end of line)"""
    PAGE_DOWN = 0x4E
    """Go forward one page"""

    RIGHT_ARROW = 0x4F
    """Move the cursor right"""
    LEFT_ARROW = 0x50
    """Move the cursor left"""
    DOWN_ARROW = 0x51
    """Move the cursor down"""
    UP_ARROW = 0x52
    """Move the cursor up"""

    KEYPAD_NUMLOCK = 0x53
    """Num Lock (Clear on Mac)"""
    KEYPAD_FORWARD_SLASH = 0x54
    """Keypad ``/``"""
    KEYPAD_ASTERISK = 0x55
    """Keypad ``*``"""
    KEYPAD_MINUS = 0x56
    """Keyapd ``-``"""
    KEYPAD_PLUS = 0x57
    """Keypad ``+``"""
    KEYPAD_ENTER = 0x58
    """Keypad Enter"""
    KEYPAD_ONE = 0x59
    """Keypad ``1`` and End"""
    KEYPAD_TWO = 0x5A
    """Keypad ``2`` and Down Arrow"""
    KEYPAD_THREE = 0x5B
    """Keypad ``3`` and PgDn"""
    KEYPAD_FOUR = 0x5C
    """Keypad ``4`` and Left Arrow"""
    KEYPAD_FIVE = 0x5D
    """Keypad ``5``"""
    KEYPAD_SIX = 0x5E
    """Keypad ``6`` and Right Arrow"""
    KEYPAD_SEVEN = 0x5F
    """Keypad ``7`` and Home"""
    KEYPAD_EIGHT = 0x60
    """Keypad ``8`` and Up Arrow"""
    KEYPAD_NINE = 0x61
    """Keypad ``9`` and PgUp"""
    KEYPAD_ZERO = 0x62
    """Keypad ``0`` and Ins"""
    KEYPAD_PERIOD = 0x63
    """Keypad ``.`` and Del"""
    KEYPAD_BACKSLASH = 0x64
    """Keypad ``\\`` and ``|`` (Non-US)"""

    APPLICATION = 0x65
    """Application: also known as the Menu key (Windows)"""
    POWER = 0x66
    """Power (Mac)"""
    KEYPAD_EQUALS = 0x67
    """Keypad ``=`` (Mac)"""
    F13 = 0x68
    """Function key F13 (Mac)"""
    F14 = 0x69
    """Function key F14 (Mac)"""
    F15 = 0x6A
    """Function key F15 (Mac)"""
    F16 = 0x6B
    """Function key F16 (Mac)"""
    F17 = 0x6C
    """Function key F17 (Mac)"""
    F18 = 0x6D
    """Function key F18 (Mac)"""
    F19 = 0x6E
    """Function key F19 (Mac)"""

    LEFT_CONTROL = 0xE0
    """Control modifier left of the spacebar"""
    CONTROL = LEFT_CONTROL
    """Alias for LEFT_CONTROL"""
    LEFT_SHIFT = 0xE1
    """Shift modifier left of the spacebar"""
    SHIFT = LEFT_SHIFT
    """Alias for LEFT_SHIFT"""
    LEFT_ALT = 0xE2
    """Alt modifier left of the spacebar"""
    ALT = LEFT_ALT
    """Alias for LEFT_ALT; Alt is also known as Option (Mac)"""
    OPTION = ALT
    """Labeled as Option on some Mac keyboards"""
    LEFT_GUI = 0xE3
    """GUI modifier left of the spacebar"""
    GUI = LEFT_GUI
    """Alias for LEFT_GUI; GUI is also known as the Windows key, Command (Mac), or Meta"""
    WINDOWS = GUI
    """Labeled with a Windows logo on Windows keyboards"""
    COMMAND = GUI
    """Labeled as Command on Mac keyboards, with a clover glyph"""
    RIGHT_CONTROL = 0xE4
    """Control modifier right of the spacebar"""
    RIGHT_SHIFT = 0xE5
    """Shift modifier right of the spacebar"""
    RIGHT_ALT = 0xE6
    """Alt modifier right of the spacebar"""
    RIGHT_GUI = 0xE7
    """GUI modifier right of the spacebar"""

    # pylint: enable-msg=invalid-name
    @classmethod
    def modifier_bit(cls, keycode):
        """Return the modifer bit to be set in an HID keycode report if this is a
        modifier key; otherwise return 0."""
        return (
            1 << (keycode - 0xE0) if cls.LEFT_CONTROL <= keycode <= cls.RIGHT_GUI else 0
        )
他にマウスクリックとかも出来るっぽい。試してないけど。 Among Us専用マクロパッドとして以下の様にしました。
code.py
    while True:
    if btn1.value:
        keyboard.send(Keycode.PERIOD, Keycode.M, Keycode.ENTER)
        time.sleep(0.1)
    if btn2.value:
        keyboard.send(Keycode.PERIOD, Keycode.U, Keycode.M, Keycode.ENTER)
        time.sleep(0.1)
    if btn3.value:
        keyboard.send(Keycode.CONTROL, Keycode.SHIFT, Keycode.M)
        time.sleep(0.1)
    if btn4.value:
        keyboard.send(Keycode.PERIOD, Keycode.D, Keycode.ENTER)
        time.sleep(0.1)
    if btn5.value:
        keyboard.send(Keycode.PERIOD, Keycode.U, Keycode.D, Keycode.ENTER)
        time.sleep(0.1)
    if btn6.value:
        keyboard.send(Keycode.PERIOD, Keycode.U, Keycode.D, Keycode.M, Keycode.E, Keycode.ENTER)
        time.sleep(0.1)
    time.sleep(0.1)

#ケースの用意
実は一番面倒な所かもしれないケースの用意。
私は自分の3Dプリンター(Ender-3 V2)で出力しました。
3Dデータはこちらから。
3Dプリンターが無い場合は、DMM.makeあたりの代行サービスを使うか、アクリルカットして作るか、頑張って手作りするしかないですね。
スイッチ固定用基板としてSU120とか無限の可能性を使うとちょっと楽かも。
ちなみに、元のデータだとコネクタの部分が狭くて手持ちのケーブルでは挿さりませんでした。
なので開口部をケース底面まで広げて出力してます。

開口部を広げたらいい感じに↓

組み立てたらキースイッチの端子がPicoと接触しまくったので、絶縁処理をするかケースを厚めに作り直した方が良いかもしれない。

#配線
配線手順は元記事を見てください。(写真撮ってなかった)

#完成

割とサクサクっと出来ちゃいましたね。
QMK Firmwareと違ってファームウェアのビルドとかが要らないのでお手軽。

17
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?