From b5b19126c28a7153649a3b9aa4cc4543c66dec3e Mon Sep 17 00:00:00 2001 From: Cade Call Date: Sun, 2 Feb 2025 10:19:21 -0700 Subject: [PATCH 1/2] feat: make display rotation configurable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add OLED_ROTATION config option to Config.h - Update DisplayController to use configurable rotation - Add comments documenting rotation values (0°, 90°, 180°, 270°) This change allows easy adjustment of the display orientation without modifying the DisplayController code. --- firmware/include/Config.h | 1 + firmware/src/controllers/DisplayController.cpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/firmware/include/Config.h b/firmware/include/Config.h index fe0c348..aaa3622 100644 --- a/firmware/include/Config.h +++ b/firmware/include/Config.h @@ -6,6 +6,7 @@ #define OLED_WIDTH 128 #define OLED_HEIGHT 64 #define OLED_ADDR 0x3C +#define OLED_ROTATION 2 // 0 = 0°, 1 = 90°, 2 = 180°, 3 = 270° #define LED_PIN 15 #define NUM_LEDS 16 diff --git a/firmware/src/controllers/DisplayController.cpp b/firmware/src/controllers/DisplayController.cpp index 8dbe684..7d43b2e 100644 --- a/firmware/src/controllers/DisplayController.cpp +++ b/firmware/src/controllers/DisplayController.cpp @@ -1,4 +1,5 @@ #include "controllers/DisplayController.h" +#include "Config.h" #include "fonts/Picopixel.h" #include "fonts/Org_01.h" @@ -13,6 +14,9 @@ void DisplayController::begin() { for (;;); // Loop forever if initialization fails } + // Set display rotation from Config.h + oled.setRotation(OLED_ROTATION); + // oled.ssd1306_command(SSD1306_SETCONTRAST); // oled.ssd1306_command(128); From c1df0423836a2b44006b60d189c42a3dd3d9ac30 Mon Sep 17 00:00:00 2001 From: Cade Call Date: Mon, 3 Feb 2025 01:50:05 -0700 Subject: [PATCH 2/2] feat: add display rotation and encoder direction configuration - Add display rotation configuration in Config.h - Update DisplayController to use configured rotation - Add encoder direction configuration - Update InputController to handle reversed encoder direction - Update state handlers for new configurations --- .gitignore | 3 ++- firmware/include/Config.h | 21 ++++++++++++---- .../src/controllers/DisplayController.cpp | 13 ++++------ firmware/src/controllers/InputController.cpp | 24 +++++++++++++------ firmware/src/main.cpp | 4 ++++ firmware/src/states/AdjustState.cpp | 9 +++++-- firmware/src/states/ResetState.cpp | 21 ++++++++++++---- 7 files changed, 68 insertions(+), 27 deletions(-) diff --git a/.gitignore b/.gitignore index 2b16c31..0285387 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ .vscode/c_cpp_properties.json .vscode/launch.json .vscode/ipch -.DS_Store \ No newline at end of file +.DS_Store +.code-workspace diff --git a/firmware/include/Config.h b/firmware/include/Config.h index aaa3622..250ad06 100644 --- a/firmware/include/Config.h +++ b/firmware/include/Config.h @@ -6,15 +6,28 @@ #define OLED_WIDTH 128 #define OLED_HEIGHT 64 #define OLED_ADDR 0x3C -#define OLED_ROTATION 2 // 0 = 0°, 1 = 90°, 2 = 180°, 3 = 270° + +// --- Device Configuration --- +#define DEVICE_ORIENTATION 0 // 0 = Default, 1 = Rotated 180° + +// Configure settings based on orientation +#if DEVICE_ORIENTATION == 1 + #define OLED_ROTATION 2 // 180° rotation + #define ENCODER_A_PIN 25 // Swapped encoder pins + #define ENCODER_B_PIN 27 + #define ENCODER_REVERSE_VALUE true // Reverse encoder for timer adjustment +#else + #define OLED_ROTATION 0 // Normal orientation + #define ENCODER_A_PIN 27 // Normal encoder pins + #define ENCODER_B_PIN 25 + #define ENCODER_REVERSE_VALUE false // Normal encoder direction +#endif #define LED_PIN 15 #define NUM_LEDS 16 #define LED_BRIGHTNESS 100 -#define ENCODER_A_PIN 27 -#define ENCODER_B_PIN 25 -#define BUTTON_PIN 26 +#define BUTTON_PIN 26 // A0 on QT Py ESP32 // --- LED Colors --- #define BLUE 0x0000FF diff --git a/firmware/src/controllers/DisplayController.cpp b/firmware/src/controllers/DisplayController.cpp index 7d43b2e..74e0b30 100644 --- a/firmware/src/controllers/DisplayController.cpp +++ b/firmware/src/controllers/DisplayController.cpp @@ -9,20 +9,17 @@ DisplayController::DisplayController(uint8_t oledWidth, uint8_t oledHeight, uint : oled(oledWidth, oledHeight, &Wire, -1), animation(&oled) {} void DisplayController::begin() { - if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { + Serial.println("Initializing display..."); + if (!oled.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) { Serial.println(F("SSD1306 allocation failed")); for (;;); // Loop forever if initialization fails } - - // Set display rotation from Config.h + Serial.println("Display initialized successfully"); + Serial.printf("Setting rotation to %d\n", OLED_ROTATION); oled.setRotation(OLED_ROTATION); - - // oled.ssd1306_command(SSD1306_SETCONTRAST); - // oled.ssd1306_command(128); - oled.clearDisplay(); oled.display(); - Serial.println("DisplayController initialized."); + Serial.println("Display setup complete"); } void DisplayController::drawSplashScreen() { diff --git a/firmware/src/controllers/InputController.cpp b/firmware/src/controllers/InputController.cpp index 98841a6..2ec6faf 100644 --- a/firmware/src/controllers/InputController.cpp +++ b/firmware/src/controllers/InputController.cpp @@ -15,6 +15,8 @@ void InputController::handleButtonInterrupt() { if (instancePtr) { + bool buttonState = digitalRead(instancePtr->buttonPin); + Serial.printf("Button state: %d\n", buttonState); instancePtr->button.tick(); } } @@ -41,6 +43,7 @@ InputController::InputController(uint8_t buttonPin, uint8_t encoderPinA, uint8_t void InputController::begin() { + Serial.printf("Initializing button on pin %d\n", buttonPin); button.setDebounceMs(20); button.setClickMs(150); button.setPressMs(400); @@ -50,9 +53,14 @@ void InputController::begin() pinMode(encoderPinA, INPUT_PULLUP); pinMode(encoderPinB, INPUT_PULLUP); + Serial.printf("Initial button state: %d\n", digitalRead(buttonPin)); + // Set up interrupts for encoder handling attachInterrupt(digitalPinToInterrupt(encoderPinA), handleEncoderInterrupt, CHANGE); attachInterrupt(digitalPinToInterrupt(encoderPinB), handleEncoderInterrupt, CHANGE); + + // Set up interrupt for button + attachInterrupt(digitalPinToInterrupt(buttonPin), handleButtonInterrupt, CHANGE); // Set up interrupt for button handling attachInterrupt(digitalPinToInterrupt(buttonPin), handleButtonInterrupt, CHANGE); // Interrupt on button state change @@ -60,17 +68,16 @@ void InputController::begin() void InputController::update() { + // Check button state button.tick(); - encoder.tick(); - - // Check encoder position and calculate delta - int currentPosition = encoder.getPosition(); - int delta = currentPosition - lastPosition; - if (delta != 0) + // Check encoder position + long newPosition = encoder.getPosition(); + if (newPosition != lastPosition) { + int delta = newPosition - lastPosition; + lastPosition = newPosition; onEncoderRotate(delta); - lastPosition = currentPosition; } } @@ -110,6 +117,7 @@ void InputController::releaseHandlers() // Internal event handlers that call the registered state handlers void InputController::onButtonClick() { + Serial.println("Button clicked!"); if (pressHandler != nullptr) { pressHandler(); @@ -118,6 +126,7 @@ void InputController::onButtonClick() void InputController::onButtonDoubleClick() { + Serial.println("Button double clicked!"); if (doublePressHandler != nullptr) { doublePressHandler(); @@ -126,6 +135,7 @@ void InputController::onButtonDoubleClick() void InputController::onButtonLongPress() { + Serial.println("Button long pressed!"); if (longPressHandler != nullptr) { longPressHandler(); diff --git a/firmware/src/main.cpp b/firmware/src/main.cpp index 4da8621..ec67fec 100644 --- a/firmware/src/main.cpp +++ b/firmware/src/main.cpp @@ -1,4 +1,5 @@ #include +#include #include "Config.h" #include "StateMachine.h" #include "Controllers.h" @@ -13,6 +14,9 @@ Preferences preferences; void setup() { Serial.begin(115200); + // Initialize I2C + Wire.begin(); + // Initialize controllers inputController.begin(); displayController.begin(); diff --git a/firmware/src/states/AdjustState.cpp b/firmware/src/states/AdjustState.cpp index b656628..5ab198b 100644 --- a/firmware/src/states/AdjustState.cpp +++ b/firmware/src/states/AdjustState.cpp @@ -22,8 +22,13 @@ void AdjustState::enter() Serial.println("Adjust State: Encoder turned"); Serial.println(delta); - // Update duration with delta and enforce bounds - this->adjustDuration += (delta * 5); + // Update duration based on orientation configuration +#if ENCODER_REVERSE_VALUE + this->adjustDuration -= (delta * 5); // Reversed +#else + this->adjustDuration += (delta * 5); // Normal +#endif + if (this->adjustDuration < MIN_TIMER) { this->adjustDuration = MIN_TIMER; } else if (this->adjustDuration > MAX_TIMER) { diff --git a/firmware/src/states/ResetState.cpp b/firmware/src/states/ResetState.cpp index 6132494..18a15e6 100644 --- a/firmware/src/states/ResetState.cpp +++ b/firmware/src/states/ResetState.cpp @@ -1,5 +1,6 @@ #include "StateMachine.h" #include "Controllers.h" +#include "Config.h" bool resetSelected = false; // button selection @@ -12,11 +13,21 @@ void ResetState::enter() // Register state-specific handlers inputController.onEncoderRotateHandler([this](int delta) { - if (delta > 0) { - resetSelected = true; // Select "RESET" - } else if (delta < 0) { - resetSelected = false; // Select "CANCEL" - } }); + Serial.print("Reset State: Encoder delta = "); + Serial.println(delta); + + // Update selection based on encoder value + // Note: When pins are swapped, clockwise = -1, counterclockwise = +1 + if (delta != 0) { +#if DEVICE_ORIENTATION == 1 + resetSelected = (delta > 0); // When rotated, counterclockwise (+1) selects RESET +#else + resetSelected = (delta < 0); // When normal, clockwise (-1) selects RESET +#endif + Serial.print("Reset Selected = "); + Serial.println(resetSelected); + } + }); inputController.onPressHandler([this]() {