first commit drum track sequencer
This commit is contained in:
parent
583969ffe5
commit
cbed6e3267
1 changed files with 77 additions and 0 deletions
77
Drum_Track_Sequencer/code.py
Normal file
77
Drum_Track_Sequencer/code.py
Normal 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())
|
||||
Loading…
Reference in a new issue