Update WebUI and convert ButtonHandler to class
Some checks failed
BTClock CI / build (push) Failing after 19m28s
BTClock CI / merge (map[name:btclock_v8 version:esp32s3], 213epd) (push) Has been skipped
BTClock CI / merge (map[name:btclock_rev_b version:esp32s3], 213epd) (push) Has been skipped
BTClock CI / merge (map[name:lolin_s3_mini version:esp32s3], 213epd) (push) Has been skipped
BTClock CI / release (push) Has been skipped
BTClock CI / merge (map[name:lolin_s3_mini version:esp32s3], 29epd) (push) Has been skipped

This commit is contained in:
Djuri Baars 2024-12-27 00:05:45 +01:00
parent 17fef80253
commit cff6131fc4
5 changed files with 53 additions and 93 deletions

2
data

@ -1 +1 @@
Subproject commit 65b6df5d92f3f936e823a5c1413681aee85ab0c5 Subproject commit 2ce53eb499e00a990be5cb0ea078e146f467ceb4

View file

@ -1,7 +1,8 @@
#include "button_handler.hpp" #include "button_handler.hpp"
TaskHandle_t buttonTaskHandle = NULL; // Initialize static members
ButtonState buttonStates[4]; TaskHandle_t ButtonHandler::buttonTaskHandle = NULL;
ButtonState ButtonHandler::buttonStates[4] = {};
#ifdef IS_BTCLOCK_V8 #ifdef IS_BTCLOCK_V8
#define BTN_1 256 #define BTN_1 256
@ -15,7 +16,7 @@ ButtonState buttonStates[4];
#define BTN_4 256 #define BTN_4 256
#endif #endif
void buttonTask(void *parameter) { void ButtonHandler::buttonTask(void *parameter) {
while (1) { while (1) {
ulTaskNotifyTake(pdTRUE, portMAX_DELAY); ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
@ -48,16 +49,6 @@ void buttonTask(void *parameter) {
} }
} }
} }
// Check for long press on pressed buttons
for (int i = 0; i < 4; i++) {
if (buttonStates[i].isPressed && !buttonStates[i].longPressHandled) {
if ((currentTime - buttonStates[i].pressStartTime) >= longPressDelay) {
handleLongPress(i);
buttonStates[i].longPressHandled = true;
}
}
}
} }
// Clear interrupt state // Clear interrupt state
@ -68,56 +59,34 @@ void buttonTask(void *parameter) {
} }
} }
void handleButtonPress(int buttonIndex) { void ButtonHandler::handleButtonPress(int buttonIndex) {
TickType_t currentTime = xTaskGetTickCount(); TickType_t currentTime = xTaskGetTickCount();
ButtonState &state = buttonStates[buttonIndex]; ButtonState &state = buttonStates[buttonIndex];
if ((currentTime - state.lastPressTime) >= debounceDelay) { if ((currentTime - state.lastPressTime) >= debounceDelay) {
state.isPressed = true; state.isPressed = true;
state.pressStartTime = currentTime;
state.longPressHandled = false;
// Check for double click
if ((currentTime - state.lastPressTime) <= doubleClickDelay) {
state.clickCount++;
if (state.clickCount == 2) {
handleDoubleClick(buttonIndex);
state.clickCount = 0;
}
} else {
state.clickCount = 1;
}
state.lastPressTime = currentTime; state.lastPressTime = currentTime;
} }
} }
void handleButtonRelease(int buttonIndex) { void ButtonHandler::handleButtonRelease(int buttonIndex) {
TickType_t currentTime = xTaskGetTickCount();
ButtonState &state = buttonStates[buttonIndex]; ButtonState &state = buttonStates[buttonIndex];
state.isPressed = false; if (!state.isPressed) return; // Ignore if button wasn't pressed
// If this wasn't a long press or double click, handle as single click state.isPressed = false;
if (!state.longPressHandled && state.clickCount == 1 && handleSingleClick(buttonIndex);
(currentTime - state.pressStartTime) < longPressDelay) {
handleSingleClick(buttonIndex);
state.clickCount = 0;
}
} }
// Button action handlers void ButtonHandler::handleSingleClick(int buttonIndex) {
void handleSingleClick(int buttonIndex) {
switch (buttonIndex) { switch (buttonIndex) {
case 0: case 0:
toggleTimerActive(); toggleTimerActive();
break; break;
case 1: case 1:
Serial.println("Button 2 single click");
ScreenHandler::nextScreen(); ScreenHandler::nextScreen();
break; break;
case 2: case 2:
Serial.println("Button 3 single click");
ScreenHandler::previousScreen(); ScreenHandler::previousScreen();
break; break;
case 3: case 3:
@ -126,15 +95,7 @@ void handleSingleClick(int buttonIndex) {
} }
} }
void handleDoubleClick(int buttonIndex) { void IRAM_ATTR ButtonHandler::handleButtonInterrupt() {
Serial.printf("Button %d double clicked\n", buttonIndex + 1);
}
void handleLongPress(int buttonIndex) {
Serial.printf("Button %d long press detected\n", buttonIndex + 1);
}
void IRAM_ATTR handleButtonInterrupt() {
BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xTaskNotifyFromISR(buttonTaskHandle, 0, eNoAction, &xHigherPriorityTaskWoken); xTaskNotifyFromISR(buttonTaskHandle, 0, eNoAction, &xHigherPriorityTaskWoken);
if (xHigherPriorityTaskWoken == pdTRUE) { if (xHigherPriorityTaskWoken == pdTRUE) {
@ -142,7 +103,7 @@ void IRAM_ATTR handleButtonInterrupt() {
} }
} }
void setupButtonTask() { void ButtonHandler::setup() {
xTaskCreate(buttonTask, "ButtonTask", 3072, NULL, tskIDLE_PRIORITY, xTaskCreate(buttonTask, "ButtonTask", 3072, NULL, tskIDLE_PRIORITY,
&buttonTaskHandle); &buttonTaskHandle);
attachInterrupt(MCP_INT_PIN, handleButtonInterrupt, FALLING); attachInterrupt(MCP_INT_PIN, handleButtonInterrupt, FALLING);

View file

@ -6,24 +6,6 @@
#include "lib/shared.hpp" #include "lib/shared.hpp"
#include "lib/timers.hpp" #include "lib/timers.hpp"
extern TaskHandle_t buttonTaskHandle;
// Task and setup functions
void buttonTask(void *pvParameters);
void IRAM_ATTR handleButtonInterrupt();
void setupButtonTask();
// Individual button handlers
void handleButton1();
void handleButton2();
void handleButton3();
void handleButton4();
// New features
const TickType_t debounceDelay = pdMS_TO_TICKS(50);
const TickType_t doubleClickDelay = pdMS_TO_TICKS(300); // Maximum time between clicks for double click
const TickType_t longPressDelay = pdMS_TO_TICKS(1000); // Time to hold for long press
// Track timing for each button // Track timing for each button
struct ButtonState { struct ButtonState {
TickType_t lastPressTime = 0; TickType_t lastPressTime = 0;
@ -33,22 +15,40 @@ struct ButtonState {
bool longPressHandled = false; bool longPressHandled = false;
}; };
extern ButtonState buttonStates[4]; class ButtonHandler {
private:
static const TickType_t debounceDelay = pdMS_TO_TICKS(50);
static const TickType_t doubleClickDelay = pdMS_TO_TICKS(1000); // Maximum time between clicks for double click
static const TickType_t longPressDelay = pdMS_TO_TICKS(1500); // Time to hold for long press
#ifdef IS_BTCLOCK_V8 static ButtonState buttonStates[4];
#define BTN_1 256 static TaskHandle_t buttonTaskHandle;
#define BTN_2 512
#define BTN_3 1024
#define BTN_4 2048
#else
#define BTN_1 2048
#define BTN_2 1024
#define BTN_3 512
#define BTN_4 256
#endif
void handleButtonPress(int buttonIndex); // Button handlers
void handleButtonRelease(int buttonIndex); static void handleButtonPress(int buttonIndex);
void handleSingleClick(int buttonIndex); static void handleButtonRelease(int buttonIndex);
void handleDoubleClick(int buttonIndex); static void handleSingleClick(int buttonIndex);
void handleLongPress(int buttonIndex); static void handleDoubleClick(int buttonIndex);
static void handleLongPress(int buttonIndex);
// Task function
static void buttonTask(void *pvParameters);
public:
static void setup();
static void IRAM_ATTR handleButtonInterrupt();
static void suspendTask() { if (buttonTaskHandle != NULL) vTaskSuspend(buttonTaskHandle); }
static void resumeTask() { if (buttonTaskHandle != NULL) vTaskResume(buttonTaskHandle); }
#ifdef IS_BTCLOCK_V8
static const uint16_t BTN_1 = 256;
static const uint16_t BTN_2 = 512;
static const uint16_t BTN_3 = 1024;
static const uint16_t BTN_4 = 2048;
#else
static const uint16_t BTN_1 = 2048;
static const uint16_t BTN_2 = 1024;
static const uint16_t BTN_3 = 512;
static const uint16_t BTN_4 = 256;
#endif
};

View file

@ -100,7 +100,7 @@ void setup()
setupMiningPoolStatsFetchTask(); setupMiningPoolStatsFetchTask();
} }
setupButtonTask(); ButtonHandler::setup();
setupOTA(); setupOTA();
waitUntilNoneBusy(); waitUntilNoneBusy();
@ -482,7 +482,7 @@ void setupHardware()
Serial.printf("Error setting pin %d to input pull up\n", i); Serial.printf("Error setting pin %d to input pull up\n", i);
} }
// Enable interrupt on CHANGE for each pin // Enable interrupt on CHANGE for each pin
if (!mcp1.enableInterrupt(i, FALLING)) { if (!mcp1.enableInterrupt(i, CHANGE)) {
Serial.printf("Error enabling interrupt for pin %d\n", i); Serial.printf("Error enabling interrupt for pin %d\n", i);
} }
} }

View file

@ -64,11 +64,10 @@ void onOTAStart()
// Stop or suspend all tasks // Stop or suspend all tasks
// vTaskSuspend(priceUpdateTaskHandle); // vTaskSuspend(priceUpdateTaskHandle);
// vTaskSuspend(blockUpdateTaskHandle); // vTaskSuspend(blockUpdateTaskHandle);
vTaskSuspend(workerTaskHandle);
vTaskSuspend(taskScreenRotateTaskHandle); vTaskSuspend(taskScreenRotateTaskHandle);
vTaskSuspend(workerTaskHandle);
// vTaskSuspend(ledTaskHandle); vTaskSuspend(eventSourceTaskHandle);
vTaskSuspend(buttonTaskHandle); ButtonHandler::suspendTask();
// stopWebServer(); // stopWebServer();
stopBlockNotify(); stopBlockNotify();