/* Programmable MIDI Drum set v01 Hari Wiguna, 2010 Features: - Up to 4 drum pads on Duemilenove, more on Mega - Each pad can be dynamically assigned to any of the 60 MIDI percussions - Adjustable sensitivity via potentiometer. Or, you can hardcode sensitivity and add a fifth drum pad. */ //-- Sensitivity Knob (Potentiometer) -- int thresholdPin = 5; //-- Drum Pads (Piezo Sensors) -- // Analog In 0,1,2,3,4 are connected to Piezo sensors (drum pads) // Analog In 5 is connected to potentiometer that controls sensitivity of the pads. // You can hard-code the threshold value and add another drum pad if you prefer. int padPin[] = {0,1,2}; // I only have three drum pads. :-( int padCount = sizeof(padPin) / 2; int lastPadHit = 0; //-- Drum Pad Indicators (LEDs) -- int ledPin[] = {8,9,10}; // I only have three drum pads. Add more led pins if you add more pads. //-- MIDI Instruments -- // Actually these are NOTES, but in MIDI channel 10, all notes have been assigned to different percussion sounds. int padInstruments[] = {33, 40, 46}; // I only have three drum pads. You must add more default instruments here if you add more pads. //-- Control pushbuttons -- int btnPin[] = {2,3, 4,5,6,7}; // The first two are used for assigning instruments to pads, the rest trigger sounds like pads. int buttonInstruments[] = {0,0, 29,39,84,84}; int btnOldValue[6]; int btnCount = sizeof(btnPin) / 2; int decrementBtnPin = btnPin[0]; int incrementBtnPin = btnPin[1]; //=== S E T U P === void setup() { Serial.begin(31250); // Set MIDI baud rate //-- Setup Buttons -- for (int i = 0; i < btnCount; i++) { pinMode(btnPin[i], INPUT); digitalWrite(btnPin[i], HIGH); // turn on internal pullup } //-- Setup Piezo sensors & LEDs -- for (int i = 0; i < padCount; i++) { pinMode( padPin[i], OUTPUT); pinMode( ledPin[i], OUTPUT); } } //=== L O O P === void loop() { HandlePiezoSensors(); // Drum pads HandleDrumButtons(); // Drum pushbuttons HandleSelectInstrumentButtons(); // Select instrument buttons } void HandlePiezoSensors() { int threshold = analogRead( thresholdPin ); //-- Read Piezo sensors -- for (int i = 0; i < padCount; i++) { if ( analogRead( padPin[i] ) > threshold ) { digitalWrite( ledPin[i], HIGH ); Midi3(0x99, padInstruments[i], 0x45); // 9=Start, 9=Channel 10 where all the percussions are delayMicroseconds(2000); Midi3(0x89, padInstruments[i], 0); //8=stop, 9=Channel 10 digitalWrite( ledPin[i], LOW ); lastPadHit = i; } } } void HandleDrumButtons() { //-- Read buttons (first two buttons are used to assign instruments, so not included here) -- for (int i = 2; i < btnCount; i++) { int curSound = buttonInstruments[i]; int value = digitalRead( btnPin[i] ); if (value != btnOldValue[i] ) { btnOldValue[i] = value; if (value == LOW) { Midi3(0x99, curSound, 0x7F); } else Midi3(0x89, curSound, 0x00); lastPadHit = 100+i; } } } void HandleSelectInstrumentButtons() { bool isIncrement = digitalRead(incrementBtnPin) == LOW; bool isDecrement = digitalRead(decrementBtnPin) == LOW; if ( isIncrement || isDecrement ) { int curSound; if (lastPadHit >= 100) curSound = buttonInstruments[ lastPadHit-100 ]; else curSound = padInstruments[ lastPadHit ]; if (isIncrement) curSound++; if (isDecrement) curSound--; if (curSound < 24) curSound = 24; if (curSound > 84) curSound = 84; Midi3(0x99, curSound, 0x7F); delay(500); Midi3(0x89, curSound, 0x00); if (lastPadHit >= 100) buttonInstruments[ lastPadHit-100 ] = curSound; else padInstruments[ lastPadHit ] = curSound; } } void Midi2(byte cmd, byte data1) { Serial.print(cmd, BYTE); Serial.print(data1, BYTE); } void Midi3(byte cmd, byte data1, byte data2) { Serial.print(cmd, BYTE); Serial.print(data1, BYTE); Serial.print(data2, BYTE); }