#include <MIDI.h>
#include <EEPROM.h>
MIDI_CREATE_DEFAULT_INSTANCE();
const int learnButtonPin = 2;
const int learnLedPin = 3;
const int trigPins[4] = {4, 5, 6, 7};
const int ledPins[4] = {8, 9, 10, 11};
int learnedNotes[4];
bool learning = false;
int learnedCount = 0;
unsigned long lastTriggerTime[4];
const unsigned long triggerLength = 20; // milliseconds
void setup() {
pinMode(learnButtonPin, INPUT_PULLUP);
pinMode(learnLedPin, OUTPUT);
for (int i = 0; i < 4; i++) {
pinMode(trigPins\[i\], OUTPUT);
pinMode(ledPins\[i\], OUTPUT);
digitalWrite(trigPins\[i\], LOW);
digitalWrite(ledPins\[i\], LOW);
learnedNotes\[i\] = EEPROM.read(i);
}
MIDI.begin(MIDI_CHANNEL_OMNI);
MIDI.setHandleNoteOn(handleNoteOn);
MIDI.setHandleNoteOff(handleNoteOff);
}
void loop() {
MIDI.read();
// Handle Learn button
static bool lastButtonState = HIGH;
bool buttonState = digitalRead(learnButtonPin);
if (lastButtonState == HIGH && buttonState == LOW) {
startLearning();
}
lastButtonState = buttonState;
// Flash LED while learning
if (learning) {
static unsigned long lastBlink = 0;
static bool ledState = false;
if (millis() - lastBlink > 300) {
ledState = !ledState;
digitalWrite(learnLedPin, ledState);
lastBlink = millis();
}
}
// Auto reset outputs after trigger length
unsigned long now = millis();
for (int i = 0; i < 4; i++) {
if (digitalRead(trigPins\[i\]) && now - lastTriggerTime\[i\] > triggerLength) {
digitalWrite(trigPins\[i\], LOW);
digitalWrite(ledPins\[i\], LOW);
}
}
}
void handleNoteOn(byte channel, byte note, byte velocity) {
if (learning) {
learnedNotes\[learnedCount++\] = note;
EEPROM.write(learnedCount - 1, note);
if (learnedCount >= 4) stopLearning();
} else {
for (int i = 0; i < 4; i++) {
if (note == learnedNotes\[i\]) {
triggerOutput(i);
}
}
}
}
void handleNoteOff(byte channel, byte note, byte velocity) {
// Optional: could make trigger last for note duration instead of fixed time
}
void startLearning() {
learning = true;
learnedCount = 0;
digitalWrite(learnLedPin, HIGH);
}
void stopLearning() {
learning = false;
digitalWrite(learnLedPin, LOW);
}
void triggerOutput(int index) {
digitalWrite(trigPins[index], HIGH);
digitalWrite(ledPins[index], HIGH);
lastTriggerTime[index] = millis();
}