first commit drum track sequencer

This commit is contained in:
John Park 2024-05-28 19:57:56 -07:00
parent 583969ffe5
commit cbed6e3267

View file

@ -0,0 +1,77 @@
# SPDX-FileCopyrightText: 2024 John Park for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
Drum Track Sequencer
Feather RP2040, Motor FeatherWing, stepper motor,
four reflection sensors, USB MIDI out
"""
import asyncio
import busio
import board
from adafruit_motorkit import MotorKit
from adafruit_motor import stepper
import keypad
import usb_midi
# Tempo setup
BPM = 100 # user set value
tempo_table = { # motor speed seems non-linear, so we'll use a lookup table
110: 0.0004,
100: 0.001,
90: 0.002,
80: 0.003,
75: 0.004,
65: 0.005,
60: 0.006,
50: 0.008
}
def get_nearest_tempo(given_bpm):
nearest_table_item = min(tempo_table.keys(), key=lambda k: abs(k - given_bpm))
return tempo_table[nearest_table_item]
motor_pause = get_nearest_tempo(BPM)
i2c=busio.I2C(board.SCL, board.SDA, frequency=400_000)
# Motor setup
kit = MotorKit(i2c=i2c)
motor_run=True
# Sensor setup
optical_pins = (board.D6, board.D9, board.D10, board.D12)
optical_sensors = keypad.Keys(optical_pins, value_when_pressed=False, pull=True)
# MIDI setup
midi = usb_midi.ports[1]
midi_notes = (36, 37, 38, 39) # typical drum voice notes
def play_drum(note):
midi_msg_on = bytearray([0x99, note, 120]) # 0x90 noteOn ch1, 0x99 noteOn ch10
midi_msg_off = bytearray([0x89, note, 0])
midi.write(midi_msg_on)
midi.write(midi_msg_off)
async def check_sensors():
while True:
optical_sensor = optical_sensors.events.get()
if optical_sensor:
if optical_sensor.pressed:
track_num = optical_sensor.key_number
# print("tripped", track_num)
play_drum(midi_notes[track_num])
await asyncio.sleep(0.008) # don't check sensors constantly or motor speed reduced
async def run_motor():
while True:
kit.stepper1.onestep(
direction=stepper.BACKWARD,
style=stepper.DOUBLE
)
await asyncio.sleep(motor_pause) # motor speed-- smaller numbers are faster
async def main():
motor_task = asyncio.create_task(run_motor())
sensor_task = asyncio.create_task(check_sensors())
await asyncio.gather(motor_task, sensor_task)
asyncio.run(main())