Skip to content

Instantly share code, notes, and snippets.

@giuliom95
Created May 3, 2020 15:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save giuliom95/658421483a4a572629fe4079efdfdc3f to your computer and use it in GitHub Desktop.
Save giuliom95/658421483a4a572629fe4079efdfdc3f to your computer and use it in GitHub Desktop.
MIDI pedal on Arduino Micro
#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