Skip to content

Instantly share code, notes, and snippets.

@stanleyondrus
Last active January 26, 2024 18:46
Show Gist options
  • Save stanleyondrus/db620dafb3cd214b2cc9a4b650b07ff5 to your computer and use it in GitHub Desktop.
Save stanleyondrus/db620dafb3cd214b2cc9a4b650b07ff5 to your computer and use it in GitHub Desktop.
Custom code for ArduinoMidiDrums - 10 drum pads, no hi-hat pedal
// *****************************************************************************************************************
// * *
// * Arduino MIDI Drums *
// * 2017 (c) StanleyProjects.com *
// * *
// * Custom code - no hi-hat pedal, 10 drum pads *
// *****************************************************************************************************************
#define NUMBER_OF_PADS 10 // number of drum pads (analog inputs)
#define VELOCITY_ACTIVE 1 // velocity sensitive ON-OFF [1-0]
#define MIDI_CHANNEL 1 // MIDI channel [1-16]
#define MIDI_MAX_VELOCITY 127
#define MIDI_NOTE_ON 0b1001 // MS nibble for note on status message
#define MIDI_NOTE_OFF 0b1000 // MS nibble for note off status message
uint8_t padNote[NUMBER_OF_PADS] = {60, 62, 64, 65, 67, 69, 71, 72, 74, 76}; // MIDI notes [0-127]
uint8_t padThreshold[NUMBER_OF_PADS] = {400, 400, 400, 400, 400, 400, 400, 400, 400, 400}; // trigger treshold values [0-1023]
uint8_t padCycles[NUMBER_OF_PADS] = {90, 90, 90, 90, 90, 90, 90, 90, 90, 90}; // number of cycles before the second trigger is allowed
uint8_t activePad; // each bit represents a pad state
uint8_t padCurrentCycles[NUMBER_OF_PADS]; // number of cycles since the pad was triggered
void setup() {
Serial.begin(115200); // initialize the serial port at baud rate 115200
}
void loop() {
for (uint8_t pin = 0; pin < NUMBER_OF_PADS; pin++) { // loop through all of the pads
uint8_t val = analogRead(pin); // read the input pin
if ((val > padThreshold[pin]) && (!padActive(pin))) { // if hit strong enough
val = VELOCITY_ACTIVE ? velocityAlgorithm(val) : MIDI_MAX_VELOCITY; // if velocity sensitive, calculate the new value, otherwise apply the maximum value
midi_tx_note_on(padNote[pin], val); // send a note on MIDI message
padCurrentCycles[pin] = 0; // reset the current pad cycle counter
activePad |= 1 << pin; // set corresponding bit (active flag)
}
if (padActive(pin)) { // enter if pad is active
padCurrentCycles[pin] += 1; // increment the cycle counter by 1
if (padCurrentCycles[pin] >= padCycles[pin]) { // enter if cycle counter reached the desired number of cycles
midi_tx_note_off(padNote[pin]); // send a note off MIDI message
activePad &= ~(1 << pin); // clear corresponding bit (active flag)
}
}
}
}
uint8_t velocityAlgorithm(uint8_t val) {
return (val - 0) * (127 - 0) / (1023 - 0) + 0; // remap the val from [0-1023] to [0-127]
}
uint8_t padActive(uint8_t currentPin) { // check if current pad active
return (activePad >> currentPin) & 1;
}
void midi_tx_note_on(uint8_t pitch, uint8_t velocity) { // send note on MIDI message
Serial.write((MIDI_NOTE_ON << 4) | (MIDI_CHANNEL - 1));
Serial.write(pitch);
Serial.write(velocity);
}
void midi_tx_note_off(uint8_t pitch) { // send note off MIDI message
Serial.write((MIDI_NOTE_OFF << 4) | (MIDI_CHANNEL - 1));
Serial.write(pitch);
Serial.write(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment