I am trying to develop a code to communicate with musical instrument shield. This uses midi commands inside different cases. Cases are activated when the corresponding char is written over serial. I am using Firmata protocol to do this coding. and example code is given below. What i am looking for is instead of changing instrument number by making a different case and defining it, i would like to create two cases defined with instrument number (0-127). if first case is activated all the variable in other cases should be instrument+1 and for second case instrument-1. That way a person can choose different instruments just by sending one of the two char through serial.
I am not sure if this is possible but any other suggestions are welcome as well.
in given code i want to change talkMIDI(0xC0,0 , 0); (specified by bold characters) to talkMIDI(0xC0,instrument , 0); and define instrument numbers (0-127). then have two more cases to select a number between 0-127 as instrument+1 and instrument-1. “instrument” being the currently specified value for instrument.
hope i could get some insight on this. Thank you for help.
#include <Firmata.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX
byte note = 0; //The MIDI note value to be played
byte resetMIDI = 4; //Tied to VS1053 Reset line
byte ledPin = 13; //MIDI traffic inidicator
int instrument = 0;
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();
switch (ser) {
case’0’:
talkMIDI(0xB0, 0, 0x79);
talkMIDI(0xC0, 0, 0); //Set instrument number. 0xC0 is a 1 data byte command
noteOn(0, 60, 60);
delay(100);
noteOff(0, 60, 60);
delay(50);
break;
case’1’:
talkMIDI(0xB0, 0, 0x79);
talkMIDI(0xC0, 0, 0); //Set instrument number. 0xC0 is a 1 data byte command
noteOn(0, 70, 60);
delay(100);
noteOff(0, 70, 60);
delay(50);
break;
case’2’:
talkMIDI(0xB0, 0, 0x79); //Default bank GM1
talkMIDI(0xC0,14 , 0); //Set instrument number. 0xC0 is a 1 data byte command
noteOn(0, 60, 60);
delay(100);
noteOff(0, 60, 60);
delay(50);
break;
case’3’:
talkMIDI(0xB0, 0, 0x79); //
** talkMIDI(0xC0, 14, 0);** //Set instrument number. 0xC0 is a 1 data byte command
noteOn(0, 70, 60);
delay(100);
noteOff(0, 70, 60);
delay(50);
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);
}