Sparkfun Musical Instrument Shield
Last updated: 28 September 2012
Prepared by Samson Young []
Cost per unit: $29.95 USD (approx. 240 HKD)


General Information
About Music Instrument Shield
This shield adds MIDI sound to your arduino project. Simply connect a speaker / pair of headphones to the 1/8" stereo jack on the shield and pass the proper serial commands to the IC. Output signal is weak though, so you’d probably want to connect this to an active powered speaker. Shield includes two large tone banks.

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
For full specs refer to datasheet available here:
Here’s a list of important features to note:
- Stereo earphone driver capable of driving a 30 ohm load

- Bass and treble controls
- Streaming support for MP3 and WAV
- Maximum ratings:
1. Higher current can cause latch-up
2. Must not exceed 3.6V

Getting it to work!
Right out of the box the shield needs a way to connect to the arduino main board – the easiest thing to do is just solder some stackable headers onto the shield. When you the headers, the shield and the arduino board together they look like this:


Pins 3 & 4 are taken by the shield. All other pins operate normally.
Connections shown are as in the Looping Drum Machine example code below.instrumentschematics.png
One leg of push button connected to 5V thru resistor
One leg of push button connected to GND
One leg of push button connected to Inputs (2, 5, 6, 7 in the example)

Example Code

4 buttons MIDI Drum Loop Machine
by Samson Young
Beerware licence (buy me a beer if you find this useful)

#include <NewSoftSerial.h>
NewSoftSerial mySerial(2, 3);
Soft TX on 3, we don't use RX in this code
byte note = 0; The MIDI note value to be played
byte resetMIDI = 4;
Tied to VS1053 Reset line
byte ledPin = 13; MIDI traffic indicator
int instrument = 0;

const int buttonPin = 2;
pushbutton @ pin 2
const int buttonPin2 = 5; pushbutton2 @ pin 5
const int buttonPin3 = 6;
pushbutton3 @ pin 6
const int buttonPin4 = 7; pushbutton4 @ pin 7

variables will change:

int buttonState = 0; variable for reading the pushbutton status
int buttonState2 = 0;
variable for reading the pushbutton2 status
int buttonState3 = 0; variable for reading the pushbutton3 status
int buttonState4 = 0;
variable for reading the pushbutton4 status

void setup() {
Setup soft serial for me serial monitor (useful for debugging)
Setup soft serial for MIDI control

Reset the VS1053 chip
pinMode(resetMIDI, OUTPUT);
digitalWrite(resetMIDI, LOW);
digitalWrite(resetMIDI, HIGH);

Initialize the pushbutton pins as an input:
pinMode(buttonPin, INPUT);
pinMode(buttonPin2, INPUT);
pinMode(buttonPin3, INPUT);
pinMode(buttonPin4, INPUT);

void loop(){
0xB0 is channel message, set channel volume to near max (127)
talkMIDI(0xB0, 0x07, 120);
Bank select drums
talkMIDI(0xB0, 0, 0x78);

read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
buttonState2 = digitalRead(buttonPin2);
buttonState3 = digitalRead(buttonPin3);
buttonState4 = digitalRead(buttonPin4);

check if the pushbutton is pressed.
if it is, the buttonState is HIGH:

if (buttonState == HIGH)
talkMIDI(0xC0, instrument, 0);
Serial.println(41, DEC);
41 = high floor tom
noteOn(0, 41, 127);
noteOff(0, 41, 60);

if (buttonState2 == HIGH)
talkMIDI(0xC0, instrument, 0);
Serial.println(44, DEC); 44 = pedal hi-hat
noteOn(0, 44, 127);
noteOff(0, 44, 60);

if (buttonState3 == HIGH)
talkMIDI(0xC0, instrument, 0);
Serial.println(51, DEC);
51 = ride cumbal
noteOn(0, 51, 127);
noteOff(0, 51, 60);

if (buttonState4 == HIGH)
talkMIDI(0xC0, instrument, 0);
Serial.println(56, DEC); 56 = cowbell
noteOn(0, 56, 127);
noteOff(0, 56, 60);


Declare the noteOn(), noteOff(), and talkMIDI() functions. No need to modify.
Send a MIDI note-on message. Like pressing a piano key.
channel ranges from 0-15.

void noteOn(byte channel, byte note, byte attack_velocity) {
talkMIDI( (0x90 | channel), note, attack_velocity);

Send a MIDI note-off message. Like releasing a piano key
void noteOff(byte channel, byte note, byte release_velocity) {
talkMIDI( (0x80 | channel), note, release_velocity);

Plays a MIDI note. Doesn't check to see that cmd is greater than 127, or that data values are less than 127
void talkMIDI(byte cmd, byte data1, byte data2) {
digitalWrite(ledPin, HIGH);
mySerial.print(cmd, BYTE);
mySerial.print(data1, BYTE);

Some commands only have one data byte. All cmds less than 0xBn have 2 data bytes
(sort of:
if( (cmd & 0xF0) <= 0xB0)
mySerial.print(data2, BYTE);

digitalWrite(ledPin, LOW);