101 lines
2.5 KiB
C++
101 lines
2.5 KiB
C++
#include "UIThread.h"
|
|
#include "SharedState.h"
|
|
#include <Arduino.h>
|
|
#include <Wire.h>
|
|
#include <Adafruit_GFX.h>
|
|
#include <Adafruit_SSD1306.h>
|
|
|
|
#define SCREEN_WIDTH 128
|
|
#define SCREEN_HEIGHT 64
|
|
#define OLED_RESET -1
|
|
#define SCREEN_ADDRESS 0x3C
|
|
|
|
// I2C Pins (GP4/GP5)
|
|
#define PIN_SDA 4
|
|
#define PIN_SCL 5
|
|
|
|
// Encoder Pins
|
|
#define PIN_ENC_CLK 12
|
|
#define PIN_ENC_DT 13
|
|
|
|
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
|
|
|
volatile int8_t encoderDelta = 0;
|
|
static uint8_t prevNextCode = 0;
|
|
static uint16_t store = 0;
|
|
|
|
// --- ENCODER INTERRUPT ---
|
|
// Robust Rotary Encoder reading
|
|
void readEncoder() {
|
|
static int8_t rot_enc_table[] = {0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0};
|
|
|
|
prevNextCode <<= 2;
|
|
if (digitalRead(PIN_ENC_DT)) prevNextCode |= 0x02;
|
|
if (digitalRead(PIN_ENC_CLK)) prevNextCode |= 0x01;
|
|
prevNextCode &= 0x0f;
|
|
|
|
// If valid state
|
|
if (rot_enc_table[prevNextCode]) {
|
|
store <<= 4;
|
|
store |= prevNextCode;
|
|
if ((store & 0xff) == 0x2b) encoderDelta--;
|
|
if ((store & 0xff) == 0x17) encoderDelta++;
|
|
}
|
|
}
|
|
|
|
void setupUI() {
|
|
Wire.setSDA(PIN_SDA);
|
|
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);
|
|
|
|
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
|
|
Serial.println(F("SSD1306 allocation failed"));
|
|
for(;;);
|
|
}
|
|
|
|
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();
|
|
|
|
if (rotation != 0) {
|
|
currentScaleIndex += rotation;
|
|
while (currentScaleIndex < 0) currentScaleIndex += NUM_SCALES;
|
|
while (currentScaleIndex >= NUM_SCALES) currentScaleIndex -= NUM_SCALES;
|
|
}
|
|
}
|
|
|
|
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();
|
|
} |