Created
May 3, 2020 15:35
-
-
Save giuliom95/658421483a4a572629fe4079efdfdc3f to your computer and use it in GitHub Desktop.
MIDI pedal on Arduino Micro
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
#include <EEPROM.h> | |
#include "MIDIUSB.h" | |
#define MIDI_NOTEON 0x90 | |
#define MIDI_NOTEOFF 0x80 | |
#define MIDI_CC 0xB0 | |
#define MIDI_SUSTAIN 64 | |
#define MIDI_GM_BASSDRUM 36 | |
#define MIDI_BASE_VELOCITY 64 | |
#define PEDAL_PIN 2 | |
#define LED_PIN 13 | |
/* | |
* EEPROM[0] holds the mode setting of the device. | |
* | |
* EEPROM[0] = s000cccc | |
* | |
* s If 1 the pedal will be a sustain pedal. | |
* If 0 will send a MIDI_GM_BASSDRUM note. | |
* | |
* cccc The MIDI channel to send messages to. | |
*/ | |
// Enables EEPROM writing on startup when grounded | |
#define EEPROM_WRITE_PIN A0 | |
// Modifies the `s` bit of EEPROM[0] | |
#define EEPROM_S_PIN A1 | |
// Modify the `cccc` bits of EEPROM[0] | |
#define EEPROM_C0_PIN A2 | |
#define EEPROM_C1_PIN A3 | |
#define EEPROM_C2_PIN A4 | |
#define EEPROM_C3_PIN A5 | |
bool pedalWasPressed = false; | |
byte midi_down_message[3]; | |
byte midi_up_message[3]; | |
void setup() { | |
// Handle EEPROM reading and writing | |
pinMode(EEPROM_WRITE_PIN, INPUT_PULLUP); | |
if(!digitalRead(EEPROM_WRITE_PIN)) { | |
// EEPROM has to be updated | |
pinMode(EEPROM_S_PIN, INPUT_PULLUP); | |
pinMode(EEPROM_C0_PIN, INPUT_PULLUP); | |
pinMode(EEPROM_C1_PIN, INPUT_PULLUP); | |
pinMode(EEPROM_C2_PIN, INPUT_PULLUP); | |
pinMode(EEPROM_C3_PIN, INPUT_PULLUP); | |
byte new_setting = 0; | |
new_setting |= !digitalRead(EEPROM_S_PIN) << 7; | |
new_setting |= !digitalRead(EEPROM_C0_PIN) << 3; | |
new_setting |= !digitalRead(EEPROM_C1_PIN) << 2; | |
new_setting |= !digitalRead(EEPROM_C2_PIN) << 1; | |
new_setting |= !digitalRead(EEPROM_C3_PIN) << 0; | |
EEPROM.update(0, new_setting); | |
// Visual feedback on EEPROM writing | |
for(byte i = 0; i < 10; ++i) { | |
delay(100); | |
digitalWrite(LED_PIN, HIGH); | |
delay(100); | |
digitalWrite(LED_PIN, LOW); | |
} | |
} | |
byte setting = EEPROM[0]; | |
// MIDI channel | |
byte channel = setting & 0x0F; | |
if(setting & 0x80) { | |
// Pedal in sustain mode | |
midi_down_message[0] = MIDI_CC | channel; | |
midi_down_message[1] = MIDI_SUSTAIN; | |
midi_down_message[2] = 127; | |
midi_up_message[0] = MIDI_CC | channel; | |
midi_up_message[1] = MIDI_SUSTAIN; | |
midi_up_message[2] = 0; | |
} else { | |
// Pedal in bass drum mode | |
midi_down_message[0] = MIDI_NOTEON | channel; | |
midi_down_message[1] = MIDI_GM_BASSDRUM; | |
midi_down_message[2] = MIDI_BASE_VELOCITY; | |
midi_up_message[0] = MIDI_NOTEOFF | channel; | |
midi_up_message[1] = MIDI_GM_BASSDRUM; | |
midi_up_message[2] = 0; | |
} | |
pinMode(PEDAL_PIN, INPUT_PULLUP); | |
} | |
void loop() { | |
bool pedalIsPressed = digitalRead(PEDAL_PIN) == HIGH; | |
if(pedalIsPressed && !pedalWasPressed) { | |
// Pedal was not pressed and has been pressed | |
// A little randomization makes the bass drum sound more natural | |
int randomvel = (midi_down_message[0] & 0xF0) == MIDI_NOTEON ? random(-10, 10) : 0; | |
MidiUSB.sendMIDI({ | |
midi_down_message[0] >> 4, | |
midi_down_message[0], | |
midi_down_message[1], | |
midi_down_message[2] + randomvel | |
}); | |
MidiUSB.flush(); | |
delay(20); | |
} | |
if(!pedalIsPressed && pedalWasPressed) { | |
// Pedal was pressed and has been released | |
MidiUSB.sendMIDI({ | |
midi_up_message[0] >> 4, | |
midi_up_message[0], | |
midi_up_message[1], | |
midi_up_message[2] | |
}); | |
MidiUSB.flush(); | |
delay(20); | |
} | |
pedalWasPressed = pedalIsPressed; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment