キーボード制作

キーボード制作

  1. 環境構築・構想
  2. 基板設計・発注
  3. 制作

制作

今回使う部品たちの価格表。1000円を少し超えてしまった。集合抵抗を表面実装タイプにしたり、つまみやキーキャップをもっと安く手に入れられるとよかったのかもしれない。

部品名 個数 備考 価格
RP2040 Zero 1 マイコンボード 1873円/5個
74HC153 1 2回路4入力 100円/20個
ロータリーエンコーダ 1 スイッチ付き 353円/5個
つまみ 1 直径26mm 452円/5個
集合抵抗 10k 2 4素子 30円/1個
キースイッチ 8 青軸 510円/50個
キーキャップ 8 半透明 400円/20個
セラミックコンデンサ 4 1608 200円/100個
プリント基板 1 JLCPCB 3.2$/5枚
合計 1073円/個
2026/03/21
circuitpy

基板が届くまで暇なので筐体の3Dモデルを作っておく。少し角度が欲しいので手前にかけて傾斜をかけておいた。基板はM3のねじで固定し、筐体側面にはモード切り替えスイッチ(Win/Mac)などを付けようと思う。このサイズなら全体を一気にプリントできそうで良い。

2026/03/26

無事に発注した基板が届いた。割愛するが、一回目の青基板は5日で、二回目の黒基板は9日で届いた。 circuitpy circuitpy 黒のほうが何倍もカッコよく見える。光沢はあるがマットな質感で良い。 circuitpy マイコンボードの裏側にRP2040が実装されている。ボードを表面実装すると裏側が干渉するので基板を一部カットしている。 circuitpy はんだ付けができた。フラックス(無洗浄タイプ)を初めて使ったが、表面実装部品はこの方がよかった。両面のプリント基板だから少しはんだのノリが悪い気がするのでフラックスのおかげで作業がスムーズに進んだ。

今回の基板設計で、ロータリーエンコーダに割り当てたGPIOが6と8だが、rotaryioは連続するピン番号でなければならないらしく、ライブラリの使用は諦めた。

    import board
import digitalio
import time
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
from adafruit_hid.mouse import Mouse

kbd = Keyboard(usb_hid.devices)
m = Mouse(usb_hid.devices)

# --- 共通関数 ---
def setup_pin(pin, direction, pull=None, value=None):
    p = digitalio.DigitalInOut(pin)
    p.direction = direction
    if pull:
        p.pull = pull
    if value is not None:
        p.value = value
    return p

# --- ロータリーエンコーダ ---
clk = setup_pin(board.GP8, digitalio.Direction.INPUT, digitalio.Pull.UP)
dt  = setup_pin(board.GP6, digitalio.Direction.INPUT, digitalio.Pull.UP)
last_clk = clk.value

# --- MUX制御 ---
pin_a = setup_pin(board.GP14, digitalio.Direction.OUTPUT)
pin_b = setup_pin(board.GP10, digitalio.Direction.OUTPUT)

pin_ENU = setup_pin(board.GP11, digitalio.Direction.OUTPUT, value=False)
pin_END = setup_pin(board.GP12, digitalio.Direction.OUTPUT, value=False)
pin_COLMU = setup_pin(board.GP26, digitalio.Direction.OUTPUT, value=True)
pin_COLMD = setup_pin(board.GP15, digitalio.Direction.OUTPUT, value=True)

# --- MUX出力 ---
mux_outU = setup_pin(board.GP9, digitalio.Direction.INPUT, digitalio.Pull.UP)
mux_outL = setup_pin(board.GP13, digitalio.Direction.INPUT)

# --- チャンネル選択 ---
def select_channel(a, b):
    pin_a.value = a
    pin_b.value = b
    time.sleep(0.001)

キースイッチの割り当てと読み取り。MUXの入力A,Bと上段(U)、下段(D)のスイッチの読み取りを行う。

    channels = [
    (False, False, "sw2", "sw3"),
    (True,  False, "sw4", "sw5"),
    (False, True,  "sw6", "sw7"),
    (True,  True,  "sw8", "sw9"),
]

def read_keys():
    keys = {}
    for a, b, k1, k2 in channels:
        select_channel(a, b)
        keys[k1] = mux_outU.value
        keys[k2] = mux_outL.value
    return keys

# --- キー割り当て ---
keymap = {
    "sw2": (Keycode.CONTROL, Keycode.Z),
    "sw3": (Keycode.CONTROL, Keycode.Y),
    "sw4": (Keycode.CONTROL, Keycode.V),
    "sw5": (Keycode.ENTER,),
    "sw6": (Keycode.CONTROL, Keycode.C),
    "sw7": (Keycode.CONTROL, Keycode.S),
    "sw8": (Keycode.CONTROL, Keycode.A),
    "sw9": (Keycode.ESCAPE,),
}
prev_keys = {k: False for k in keymap}

ループ部分。キースイッチの検知をしながらロータリーエンコーダの読み取りをする。キースイッチもロータリーエンコーダも入力の変化を検知している。 key(sw2, sw3, ...)に対するkey_statesを読んでスイッチを押したかを検知、押していた場合そのkeykey(Keycode.A, ...)kbd.press(*codes)で入力。

    while True:
    key_states = read_keys()

    for key, codes in keymap.items():
        if prev_keys[key] and not key_states[key]:
            kbd.press(*codes)
            kbd.release_all()

    prev_keys = key_states.copy()

    # --- エンコーダ ---
    current_clk = clk.value
    if current_clk != last_clk:
        m.move(wheel=1 if dt.value != current_clk else -1)
    last_clk = current_clk

    time.sleep(0.0001)
  

次回は筐体を3Dプリントしたい。

1ページ 2ページ 3ページ

References

  1. Pi Picoに、CircuitPythonを入れてみた
  2. RP2040*CircuitPythonワンボタンで Ctrl+C / V / A!ショートカットマクロを自作する
  3. API Reference (adafruit_hid)
  4. KiCad9.0で設計した基板をJLCPCBに発注する