Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Sketch to drive the SparkFun Music Instrument Shield (VS1053 MP3 and MIDI codec IC) from an Arduino UNO.
/**
* Author: Rick Winscot, Nathan Seidle
* Copyright: PUBLIC DOMAIN ( Beerware License )
*
* Hardware: Arduino UNO R3
* SparkFun Musical Instrument Shield ( http://www.sparkfun.com/products/10587 )
*
* IDE: Arduino 1.0 ( http://arduino.cc/en/Main/Software )
*
* Original sketch by Nathan Seidle on 2-12-2011. Transmogrified by Rick Winscot on 17-12-2011
* in hopes of improving re-usability on future projects. Keep to the above hardware/ide specs
* and you'll be able to slap the shield on an UNO, copy the sketch into the ide, and compile.
*/
#include <SoftwareSerial.h>
// Connect to the VS1053 on TX pin 3. RX pin 2 is not used.
SoftwareSerial midi( 2, 3 );
// Sound-banks available on the VS1053.
// 0x00 : GM1 (default)
// 0x78 : Drums
// 0x79 : GM2
byte SOUND_BANK = 0x00;
// Constant used to control channel volume.
// Range : 0 - 127
int VOLUME = 90;
// Constant used to control attack and sustain velocity.
// Range : 0 - 127
int ATK_VELOCITY = 60;
int REL_VELOCITY = 60;
// Constants used to start or stop note playback.
byte PLAY = 0x90;
byte STOP = 0x80;
// Constant used to map Arduino pin to VS1053 reset.
int VS1053_RESET = 4;
// Constant used to supress serial debugging.
boolean DEBUG = true;
// Variable used to navigate instrument selection.
int instrument = 0;
// Variable used to control note playback.
byte note = 0;
/**
* Initialize debugging, connect to the VS1053, init the VS1053, and
* set initial sound-bank and volume.
*/
void setup()
{
Serial.begin( 57600 ); // For debug messages
midi.begin( 31250 ); // MIDI control via SoftwareSerial
pinMode( VS1053_RESET, OUTPUT ); // Reset VS1053
digitalWrite( VS1053_RESET, LOW ); // ..
delay( 100 ); // ..
digitalWrite( VS1053_RESET, HIGH ); // ..
delay( 100 ); // ..
setBank( SOUND_BANK ); // Set sound-bank via constant
setVolume( VOLUME ); // Set channel volume via constant
}
/**
* Some applications run forever.
*/
void loop()
{
for ( instrument = 0 ; instrument < 127 ; instrument++ )
{
setInstrument( instrument );
for ( note = 30 ; note < 42 ; note++ )
{
setNote( note, PLAY ); // Play specified note by ATK_VELOCITY
delay(50); // ..
setNote( note, STOP ); // Stop specified note by REL_VELOCITY
delay(50); // ..
}
}
}
/**
* Set the sound-bank to one of the three available.
*/
void setBank( byte bank )
{
if ( DEBUG )
Serial.print( "Bank: " + (String)bank );
midi.write( 0xB0 );
midi.write( (byte)0 );
midi.write( bank );
}
/**
* Set channel volume to a value between 0 and 127.
*/
void setVolume( int vol )
{
if ( vol < 0 )
vol = 0;
if ( vol > 127 )
vol = 127;
if ( DEBUG )
Serial.print( "Volume: " + (String)vol );
midi.write( 0xB0 );
midi.write( 0x07 );
midi.write( (byte)vol );
}
/**
* Set the sound-bank instrument to a value between 0 - 127.
*/
void setInstrument( byte inst )
{
if ( inst < 0 )
inst = 0;
if ( inst > 127 )
inst = 127;
if ( DEBUG )
Serial.print( "Instrument: " + (String)inst );
midi.write( 0xC0 );
midi.write( inst );
}
/**
* Play or stop the specified note.
*
* Example : setNote( 30, PLAY ); // Plays F# 0
* setNote( 30, STOP ); // Stops F# 0
*
* Range: 0 - 127
*/
void setNote( byte note, byte cmd )
{
if ( note < 0 )
note = 0;
if ( note > 127 )
note = 127;
if ( DEBUG )
Serial.println( "Note: " + (String)note + " Play:" + ( cmd == PLAY ? "play" : "stop" ) );
midi.write( cmd );
midi.write( note );
midi.write( ( cmd == PLAY ? ATK_VELOCITY : REL_VELOCITY ) );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.