Sparkfun MIDI Shield
Last updated: 3 October 2012
Prepared by Samson Young [skfyoung@cityu.edu.hk]
URL: https://www.sparkfun.com/products/9595
Cost per unit: $19.95 USD (approx. 155 HKD)

midishield.jpg


General Information

About MIDI Shield
This board gives arduino access to MIDI, so you can control synthesizers, sequencers, and other musical devices directly from your arduino board. 3 buttons and 2 potentiometers on board for easy prototyping.

About MIDI
You need to have a basic understanding of the MIDI format in order to program for this shield. Please refer to Vanissa’s quick-start guide to MIDI on the L.U.M.E. website. Most of the work is done for you in the example code; if you wanted to start making sound quickly without diving too deep into MIDI, then just focus on understanding (1) program change (2) bank & instrument select, and (3) note change.

Features & Specifications
- MIDI In / Out
- Switch for programming mode / running mode
- Turning knobs use pins A0 and A1
- Push buttons are on D2, D3 and D4
- Serial MIDI baudrate: 31250



Getting it to work!
Assembly
Right out of the box the the MIDI Shield does not come with the MIDI connectors or trimpots soldered on.
It also needs a way to connect to the arduino main board – the easiest thing to do is just solder some stackable header pins onto the shield. When you put the headers and the shield together they look like this:

Description: Macintosh HD:Users:samsonyoung:Desktop:IMG_20121003_154721.jpg
Description: Macintosh HD:Users:samsonyoung:Desktop:IMG_20121003_154721.jpg


Connection
No special connection from the board is required in the example code. Simply put the shield on top of your arduino board (see above). However you need to connect the MIDI OUT of your shield to either a MIDI synthesizer or a MIDI interface (driving Garage Band, for example) via a MIDI cable in order to make music.

Example Code

"MIDI shield arpeggiator"
A modification of Sparkfun's example program
By Samson Young [skfyoung@cityu.edu.hk]

Defines MIDI Shield components
#define KNOB1 0
#define KNOB2 1
#define BUTTON1 2
#define BUTTON2 3
#define BUTTON3 4
#define STAT1 7
#define STAT2 6
#define OFF 1
#define ON 2
#define WAIT 3
byte incomingByte;
byte note; to store the "root" of the chord
byte interval; to store the interval
byte velocity;
int pot1;
int pot2;
byte byte1;
byte byte2;
byte byte3;
int action=2; 1 =note off ; 2=note on ; 3= wait

void setup() {
pinMode(STAT1,OUTPUT);
pinMode(STAT2,OUTPUT);
pinMode(BUTTON1,INPUT);
pinMode(BUTTON2,INPUT);
pinMode(BUTTON3,INPUT);
digitalWrite(BUTTON1,HIGH);
digitalWrite(BUTTON2,HIGH);
digitalWrite(BUTTON3,HIGH);

for(int i = 0;i < 10;i++) flash MIDI Sheild LED's on startup
{
digitalWrite(STAT1,HIGH);
digitalWrite(STAT2,LOW);
delay(30);
digitalWrite(STAT1,LOW);
digitalWrite(STAT2,HIGH);
delay(30);
}
digitalWrite(STAT1,HIGH);
digitalWrite(STAT2,HIGH);
start serial with midi baudrate 31250
Serial.begin(31250);
}

void loop () {

      • MIDI OUT *
This is where we program the arpeggiating behavior

KNOB1 behavior - changes pitch
pot1 = analogRead(KNOB1);
KNOB2 behavior - change arpeggiating interval
pot2 = analogRead(KNOB2);
Convert pot value to note value 0-127
note = pot1/8;
Convert pot value to intervallic values (1-16)
interval = pot2/128;
Buttons behavior
if(button(BUTTON1))
{
Midi_Send(0x90,note,0x45); Play selected note
delay(100); smaller value = faster arpeggiation
}
if(button(BUTTON2))
{
Midi_Send(0x90,note+interval,0x45); Play selected note + interval
delay(100);
}
if(button(BUTTON3))
{
Midi_Send(0x90,note+interval+12,0x45); Play selected note + interval + octave (12 semitones)
delay(100);
}

Following are loopback and midiout controls. Straight out of the Sparkfun example.

* MIDI LOOPBACK
if(Serial.available() > 0)
{
byte1 = Serial.read();
byte2 = Serial.read();
byte3 = Serial.read();
Midi_Send(byte1, byte2, byte3);
}

* MIDI IN** *
if (Serial.available() > 0) {
read the incoming byte:
incomingByte = Serial.read();
wait for as status-byte, channel 1, note on or off
if (incomingByte== 144) Note on
{
action = OFF;
}
else if (incomingByte== 128) Note off
{
action = ON;
}
else if (note==0 && action != WAIT) note on, wait for note value
{
note=incomingByte;
}
else if (note!=0 && action != WAIT) velocity
{
velocity=incomingByte;
if(action == ON){
Midi_Send(0x90,note,velocity);
}
if(action == OFF){
Midi_Send(0x80,note,velocity);
}
note=0;
velocity=0;
action=WAIT;
}
else{
}
}

}

// Default functions. Do not modify.

void Midi_Send(byte cmd, byte data1, byte data2) {
Serial.print(cmd, BYTE);
Serial.print(data1, BYTE);
Serial.print(data2, BYTE);
}

void blink(){
digitalWrite(STAT1, HIGH);
delay(100);
digitalWrite(STAT1, LOW);
delay(100);
}

char button(char button_num)
{
return (!(digitalRead(button_num)));
}