#define rowOne 0 // Defines the midi note played by the first row. #define rowTwo 1 // Defines the midi note played by the second row. #define rowThree 2 // Defines the midi note played by the third row. #define rowFour 3 // Defines the midi note played by the fourth row. #define columnOne 2 // Defines the pin connected to the first column. #define columnTwo 3 // Defines the pin connected to the first column. #define columnThree 4 // Defines the pin connected to the first column. #define columnFour 5 // Defines the pin connected to the first column. int delayTime; // Holds the number of milliseconds the program waits between columns. byte noteOne; byte noteTwo; byte noteThree; byte noteFour; // Sets the pin modes for all of the inputs and outputs of the arduino void setup() { pinMode(7, INPUT); pinMode(8, INPUT); pinMode(9, INPUT); pinMode(10, INPUT); pinMode(11, INPUT); pinMode(12, INPUT); digitalWrite(12, HIGH); pinMode(columnOne, OUTPUT); pinMode(columnTwo, OUTPUT); pinMode(columnThree, OUTPUT); pinMode(columnFour, OUTPUT); } void loop() { setDelay(); flashColumn(columnOne); flashColumn(columnTwo); flashColumn(columnThree); flashColumn(columnFour); if(digitalRead(12) == 0){ playTimingNotes(); } else { playNormalNotes(); delay(delayTime); } noteOne = 0; noteTwo = 0; noteThree = 0; noteFour = 0; } // First parameter is the event type (0x09 = note on, 0x08 = note off). // Second parameter is note-on/note-off, combined with the channel. // Channel can be anything between 0-15. Typically reported to the user as 1-16. // Third parameter is the note number (48 = middle C). // Fourth parameter is the velocity (64 = normal, 127 = fastest). void noteOn(byte channel, byte pitch, byte velocity) { MIDIEvent noteOn = {0x09, 0x90 | channel, pitch, velocity}; MIDIUSB.write(noteOn); } void noteOff(byte channel, byte pitch, byte velocity) { MIDIEvent noteOff = {0x08, 0x80 | channel, pitch, velocity}; MIDIUSB.write(noteOff); } // Combines note on and note off information into one method void playNote(byte channel, byte pitch, byte velocity){ noteOn(channel, pitch, velocity); MIDIUSB.flush(); noteOff(channel, pitch, velocity); MIDIUSB.flush(); } // Powers a column of the matrix, then reads out which switches are closed // then sets the column back down to low void flashColumn(byte column){ digitalWrite(column, HIGH); readColumn(column); digitalWrite(column, LOW); } // Reads each row, then plays the respective notes if the switches are closed void readColumn(int column){ int noteNumber = 100; if(digitalRead(8) == 1){ noteNumber = rowOne + (column-1)*12; } else if(digitalRead(9) == 1){ noteNumber = rowTwo + (column-1)*12; } else if(digitalRead(10) == 1){ noteNumber = rowThree + (column-1)*12; } else if(digitalRead(11) == 1){ noteNumber = rowFour + (column-1)*12; } if(column == 2){ noteOne = noteNumber; } else if(column == 3){ noteTwo = noteNumber; } else if(column == 4){ noteThree = noteNumber; } else if(column == 5){ noteFour = noteNumber; } } void playTimingNotes(){ for(int i = 0; i < 4; i++){ playNote(0, 100, 64); delay(delayTime/32); } } void playNormalNotes(){ if(noteOne != 0){ playNote(0, noteOne, 64); } if(noteTwo != 0){ playNote(0, noteTwo, 64); } if(noteThree != 0){ playNote(0, noteThree, 64); } if(noteFour != 0){ playNote(0, noteFour, 64); } } void setDelay(){ delayTime = ((analogRead(A0)/2)+300)*32; }