Menu with button support to switch wave tables
This commit is contained in:
+121
-34
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user