From 23cf6e6f3efe506212dc98fd62484d5dcedf96d6 Mon Sep 17 00:00:00 2001 From: jonny Date: Wed, 4 Sep 2024 23:04:54 +0200 Subject: [PATCH] Add Display-notification, default position, Push+scroll --- board_single/main/button.cpp | 64 ++++++++++++++++++----------------- board_single/main/display.cpp | 33 ++++++++++++++++++ board_single/main/display.hpp | 3 ++ board_single/main/main.cpp | 4 +-- common/chairAdjust.cpp | 4 ++- common/chairAdjust.hpp | 2 +- 6 files changed, 75 insertions(+), 35 deletions(-) diff --git a/board_single/main/button.cpp b/board_single/main/button.cpp index a2dd59e..3f84205 100644 --- a/board_single/main/button.cpp +++ b/board_single/main/button.cpp @@ -186,7 +186,7 @@ void buttonCommands::action (uint8_t count, bool lastPressLong){ void buttonCommands::startHandleLoop() { //-- variables -- - bool isPressed = false; + static bool isPressed = false; static rotary_encoder_event_t event; // store event data int rotateCount = 0; // temporary count clicks encoder was rotated // int count = 0; (from class) @@ -221,27 +221,39 @@ void buttonCommands::startHandleLoop() ESP_LOGD(TAG, "Button released"); isPressed = false; // rest stored state break; - case RE_ET_CHANGED: // scroll through status pages when simply rotating encoder - - if (event.diff > 0) - legRest->setTargetPercent(legRest->getTargetPercent() - 5); - //TODO display notification + case RE_ET_CHANGED: + if (isPressed){ + /////### scroll through status pages when PRESSED + ROTATED ### + ///if (event.diff > 0) + /// display_rotateStatusPage(true, true); // select NEXT status screen, stay at last element (dont rotate to first) + ///else + /// display_rotateStatusPage(false, true); // select PREVIOUS status screen, stay at first element (dont rotate to last) + //### adjust back support when PRESSED + ROTATED ### + if (event.diff > 0) + backRest->setTargetPercent(backRest->getTargetPercent() - 5); + else + backRest->setTargetPercent(backRest->getTargetPercent() + 5); + // show temporary notification on display + char buf[8]; + snprintf(buf, 8, "%.1f%%", backRest->getTargetPercent()); + display_showNotification(1000, "moving Rest:", "LEG", buf); + } + //### adjust leg support when ROTATED ### else - legRest->setTargetPercent(legRest->getTargetPercent() + 5); - - //## switch status page with rotate - disabled - ///rotateCount++; - ///if (rotateCount >= 2) // at least two rotate-clicks necessary for one page switch - ///{ - /// if (event.diff > 0) - /// display_rotateStatusPage(true, true); // select NEXT status screen, stay at last element (dont rotate to first) - /// else - /// display_rotateStatusPage(false, true); // select PREVIOUS status screen, stay at first element (dont rotate to last) - /// rotateCount = 0; - /// buzzer->beep(1, 90, 0); - ///} - ///else - /// buzzer->beep(1, 65, 0); + { + // increment target position each click + // TODO: ignore first 2 clicks + // TODO: control back rest too? + if (event.diff > 0) + legRest->setTargetPercent(legRest->getTargetPercent() - 5); + else + legRest->setTargetPercent(legRest->getTargetPercent() + 5); + // show temporary notification on display + char buf[8]; + snprintf(buf, 8, "%.1f%%", legRest->getTargetPercent()); + display_showNotification(1000, "moving Rest:", "LEG", buf); + } + buzzer->beep(1, 90, 0); break; case RE_ET_BTN_LONG_PRESSED: case RE_ET_BTN_CLICKED: @@ -251,16 +263,6 @@ void buttonCommands::startHandleLoop() } else // timeout (no event received within TIMEOUT) { - //## switch status page with rotate - disabled - // switch back to default status screen in case less than 2 rotate-clicks received - ///if (rotateCount != 0) - ///{ - /// rotateCount = 0; - /// display_selectStatusPage(STATUS_SCREEN_OVERVIEW); - /// //TODO only change/beep if not already at STATUS_SCREEN_OVERVIEW - /// //buzzer->beep(1, 100, 0); - ///} - // encoder was pressed if (count > 0) { diff --git a/board_single/main/display.cpp b/board_single/main/display.cpp index 2923b4d..52711fa 100644 --- a/board_single/main/display.cpp +++ b/board_single/main/display.cpp @@ -23,6 +23,11 @@ extern "C"{ // every function can access the display configuration from config.cpp static display_config_t displayConfig; +// communicate with display task to block+restore display writing, when a notification was triggered +uint32_t timestampNotificationStop = 0; +bool notificationIsActive = false; + + //-------------------------- //------- getVoltage ------- @@ -584,6 +589,25 @@ void handleStatusScreen(display_task_parameters_t *objects) } + +//============================== +//====== showNotification ====== +//============================== +// trigger custom notification that is shown in any mode for set amount of time +void display_showNotification(uint32_t showDurationMs, const char *line1, const char *line2Large, const char *line3Large) +{ + timestampNotificationStop = esp_log_timestamp() + showDurationMs; + notificationIsActive = true; + // void displayTextLineCentered(SSD1306_t *display, int line, bool isLarge, bool inverted, const char *format, ...); + displayTextLineCentered(&dev, 0, false, false, "%s", line1); + displayTextLineCentered(&dev, 1, true, false, "%s", line2Large); + displayTextLineCentered(&dev, 4, true, false, "%s", line3Large); + displayTextLine(&dev, 7, false, false, " "); + ESP_LOGW(TAG, "start showing notification '%s' '%s' for %d ms", line1, line2Large, showDurationMs); +} + + + //============================ //======= display task ======= //============================ @@ -606,6 +630,15 @@ void display_task(void *pvParameters) // repeatedly update display with content depending on current mode while (1) { + // dont update anything when a notification is active + check timeout + if (notificationIsActive){ + if (esp_log_timestamp() >= timestampNotificationStop) + notificationIsActive = false; + vTaskDelay(100 / portTICK_PERIOD_MS); + continue; + } + + //update display according to current control mode switch (objects->control->getCurrentMode()) { case controlMode_t::MENU_SETTINGS: diff --git a/board_single/main/display.hpp b/board_single/main/display.hpp index 791246e..3498da1 100644 --- a/board_single/main/display.hpp +++ b/board_single/main/display.hpp @@ -67,6 +67,9 @@ void display_selectStatusPage(displayStatusPage_t newStatusPage); // select next/previous status screen to be shown, when noRotate is set is stays at first/last screen void display_rotateStatusPage(bool reverseDirection = false, bool noRotate = false); +// show content for certain time in any mode +void display_showNotification(uint32_t showDurationMs, const char *line1, const char * line2Large, const char * line3Large ); + //task that inititialized the display, displays welcome message //and releatedly updates the display with certain content void display_task( void * pvParameters ); diff --git a/board_single/main/main.cpp b/board_single/main/main.cpp index 15e253f..4876850 100644 --- a/board_single/main/main.cpp +++ b/board_single/main/main.cpp @@ -161,9 +161,9 @@ void createObjects() buzzer = new buzzer_t(GPIO_NUM_12, 1); // create objects for controlling the chair position - // gpio_up, gpio_down, name + // gpio_up, gpio_down, travelDuration, name, defaultPosition legRest = new cControlledRest(GPIO_NUM_2, GPIO_NUM_15, 12000, "legRest"); - backRest = new cControlledRest(GPIO_NUM_16, GPIO_NUM_4, 12000, "backRest"); + backRest = new cControlledRest(GPIO_NUM_16, GPIO_NUM_4, 12000, "backRest", 100); //default position "100% up" // create control object (control.hpp) // with configuration from config.cpp diff --git a/common/chairAdjust.cpp b/common/chairAdjust.cpp index cb777ad..d8e9595 100644 --- a/common/chairAdjust.cpp +++ b/common/chairAdjust.cpp @@ -24,10 +24,12 @@ static const char * TAG = "chair-adjustment"; //============================= //======== constructor ======== //============================= -cControlledRest::cControlledRest(gpio_num_t gpio_up_f, gpio_num_t gpio_down_f, uint32_t travelDurationMs, const char * name_f):travelDuration(travelDurationMs){ +cControlledRest::cControlledRest(gpio_num_t gpio_up_f, gpio_num_t gpio_down_f, uint32_t travelDurationMs, const char * name_f, float defaultPosition):travelDuration(travelDurationMs){ strcpy(name, name_f); gpio_up = gpio_up_f; gpio_down = gpio_down_f; + positionNow = defaultPosition; + positionTarget = positionNow; init(); } diff --git a/common/chairAdjust.hpp b/common/chairAdjust.hpp index 61074fe..4c3fc00 100644 --- a/common/chairAdjust.hpp +++ b/common/chairAdjust.hpp @@ -18,7 +18,7 @@ extern const char* restStateStr[]; //2 instances will be created one for back and one for leg rest class cControlledRest { public: - cControlledRest(gpio_num_t gpio_up, gpio_num_t gpio_down, uint32_t travelDurationMs, const char *name); + cControlledRest(gpio_num_t gpio_up, gpio_num_t gpio_down, uint32_t travelDurationMs, const char *name, float defaultPosition = 0); void setState(restState_t targetState); float getPercent(); //TODO update position first void setTargetPercent(float targetPercent);