So far the neotrellis is a somewhat pretty blinkie toy. We can make it a bit more useful by turning it into a 16 button Midi keypad. That is having each key send a different Midi Note over USB. Press and send Midi.NoteOn, Release and send Midi.NoteOff. A PC (mac etc) application can receive the MIdi data and use it for application control (music synthesizer, video switcher commands, etc). We did the same thing back in the Astral TV midi controller project that inspired this one.
The new modular design makes it really easy to implement.using the adafruit_midi and usb_midi libraries. We added a module to our project called neotrellis_midi.py. It exposes three methods:
- setup_midi() - sets up the module by creating an adafruit_midi.MIDI object
- send_note_on(idx) - sends a NoteOn message with requested note index
- and send_note_off()- sends a NoteOff message with requested note index
A couple module constants let the client application chose the midi channel and notes associated with the 16 keys. Simply edit these values and rerun the application. A fancier version might read them at runtime from a configuration file.
import usb_midi
import adafruit_midi
from adafruit_midi.note_on import NoteOn
from adafruit_midi.note_off import NoteOff
# constants for channel, velocity and notes to associate with keys
# caveat: programmers count channels from 0, normal folks count from 1
# you can see difference viewing midi traffic using
# https://www.kilpatrickaudio.com/apps/midiview/
# we send zero, it receives 0 but prints out 1
#
__midi_channel = 0
# 16 midi notes to associate with keypad by number
__midiNotes = [
60, 61, 62, 63,
64, 65, 66, 67,
68, 69, 70, 71,
72, 73, 74, 75,
]
__midi = None
def setup_midi():
global __midi, __midi_channel
# MIDI setup as MIDI out device
print("setup midi out device")
__midi = adafruit_midi.MIDI(midi_out=usb_midi.ports[1], out_channel=__midi_channel)
def send_note_on(idx):
global __midi
print("YO send_note_on", idx, __midi)
if __midi is None:
print("Midi not defined")
else:
print("send midi NoteOn ", idx, __midiNotes[idx], __midi)
__midi.send(NoteOn(__midiNotes[idx], 120))
def send_note_off(idx):
global __midi
if __midi is None:
print("Midi not defined")
else:
__midi.send(NoteOff(__midiNotes[idx], 120))
print("send midi NoteOff ", idx, __midiNotes[idx])
That's all there is to the midi module. It is pretty simple with more data checking and print statements than real function stuff. Adding it to the rest of the application is also pretty simple - add four lines to the neotrellis_keypad.py module.
First add the import at the top
import neotrellis_midi
Then in setup_keypad(), call the setup_midi()
neotrellis_midi.setup_midi()
Then down in doKey(), we add lines to send NoteOn and NoteOff. In the NeoTrellis.EDGE_RISING block, we add
neotrellis_midi.send_note_on(event.number)
and then in the NeoTrellis.EDGE_FALLING block, we add
neotrellis_midi.send_note_off(event.number)
Thats it. The neotrellis will now send the midi commands.
You can use a midi enabled browser, like Google Chrome, to view MIDI traffic on the MidiView web page https://www.kilpatrickaudio.com/apps/midiview/
It is interesting to note that while we sending data on midi channel 0, the tool reports it as channel 1. This is because musicians and other normal people count from 1, while programmers start with zero. It is the 0 index into the array, right?
Anyway the neotrellis has now become a useful midi keypad device. yay!!
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.