Add MIDI panic function
This commit is contained in:
@@ -63,4 +63,13 @@ const unsigned char savetorom [] PROGMEM = {
|
||||
0x00, 0x05, 0x55, 0x54, 0x00, 0x0f, 0xff, 0xfe, 0x01, 0x0c, 0x00, 0x02, 0x01, 0x8c, 0x00, 0x02,
|
||||
0x01, 0xcd, 0x89, 0xb2, 0xbf, 0xed, 0x55, 0x54, 0x5f, 0xed, 0x95, 0x14, 0x01, 0xcd, 0x49, 0x12,
|
||||
0x01, 0x8c, 0x00, 0x02, 0x01, 0x0c, 0x00, 0x02, 0x00, 0x0f, 0xff, 0xfe, 0x00, 0x05, 0x55, 0x54
|
||||
};
|
||||
|
||||
// 'panic', 32x12px
|
||||
#define ICONPANIC_WIDTH 32
|
||||
#define ICONPANIC_HEIGHT 12
|
||||
const unsigned char iconpanic [] PROGMEM = {
|
||||
0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x01, 0x8e, 0x38, 0xc9, 0x4d, 0x91, 0x25, 0x29, 0x51,
|
||||
0xa4, 0xa5, 0x2d, 0x51, 0xa4, 0xb9, 0xed, 0x51, 0xa0, 0xa1, 0x2b, 0x51, 0xa4, 0xa1, 0x2b, 0x51,
|
||||
0x91, 0x21, 0x29, 0x51, 0x8e, 0x21, 0x29, 0x4d, 0x80, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff
|
||||
};
|
||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
@@ -1,6 +1,7 @@
|
||||
#define FW_VER 1.01
|
||||
#define FW_VER 1.02
|
||||
#define USE_OLED true // OLED displays
|
||||
#define USE_ENCODER true
|
||||
#define USE_PANIC true
|
||||
#define EEPROM_MIDI_CHANNEL_ADDR 0 // Address to save MIDI channel in EEPROM
|
||||
|
||||
// include libraries
|
||||
@@ -25,13 +26,18 @@
|
||||
int lastClk = HIGH;
|
||||
#endif
|
||||
|
||||
#if USE_PANIC
|
||||
#define PANIC_BUTTON 4
|
||||
bool midiPanic = false;
|
||||
#endif
|
||||
|
||||
unsigned long lastChannelChangeTime = 0;
|
||||
bool channelChanged = false;
|
||||
const unsigned long saveDelay = 2000; // 2 seconds
|
||||
|
||||
bool showSavedMessage = false;
|
||||
unsigned long savedMessageStart = 0;
|
||||
const unsigned long savedMessageDuration = 3000; // 1 second
|
||||
const unsigned long savedMessageDuration = 3000; // 3 seconds
|
||||
|
||||
// Instantiate libraries
|
||||
Adafruit_MCP23X17 mcp1; // First MCP23017
|
||||
@@ -112,6 +118,12 @@ void updateOLED() {
|
||||
oled.drawBitmap(88, 0, savetorom, SAVETOROM_WIDTH, SAVETOROM_HEIGHT, 1);
|
||||
}
|
||||
|
||||
#if USE_PANIC
|
||||
if (midiPanic) {
|
||||
oled.drawBitmap(1, 0, iconpanic, ICONPANIC_WIDTH, ICONPANIC_HEIGHT, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
oled.display();
|
||||
#endif
|
||||
}
|
||||
@@ -148,6 +160,84 @@ void checkEncoder() {
|
||||
}
|
||||
|
||||
|
||||
void handleNoteOn(byte channel, byte pitch, byte velocity) {
|
||||
#if USE_PANIC
|
||||
if (midiPanic) return; // suppress all notes during panic
|
||||
#endif
|
||||
|
||||
if (currentMidiChannel == MIDI_CHANNEL_OMNI || channel == currentMidiChannel) {
|
||||
|
||||
if (pitch >= 57 && pitch <= 88) {
|
||||
MCPOutput out = noteToMCP[pitch - 57];
|
||||
if (out.chip == 0) {
|
||||
mcp1.digitalWrite(out.pin, HIGH);
|
||||
} else if (out.chip == 1) {
|
||||
mcp2.digitalWrite(out.pin, HIGH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flash LED on Note On
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
ledOnTime = millis();
|
||||
ledActive = true;
|
||||
}
|
||||
|
||||
void handleNoteOff(byte channel, byte pitch, byte velocity) {
|
||||
#if USE_PANIC
|
||||
if (midiPanic) return; // suppress all notes during panic
|
||||
#endif
|
||||
|
||||
if (currentMidiChannel == MIDI_CHANNEL_OMNI || channel == currentMidiChannel) {
|
||||
if (pitch >= 57 && pitch <= 88) {
|
||||
MCPOutput out = noteToMCP[pitch - 57];
|
||||
if (out.chip == 0) {
|
||||
mcp1.digitalWrite(out.pin, LOW);
|
||||
} else if (out.chip == 1) {
|
||||
mcp2.digitalWrite(out.pin, LOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void checkMidiPanic() {
|
||||
#if USE_PANIC
|
||||
static bool lastButtonState = HIGH;
|
||||
static unsigned long lastToggleTime = 0;
|
||||
const unsigned long debounceDelay = 50;
|
||||
|
||||
bool currentButtonState = digitalRead(PANIC_BUTTON);
|
||||
|
||||
if (lastButtonState == HIGH && currentButtonState == LOW) {
|
||||
unsigned long now = millis();
|
||||
if (now - lastToggleTime > debounceDelay) {
|
||||
midiPanic = !midiPanic;
|
||||
lastToggleTime = now;
|
||||
|
||||
if (midiPanic) {
|
||||
// Turn off all notes immediately
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if (noteToMCP[i].chip == 0) {
|
||||
mcp1.digitalWrite(noteToMCP[i].pin, LOW);
|
||||
} else {
|
||||
mcp2.digitalWrite(noteToMCP[i].pin, LOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_OLED
|
||||
updateOLED(); // Only update display when state changes
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
lastButtonState = currentButtonState;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void setup() {
|
||||
// Validate saved midi channel in EEPROM
|
||||
if (savedChannel <= 16) {
|
||||
@@ -175,6 +265,10 @@ void setup() {
|
||||
pinMode(ENCODER_CLK, INPUT_PULLUP);
|
||||
pinMode(ENCODER_DT, INPUT_PULLUP);
|
||||
#endif
|
||||
|
||||
#if USE_PANIC
|
||||
pinMode(PANIC_BUTTON, INPUT_PULLUP);
|
||||
#endif
|
||||
// Midi Activity LED on Pin 13 (aka LED_BUILTIN)
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
|
||||
@@ -196,12 +290,18 @@ void setup() {
|
||||
updateOLED();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void loop() {
|
||||
MIDI.read();
|
||||
|
||||
#if USE_ENCODER
|
||||
checkEncoder();
|
||||
#endif
|
||||
|
||||
#if USE_PANIC
|
||||
checkMidiPanic();
|
||||
#endif
|
||||
|
||||
// Save channel if change timeout has passed
|
||||
if (channelChanged && (millis() - lastChannelChangeTime >= saveDelay)) {
|
||||
@@ -228,37 +328,4 @@ void loop() {
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
ledActive = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void handleNoteOn(byte channel, byte pitch, byte velocity) {
|
||||
if (currentMidiChannel == MIDI_CHANNEL_OMNI || channel == currentMidiChannel) {
|
||||
|
||||
if (pitch >= 57 && pitch <= 88) {
|
||||
MCPOutput out = noteToMCP[pitch - 57];
|
||||
if (out.chip == 0) {
|
||||
mcp1.digitalWrite(out.pin, HIGH);
|
||||
} else if (out.chip == 1) {
|
||||
mcp2.digitalWrite(out.pin, HIGH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flash LED on Note On
|
||||
digitalWrite(LED_BUILTIN, HIGH);
|
||||
ledOnTime = millis();
|
||||
ledActive = true;
|
||||
}
|
||||
|
||||
void handleNoteOff(byte channel, byte pitch, byte velocity) {
|
||||
if (currentMidiChannel == MIDI_CHANNEL_OMNI || channel == currentMidiChannel) {
|
||||
if (pitch >= 57 && pitch <= 88) {
|
||||
MCPOutput out = noteToMCP[pitch - 57];
|
||||
if (out.chip == 0) {
|
||||
mcp1.digitalWrite(out.pin, LOW);
|
||||
} else if (out.chip == 1) {
|
||||
mcp2.digitalWrite(out.pin, LOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user