RPi Pico でmidi ドラム

目次
以前に作った midi keyboard
タクトスイッチは押しにくいので、ちょっといいキースイッチを購入
売り物はPCB基板(neopixel1個付き)。キースイッチとキーキャップは、別途用意する。
キースイッチ、最初はクリック感のある茶軸を使っていたが、クリック感なしの赤軸のほうがしっくり来た。

neopixelがついてるので、キーキャップは透明なものを利用
circuitpython driver
探したけどみつからない。
キーなので、GPIO 1個につき1KEYで、PULL UPのINPUT制御。 ここいらは、以前の記事と同じ。
neopixel は、組み込まれているので、特に追加driverはなし。
基板に IN と OUT と書いてるPINが、制御PINとして制御すればOK
IN/OUT は基板の横方向と縦方向の両方にあるが、自分はPINが5個ある方向のやつを使った。
配線

program
キーを押すと、midi に出力するプログラム。
KEY1 を押すとC2 、 KEY2 を押すと D2 をmidi出力する。
プログラムの 以下の部分を変えれば、スキなnoteに変更できる。
python
37 # key1 and key2 note
38 CHORDS = [C2, D2]midi_drum.py · Gistpython
import board
import busio
import digitalio
import time
import neopixel
import usb_midi
import adafruit_midi
from adafruit_midi.note_off import NoteOff
from adafruit_midi.note_on import NoteOn
try:
import _pixelbuf
except ImportError:
import adafruit_pypixelbuf as _pixelbuf
# pitch class
C2 = 50
D2 = 52
E2 = 54
G2 = 55
A3 = 57
B3 = 59
C3 = 60
D3 = 62
E3 = 64
F3 = 65
F3S = 66
G3 = 67
A3 = 69
B3 = 71
C4 = 72
D4 = 74
E4 = 76
# key1 and key2 note
CHORDS = [C2, D2]
# for neopixel color
RED = (100, 0, 0)
BLUE = (0, 0, 100)
GREEN = (0, 100, 0)
BLACK = (0, 0, 0)
class MidiDrum:
def __init__(self, sda=board.GP2, scl=board.GP3):
i2c = busio.I2C(scl, sda)
#
# key
# https://shop.pimoroni.com/products/neokey-socket-breakout-for-mechanical-key-switches-with-neopixel-for-mx-compatible-switches
#
# KEY1=GP26, KEY2=GP27, NeoPixel=GP28
self.keys_ = []
for pin in (board.GP26, board.GP27):
key = digitalio.DigitalInOut(pin)
key.switch_to_input(pull=digitalio.Pull.UP)
self.keys_.append(key)
self.pixels_ = neopixel.NeoPixel(board.GP28, 2, auto_write=False)
self.set_key_pixel([0, 0]) # init black
#
# USB MIDI up on channel 0
# doc: https://circuitpython.readthedocs.io/projects/midi/en/latest/api.html
#
self.midi_ = adafruit_midi.MIDI(midi_out=usb_midi.ports[1], out_channel=0)
def set_key_pixel(self, statuses):
self.pixels_[0] = BLACK
self.pixels_[1] = BLACK
if statuses[0]:
self.pixels_[1] = BLUE
if statuses[1]:
self.pixels_[0] = GREEN
self.pixels_.show()
def is_key_press(self):
is_pressed = []
for key in self.keys_:
# press False, release True
is_pressed.append(not key.value)
return is_pressed
def set_led(self, status):
if status:
self.pixel_.brightness = 0.3
else:
self.pixel_.brightness = 0.0
if __name__ == "__main__":
mk = MidiDrum()
current_key_statuses = [False, False]
while True:
# get current key press or release
is_presses = mk.is_key_press()
is_changes = [False, False]
# check changed to press or release
for no, is_press in enumerate(is_presses):
if current_key_statuses[no] != is_press:
is_changes[no] = True
current_key_statuses[no] = is_press
if is_changes[0] or is_changes[1]:
# changed!
mk.set_key_pixel(current_key_statuses)
for no in range(len(CHORDS)):
if not is_changes[no]:
continue
is_pressed = current_key_statuses[no]
print("key {} press {} {}".format(no, is_pressed, CHORDS[no]))
if is_pressed:
mk.midi_.send(NoteOn(CHORDS[no], 127))
else:
mk.midi_.send(NoteOff(CHORDS[no], 0))動作確認
Mac の GarageBand を起動して、Track に適当なDrumを設定する。 本当にデータが送られているかは、GarageBandのソフトウェアキーボードを表示する。
実際には、 Show Musical Typing メニューか command + k 。


作成したプログラムを実行し、KEYを押すと、ソフトウェアキーボード上で該当する C2 、 D2 がクリックエフェクト表示される。
音が鳴らない時は、たまたま選択したDrumの C2 , D2 に音源が割り振られていないかもしれないので、 最初は Drum Kit - East bay がお薦め。

