Hello all!
I am using the Musical Instrument Shield from Sparkfun to build a piano that uses infrared emitter/detectors, and I haven't been able to make my project polyphonic. Since all 8 notes are on the same channel, when I play multiple notes they get arpeggiated, instead of ringing simultaneously. Does anyone know a way to fix this? I assume that I need to have each IR receiver on a different channel but I've tried several different things with no luck. Any suggestions are greatly appreciated!
Here's a simple version of my code:
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); //Soft TX on 3 (we don't use RX in this code?)
int irEmitters[] = {46,47,48,49,50,51,52,53}; // irEmitters: digital pins 46-52
int inputPins[] = {A8,A9,A10,A11,A12,A13,A14,A15}; // irDetectors: analog pins 8-15
int notes[] = {60,62,64,65,67,69,71,72}; // notes: 60 = Middle C (C MAJOR SCALE)
int pinCount = 8;
int inputState[8];
int threshold = 500;
byte resetMIDI = 4; //Pin 4 is ties to VS1053 Reset line.
void setup() {
//Setup soft serial for MIDI control
mySerial.begin(31250);
for (int i=0; i<pinCount;i++) {
// Sets ir Emitters as OUTPUTS, and turns them on.
pinMode(irEmitters[i], OUTPUT);
digitalWrite(irEmitters[i], HIGH);
pinMode(inputPins[i], OUTPUT); // pinMode(outputPins, OUTPUT) <- Turns inputs into outputs
pinMode(inputPins[i], INPUT);
}
//Reset the VS1053
digitalWrite(resetMIDI, LOW);
delay(100);
digitalWrite(resetMIDI, HIGH);
delay(100);
talkMIDI(0xB0, 0x07, 126); //0xB0 is channel message, set channel volume to near max (127)
talkMIDI(0xB0, 0, 0x79); //Default bank GM1
talkMIDI(0xC0, 108, 0); //INSTRUMENT 108
}
void loop() {
for (int i=0; i<pinCount; i++) {
inputState[i]= analogRead(inputPins[i]);
delay(1);
if (inputState[i] > threshold) {
noteOn(0,notes[i],100);
delay(200);
if (inputState[i] > threshold) {
noteOff(0,notes[i],100);
}
}
}
}
//Send a MIDI note-on message. Like Pressing a piano key
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) {
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 || (cmd & 0xF0) == 0xE0) // Wee bug seen in Sparkfun Comments page.
mySerial.write(data2);
}