Skip to content

Instantly share code, notes, and snippets.

@jedgarpark
Created May 24, 2024 15:52
Show Gist options
  • Save jedgarpark/95c432ca8a1272910c7de3c3d49d4470 to your computer and use it in GitHub Desktop.
Save jedgarpark/95c432ca8a1272910c7de3c3d49d4470 to your computer and use it in GitHub Desktop.
# SPDX-FileCopyrightText: 2024 John Park for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
Drum Track Sequencer
Feather RP2040, Motor FeatherWing, stepper motor,
four reflection sensors (either MIDI out or synthio w amp)
"""
"""
# TO DO:
add rotary encoder for pause/play and bpm
"""
import time
import busio
from adafruit_seesaw import seesaw, rotaryio, digitalio
import asyncio
import board
from adafruit_motorkit import MotorKit
from adafruit_motor import stepper
import keypad
import usb_midi
i2c=busio.I2C(board.SCL, board.SDA, frequency=400_000)
seesaw = seesaw.Seesaw(i2c, addr=0x36)
seesaw.pin_mode(24, seesaw.INPUT_PULLUP)
encoder_button = digitalio.DigitalIO(seesaw, 24)
encoder_button_held = False
encoder = rotaryio.IncrementalEncoder(seesaw)
encoder_last_position = None
# 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)
def play_drum(note):
midi_msg_on = bytearray([0x99, note, 120]) # 0x90 is noteon ch 1, 0x99 is noteon ch 10
midi_msg_off = bytearray([0x89, note, 0])
midi.write(midi_msg_on)
midi.write(midi_msg_off)
async def check_encoder():
while True:
encoder_position = -encoder.position
if encoder_position != encoder_last_position:
encoder_last_position = encoder_position
print(encoder_position)
if not encoder_button.value and not encoder_button_held:
encoder_button_held = encoder_button_held = True
print("encoder button pressed")
if encoder_button.value and encoder_button_held:
encoder_button_held = False
print("encoder button released")
await asyncio.sleep(0)
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)
async def run_motor():
while True:
kit.stepper1.onestep(
direction=stepper.BACKWARD,
style=stepper.DOUBLE
)
await asyncio.sleep(0.002) # motor speed
async def main():
motor_task = asyncio.create_task(run_motor())
sensor_task = asyncio.create_task(check_sensors())
encoder_task = asyncio.create_task(check_encoder())
await asyncio.gather(motor_task, sensor_task, encoder_task)
asyncio.run(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment