Created
May 24, 2024 15:52
-
-
Save jedgarpark/95c432ca8a1272910c7de3c3d49d4470 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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