Menu with button support to switch wave tables

This commit is contained in:
Dejvino
2026-02-27 06:48:19 +01:00
parent 59b48c1ab3
commit 34d15a7f1c
4 changed files with 196 additions and 42 deletions
+121 -34
View File
@@ -17,6 +17,7 @@
// Encoder Pins
#define PIN_ENC_CLK 12
#define PIN_ENC_DT 13
#define PIN_ENC_SW 14
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
@@ -24,6 +25,15 @@ volatile int8_t encoderDelta = 0;
static uint8_t prevNextCode = 0;
static uint16_t store = 0;
// Button state
static int lastButtonReading = HIGH;
static int currentButtonState = HIGH;
static unsigned long lastDebounceTime = 0;
static bool buttonClick = false;
void handleInput();
void drawUI();
// --- ENCODER INTERRUPT ---
// Robust Rotary Encoder reading
void readEncoder() {
@@ -48,10 +58,11 @@ void setupUI() {
Wire.setSCL(PIN_SCL);
Wire.begin();
pinMode(PIN_ENC_CLK, INPUT_PULLUP);
pinMode(PIN_ENC_DT, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(PIN_ENC_CLK), readEncoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(PIN_ENC_DT), readEncoder, CHANGE);
pinMode(PIN_ENC_CLK, INPUT_PULLUP);
pinMode(PIN_ENC_DT, INPUT_PULLUP);
pinMode(PIN_ENC_SW, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(PIN_ENC_CLK), readEncoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(PIN_ENC_DT), readEncoder, CHANGE);
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
@@ -59,43 +70,119 @@ void setupUI() {
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(F("Lorem ipsum dolor sit amet, consectetur adipiscing elit."));
display.display();
}
void handleInput() {
// Handle Encoder Rotation
int rotation = 0;
noInterrupts();
rotation = encoderDelta;
encoderDelta = 0;
interrupts();
// Handle Encoder Rotation
int rotation = 0;
noInterrupts();
rotation = encoderDelta;
encoderDelta = 0;
interrupts();
if (rotation != 0) {
currentScaleIndex += rotation;
while (currentScaleIndex < 0) currentScaleIndex += NUM_SCALES;
while (currentScaleIndex >= NUM_SCALES) currentScaleIndex -= NUM_SCALES;
}
if (rotation != 0) {
switch (currentState) {
case UI_MENU:
menuSelection += rotation;
while (menuSelection < 0) menuSelection += NUM_MENU_ITEMS;
menuSelection %= NUM_MENU_ITEMS;
break;
case UI_EDIT_SCALE_TYPE:
currentScaleIndex += rotation;
while (currentScaleIndex < 0) currentScaleIndex += NUM_SCALES;
currentScaleIndex %= NUM_SCALES;
break;
case UI_EDIT_SCALE_KEY:
currentKeyIndex += rotation;
while (currentKeyIndex < 0) currentKeyIndex += NUM_KEYS;
currentKeyIndex %= NUM_KEYS;
break;
case UI_EDIT_WAVETABLE:
currentWavetableIndex += rotation;
while (currentWavetableIndex < 0) currentWavetableIndex += NUM_WAVETABLES;
currentWavetableIndex %= NUM_WAVETABLES;
break;
}
}
// Handle Button Click
int reading = digitalRead(PIN_ENC_SW);
if (reading != lastButtonReading) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > 50) {
if (reading != currentButtonState) {
currentButtonState = reading;
if (currentButtonState == LOW) {
buttonClick = true;
}
}
}
lastButtonReading = reading;
if (buttonClick) {
buttonClick = false;
if (currentState == UI_MENU) {
currentState = MENU_ITEMS[menuSelection].editState;
} else {
currentState = UI_MENU;
}
}
}
void drawUI() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
if (currentState == UI_MENU) {
for (int i = 0; i < NUM_MENU_ITEMS; i++) {
if (i == menuSelection) {
display.fillRect(0, i * 10, SCREEN_WIDTH, 10, SSD1306_WHITE);
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
} else {
display.setTextColor(SSD1306_WHITE);
}
display.setCursor(2, i * 10 + 1);
display.print(MENU_ITEMS[i].label);
display.print(": ");
// Display current value
switch (MENU_ITEMS[i].editState) {
case UI_EDIT_SCALE_TYPE: display.print(SCALES[currentScaleIndex].name); break;
case UI_EDIT_SCALE_KEY: display.print(KEY_NAMES[currentKeyIndex]); break;
case UI_EDIT_WAVETABLE: display.print(WAVETABLE_NAMES[currentWavetableIndex]); break;
default: break;
}
}
} else {
// In an edit screen
const char* title = MENU_ITEMS[menuSelection].label;
const char* value = "";
switch (currentState) {
case UI_EDIT_SCALE_TYPE: value = SCALES[currentScaleIndex].name; break;
case UI_EDIT_SCALE_KEY: value = KEY_NAMES[currentKeyIndex]; break;
case UI_EDIT_WAVETABLE: value = WAVETABLE_NAMES[currentWavetableIndex]; break;
default: break;
}
display.println(title);
display.drawLine(0, 10, SCREEN_WIDTH, 10, SSD1306_WHITE);
display.setCursor(10, 25);
display.setTextSize(2);
display.print(value);
display.setTextSize(1);
display.setCursor(0, 50);
display.println(F("(Press to confirm)"));
}
display.display();
}
void loopUI() {
// sleep to avoid thread starvation
delay(10);
handleInput();
// The loop on core 0 is responsible for updating the UI.
static unsigned long lastUpdate = 0;
if (millis() - lastUpdate < 100) return;
lastUpdate = millis();
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(1);
display.println(F("Current Scale:"));
display.setTextSize(2);
display.println(SCALES[currentScaleIndex].name);
display.display();
drawUI();
delay(20); // Prevent excessive screen refresh
}