NoiceSynth/UIThread.cpp
2026-02-26 22:34:36 +01:00

90 lines
2.4 KiB
C++

#include "UIThread.h"
#include "SharedState.h"
#include <Wire.h>
// --- Local State ---
static int g_last_clk_state;
// --- Forward Declarations ---
static void readEncoder();
static void updateDisplay();
void setupUI() {
// --- Initialize I2C and Display ---
Wire.setSDA(OLED_SDA_PIN);
Wire.setSCL(OLED_SCL_PIN);
Wire.begin();
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Don't proceed, loop forever
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.println("NoiceSynth Booting...");
display.display();
delay(1000);
// --- Initialize Controls ---
pinMode(ENCODER_CLK_PIN, INPUT_PULLUP);
pinMode(ENCODER_DT_PIN, INPUT_PULLUP);
pinMode(ENCODER_SW_PIN, INPUT_PULLUP);
g_last_clk_state = digitalRead(ENCODER_CLK_PIN);
}
void loopUI() {
// Read the volume potentiometer (Pico ADC is 12-bit, 0-4095)
// We use a bit of filtering by averaging with the old value to reduce noise.
float new_volume = analogRead(VOL_POT_PIN) / 4095.0f;
g_volume = (g_volume * 0.95) + (new_volume * 0.05);
// Read the rotary encoder
readEncoder();
// Update the display periodically
static uint32_t last_display_update = 0;
if (millis() - last_display_update > 100) { // Update 10 times/sec
last_display_update = millis();
updateDisplay();
}
}
static void updateDisplay() {
display.clearDisplay();
display.setCursor(0, 0);
display.println(F(" NoiceSynth"));
display.println(F("--------------------"));
if (g_note_on) {
display.print(F("Note Freq: "));
display.print(g_note_frequency, 2);
display.println(F(" Hz"));
} else {
display.println(F("Note: Off"));
}
display.print(F("Volume: "));
display.print(static_cast<int>(g_volume * 100));
display.println(F("%"));
display.print(F("Encoder: "));
display.println(g_encoder_value);
display.display();
}
static void readEncoder() {
int new_clk_state = digitalRead(ENCODER_CLK_PIN);
// Check for a change on the CLK pin (a "tick" of the encoder)
if (new_clk_state != g_last_clk_state && new_clk_state == LOW) {
// Read the DT pin to determine direction
if (digitalRead(ENCODER_DT_PIN) == LOW) {
g_encoder_value++; // Clockwise
} else {
g_encoder_value--; // Counter-clockwise
}
}
g_last_clk_state = new_clk_state;
}