You are on page 1of 4

\/*

* Firmata is a generic protocol for communicating with microcontrollers


* from software on a host computer. It is intended to work with
* any host computer software package.
*
* To download a host software package, please clink on the following link
* to open the download page in your default browser.
*
* http://firmata.org/wiki/Download
*/
/* Supports as many digital inputs and outputs as possible.
*
* This example code is in the public domain.
*/
#include <Firmata.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX
byte
byte
byte
int

note = 0; //The MIDI note value to be played


resetMIDI = 4; //Tied to VS1053 Reset line
ledPin = 13; //MIDI traffic inidicator
instrument = 0;

String readString;
byte previousPIN[TOTAL_PORTS]; // PIN means PORT for input
byte previousPORT[TOTAL_PORTS];
void outputPort(byte portNumber, byte portValue)
{
// only send the data when it changes, otherwise you get too many messages!
if (previousPIN[portNumber] != portValue) {
Firmata.sendDigitalPort(portNumber, portValue);
previousPIN[portNumber] = portValue;
}
}
void setPinModeCallback(byte pin, int mode) {
if (IS_PIN_DIGITAL(pin)) {
pinMode(PIN_TO_DIGITAL(pin), mode);
}
}
void digitalWriteCallback(byte port, int value)

{
byte i;
byte currentPinValue, previousPinValue;
if (port < TOTAL_PORTS && value != previousPORT[port]) {
for (i = 0; i < 8; i++) {
currentPinValue = (byte) value & (1 << i);
previousPinValue = previousPORT[port] & (1 << i);
if (currentPinValue != previousPinValue) {
digitalWrite(i + (port * 8), currentPinValue);
}
}
previousPORT[port] = value;
}
}
void setup()
{
Firmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION);
Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
Firmata.attach(SET_PIN_MODE, setPinModeCallback);
Firmata.begin(57600);
mySerial.begin(31250);
//Reset the VS1053
pinMode(resetMIDI, OUTPUT);
digitalWrite(resetMIDI, LOW);
delay(100);
digitalWrite(resetMIDI, HIGH);
delay(100);
talkMIDI(0xB0, 0x07, 120);
}
void loop()
{
byte i;

for (i = 0; i < TOTAL_PORTS; i++) {


outputPort(i, readPort(i, 0xff));
}
while (Firmata.available()) {
Firmata.processInput();
}

if (Serial.available()){
//read serial as a character
char ser= Serial.read();
readString += ser;
switch (ser) {
case'<ab>':
talkMIDI(0xB0, 0, 0x79); //Default bank GM1
talkMIDI(0xC0, instrument, 0); //Set instrument number. 0xC0 is a 1 data byte
command
//Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
noteOn(0, 60, 60);
delay(100);
noteOff(0, 60, 60);
delay(50);
break;
case'1':
talkMIDI(0xB0, 0, 0x79); //Default bank GM1
talkMIDI(0xC0, instrument, 0); //Set instrument number. 0xC0 is a 1 data byte
command
//Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
noteOn(0, 70, 60);
break;
case'2':
talkMIDI(0xB0, 0, 0x79); //Default bank GM1
talkMIDI(0xC0,instrument , 0); //Set instrument number. 0xC0 is a 1 data byte
command
//Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
noteOn(0, 65, 60);
delay(100);
noteOff(0, 65, 60);
delay(50);
break;
case'3':
talkMIDI(0xB0, 0, 0x79); //Default bank GM1
talkMIDI(0xC0, instrument, 0); //Set instrument number. 0xC0 is a 1 data byte
command
//Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
noteOn(0, 71, 60);
delay(100);
noteOff(0, 71, 60);
delay(50);
break;
case'4':
instrument= instrument+1;

if (instrument > 127){ instrument = 0}


break;
case'5':
instrument=instrument-1;
if (instrument < 0){ instrument = 127}
break;

}
}
}
}
//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.write(cmd);
mySerial.write(data1);

//Some commands only have one data byte. All cmds less than 0xBn have 2 data bytes
//(sort of: http://253.ccarh.org/handout/midiprotocol/)
if( (cmd & 0xF0) <= 0xB0)
mySerial.write(data2);
digitalWrite(ledPin, LOW);

You might also like