I'm starting to wonder. Couldn't it simply be that I'm losing some values because the Arduino has some code to execute in between two readings? I wonder if it'd be more sensitive to capture 10 values for each reading and only keep the max?
Here is the code (courtesy of SpikenzieLabs):
unsigned char PadNote[6] = {38,49,43,63,40,65}; // MIDI notes from 0 to 127, see values below
unsigned char DPadNote[6] = {36,22,43,63,40,65}; // MIDI notes from 0 to 127, see values below (for digital inputs)
// For SuperDrum FX:
// 22 = closed hi hat
// 26 = Cymbal
// 36 = bass kick
// 38 = snare 1
// 40 = snare 2 or rim shot
// 41 = bass tom
// 42 = closed hi hat
// 43 = mid tom
// 44 = underfoot hi hat
// 45 = mid high tom
// 46 = open hi hat
// 48 = high tom
// 49 = cymbal 1
// 51 = ride bell
// 52 = cymbal 2
// 53 = ride rim
// 55 = cymbal 1
// 57 = cymbal 2
int PadCutOff[6] = {100,100,100,100,100,100}; // Minimum Analog value to cause a drum hit, careful, will pick up neighboring drums if set too low, 400 is fine
int MaxPlayTime[6] = {90,90,90,90,90,90}; // Cycles before a 2nd hit is allowed
int DMaxPlayTime[6] = {500,500,500,500,500,500}; // Cycles before a 2nd hit is allowed
#define midichannel 0; // MIDI channel from 0 to 15 (+1 in "real world")
boolean VelocityFlag = true; // Velocity ON (true) or OFF (false)
//*******************************************************************************************************************
// Internal Use Variables
//*******************************************************************************************************************
boolean activePad[6] = {0,0,0,0,0,0}; // Array of flags of pad currently playing (analog pins)
int PinPlayTime[6] = {0,0,0,0,0,0}; // Counter since pad started to play (analog pins)
boolean DactivePad[6] = {0,0,0,0,0,0}; // Array of flags of pad currently playing (digital pins)
int DPinPlayTime[6] = {0,0,0,0,0,0}; // Counter since pad started to play (digital pins)
unsigned char status;
int pin = 0;
int hit = 0;
float hit_avg = 0.;
boolean hitdetect = false;
//*******************************************************************************************************************
// Setup
//*******************************************************************************************************************
void setup()
{
Serial.begin(31250); // connect to the serial port 31250
}
//*******************************************************************************************************************
// Main Program
//*******************************************************************************************************************
void loop()
{
for(int pin=0; pin < 3; pin++) // ANALOG INPUTS LOOP - adjust how many analog inputs are read
{
hit = analogRead(pin); // read the input pin
if((hit > PadCutOff[pin]))
{
if((activePad[pin] == false))
{
if(VelocityFlag == true)
{
hit = 127 / ((1023 - PadCutOff[pin]) / (hit - PadCutOff[pin])); // With full range (Too sensitive ?)
// hit = (hit / 8) -1 ; // Upper range
}
else
{
hit = 127;
}
MIDI_TX(144,PadNote[pin],hit);
PinPlayTime[pin] = 0;
activePad[pin] = true;
}
else
{
PinPlayTime[pin] = PinPlayTime[pin] + 1;
}
}
else if((activePad[pin] == true))
{
PinPlayTime[pin] = PinPlayTime[pin] + 1;
if(PinPlayTime[pin] > MaxPlayTime[pin])
{
activePad[pin] = false;
MIDI_TX(128,PadNote[pin],127);
}
}
}
// DIGITAL INPUTS LOOP - adjust how many digital inputs are read
for(int pin=8; pin < 9; pin++)
{
hitdetect = digitalRead(pin); // read the input pin
if((hitdetect == true))
{
if((DactivePad[pin-8] == false))
{
// Serial.println("Hit detected and pad was ready");
// Serial.println(hitdetect, BIN);
// Serial.println(DactivePad[pin-8], BIN);
hit = 127;
MIDI_TX(144,DPadNote[pin-8],hit);
// Serial.println("Play note and change pad to not ready");
DPinPlayTime[pin-8] = 0;
DactivePad[pin-8] = true;
}
else
{
// Serial.println("Hit detected and pad was not ready, increment timer");
DPinPlayTime[pin-8] = DPinPlayTime[pin-8] + 1;
}
}
else if((DactivePad[pin-8] == true))
// else if((hitdetect == false))
{
// Serial.println("Pad was not ready, increment timer");
DPinPlayTime[pin-8] = DPinPlayTime[pin-8] + 1;
if(DPinPlayTime[pin-8] > DMaxPlayTime[pin-8])
{
// Serial.println("Time exceeded, pad changed back to ready, send note OFF");
// Serial.println(hitdetect, BIN);
// Serial.println(DactivePad[pin-8], BIN);
DactivePad[pin-8] = false;
MIDI_TX(128,DPadNote[pin-8],127);
}
}
}
}
//*******************************************************************************************************************
// Transmit MIDI Message
//*******************************************************************************************************************
void MIDI_TX(unsigned char MESSAGE, unsigned char PITCH, unsigned char VELOCITY)
{
status = MESSAGE + midichannel;
Serial.print(status);
Serial.print(PITCH);
Serial.print(VELOCITY);
}