diff --git a/Toy_Robot_Xylophone/code.py b/Toy_Robot_Xylophone/code.py new file mode 100644 index 000000000..458214193 --- /dev/null +++ b/Toy_Robot_Xylophone/code.py @@ -0,0 +1,97 @@ +# SPDX-FileCopyrightText: 2025 Liz Clark for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +import os +from random import randint +import board +import usb_midi +import keypad +from adafruit_mcp230xx.mcp23017 import MCP23017 +import adafruit_midi +from adafruit_midi.note_on import NoteOn +from adafruit_midi.note_off import NoteOff +import adafruit_midi_parser + +# music_box plays back MIDI files on CP drive +# set to false for live MIDI over USB control +music_box = True +# define the notes that correspond to each solenoid +notes = [48, 50, 52, 53, 55, 57, 59, 60] + +key = keypad.Keys((board.BUTTON,), value_when_pressed=False, pull=True) + +i2c = board.STEMMA_I2C() +mcp = MCP23017(i2c) +noids = [] +for i in range(8): + noid = mcp.get_pin(i) + noid.switch_to_output(value=False) + noids.append(noid) +# pylint: disable=used-before-assignment, unused-argument, global-statement +if not music_box: + midi = adafruit_midi.MIDI( + midi_in=usb_midi.ports[0], in_channel=0, midi_out=usb_midi.ports[1], out_channel=0 + ) +else: + midi_files = [] + for filename in os.listdir('/'): + if filename.lower().endswith('.mid') and not filename.startswith('.'): + midi_files.append("/"+filename) + print(midi_files) + + class Custom_Player(adafruit_midi_parser.MIDIPlayer): + def on_note_on(self, note, velocity, channel): # noqa: PLR6301 + for z in range(len(notes)): + if notes[z] == note: + print(f"Playing note: {note}") + noids[z].value = True + + def on_note_off(self, note, velocity, channel): # noqa: PLR6301 + for z in range(len(notes)): + if notes[z] == note: + noids[z].value = False + + def on_end_of_track(self, track): # noqa: PLR6301 + print(f"End of track {track}") + for z in range(8): + noids[z].value = False + + def on_playback_complete(self): # noqa: PLR6301 + global now_playing + now_playing = False + for z in range(8): + noids[z].value = False + parser = adafruit_midi_parser.MIDIParser() + parser.parse(midi_files[randint(0, (len(midi_files) - 1))]) + player = Custom_Player(parser) + new_file = False + now_playing = False + +while True: + if music_box: + event = key.events.get() + if event: + if event.pressed: + now_playing = not now_playing + if now_playing: + new_file = True + if new_file: + parser.parse(midi_files[randint(0, (len(midi_files) - 1))]) + print(f"Successfully parsed! Found {len(parser.events)} events.") + print(f"BPM: {parser.bpm:.1f}") + print(f"Note Count: {parser.note_count}") + new_file = False + if now_playing: + player.play(loop=False) + + else: + msg = midi.receive() + if msg is not None: + for i in range(8): + noid_output = noids[i] + notes_played = notes[i] + if isinstance(msg, NoteOn) and msg.note == notes_played: + noid_output.value = True + elif isinstance(msg, NoteOff) and msg.note == notes_played: + noid_output.value = False diff --git a/Toy_Robot_Xylophone/song_1.mid b/Toy_Robot_Xylophone/song_1.mid new file mode 100644 index 000000000..87bbc1b8c Binary files /dev/null and b/Toy_Robot_Xylophone/song_1.mid differ diff --git a/Toy_Robot_Xylophone/song_2.mid b/Toy_Robot_Xylophone/song_2.mid new file mode 100644 index 000000000..bc4602a4b Binary files /dev/null and b/Toy_Robot_Xylophone/song_2.mid differ diff --git a/Toy_Robot_Xylophone/song_3.mid b/Toy_Robot_Xylophone/song_3.mid new file mode 100644 index 000000000..46fda0d23 Binary files /dev/null and b/Toy_Robot_Xylophone/song_3.mid differ diff --git a/Toy_Robot_Xylophone/song_4.mid b/Toy_Robot_Xylophone/song_4.mid new file mode 100644 index 000000000..0ee97a9a3 Binary files /dev/null and b/Toy_Robot_Xylophone/song_4.mid differ