Simple MIDI sequencer

This project is a simple MIDI sequencer sketch. It assumes that you have a 5-pin MIDI OUT interface attached to Arduino pin D1 (also called “TX”). If you don’t have a MIDI OUT interface, check out the design of my basic MIDI IN/OUT interface for Arduino. Then come back here. This sketch is a good MIDI OUT test program. In fact, I use this sketch to test the MIDI OUT portion of my home brew interface.

The sketch is based on the simple Arduino tone sequencer sketch. Please read that page first. Both sketches are built around a two dimensional array (sequencer) that holds a musical sequence consisting of notes and rests. In the MIDI sequencer, the first column of the array is the MIDI note number and the second column is the note (or rest) duration.

5-pin MIDI communicates through the Arduino’s transmit (TX) and receive (RX) serial port pins. The MIDI standard serial speed is 31,250 bits per second. The setup() function initializes the serial interface at MIDI speed:

    Serial.begin(31250) ;

I defined three helper functions (MidiSend(), MidiNoteOn(), MidiNoteOff()) to send 3-byte MIDI messages. The helper functions make the code a bit more readable and maintainable. For a simple sketch like this, it makes sense to speak MIDI directly through the serial interface. I strongly recommend the Arduino MIDI library when writing more complicated sketches, however. The MIDI standard has many message types and the Arduino MIDI library hides a lot of low level detail.

//
// Send a short, 3-byte MIDI message
//
void MidiSend(byte cmd, byte data1, byte data2)
{
  Serial.write(cmd | CHANNEL) ;
  Serial.write(data1) ; 
  Serial.write(data2) ; 
}

//
// MIDI note ON message
//
void MidiNoteOn(byte note, byte velocity)
{
  MidiSend(0x90, note, velocity) ; 
}

//
// MIDI note OFF message
//
void MidiNoteOff(byte note)
{
  // MidiSend(0x80, note, 0) ; 
  MidiSend(0x90, note, 0) ; 
}

The setup() and loop() functions are very similar to the corresponding functions in the simple Arduino tone sequencer sketch. Instead of calling tone(), the MIDI sketch calls the helper functions to send MIDI note on and note off messages.

There is one possible gotcha when uploading the sketch. The Arduino IDE communicates with the Arduino through the same serial port as the 5-pin MIDI interface. First off, the Arduino IDE does not communicate at the same serial speed as MIDI (31,250 bits per second). Second, the Arduino IDE doesn’t like it if MIDI and IDE messages get intermixed. So, if you see synchronization errors when uploading a sketch, disconnect the MIDI interface from the Arduino. Then try the upload again. Commercial MIDI shields like the Sparkfun MIDI Shield have a RUN/PROG switch that put the shield into the appropriate state for MIDI (the RUN position) or uploading (the PROG position). This gotcha can drive you crazy, so please be forewarned!

Here are links to the three source code files:

MidiNoteNum.h: Defines symbolic constants for the note names
ToneNote.h: Defines symbolic constands for note/rest durations
MidiSeq.ino: The simple MIDI sequencer Arduino sketch

The ToneNote.h include file is part of the original Arduino tone sequencer sketch. The MIDI sequencer sketch demonstrates the power of “copy and modify” to reuse existing source code for new purposes. Professional programmers reuse code (and libraries!) as much as possible because reuse is faster and cheaper than writing code from scratch.