From 0e10fcfee286fdcfa97e60b79aa7816eeb5e8783 Mon Sep 17 00:00:00 2001 From: andreas Date: Tue, 24 Oct 2023 15:58:43 +0200 Subject: [PATCH] handle buttons and leds completely as user tasks --- lib/api/GwApi.h | 10 ---- lib/buttons/GwButtons.h | 5 -- .../GwButtonTask.cpp} | 45 ++++++++++------- lib/buttontask/GwButtonTask.h | 7 +++ lib/buttontask/GwIButtonTask.h | 19 +++++++ lib/ledtask/GwLedTask.cpp | 49 ++++++++++++++----- lib/ledtask/GwLedTask.h | 9 +--- src/main.cpp | 4 -- 8 files changed, 91 insertions(+), 57 deletions(-) delete mode 100644 lib/buttons/GwButtons.h rename lib/{buttons/GwButtons.cpp => buttontask/GwButtonTask.cpp} (69%) create mode 100644 lib/buttontask/GwButtonTask.h create mode 100644 lib/buttontask/GwIButtonTask.h diff --git a/lib/api/GwApi.h b/lib/api/GwApi.h index 6fbad61..9511c06 100644 --- a/lib/api/GwApi.h +++ b/lib/api/GwApi.h @@ -61,12 +61,6 @@ class GwApi{ }; class Status{ public: - typedef enum{ - OFF, - PRESSED, - PRESSED_5, //5...10s - PRESSED_10 //>10s...30s - } ButtonState; bool wifiApOn=false; bool wifiClientOn=false; bool wifiClientConnected=false; @@ -89,8 +83,6 @@ class GwApi{ bool tcpClientConnected=false; unsigned long n2kRx=0; unsigned long n2kTx=0; - ButtonState button=OFF; - unsigned long buttonPresses=0; void empty(){ wifiApOn=false; wifiClientOn=false; @@ -114,8 +106,6 @@ class GwApi{ tcpClientConnected=false; n2kRx=0; n2kTx=0; - button=OFF; - buttonPresses=0; } }; /** diff --git a/lib/buttons/GwButtons.h b/lib/buttons/GwButtons.h deleted file mode 100644 index 6218e5d..0000000 --- a/lib/buttons/GwButtons.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef _GWBUTTONS_H -#define _GWBUTTONS_H -//task function -void handleButtons(void *param); -#endif \ No newline at end of file diff --git a/lib/buttons/GwButtons.cpp b/lib/buttontask/GwButtonTask.cpp similarity index 69% rename from lib/buttons/GwButtons.cpp rename to lib/buttontask/GwButtonTask.cpp index b810f4f..49a2bb1 100644 --- a/lib/buttons/GwButtons.cpp +++ b/lib/buttontask/GwButtonTask.cpp @@ -1,4 +1,5 @@ -#include "GwButtons.h" +#include "GwButtonTask.h" +#include "GwIButtonTask.h" #include "GwHardware.h" #include "GwApi.h" #include "GwLedTask.h" @@ -22,9 +23,12 @@ class FactoryResetRequest: public GwMessage{ },"reset",1000,NULL,0,NULL); }; }; -void handleButtons(void *param){ - GwApi *api=(GwApi*)param; +void handleButtons(GwApi *api){ GwLog *logger=api->getLogger(); + IButtonTask state; + if (!apiSetIButtonTask(api,state)){ + LOG_DEBUG(GwLog::ERROR,"unable to set button state"); + } #ifndef GWBUTTON_PIN LOG_DEBUG(GwLog::LOG,"no button pin defined, do not watch"); vTaskDelete(NULL); @@ -50,46 +54,51 @@ void handleButtons(void *param){ unsigned long lastReport=0; const unsigned long OFF_TIME=20; const unsigned long REPORT_TIME=1000; - const unsigned long HARD_REST_TIME=10000; - GwLedMode ledMode=LED_OFF; + const unsigned long PRESS_5_TIME=5000; + const unsigned long PRESS_10_TIME=10000; + const unsigned long PRESS_RESET_TIME=12000; + LOG_DEBUG(GwLog::LOG,"button task started"); while(true){ delay(10); int current=digitalRead(GWBUTTON_PIN); unsigned long now=millis(); + IButtonTask::ButtonState lastState=state.state; if (current != activeState){ if (lastPressed != 0 && (lastPressed+OFF_TIME) < now){ lastPressed=0; //finally off firstPressed=0; - if (ledMode != LED_OFF){ - setLedMode(LED_GREEN); //TODO: better "go back" - ledMode=LED_OFF; - } + state.state=IButtonTask::OFF; LOG_DEBUG(GwLog::LOG,"Button press stopped"); } + if (state.state != lastState){ + apiSetIButtonTask(api,state); + } continue; } lastPressed=now; if (firstPressed == 0) { firstPressed=now; LOG_DEBUG(GwLog::LOG,"Button press started"); + state.pressCount++; + state.state=IButtonTask::PRESSED; + apiSetIButtonTask(api,state); lastReport=now; + continue; } if (lastReport != 0 && (lastReport + REPORT_TIME) < now ){ LOG_DEBUG(GwLog::LOG,"Button active for %ld",(now-firstPressed)); lastReport=now; } - GwLedMode nextMode=ledMode; - if (now > (firstPressed+HARD_REST_TIME/2)){ - nextMode=LED_BLUE; + if (now > (firstPressed+PRESS_5_TIME)){ + state.state=IButtonTask::PRESSED_5; } - if (now > (firstPressed+HARD_REST_TIME*0.9)){ - nextMode=LED_RED; + if (now > (firstPressed+PRESS_10_TIME)){ + state.state=IButtonTask::PRESSED_10; } - if (ledMode != nextMode){ - setLedMode(nextMode); - ledMode=nextMode; + if (lastState != state.state){ + apiSetIButtonTask(api,state); } - if (now > (firstPressed+HARD_REST_TIME)){ + if (now > (firstPressed+PRESS_RESET_TIME)){ LOG_DEBUG(GwLog::ERROR,"Factory reset by button"); GwMessage *r=new FactoryResetRequest(api); api->getQueue()->sendAndForget(r); diff --git a/lib/buttontask/GwButtonTask.h b/lib/buttontask/GwButtonTask.h new file mode 100644 index 0000000..76a3301 --- /dev/null +++ b/lib/buttontask/GwButtonTask.h @@ -0,0 +1,7 @@ +#ifndef _GWBUTTONTASK_H +#define _GWBUTTONTASK_H +#include "GwApi.h" +//task function +void handleButtons(GwApi *param); +DECLARE_USERTASK(handleButtons); +#endif \ No newline at end of file diff --git a/lib/buttontask/GwIButtonTask.h b/lib/buttontask/GwIButtonTask.h new file mode 100644 index 0000000..df6e73a --- /dev/null +++ b/lib/buttontask/GwIButtonTask.h @@ -0,0 +1,19 @@ +#ifndef _GWIBUTTONTASK_H +#define _GWIBUTTONTASK_H +#include "GwApi.h" +class IButtonTask : public GwApi::TaskInterfaces::Base +{ +public: + typedef enum + { + OFF, + PRESSED, + PRESSED_5, // 5...10s + PRESSED_10 //>10s + } ButtonState; + ButtonState state=OFF; + long pressCount=0; +}; +DECLARE_TASKIF(handleButtons,IButtonTask); + +#endif \ No newline at end of file diff --git a/lib/ledtask/GwLedTask.cpp b/lib/ledtask/GwLedTask.cpp index 54c28bd..17dcc07 100644 --- a/lib/ledtask/GwLedTask.cpp +++ b/lib/ledtask/GwLedTask.cpp @@ -2,12 +2,14 @@ #include "GwHardware.h" #include "GwApi.h" #include "FastLED.h" - -static GwLedMode mode=LED_OFF; -void setLedMode(GwLedMode newMode){ - //we consider the mode to an atomic item... - mode=newMode; -} +#include "GwIButtonTask.h" +typedef enum { + LED_OFF, + LED_GREEN, + LED_BLUE, + LED_RED, + LED_WHITE +} GwLedMode; static CRGB::HTMLColorCode colorFromMode(GwLedMode cmode){ switch(cmode){ @@ -38,18 +40,41 @@ void handleLeds(GwApi *api){ FastLED.addLeds(leds,1); #endif uint8_t brightness=api->getConfig()->getInt(GwConfigDefinitions::ledBrightness,128); - GwLedMode currentMode=mode; + GwLedMode currentMode=LED_GREEN; leds[0]=colorFromMode(currentMode); FastLED.setBrightness(brightness); FastLED.show(); LOG_DEBUG(GwLog::LOG,"led task started with mode %d",(int)currentMode); - while(true){ + int apiResult=0; + while (true) + { delay(50); - GwLedMode newMode=mode; - if (newMode != currentMode){ - leds[0]=colorFromMode(newMode); + GwLedMode newMode = currentMode; + IButtonTask buttonState = apiGetIButtonTask(api, apiResult); + if (apiResult >= 0) + { + switch (buttonState.state) + { + case IButtonTask::PRESSED_5: + newMode = LED_BLUE; + break; + case IButtonTask::PRESSED_10: + newMode = LED_RED; + break; + default: + newMode = LED_GREEN; + break; + } + } + else + { + newMode = LED_WHITE; + } + if (newMode != currentMode) + { + leds[0] = colorFromMode(newMode); FastLED.show(); - currentMode=newMode; + currentMode = newMode; } } vTaskDelete(NULL); diff --git a/lib/ledtask/GwLedTask.h b/lib/ledtask/GwLedTask.h index a868537..2ae1532 100644 --- a/lib/ledtask/GwLedTask.h +++ b/lib/ledtask/GwLedTask.h @@ -3,13 +3,6 @@ #include "GwApi.h" //task function void handleLeds(GwApi *param); -typedef enum { - LED_OFF, - LED_GREEN, - LED_BLUE, - LED_RED, - LED_WHITE -} GwLedMode; -void setLedMode(GwLedMode mode); + DECLARE_USERTASK(handleLeds); #endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 52f37ef..bdb0261 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -53,8 +53,6 @@ const unsigned long HEAP_REPORT_TIME=2000; //set to 0 to disable heap reporting #include "GwSerial.h" #include "GwWebServer.h" #include "NMEA0183DataToN2K.h" -#include "GwButtons.h" -#include "GwLedTask.h" #include "GwCounter.h" #include "GwXDRMappings.h" #include "GwSynchronized.h" @@ -852,8 +850,6 @@ void setup() { NMEA2000.Open(); logger.logDebug(GwLog::LOG,"starting addon tasks"); logger.flush(); - setLedMode(LED_GREEN); - userCodeHandler.startAddonTask(F("handleButtons"),handleButtons,100); { GWSYNCHRONIZED(&mainLock); userCodeHandler.startUserTasks(MIN_USER_TASK);