Last active
January 26, 2024 18:46
-
-
Save stanleyondrus/db620dafb3cd214b2cc9a4b650b07ff5 to your computer and use it in GitHub Desktop.
Custom code for ArduinoMidiDrums - 10 drum pads, no hi-hat pedal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ***************************************************************************************************************** | |
// * * | |
// * 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