From 34968af713f7901f21f9e15e66b5713e5ad9c23d Mon Sep 17 00:00:00 2001 From: Steve Gilissen Date: Sat, 14 Jun 2025 03:10:02 +0200 Subject: [PATCH] Save MIDI channel to EPROM, add EPROM save indicator --- purrChestrion-arduino/gfx.h | 10 +++ .../purrChestrion-arduino.ino | 73 ++++++++++++++---- purrChestrion-arduino/savetorom.bmp | Bin 0 -> 1462 bytes .../~purrChestrion-board.kicad_sch.lck | 1 + 4 files changed, 70 insertions(+), 14 deletions(-) create mode 100644 purrChestrion-arduino/savetorom.bmp create mode 100644 purrChestrion-board/purrChestrion-board/~purrChestrion-board.kicad_sch.lck diff --git a/purrChestrion-arduino/gfx.h b/purrChestrion-arduino/gfx.h index 00cd300..0b8cbbd 100644 --- a/purrChestrion-arduino/gfx.h +++ b/purrChestrion-arduino/gfx.h @@ -53,4 +53,14 @@ const unsigned char midich [] PROGMEM = { 0x78, 0xf1, 0xe3, 0xc7, 0xff, 0xf1, 0xe0, 0x60, 0x18, 0x60, 0x78, 0xf1, 0xe3, 0xc7, 0xff, 0xf1, 0xe0, 0x7f, 0x98, 0x66, 0x78, 0xf1, 0xe3, 0xc7, 0xff, 0xe1, 0xe0, 0x3f, 0x98, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + + +// 'savetorom', 32x12px +#define SAVETOROM_WIDTH 32 +#define SAVETOROM_HEIGHT 12 +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 }; \ No newline at end of file diff --git a/purrChestrion-arduino/purrChestrion-arduino.ino b/purrChestrion-arduino/purrChestrion-arduino.ino index 7f33b54..cd0f504 100644 --- a/purrChestrion-arduino/purrChestrion-arduino.ino +++ b/purrChestrion-arduino/purrChestrion-arduino.ino @@ -1,8 +1,10 @@ #define FW_VER 1.0 #define USE_OLED true // OLED displays #define USE_ENCODER true +#define EEPROM_MIDI_CHANNEL_ADDR 0 // Address to save MIDI channel in EEPROM // include libraries +#include #include #include @@ -23,22 +25,24 @@ int lastClk = HIGH; #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 + // Instantiate libraries Adafruit_MCP23X17 mcp1; // First MCP23017 Adafruit_MCP23X17 mcp2; // Second MCP23017 // Default hardware MIDI. SoftwareSerial is too slow... MIDI_CREATE_DEFAULT_INSTANCE(); -// A7 A6 A5 A4 A3 A2 A1 A0 <-- GPIO A -// MCP pins 28 27 26 25 24 23 22 21 20 19 18 17 16 15 -// 8 = pin 1 ╔══════════════════════════════════════════╗ -// 9 = pin 2 ╠ MCP23017 ║ -// 10 = pin 3 ╚══════════════════════════════════════════╝ -// 01 02 03 04 05 06 07 08 9 10 11 12 13 14 -// B0 B1 B2 B3 B4 B5 B6 B7 <-- GPIO B // Default MIDI channel byte currentMidiChannel = MIDI_CHANNEL_OMNI; //8; // Default MIDI channel +byte savedChannel = EEPROM.read(EEPROM_MIDI_CHANNEL_ADDR); // Struct for 2 MCP chips. struct MCPOutput { @@ -95,7 +99,7 @@ MCPOutput noteToMCP[32] = { void updateOLED() { #if USE_OLED oled.clearDisplay(); - oled.drawBitmap(0, 13, midich, MIDICH_WIDTH, MIDICH_HEIGHT, 1); + oled.drawBitmap(0, 12, midich, MIDICH_WIDTH, MIDICH_HEIGHT, 1); oled.setCursor(86, 32); oled.setTextColor(SSD1306_WHITE); if (currentMidiChannel == MIDI_CHANNEL_OMNI) { @@ -103,6 +107,11 @@ void updateOLED() { } else { oled.print(currentMidiChannel); } + + if (showSavedMessage) { + oled.drawBitmap(88, 0, savetorom, SAVETOROM_WIDTH, SAVETOROM_HEIGHT, 1); + } + oled.display(); #endif } @@ -111,23 +120,39 @@ void checkEncoder() { #if USE_ENCODER int newClk = digitalRead(ENCODER_CLK); if (newClk != lastClk && newClk == LOW) { + int newChannel = currentMidiChannel; + if (digitalRead(ENCODER_DT) == LOW) { - currentMidiChannel++; + newChannel++; } else { - currentMidiChannel--; + newChannel--; } - // Wraparound: OMNI = 0, channels 1–16 - if (currentMidiChannel > 16) currentMidiChannel = 0; - if (currentMidiChannel < 0) currentMidiChannel = 16; + if (newChannel > 16) newChannel = 0; + if (newChannel < 0) newChannel = 16; - updateOLED(); + if (newChannel != currentMidiChannel) { + currentMidiChannel = newChannel; + updateOLED(); + + // Mark that channel changed and restart delay timer + lastChannelChangeTime = millis(); + channelChanged = true; + } } lastClk = newClk; #endif } + void setup() { + // Validate saved midi channel in EEPROM + if (savedChannel <= 16) { + currentMidiChannel = savedChannel; + } else { + currentMidiChannel = MIDI_CHANNEL_OMNI; + } + #if USE_OLED if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // I2C addr 0x3C // Don't halt if missing, just skip display @@ -174,6 +199,26 @@ void loop() { #if USE_ENCODER checkEncoder(); #endif + + // Save channel if change timeout has passed + if (channelChanged && (millis() - lastChannelChangeTime >= saveDelay)) { + EEPROM.update(EEPROM_MIDI_CHANNEL_ADDR, currentMidiChannel); + channelChanged = false; + + // Show "Saved" message + showSavedMessage = true; + savedMessageStart = millis(); + #if USE_OLED + updateOLED(); + #endif + } + + if (showSavedMessage && (millis() - savedMessageStart >= savedMessageDuration)) { + showSavedMessage = false; + #if USE_OLED + updateOLED(); // Return to normal channel display + #endif + } // LED feedback if (ledActive && millis() - ledOnTime >= ledDuration) { diff --git a/purrChestrion-arduino/savetorom.bmp b/purrChestrion-arduino/savetorom.bmp new file mode 100644 index 0000000000000000000000000000000000000000..03f56521d7625c557fddbcb02f313abf743af860 GIT binary patch literal 1462 zcmZ?r-NwoQ24*Y_3>rX|0ub{6F(U&9kYr$JU}Rtr;)YlXOcazDY&2XM3@y_b zti$>l)C%u2q%F9~FzfI;2D4AU83LZpWH8v5#gI3}oIyX+n?c1ph{4jvh@r&Zo}nqh zfZ<_YG{gVd$qY}<#xwl6eVXC_|Njiz*Un~WuWMn*%F1L23X5duaw=mmGFros9Db8w zSM_xUuj%~^2KikO2aJ-VAut*O10MpS4CoNWO`@0pCNBzNh=NI&5Lg7p0ZZYP2kHgN zgCG>aSuk6{@?dGODwtZBG*A$tADKkh4>cc1fei+$2C*Q3p!-0|@VFmr3fv_K2E=q2 KiR>~6n*ji2);jF~ literal 0 HcmV?d00001 diff --git a/purrChestrion-board/purrChestrion-board/~purrChestrion-board.kicad_sch.lck b/purrChestrion-board/purrChestrion-board/~purrChestrion-board.kicad_sch.lck new file mode 100644 index 0000000..e9832ab --- /dev/null +++ b/purrChestrion-board/purrChestrion-board/~purrChestrion-board.kicad_sch.lck @@ -0,0 +1 @@ +{"hostname":"Aletheia","username":"sgilissen"} \ No newline at end of file