From f1e681bb5f7bbfb643cffca3831906d2eb3e4be2 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 17 May 2023 16:33:01 -0400 Subject: [PATCH 01/24] Fixed warnings on float calculation Added empty button handler function --- ESPixelStick/src/input/InputEffectEngine.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ESPixelStick/src/input/InputEffectEngine.cpp b/ESPixelStick/src/input/InputEffectEngine.cpp index d4a59c35a..a9f5dd758 100644 --- a/ESPixelStick/src/input/InputEffectEngine.cpp +++ b/ESPixelStick/src/input/InputEffectEngine.cpp @@ -367,6 +367,12 @@ void c_InputEffectEngine::Process () } // process +//---------------------------------------------------------------------------- +void c_InputEffectEngine::ProcessEffectsButtonActions(c_ExternalInput::InputValue_t value) +{ + +} // ProcessEffectsButtonActions + //----------------------------------------------------------------------------- void c_InputEffectEngine::SetBufferInfo (uint32_t BufferSize) { @@ -1278,7 +1284,7 @@ uint16_t c_InputEffectEngine::effectBreathe () */ // sin() is in radians, so 2*PI rad is a full period; compiler should optimize. // DEBUG_START; - float val = (exp (sin (millis () / (EffectDelay * 5.0) * 2 * PI)) - 0.367879441) * 0.106364766 + 0.75; + float val = (exp (sin (float(millis ()) / (float(EffectDelay) * 5.0) * 2.0 * PI)) - 0.367879441) * 0.106364766 + 0.75; setAll ({ uint8_t (EffectColor.r * val), uint8_t (EffectColor.g * val), uint8_t (EffectColor.b * val) }); From 36899ff076725d5203a8bf18480a234c95c5998e Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 17 May 2023 16:36:19 -0400 Subject: [PATCH 02/24] Refactoring for clarity --- ESPixelStick/src/input/externalInput.cpp | 138 ++++++++--------------- ESPixelStick/src/input/externalInput.h | 27 ++--- 2 files changed, 61 insertions(+), 104 deletions(-) diff --git a/ESPixelStick/src/input/externalInput.cpp b/ESPixelStick/src/input/externalInput.cpp index 93db3d99e..7f372f463 100644 --- a/ESPixelStick/src/input/externalInput.cpp +++ b/ESPixelStick/src/input/externalInput.cpp @@ -23,7 +23,7 @@ fsm_ExternalInput_wait_for_off_state fsm_ExternalInput_wait_for_off_state_imp; /*****************************************************************************/ c_ExternalInput::c_ExternalInput(void) : - m_CurrentFsmState(fsm_ExternalInput_boot_imp) + CurrentFsmState(fsm_ExternalInput_boot_imp) { // DEBUG_START; fsm_ExternalInput_boot_imp.Init(*this); // currently redundant, but might Init() might do more ... so important to leave this @@ -31,78 +31,56 @@ c_ExternalInput::c_ExternalInput(void) : } // c_ExternalInput +/*****************************************************************************/ void c_ExternalInput::Init(uint32_t iInputId, uint32_t iPinId, Polarity_t Polarity, String & sName) { // DEBUG_START; // Remember the pin number for future calls - m_iPinId = iPinId; - m_name = sName; - m_polarity = Polarity; + GpioId = iPinId; + name = sName; + polarity = Polarity; // set the pin direction to input - pinMode(m_iPinId, INPUT); + pinMode(GpioId, INPUT); // DEBUG_END; } // Init /*****************************************************************************/ -/* - * Get the input value. - * - * needs - * nothing - * returns - * input value - */ c_ExternalInput::InputValue_t c_ExternalInput::Get() { // DEBUG_START; - return m_CurrentFsmState.Get(); + return CurrentFsmState.Get(); // DEBUG_END; } // Get /*****************************************************************************/ -/* - * Process the current configuration - * - * needs - * reference to a json config object - * returns - * nothing - */ void c_ExternalInput::GetConfig (JsonObject JsonData) { - // DEBUG_START; + DEBUG_START; - JsonData[M_IO_ENABLED] = m_bIsEnabled; - JsonData[M_NAME] = m_name; - JsonData[M_ID] = m_iPinId; - JsonData[M_POLARITY] = (ActiveHigh == m_polarity) ? CN_ActiveHigh : CN_ActiveLow; + JsonData[M_IO_ENABLED] = Enabled; + JsonData[M_NAME] = name; + JsonData[M_ID] = GpioId; + JsonData[M_POLARITY] = (ActiveHigh == polarity) ? CN_ActiveHigh : CN_ActiveLow; + JsonData[CN_channels] = TriggerChannel; // DEBUG_V (String ("m_iPinId: ") + String (m_iPinId)); - // DEBUG_END; + DEBUG_END; } // GetConfig /*****************************************************************************/ -/* - * Process the current configuration - * - * needs - * reference to a json config object - * returns - * nothing - */ void c_ExternalInput::GetStatistics (JsonObject JsonData) { // DEBUG_START; - JsonData[M_ID] = m_iPinId; + JsonData[M_ID] = GpioId; JsonData[M_STATE] = (InputValue_t::on == Get ()) ? "on" : "off"; // DEBUG_END; @@ -110,34 +88,28 @@ void c_ExternalInput::GetStatistics (JsonObject JsonData) } // GetStatistics /*****************************************************************************/ -/* - * Process the current configuration - * - * needs - * reference to a json config object - * returns - * nothing - */ void c_ExternalInput::ProcessConfig (JsonObject JsonData) { // DEBUG_START; - String sPolarity = (ActiveHigh == m_polarity) ? CN_ActiveHigh : CN_ActiveLow; + String Polarity = (ActiveHigh == polarity) ? CN_ActiveHigh : CN_ActiveLow; - uint32_t oldInputId = m_iPinId; + uint32_t oldInputId = GpioId; - setFromJSON (m_bIsEnabled, JsonData, M_IO_ENABLED); - setFromJSON (m_name, JsonData, M_NAME); - setFromJSON (m_iPinId, JsonData, M_ID); - setFromJSON (sPolarity, JsonData, M_POLARITY); + setFromJSON (Enabled, JsonData, M_IO_ENABLED); + setFromJSON (name, JsonData, M_NAME); + setFromJSON (GpioId, JsonData, M_ID); + setFromJSON (Polarity, JsonData, M_POLARITY); + setFromJSON (TriggerChannel, JsonData, CN_channels); - m_polarity = (String(CN_ActiveHigh) == sPolarity) ? ActiveHigh : ActiveLow; + polarity = (String(CN_ActiveHigh) == Polarity) ? ActiveHigh : ActiveLow; - if ((oldInputId != m_iPinId) || (false == m_bIsEnabled)) + if ((oldInputId != GpioId) || (false == Enabled)) { - pinMode (m_iPinId, INPUT); - m_bHadLongPush = false; - m_bHadShortPush = false; + pinMode (oldInputId, INPUT); + pinMode (GpioId, INPUT_PULLUP); + HadLongPush = false; + HadShortPush = false; fsm_ExternalInput_boot_imp.Init (*this); } @@ -148,39 +120,23 @@ void c_ExternalInput::ProcessConfig (JsonObject JsonData) } // ProcessConfig /*****************************************************************************/ -/* - * Poll the state machine - * - * needs - * Nothing - * returns - * nothing - */ void c_ExternalInput::Poll (void) { // DEBUG_START; - m_CurrentFsmState.Poll (*this); + CurrentFsmState.Poll (*this); // DEBUG_END; } // Poll /*****************************************************************************/ -/* - * read the adjusted value of the input pin - * - * needs - * Nothing - * returns - * true - input is "on" - */ bool c_ExternalInput::ReadInput (void) { // read the input - bool bInputValue = digitalRead (m_iPinId); + bool bInputValue = digitalRead (GpioId); // do we need to invert the input? - if (Polarity_t::ActiveLow == m_polarity) + if (Polarity_t::ActiveLow == polarity) { // invert the input value bInputValue = !bInputValue; @@ -200,7 +156,7 @@ bool c_ExternalInput::ReadInput (void) // waiting for the system to come up void fsm_ExternalInput_boot::Init (c_ExternalInput& pExternalInput) { - pExternalInput.m_CurrentFsmState = fsm_ExternalInput_boot_imp; + pExternalInput.CurrentFsmState = fsm_ExternalInput_boot_imp; // dont do anything @@ -211,7 +167,7 @@ void fsm_ExternalInput_boot::Init (c_ExternalInput& pExternalInput) void fsm_ExternalInput_boot::Poll (c_ExternalInput& pExternalInput) { // start normal operation - if (pExternalInput.m_bIsEnabled) + if (pExternalInput.Enabled) { fsm_ExternalInput_off_state_imp.Init (pExternalInput); } @@ -226,8 +182,8 @@ void fsm_ExternalInput_off_state::Init(c_ExternalInput& pExternalInput) { // DEBUG_START; - pExternalInput.m_iInputDebounceCount = MIN_INPUT_STABLE_VALUE; - pExternalInput.m_CurrentFsmState = fsm_ExternalInput_off_state_imp; + pExternalInput.InputDebounceCount = MIN_INPUT_STABLE_VALUE; + pExternalInput.CurrentFsmState = fsm_ExternalInput_off_state_imp; // DEBUG_V ("Entring OFF State"); } // fsm_ExternalInput_off_state::Init @@ -245,7 +201,7 @@ void fsm_ExternalInput_off_state::Poll(c_ExternalInput& pExternalInput) if (true == bInputValue) { // decrement the counter - if (0 == --pExternalInput.m_iInputDebounceCount) + if (0 == --pExternalInput.InputDebounceCount) { // we really are on fsm_ExternalInput_on_wait_short_state_imp.Init(pExternalInput); @@ -255,7 +211,7 @@ void fsm_ExternalInput_off_state::Poll(c_ExternalInput& pExternalInput) { // DEBUG_V (""); // reset the debounce counter - pExternalInput.m_iInputDebounceCount = MIN_INPUT_STABLE_VALUE; + pExternalInput.InputDebounceCount = MIN_INPUT_STABLE_VALUE; } // DEBUG_END; @@ -270,8 +226,8 @@ void fsm_ExternalInput_on_wait_short_state::Init(c_ExternalInput& pExternalInput { // DEBUG_START; - pExternalInput.m_InputHoldTimer.StartTimer(INPUT_SHORT_VALUE_MS); - pExternalInput.m_CurrentFsmState = fsm_ExternalInput_on_wait_short_state_imp; + pExternalInput.InputHoldTimer.StartTimer(INPUT_SHORT_VALUE_MS); + pExternalInput.CurrentFsmState = fsm_ExternalInput_on_wait_short_state_imp; // DEBUG_V ("Entring Wait Short State"); } // fsm_ExternalInput_on_wait_short_state::Init @@ -289,7 +245,7 @@ void fsm_ExternalInput_on_wait_short_state::Poll(c_ExternalInput& pExternalInput { // DEBUG_V(""); // decrement the counter - if (pExternalInput.m_InputHoldTimer.IsExpired()) + if (pExternalInput.InputHoldTimer.IsExpired()) { // we really are on fsm_ExternalInput_on_wait_long_state_imp.Init(pExternalInput); @@ -309,8 +265,8 @@ void fsm_ExternalInput_on_wait_short_state::Poll(c_ExternalInput& pExternalInput // Input is always on void fsm_ExternalInput_on_wait_long_state::Init (c_ExternalInput& pExternalInput) { - pExternalInput.m_InputHoldTimer.StartTimer(INPUT_LONG_VALUE_MS); - pExternalInput.m_CurrentFsmState = fsm_ExternalInput_on_wait_long_state_imp; + pExternalInput.InputHoldTimer.StartTimer(INPUT_LONG_VALUE_MS); + pExternalInput.CurrentFsmState = fsm_ExternalInput_on_wait_long_state_imp; // DEBUG_V ("Entring Wait Long State"); } // fsm_ExternalInput_on_wait_long_state::Init @@ -329,16 +285,16 @@ void fsm_ExternalInput_on_wait_long_state::Poll (c_ExternalInput& pExternalInput { // DEBUG_V(""); // decrement the counter - if (pExternalInput.m_InputHoldTimer.IsExpired()) + if (pExternalInput.InputHoldTimer.IsExpired()) { // we really are on fsm_ExternalInput_wait_for_off_state_imp.Init (pExternalInput); - pExternalInput.m_bHadLongPush = true; + pExternalInput.HadLongPush = true; } } else // Turned off { - pExternalInput.m_bHadShortPush = true; + pExternalInput.HadShortPush = true; fsm_ExternalInput_off_state_imp.Init (pExternalInput); } @@ -352,7 +308,7 @@ void fsm_ExternalInput_on_wait_long_state::Poll (c_ExternalInput& pExternalInput // Input is always on void fsm_ExternalInput_wait_for_off_state::Init (c_ExternalInput& pExternalInput) { - pExternalInput.m_CurrentFsmState = fsm_ExternalInput_wait_for_off_state_imp; + pExternalInput.CurrentFsmState = fsm_ExternalInput_wait_for_off_state_imp; // DEBUG_V ("Entring Wait OFF State"); } // fsm_ExternalInput_wait_for_off_state::Init @@ -366,7 +322,7 @@ void fsm_ExternalInput_wait_for_off_state::Poll (c_ExternalInput& pExternalInput // read the input bool bInputValue = pExternalInput.ReadInput (); - // If the input is "on" + // If the input is "on" then we wait for it to go off if (false == bInputValue) { fsm_ExternalInput_off_state_imp.Init (pExternalInput); diff --git a/ESPixelStick/src/input/externalInput.h b/ESPixelStick/src/input/externalInput.h index c4d90407c..886f2d5c4 100644 --- a/ESPixelStick/src/input/externalInput.h +++ b/ESPixelStick/src/input/externalInput.h @@ -28,13 +28,13 @@ class c_ExternalInput final void Init (uint32_t iInputId, uint32_t iPinId, Polarity_t Poliarity, String & sName); InputValue_t Get (); - inline bool InputHadLongPush (bool bClearFlag) { bool tmp = m_bHadLongPush; if (true == bClearFlag) { m_bHadLongPush = false; } return tmp; } - inline bool InputHadShortPush (bool bClearFlag) { bool tmp = m_bHadShortPush; if (true == bClearFlag) { m_bHadShortPush = false; } return tmp; } + inline bool InputHadLongPush (bool bClearFlag) { bool tmp = HadLongPush; if (true == bClearFlag) { HadLongPush = false; } return tmp; } + inline bool InputHadShortPush (bool bClearFlag) { bool tmp = HadShortPush; if (true == bClearFlag) { HadShortPush = false; } return tmp; } void Poll (void); void GetConfig (JsonObject JsonData); void GetStatistics (JsonObject JsonData); void ProcessConfig (JsonObject JsonData); - bool IsEnabled () { return m_bIsEnabled; } + bool IsEnabled () { return Enabled; } void GetDriverName (String & Name) { Name = "ExtInput"; } protected: @@ -48,16 +48,17 @@ class c_ExternalInput final # define M_POLARITY CN_polarity # define M_ID CN_id - String m_name; - uint32_t m_iPinId = 0; - Polarity_t m_polarity = Polarity_t::ActiveLow; - time_t m_ExpirationTime = 0; - bool m_bIsEnabled = false; - uint32_t m_iInputDebounceCount = 0; - FastTimer m_InputHoldTimer; - bool m_bHadLongPush = false; - bool m_bHadShortPush = false; - fsm_ExternalInput_state& m_CurrentFsmState; // initialized in constructor + String name; + uint32_t GpioId = 0; + uint32_t TriggerChannel = uint32_t(-1); + Polarity_t polarity = Polarity_t::ActiveLow; + // time_t m_ExpirationTime = 0; + bool Enabled = false; + uint32_t InputDebounceCount = 0; + FastTimer InputHoldTimer; + bool HadLongPush = false; + bool HadShortPush = false; + fsm_ExternalInput_state& CurrentFsmState; // initialized in constructor friend class fsm_ExternalInput_boot; friend class fsm_ExternalInput_off_state; From 4f0ab21cafbb3754ad29405f550266a8d0f6156c Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 17 May 2023 16:37:31 -0400 Subject: [PATCH 03/24] Removed input trigger settings --- html/index.html | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/html/index.html b/html/index.html index 12e882f08..466538bd0 100644 --- a/html/index.html +++ b/html/index.html @@ -638,30 +638,6 @@
- -
From 83f6b943681f79a192c5ebe6c1ed3f2183cb25ad Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 17 May 2023 16:38:44 -0400 Subject: [PATCH 04/24] Added ecb_channel selector --- html/script.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/html/script.js b/html/script.js index c142cb49c..9eff432eb 100644 --- a/html/script.js +++ b/html/script.js @@ -920,6 +920,7 @@ function ProcessInputConfig() { $("#ecb_enable").prop("checked", Input_Config.ecb.enabled); $("#ecb_gpioid").val(Input_Config.ecb.id); $("#ecb_polarity").val(Input_Config.ecb.polarity); + $("#ecb_chanid").val(Input_Config.ecb.channels); } // ProcessInputConfig @@ -1438,6 +1439,7 @@ function submitDeviceConfig() { Input_Config.ecb.enabled = $("#ecb_enable").is(':checked'); Input_Config.ecb.id = $("#ecb_gpioid").val(); Input_Config.ecb.polarity = $("#ecb_polarity").val(); + Input_Config.ecb.channels = $("#ecb_chanid").val(); ExtractChannelConfigFromHtmlPage(Output_Config.channels, "output"); From 10e16c7ec5b546efedba240cb620f651d52027c3 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 17 May 2023 16:39:14 -0400 Subject: [PATCH 05/24] Adjusted trigger event settings --- html/effects.html | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/html/effects.html b/html/effects.html index bf4799592..8493811b8 100644 --- a/html/effects.html +++ b/html/effects.html @@ -117,21 +117,24 @@
- Triggered Effect -
- -
- -
- -
- -
- -
- +
+ Triggered Effect +
+ + + + + + + + + + + +
- -
From 473eeea19c25924a60c150e8c3116b5c2988c07d Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 17 May 2023 16:39:57 -0400 Subject: [PATCH 06/24] Added virtual function to handle button events. --- ESPixelStick/src/input/InputCommon.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/ESPixelStick/src/input/InputCommon.hpp b/ESPixelStick/src/input/InputCommon.hpp index e9bb3b2f5..58e56da0a 100644 --- a/ESPixelStick/src/input/InputCommon.hpp +++ b/ESPixelStick/src/input/InputCommon.hpp @@ -42,6 +42,7 @@ class c_InputCommon virtual void SetOperationalState (bool ActiveFlag) { IsInputChannelActive = ActiveFlag; } virtual void NetworkStateChanged (bool IsConnected) {}; // used by poorly designed rx functions virtual bool isShutDownRebootNeeded () { return false; } + virtual void ProcessEffectsButtonActions(c_ExternalInput::InputValue_t value) {}; c_InputMgr::e_InputChannelIds GetInputChannelId () { return InputChannelId; } c_InputMgr::e_InputType GetInputType () { return ChannelType; } From 3f71deac961421bc4af5af423534534847e0493a Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 17 May 2023 18:56:55 -0400 Subject: [PATCH 07/24] Made button processing distributed. --- ESPixelStick/src/input/InputMgr.cpp | 44 ++++------------------------- 1 file changed, 5 insertions(+), 39 deletions(-) diff --git a/ESPixelStick/src/input/InputMgr.cpp b/ESPixelStick/src/input/InputMgr.cpp index 44b960eed..fa4168e60 100644 --- a/ESPixelStick/src/input/InputMgr.cpp +++ b/ESPixelStick/src/input/InputMgr.cpp @@ -160,9 +160,9 @@ void c_InputMgr::CreateJsonConfig (JsonObject & jsonConfig) // DEBUG_V (""); // extern void PrettyPrint (JsonObject & jsonStuff, String Name); - // PrettyPrint (InputMgrButtonData, String("Before")); + // PrettyPrint (InputMgrButtonData, String("Before ECB")); ExternalInput.GetConfig (InputMgrButtonData); - // PrettyPrint (InputMgrButtonData, String("After")); + // PrettyPrint (InputMgrButtonData, String("After ECB")); // DEBUG_V (""); @@ -693,45 +693,11 @@ void c_InputMgr::ProcessEffectsButtonActions () { // DEBUG_START; - if (false == ExternalInput.IsEnabled ()) + if (true == ExternalInput.IsEnabled ()) { - // DEBUG_V ("Effects Button is disabled"); - // is the effects engine running? - if (e_InputType::InputType_Effects == InputChannelDrivers[EffectsChannel].pInputChannelDriver->GetInputType ()) + for(auto & CurrentInputChannel : InputChannelDrivers) { - // is the effects engine configured to be running? - if (false == EffectEngineIsConfiguredToRun[EffectsChannel]) - { - // DEBUG_V ("turn off effects engine"); - InstantiateNewInputChannel (e_InputChannelIds (EffectsChannel), e_InputType::InputType_Disabled); - } - } - } - - else if (ExternalInput.InputHadLongPush (true)) - { - // DEBUG_V ("Had a Long Push"); - // Is the effects engine already running? - if (e_InputType::InputType_Effects == InputChannelDrivers[EffectsChannel].pInputChannelDriver->GetInputType ()) - { - // DEBUG_V ("turn off effects engine"); - InstantiateNewInputChannel (e_InputChannelIds (EffectsChannel), e_InputType::InputType_Disabled); - } - else - { - // DEBUG_V ("turn on effects engine"); - InstantiateNewInputChannel (e_InputChannelIds (EffectsChannel), e_InputType::InputType_Effects); - } - } - - else if (ExternalInput.InputHadShortPush (true)) - { - // DEBUG_V ("Had a Short Push"); - // is the effects engine running? - if (e_InputType::InputType_Effects == InputChannelDrivers[EffectsChannel].pInputChannelDriver->GetInputType ()) - { - // DEBUG_V ("tell the effects engine to go to the next effect"); - ((c_InputEffectEngine*)(InputChannelDrivers[EffectsChannel].pInputChannelDriver))->NextEffect (); + CurrentInputChannel.pInputChannelDriver->ProcessEffectsButtonActions(ExternalInput.Get()); } } From 0291173c683fe9151855f7d39707e6fa77be4ecb Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 17 May 2023 18:57:37 -0400 Subject: [PATCH 08/24] Added stub for button processing --- ESPixelStick/src/input/InputEffectEngine.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ESPixelStick/src/input/InputEffectEngine.hpp b/ESPixelStick/src/input/InputEffectEngine.hpp index 5d1a4beab..fc2955178 100644 --- a/ESPixelStick/src/input/InputEffectEngine.hpp +++ b/ESPixelStick/src/input/InputEffectEngine.hpp @@ -106,6 +106,7 @@ class c_InputEffectEngine : public c_InputCommon void GetDriverName (String & sDriverName) { sDriverName = "Effects"; } ///< get the name for the instantiated driver void SetBufferInfo (uint32_t BufferSize); void NextEffect (); + void ProcessEffectsButtonActions(c_ExternalInput::InputValue_t value); // Effect functions uint16_t effectSolidColor (); @@ -199,4 +200,10 @@ class c_InputEffectEngine : public c_InputCommon FastTimer delaytimer; FastTimer durationtimer; } FlashInfo; + + struct TriggerConfig_t + { + + } TriggerConfig; + }; From 6fe9036bfa9ecb950072a903548396126e45ce92 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 18 May 2023 19:41:09 -0400 Subject: [PATCH 09/24] Fixed detection FSM --- ESPixelStick/src/input/externalInput.cpp | 113 +++++++++-------------- ESPixelStick/src/input/externalInput.h | 35 ++----- 2 files changed, 56 insertions(+), 92 deletions(-) diff --git a/ESPixelStick/src/input/externalInput.cpp b/ESPixelStick/src/input/externalInput.cpp index 7f372f463..3076f0f64 100644 --- a/ESPixelStick/src/input/externalInput.cpp +++ b/ESPixelStick/src/input/externalInput.cpp @@ -14,7 +14,6 @@ fsm_ExternalInput_boot fsm_ExternalInput_boot_imp; fsm_ExternalInput_off_state fsm_ExternalInput_off_state_imp; -fsm_ExternalInput_on_wait_short_state fsm_ExternalInput_on_wait_short_state_imp; fsm_ExternalInput_on_wait_long_state fsm_ExternalInput_on_wait_long_state_imp; fsm_ExternalInput_wait_for_off_state fsm_ExternalInput_wait_for_off_state_imp; @@ -22,8 +21,7 @@ fsm_ExternalInput_wait_for_off_state fsm_ExternalInput_wait_for_off_state_imp; /* Code */ /*****************************************************************************/ -c_ExternalInput::c_ExternalInput(void) : - CurrentFsmState(fsm_ExternalInput_boot_imp) +c_ExternalInput::c_ExternalInput(void) { // DEBUG_START; fsm_ExternalInput_boot_imp.Init(*this); // currently redundant, but might Init() might do more ... so important to leave this @@ -53,7 +51,7 @@ c_ExternalInput::InputValue_t c_ExternalInput::Get() { // DEBUG_START; - return CurrentFsmState.Get(); + return CurrentFsmState->Get(); // DEBUG_END; @@ -62,16 +60,18 @@ c_ExternalInput::InputValue_t c_ExternalInput::Get() /*****************************************************************************/ void c_ExternalInput::GetConfig (JsonObject JsonData) { - DEBUG_START; + // DEBUG_START; JsonData[M_IO_ENABLED] = Enabled; JsonData[M_NAME] = name; JsonData[M_ID] = GpioId; JsonData[M_POLARITY] = (ActiveHigh == polarity) ? CN_ActiveHigh : CN_ActiveLow; JsonData[CN_channels] = TriggerChannel; + JsonData["long"] = LongPushDelayMS; + // DEBUG_V (String ("m_iPinId: ") + String (m_iPinId)); - DEBUG_END; + // DEBUG_END; } // GetConfig @@ -96,11 +96,12 @@ void c_ExternalInput::ProcessConfig (JsonObject JsonData) uint32_t oldInputId = GpioId; - setFromJSON (Enabled, JsonData, M_IO_ENABLED); - setFromJSON (name, JsonData, M_NAME); - setFromJSON (GpioId, JsonData, M_ID); - setFromJSON (Polarity, JsonData, M_POLARITY); - setFromJSON (TriggerChannel, JsonData, CN_channels); + setFromJSON (Enabled, JsonData, M_IO_ENABLED); + setFromJSON (name, JsonData, M_NAME); + setFromJSON (GpioId, JsonData, M_ID); + setFromJSON (Polarity, JsonData, M_POLARITY); + setFromJSON (TriggerChannel, JsonData, CN_channels); + setFromJSON (LongPushDelayMS, JsonData, "long"); polarity = (String(CN_ActiveHigh) == Polarity) ? ActiveHigh : ActiveLow; @@ -123,7 +124,8 @@ void c_ExternalInput::ProcessConfig (JsonObject JsonData) void c_ExternalInput::Poll (void) { // DEBUG_START; - CurrentFsmState.Poll (*this); + + CurrentFsmState->Poll (*this); // DEBUG_END; @@ -156,22 +158,29 @@ bool c_ExternalInput::ReadInput (void) // waiting for the system to come up void fsm_ExternalInput_boot::Init (c_ExternalInput& pExternalInput) { - pExternalInput.CurrentFsmState = fsm_ExternalInput_boot_imp; + // DEBUG_START; + pExternalInput.CurrentFsmState = &fsm_ExternalInput_boot_imp; // dont do anything + // DEBUG_END; + } // fsm_ExternalInput_boot::Init /*****************************************************************************/ // waiting for the system to come up void fsm_ExternalInput_boot::Poll (c_ExternalInput& pExternalInput) { + // DEBUG_START; + // start normal operation if (pExternalInput.Enabled) { fsm_ExternalInput_off_state_imp.Init (pExternalInput); } + // DEBUG_END; + } // fsm_ExternalInput_boot::Poll /*****************************************************************************/ @@ -180,11 +189,13 @@ void fsm_ExternalInput_boot::Poll (c_ExternalInput& pExternalInput) // Input is off and is stable void fsm_ExternalInput_off_state::Init(c_ExternalInput& pExternalInput) { - // DEBUG_START; + // DEBUG_START; + // DEBUG_V ("Entring OFF State"); pExternalInput.InputDebounceCount = MIN_INPUT_STABLE_VALUE; - pExternalInput.CurrentFsmState = fsm_ExternalInput_off_state_imp; - // DEBUG_V ("Entring OFF State"); + pExternalInput.CurrentFsmState = &fsm_ExternalInput_off_state_imp; + + // DEBUG_END; } // fsm_ExternalInput_off_state::Init @@ -204,70 +215,32 @@ void fsm_ExternalInput_off_state::Poll(c_ExternalInput& pExternalInput) if (0 == --pExternalInput.InputDebounceCount) { // we really are on - fsm_ExternalInput_on_wait_short_state_imp.Init(pExternalInput); + fsm_ExternalInput_on_wait_long_state_imp.Init(pExternalInput); } } else // still off { - // DEBUG_V (""); - // reset the debounce counter + // DEBUG_V ("reset the debounce counter"); pExternalInput.InputDebounceCount = MIN_INPUT_STABLE_VALUE; } - // DEBUG_END; + // DEBUG_END; } // fsm_ExternalInput_off_state::Poll -/*****************************************************************************/ -/*****************************************************************************/ -/*****************************************************************************/ -// Input is on and is stable -void fsm_ExternalInput_on_wait_short_state::Init(c_ExternalInput& pExternalInput) -{ - // DEBUG_START; - - pExternalInput.InputHoldTimer.StartTimer(INPUT_SHORT_VALUE_MS); - pExternalInput.CurrentFsmState = fsm_ExternalInput_on_wait_short_state_imp; - // DEBUG_V ("Entring Wait Short State"); - -} // fsm_ExternalInput_on_wait_short_state::Init - -/*****************************************************************************/ -// Input is on and is stable -void fsm_ExternalInput_on_wait_short_state::Poll(c_ExternalInput& pExternalInput) -{ - // DEBUG_START; - // read the input - bool bInputValue = pExternalInput.ReadInput (); - - // If the input is "on" - if (true == bInputValue) - { - // DEBUG_V(""); - // decrement the counter - if (pExternalInput.InputHoldTimer.IsExpired()) - { - // we really are on - fsm_ExternalInput_on_wait_long_state_imp.Init(pExternalInput); - } - } - else // Turned off - { - fsm_ExternalInput_off_state_imp.Init (pExternalInput); - } - // DEBUG_END; - -} // fsm_ExternalInput_on_wait_short_state::Poll - /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ // Input is always on void fsm_ExternalInput_on_wait_long_state::Init (c_ExternalInput& pExternalInput) { - pExternalInput.InputHoldTimer.StartTimer(INPUT_LONG_VALUE_MS); - pExternalInput.CurrentFsmState = fsm_ExternalInput_on_wait_long_state_imp; - // DEBUG_V ("Entring Wait Long State"); + // DEBUG_START; + + // DEBUG_V ("Entring Wait Long State"); + pExternalInput.InputHoldTimer.StartTimer(pExternalInput.LongPushDelayMS); + pExternalInput.CurrentFsmState = &fsm_ExternalInput_on_wait_long_state_imp; + + // DEBUG_END; } // fsm_ExternalInput_on_wait_long_state::Init @@ -290,12 +263,14 @@ void fsm_ExternalInput_on_wait_long_state::Poll (c_ExternalInput& pExternalInput // we really are on fsm_ExternalInput_wait_for_off_state_imp.Init (pExternalInput); pExternalInput.HadLongPush = true; + // DEBUG_V("HadLongPush = true") } } else // Turned off { + // DEBUG_V("HadShortPush = true") pExternalInput.HadShortPush = true; - fsm_ExternalInput_off_state_imp.Init (pExternalInput); + fsm_ExternalInput_wait_for_off_state_imp.Init (pExternalInput); } // DEBUG_END; @@ -308,8 +283,12 @@ void fsm_ExternalInput_on_wait_long_state::Poll (c_ExternalInput& pExternalInput // Input is always on void fsm_ExternalInput_wait_for_off_state::Init (c_ExternalInput& pExternalInput) { - pExternalInput.CurrentFsmState = fsm_ExternalInput_wait_for_off_state_imp; - // DEBUG_V ("Entring Wait OFF State"); + // DEBUG_START; + + // DEBUG_V ("Entring Wait OFF State"); + pExternalInput.CurrentFsmState = &fsm_ExternalInput_wait_for_off_state_imp; + + // DEBUG_END; } // fsm_ExternalInput_wait_for_off_state::Init diff --git a/ESPixelStick/src/input/externalInput.h b/ESPixelStick/src/input/externalInput.h index 886f2d5c4..c03e1c4e8 100644 --- a/ESPixelStick/src/input/externalInput.h +++ b/ESPixelStick/src/input/externalInput.h @@ -16,8 +16,8 @@ class c_ExternalInput final { off = 0, // input is off on, // input is on - shortOn, // input was on for 0.5 sec -- NOT CURRENTLY USED/IMPLEMENTED ... must call InputHadShortPush() - longOn, // input was on for 2.0 sec -- NOT CURRENTLY USED/IMPLEMENTED ... must call InputHadLongPush() + shortOn, // input was on for Date: Thu, 18 May 2023 19:42:40 -0400 Subject: [PATCH 10/24] Got ECB working --- html/effects.html | 33 ++++++++++++++++++------------- html/script.js | 50 ++++++++++++++++++++++++++++------------------- 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/html/effects.html b/html/effects.html index 8493811b8..00476cd7c 100644 --- a/html/effects.html +++ b/html/effects.html @@ -117,24 +117,29 @@
-
- Triggered Effect -
+
+
+ Triggered Effect +
- - + + - - + + - - + + - - + + + + + +
diff --git a/html/script.js b/html/script.js index 9eff432eb..15033f6cb 100644 --- a/html/script.js +++ b/html/script.js @@ -917,11 +917,14 @@ function ProcessModeConfigurationDataServoPCA9685(ServoConfig) { } // ProcessModeConfigurationDataServoPCA9685 function ProcessInputConfig() { - $("#ecb_enable").prop("checked", Input_Config.ecb.enabled); - $("#ecb_gpioid").val(Input_Config.ecb.id); - $("#ecb_polarity").val(Input_Config.ecb.polarity); - $("#ecb_chanid").val(Input_Config.ecb.channels); - + if($('#ecb_gpioid').length) + { + $('#ecb_enable').prop("checked", Input_Config.ecb.enabled); + $('#ecb_gpioid').val(Input_Config.ecb.id); + $('#ecb_polarity').val(Input_Config.ecb.polarity); + $('#ecb_chanid').val(Input_Config.ecb.channels); + $('#ecb_longPress').val(Input_Config.ecb.long); + } } // ProcessInputConfig function ProcessModeConfigurationData(channelId, ChannelType, JsonConfig) { @@ -1106,8 +1109,8 @@ function LoadDeviceSetupSelectedOption(OptionListName, DisplayedChannelId) { // try to load the field definition file for this channel type $('#' + OptionListName + 'mode' + DisplayedChannelId).load(HtmlLoadFileName, function () { if ("input" === OptionListName) { - ProcessInputConfig(); ProcessModeConfigurationData(DisplayedChannelId, OptionListName, Input_Config); + ProcessInputConfig(); } else if ("output" === OptionListName) { ProcessModeConfigurationData(DisplayedChannelId, OptionListName, Output_Config); @@ -1436,10 +1439,15 @@ function ValidateConfigFields(ElementList) { // Build dynamic JSON config submission for "Device" tab function submitDeviceConfig() { ExtractChannelConfigFromHtmlPage(Input_Config.channels, "input"); - Input_Config.ecb.enabled = $("#ecb_enable").is(':checked'); - Input_Config.ecb.id = $("#ecb_gpioid").val(); - Input_Config.ecb.polarity = $("#ecb_polarity").val(); - Input_Config.ecb.channels = $("#ecb_chanid").val(); + + if($('#ecb_gpioid').length) + { + Input_Config.ecb.enabled = $('#ecb_enable').is(':checked'); + Input_Config.ecb.id = $('#ecb_gpioid').val(); + Input_Config.ecb.polarity = $("#ecb_polarity").val(); + Input_Config.ecb.channels = $("#ecb_chanid").val(); + Input_Config.ecb.long = $("#ecb_longPress").val(); + } ExtractChannelConfigFromHtmlPage(Output_Config.channels, "output"); @@ -2019,16 +2027,18 @@ function ProcessReceivedJsonStatusMessage(data) { } let OutputStatus = Status.output[1]; - - if ({}.hasOwnProperty.call(OutputStatus, 'Relay')) { - $('#RelayStatus').removeClass("hidden") - - OutputStatus.Relay.forEach(function (currentRelay) { - $('#RelayValue_' + currentRelay.id).text(currentRelay.activevalue); - }); - } - else { - $('#RelayStatus').addClass("hidden") + if(undefined !== OutputStatus) + { + if ({}.hasOwnProperty.call(OutputStatus, 'Relay')) { + $('#RelayStatus').removeClass("hidden") + + OutputStatus.Relay.forEach(function (currentRelay) { + $('#RelayValue_' + currentRelay.id).text(currentRelay.activevalue); + }); + } + else { + $('#RelayStatus').addClass("hidden") + } } // Device Refresh is dynamic From 15bee93ce64756bf7acc019e8ec8f3673229047b Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 20 May 2023 11:48:22 -0400 Subject: [PATCH 11/24] Made process button actions public. Updated for latest API with external Input --- ESPixelStick/src/input/InputMgr.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ESPixelStick/src/input/InputMgr.hpp b/ESPixelStick/src/input/InputMgr.hpp index e67765973..d2987415d 100644 --- a/ESPixelStick/src/input/InputMgr.hpp +++ b/ESPixelStick/src/input/InputMgr.hpp @@ -60,8 +60,9 @@ class c_InputMgr void DeleteConfig () { FileMgr.DeleteConfigFile (ConfigFileName); } bool GetNetworkState () { return IsConnected; } void GetDriverName (String & Name) { Name = "InputMgr"; } - void RestartBlankTimer (c_InputMgr::e_InputChannelIds Selector) { BlankEndTime[int(Selector)].StartTimer(config.BlankDelay * 1000); } - bool BlankTimerHasExpired (c_InputMgr::e_InputChannelIds Selector) { return (BlankEndTime[int(Selector)].IsExpired()); } + void RestartBlankTimer (e_InputChannelIds Selector) { BlankEndTime[int(Selector)].StartTimer(config.BlankDelay * 1000); } + bool BlankTimerHasExpired (e_InputChannelIds Selector) { return (BlankEndTime[int(Selector)].IsExpired()); } + void ProcessButtonActions (c_ExternalInput::InputValue_t value); enum e_InputType { @@ -106,7 +107,6 @@ class c_InputMgr void CreateJsonConfig (JsonObject & jsonConfig); bool ProcessJsonChannelConfig (JsonObject & jsonConfig, uint32_t ChannelIndex); bool InputTypeIsAllowedOnChannel (e_InputType type, e_InputChannelIds ChannelId); - void ProcessEffectsButtonActions (void); String ConfigFileName; bool rebootNeeded = false; From 4cf0cf235f12c614218f350cd8cdb11625d45a77 Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 20 May 2023 11:49:05 -0400 Subject: [PATCH 12/24] Updated for latest API with external Input --- ESPixelStick/src/input/InputMgr.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/ESPixelStick/src/input/InputMgr.cpp b/ESPixelStick/src/input/InputMgr.cpp index fa4168e60..bb0bee19b 100644 --- a/ESPixelStick/src/input/InputMgr.cpp +++ b/ESPixelStick/src/input/InputMgr.cpp @@ -644,7 +644,6 @@ void c_InputMgr::Process () } ExternalInput.Poll (); - ProcessEffectsButtonActions (); if (true == configLoadNeeded) { @@ -689,21 +688,18 @@ void c_InputMgr::Process () } // Process //----------------------------------------------------------------------------- -void c_InputMgr::ProcessEffectsButtonActions () +void c_InputMgr::ProcessButtonActions (c_ExternalInput::InputValue_t value) { // DEBUG_START; - if (true == ExternalInput.IsEnabled ()) + for(auto & CurrentInputChannel : InputChannelDrivers) { - for(auto & CurrentInputChannel : InputChannelDrivers) - { - CurrentInputChannel.pInputChannelDriver->ProcessEffectsButtonActions(ExternalInput.Get()); - } + CurrentInputChannel.pInputChannelDriver->ProcessButtonActions(value); } // DEBUG_END; -} // ProcessEffectsButtonActions +} // ProcessButtonActions //----------------------------------------------------------------------------- /* From 7393c947765e219a1468fcd8c5187633f7ca81b1 Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 20 May 2023 11:51:00 -0400 Subject: [PATCH 13/24] Converted to an event driven API towards the input manager --- ESPixelStick/src/input/externalInput.cpp | 22 ++++++---------------- ESPixelStick/src/input/externalInput.h | 15 ++------------- 2 files changed, 8 insertions(+), 29 deletions(-) diff --git a/ESPixelStick/src/input/externalInput.cpp b/ESPixelStick/src/input/externalInput.cpp index 3076f0f64..6b2f77e9a 100644 --- a/ESPixelStick/src/input/externalInput.cpp +++ b/ESPixelStick/src/input/externalInput.cpp @@ -3,6 +3,7 @@ */ #include "externalInput.h" #include "../FileMgr.hpp" +#include "InputMgr.hpp" /*****************************************************************************/ /* Global Data */ @@ -46,17 +47,6 @@ void c_ExternalInput::Init(uint32_t iInputId, uint32_t iPinId, Polarity_t Polari } // Init -/*****************************************************************************/ -c_ExternalInput::InputValue_t c_ExternalInput::Get() -{ - // DEBUG_START; - - return CurrentFsmState->Get(); - - // DEBUG_END; - -} // Get - /*****************************************************************************/ void c_ExternalInput::GetConfig (JsonObject JsonData) { @@ -81,7 +71,7 @@ void c_ExternalInput::GetStatistics (JsonObject JsonData) // DEBUG_START; JsonData[M_ID] = GpioId; - JsonData[M_STATE] = (InputValue_t::on == Get ()) ? "on" : "off"; + JsonData[M_STATE] = (ReadInput()) ? "on" : "off"; // DEBUG_END; @@ -109,8 +99,6 @@ void c_ExternalInput::ProcessConfig (JsonObject JsonData) { pinMode (oldInputId, INPUT); pinMode (GpioId, INPUT_PULLUP); - HadLongPush = false; - HadShortPush = false; fsm_ExternalInput_boot_imp.Init (*this); } @@ -160,6 +148,7 @@ void fsm_ExternalInput_boot::Init (c_ExternalInput& pExternalInput) { // DEBUG_START; + // DEBUG_V ("Entring BOOT State"); pExternalInput.CurrentFsmState = &fsm_ExternalInput_boot_imp; // dont do anything @@ -194,6 +183,7 @@ void fsm_ExternalInput_off_state::Init(c_ExternalInput& pExternalInput) // DEBUG_V ("Entring OFF State"); pExternalInput.InputDebounceCount = MIN_INPUT_STABLE_VALUE; pExternalInput.CurrentFsmState = &fsm_ExternalInput_off_state_imp; + InputMgr.ProcessButtonActions(c_ExternalInput::InputValue_t::off); // DEBUG_END; @@ -262,14 +252,14 @@ void fsm_ExternalInput_on_wait_long_state::Poll (c_ExternalInput& pExternalInput { // we really are on fsm_ExternalInput_wait_for_off_state_imp.Init (pExternalInput); - pExternalInput.HadLongPush = true; + InputMgr.ProcessButtonActions(c_ExternalInput::InputValue_t::longOn); // DEBUG_V("HadLongPush = true") } } else // Turned off { // DEBUG_V("HadShortPush = true") - pExternalInput.HadShortPush = true; + InputMgr.ProcessButtonActions(c_ExternalInput::InputValue_t::shortOn); fsm_ExternalInput_wait_for_off_state_imp.Init (pExternalInput); } diff --git a/ESPixelStick/src/input/externalInput.h b/ESPixelStick/src/input/externalInput.h index c03e1c4e8..8198c3fba 100644 --- a/ESPixelStick/src/input/externalInput.h +++ b/ESPixelStick/src/input/externalInput.h @@ -15,9 +15,8 @@ class c_ExternalInput final enum InputValue_t { off = 0, // input is off - on, // input is on - shortOn, // input was on for Date: Sat, 20 May 2023 11:51:30 -0400 Subject: [PATCH 14/24] Updated for latest API with external Input Fixed a wraparound bug in nexteffect action. --- ESPixelStick/src/input/InputCommon.hpp | 2 +- ESPixelStick/src/input/InputEffectEngine.cpp | 35 ++++++++++++++++---- ESPixelStick/src/input/InputEffectEngine.hpp | 8 ++--- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/ESPixelStick/src/input/InputCommon.hpp b/ESPixelStick/src/input/InputCommon.hpp index 58e56da0a..a0a6043d1 100644 --- a/ESPixelStick/src/input/InputCommon.hpp +++ b/ESPixelStick/src/input/InputCommon.hpp @@ -42,7 +42,7 @@ class c_InputCommon virtual void SetOperationalState (bool ActiveFlag) { IsInputChannelActive = ActiveFlag; } virtual void NetworkStateChanged (bool IsConnected) {}; // used by poorly designed rx functions virtual bool isShutDownRebootNeeded () { return false; } - virtual void ProcessEffectsButtonActions(c_ExternalInput::InputValue_t value) {}; + virtual void ProcessButtonActions(c_ExternalInput::InputValue_t value) {}; c_InputMgr::e_InputChannelIds GetInputChannelId () { return InputChannelId; } c_InputMgr::e_InputType GetInputType () { return ChannelType; } diff --git a/ESPixelStick/src/input/InputEffectEngine.cpp b/ESPixelStick/src/input/InputEffectEngine.cpp index a9f5dd758..732f30b0a 100644 --- a/ESPixelStick/src/input/InputEffectEngine.cpp +++ b/ESPixelStick/src/input/InputEffectEngine.cpp @@ -109,6 +109,7 @@ c_InputEffectEngine::c_InputEffectEngine () : // DEBUG_END; } // c_InputEffectEngine + //----------------------------------------------------------------------------- c_InputEffectEngine::~c_InputEffectEngine () { @@ -264,7 +265,7 @@ void c_InputEffectEngine::NextEffect () // we now have the index of the current effect ++CurrentEffectIndex; - if (String ("Breathe") == ActiveEffect->name) + if (sizeof(ListOfEffects)/sizeof(ListOfEffects[0]) <= CurrentEffectIndex) { // DEBUG_V ("Wrap to first effect"); CurrentEffectIndex = 0; @@ -341,7 +342,7 @@ void c_InputEffectEngine::Process () } // DEBUG_V ("Init OK"); - if (0 == PixelCount) + if ((0 == PixelCount) || (StayDark)) { break; } @@ -349,29 +350,49 @@ void c_InputEffectEngine::Process () if(!EffectDelayTimer.IsExpired()) { + PollFlash(); break; } // DEBUG_V ("Update output"); - EffectDelayTimer.StartTimer(EffectWait); uint32_t wait = (this->*ActiveEffect->func)(); EffectWait = max ((int)wait, MIN_EFFECT_DELAY); + EffectDelayTimer.StartTimer(EffectWait); EffectCounter++; InputMgr.RestartBlankTimer (GetInputChannelId ()); - } while (false); + PollFlash(); - PollFlash(); + } while (false); // DEBUG_END; } // process //---------------------------------------------------------------------------- -void c_InputEffectEngine::ProcessEffectsButtonActions(c_ExternalInput::InputValue_t value) +void c_InputEffectEngine::ProcessButtonActions(c_ExternalInput::InputValue_t value) { + // DEBUG_START; + + if(c_ExternalInput::InputValue_t::longOn == value) + { + // DEBUG_V("flip the dark flag"); + StayDark = !StayDark; + // DEBUG_V(String("StayDark: ") + String(StayDark)); -} // ProcessEffectsButtonActions + } + else if(c_ExternalInput::InputValue_t::shortOn == value) + { + // DEBUG_V("Move to the next effect"); + NextEffect(); + } + else if(c_ExternalInput::InputValue_t::off == value) + { + // DEBUG_V("Got input Off notification"); + } + + // DEBUG_END; +} // ProcessButtonActions //----------------------------------------------------------------------------- void c_InputEffectEngine::SetBufferInfo (uint32_t BufferSize) diff --git a/ESPixelStick/src/input/InputEffectEngine.hpp b/ESPixelStick/src/input/InputEffectEngine.hpp index fc2955178..3096ab34a 100644 --- a/ESPixelStick/src/input/InputEffectEngine.hpp +++ b/ESPixelStick/src/input/InputEffectEngine.hpp @@ -106,7 +106,7 @@ class c_InputEffectEngine : public c_InputCommon void GetDriverName (String & sDriverName) { sDriverName = "Effects"; } ///< get the name for the instantiated driver void SetBufferInfo (uint32_t BufferSize); void NextEffect (); - void ProcessEffectsButtonActions(c_ExternalInput::InputValue_t value); + void ProcessButtonActions(c_ExternalInput::InputValue_t value); // Effect functions uint16_t effectSolidColor (); @@ -146,6 +146,7 @@ class c_InputEffectEngine : public c_InputCommon bool EffectWhiteChannel = false; float EffectBrightness = 1.0; /* Externally controlled effect brightness [0, 255] */ CRGB EffectColor = { 183, 0, 255 }; /* Externally controlled effect color */ + bool StayDark = false; uint32_t effectMarqueePixelAdvanceCount = 1; uint32_t effectMarqueePixelLocation = 0; @@ -201,9 +202,4 @@ class c_InputEffectEngine : public c_InputCommon FastTimer durationtimer; } FlashInfo; - struct TriggerConfig_t - { - - } TriggerConfig; - }; From eaf9673ef0d29339704155f501ae28d8205ccbd6 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 23 May 2023 16:01:43 -0400 Subject: [PATCH 15/24] Build a vector list of the files on the SD card. --- ESPixelStick/src/FileMgr.cpp | 49 ++++++++++++++++++++++++++++++++++++ ESPixelStick/src/FileMgr.hpp | 2 ++ 2 files changed, 51 insertions(+) diff --git a/ESPixelStick/src/FileMgr.cpp b/ESPixelStick/src/FileMgr.cpp index 047240d23..690da8818 100644 --- a/ESPixelStick/src/FileMgr.cpp +++ b/ESPixelStick/src/FileMgr.cpp @@ -794,6 +794,55 @@ void c_FileMgr::GetListOfSdFiles (String & Response) } // GetListOfFiles +//----------------------------------------------------------------------------- +void c_FileMgr::GetListOfSdFiles (std::vector & Response) +{ + // DEBUG_START; + + Response.clear(); + do // once + { + if (false == SdCardIsInstalled ()) + { + // DEBUG_V("No SD Card installed"); + break; + } + + File dir = ESP_SDFS.open ("/", CN_r); + + while (true) + { + File entry = dir.openNextFile (); + + if (!entry) + { + // DEBUG_V("no more files"); + break; + } + + String EntryName = String (entry.name ()); + EntryName = EntryName.substring ((('/' == EntryName[0]) ? 1 : 0)); + // DEBUG_V ("EntryName: '" + EntryName + "'"); + // DEBUG_V ("EntryName.length(): " + String(EntryName.length ())); + + if ((0 != EntryName.length ()) && + (EntryName != String (F ("System Volume Information"))) && + (0 != entry.size ()) + ) + { + // DEBUG_V ("Adding File: '" + EntryName + "'"); + Response.push_back(EntryName); + } + + entry.close (); + } + + dir.close(); + } while (false); + + // DEBUG_END; +} // GetListOfSdFiles + //----------------------------------------------------------------------------- void c_FileMgr::printDirectory (File dir, int numTabs) { diff --git a/ESPixelStick/src/FileMgr.hpp b/ESPixelStick/src/FileMgr.hpp index 64fcdd04d..7c2992116 100644 --- a/ESPixelStick/src/FileMgr.hpp +++ b/ESPixelStick/src/FileMgr.hpp @@ -27,6 +27,7 @@ # include #endif // def SUPPORT_SD_MMC #include +#include #ifdef ARDUINO_ARCH_ESP32 # ifdef SUPPORT_SD_MMC @@ -89,6 +90,7 @@ class c_FileMgr size_t WriteSdFile (const FileId & FileHandle, byte * FileData, size_t NumBytesToWrite, size_t StartingPosition); void CloseSdFile (const FileId & FileHandle); void GetListOfSdFiles (String & Response); + void GetListOfSdFiles (std::vector & Response); size_t GetSdFileSize (const String & FileName); size_t GetSdFileSize (const FileId & FileHandle); void GetDriverName (String& Name) { Name = "FileMgr"; } From ffc7f6b792b29e627a551cffc05913224854c558 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 23 May 2023 16:02:23 -0400 Subject: [PATCH 16/24] Added support for cycleing through fseq files in response to a button press. --- ESPixelStick/src/input/InputFPPRemote.cpp | 105 +++++++++++++++++++++- ESPixelStick/src/input/InputFPPRemote.h | 9 +- 2 files changed, 108 insertions(+), 6 deletions(-) diff --git a/ESPixelStick/src/input/InputFPPRemote.cpp b/ESPixelStick/src/input/InputFPPRemote.cpp index 84890acf1..203ecb423 100644 --- a/ESPixelStick/src/input/InputFPPRemote.cpp +++ b/ESPixelStick/src/input/InputFPPRemote.cpp @@ -109,11 +109,87 @@ void c_InputFPPRemote::GetStatus (JsonObject& jsonStatus) } // GetStatus +//----------------------------------------------------------------------------- +void c_InputFPPRemote::PlayNextFile () +{ + // DEBUG_START; + do // once + { + std::vector ListOfFiles; + FileMgr.GetListOfSdFiles(ListOfFiles); + ListOfFiles.shrink_to_fit(); + // DEBUG_V(String("Num Files Found: ") + String(ListOfFiles.size())); + + if(0 == ListOfFiles.size()) + { + // no files. Dont continue + break; + } + + // DEBUG_V(String("File Being Played: '") + FileBeingPlayed + "'"); + // find the current file + std::vector::iterator FileIterator = ListOfFiles.end(); + std::vector::iterator CurrentFileInList = ListOfFiles.begin(); + while (CurrentFileInList != ListOfFiles.end()) + { + // DEBUG_V(String("CurrentFileInList: '") + *CurrentFileInList + "'"); + + if((*CurrentFileInList).equals(FileBeingPlayed)) + { + // DEBUG_V("Found File"); + FileIterator = ++CurrentFileInList; + break; + } + ++CurrentFileInList; + } + + // DEBUG_V("now find the next file"); + do + { + // did we wrap? + if(ListOfFiles.end() == CurrentFileInList) + { + // DEBUG_V("Handle wrap"); + CurrentFileInList = ListOfFiles.begin(); + } + // DEBUG_V(String("CurrentFileInList: '") + *CurrentFileInList + "'"); + + // is this a valid file? + if( (-1 != (*CurrentFileInList).indexOf(".fseq")) && (-1 != (*CurrentFileInList).indexOf(".pl"))) + { + // DEBUG_V("try the next file"); + // get the next file + ++CurrentFileInList; + + continue; + } + + // DEBUG_V(String("CurrentFileInList: '") + *CurrentFileInList + "'"); + + // did we come all the way around? + if((*CurrentFileInList).equals(FileBeingPlayed)) + { + // DEBUG_V("no other file to play. Keep playing it."); + break; + } + + // DEBUG_V(String("Succes - we have found a new file to play: '") + *CurrentFileInList + "'"); + StopPlaying(); + StartPlaying(*CurrentFileInList); + break; + } while (FileIterator != CurrentFileInList); + + } while(false); + + // DEBUG_END; + +} // PlayNextFile + //----------------------------------------------------------------------------- void c_InputFPPRemote::Process () { // DEBUG_START; - if (!IsInputChannelActive) + if (!IsInputChannelActive || StayDark) { // DEBUG_V ("dont do anything if the channel is not active"); StopPlaying (); @@ -134,14 +210,35 @@ void c_InputFPPRemote::Process () StartPlaying (FileBeingPlayed); } } - else - { - } // DEBUG_END; } // process +//----------------------------------------------------------------------------- +void c_InputFPPRemote::ProcessButtonActions(c_ExternalInput::InputValue_t value) +{ + // DEBUG_START; + + if(c_ExternalInput::InputValue_t::longOn == value) + { + // DEBUG_V("flip the dark flag"); + StayDark = !StayDark; + // DEBUG_V(String("StayDark: ") + String(StayDark)); + } + else if(c_ExternalInput::InputValue_t::shortOn == value) + { + // DEBUG_V("Are we playing a local file?"); + PlayNextFile(); + } + else if(c_ExternalInput::InputValue_t::off == value) + { + // DEBUG_V("Got input Off notification"); + } + + // DEBUG_END; +} // ProcessButtonActions + //----------------------------------------------------------------------------- void c_InputFPPRemote::SetBufferInfo (uint32_t BufferSize) { diff --git a/ESPixelStick/src/input/InputFPPRemote.h b/ESPixelStick/src/input/InputFPPRemote.h index 92a67d83f..c56aa0fe3 100644 --- a/ESPixelStick/src/input/InputFPPRemote.h +++ b/ESPixelStick/src/input/InputFPPRemote.h @@ -41,13 +41,17 @@ class c_InputFPPRemote : public c_InputCommon void Process (); ///< Call from loop(), renders Input data void GetDriverName (String& sDriverName) { sDriverName = "FPP Remote"; } ///< get the name for the instantiated driver void SetBufferInfo (uint32_t BufferSize); + void ProcessButtonActions(c_ExternalInput::InputValue_t value); protected: - c_InputFPPRemotePlayItem * pInputFPPRemotePlayItem = nullptr; - String StatusType; # define No_LocalFileToPlay "..." + + c_InputFPPRemotePlayItem * pInputFPPRemotePlayItem = nullptr; int32_t GetSyncOffsetMS () { return SyncOffsetMS; } + String StatusType; + bool StayDark = false; + private: void validateConfiguration (); @@ -57,6 +61,7 @@ class c_InputFPPRemote : public c_InputCommon void StopPlaying (); bool PlayingFile (); bool PlayingRemoteFile (); + void PlayNextFile (); void load (); ///< Load configuration from File System void save (); ///< Save configuration to File System From a90cd5267df9c9e1d57315e1f310f6e400817ad1 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 23 May 2023 16:35:42 -0400 Subject: [PATCH 17/24] Upgraded to Arduion ESP version 2.0.9 --- platformio.ini | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 390998dd2..f671faf48 100644 --- a/platformio.ini +++ b/platformio.ini @@ -103,8 +103,10 @@ extra_scripts = ${env.extra_scripts} extends = esp32 build_flags = ${esp32.build_flags} -mtext-section-literals platform = https://github.com/platformio/platform-espressif32.git#48c4226e5240c873dae6b28adbb93ad8ca582b5d +; platform = https://github.com/platformio/platform-espressif32.git platform_packages = - framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.3 ; + framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.9 ; +; framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.3 ; ; framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.2 ; runs real slow ; framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.1 ; Has general issues ; framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.0 ; SD card not stable on cam card From 66b509ffd56641ca050a49c9ccfa476ce1d3770d Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 23 May 2023 16:55:53 -0400 Subject: [PATCH 18/24] Moved ECB to a common space since it is shared by input modes. --- html/effects.html | 26 -------------------------- html/index.html | 25 +++++++++++++++++++++++++ html/script.js | 31 +++++++++++++++---------------- 3 files changed, 40 insertions(+), 42 deletions(-) diff --git a/html/effects.html b/html/effects.html index 00476cd7c..5bcb91e26 100644 --- a/html/effects.html +++ b/html/effects.html @@ -116,30 +116,4 @@
- -
-
- Triggered Effect -
- - - - - - - - - - - - - - - -
-
-
diff --git a/html/index.html b/html/index.html index 466538bd0..8d403feae 100644 --- a/html/index.html +++ b/html/index.html @@ -636,6 +636,31 @@
+ +
+ Triggered Effect +
+ + + + + + + + + + + + + + + +
+
+
diff --git a/html/script.js b/html/script.js index 15033f6cb..d32d31f65 100644 --- a/html/script.js +++ b/html/script.js @@ -917,14 +917,11 @@ function ProcessModeConfigurationDataServoPCA9685(ServoConfig) { } // ProcessModeConfigurationDataServoPCA9685 function ProcessInputConfig() { - if($('#ecb_gpioid').length) - { - $('#ecb_enable').prop("checked", Input_Config.ecb.enabled); - $('#ecb_gpioid').val(Input_Config.ecb.id); - $('#ecb_polarity').val(Input_Config.ecb.polarity); - $('#ecb_chanid').val(Input_Config.ecb.channels); - $('#ecb_longPress').val(Input_Config.ecb.long); - } + $('#ecb_enable').prop("checked", Input_Config.ecb.enabled); + $('#ecb_gpioid').val(Input_Config.ecb.id); + $('#ecb_polarity').val(Input_Config.ecb.polarity); + $('#ecb_chanid').val(Input_Config.ecb.channels); + $('#ecb_longPress').val(Input_Config.ecb.long); } // ProcessInputConfig function ProcessModeConfigurationData(channelId, ChannelType, JsonConfig) { @@ -970,13 +967,18 @@ function ProcessModeConfigurationData(channelId, ChannelType, JsonConfig) { } }); + // by default, do not show the ECB config data + $('#ecb').addClass("hidden"); + if ("fpp_remote" === ChannelTypeName) { + $('#ecb').removeClass("hidden"); if (null !== Fseq_File_List) { ProcessModeConfigurationDatafppremote(channelConfig); } } else if ("effects" === ChannelTypeName) { + $('#ecb').removeClass("hidden"); ProcessModeConfigurationDataEffects(channelConfig); } @@ -1440,14 +1442,11 @@ function ValidateConfigFields(ElementList) { function submitDeviceConfig() { ExtractChannelConfigFromHtmlPage(Input_Config.channels, "input"); - if($('#ecb_gpioid').length) - { - Input_Config.ecb.enabled = $('#ecb_enable').is(':checked'); - Input_Config.ecb.id = $('#ecb_gpioid').val(); - Input_Config.ecb.polarity = $("#ecb_polarity").val(); - Input_Config.ecb.channels = $("#ecb_chanid").val(); - Input_Config.ecb.long = $("#ecb_longPress").val(); - } + Input_Config.ecb.enabled = $('#ecb_enable').is(':checked'); + Input_Config.ecb.id = $('#ecb_gpioid').val(); + Input_Config.ecb.polarity = $("#ecb_polarity").val(); + Input_Config.ecb.channels = $("#ecb_chanid").val(); + Input_Config.ecb.long = $("#ecb_longPress").val(); ExtractChannelConfigFromHtmlPage(Output_Config.channels, "output"); From fa19731d14a7dd72379a1bc9ff3985929c13a89f Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 23 May 2023 17:02:34 -0400 Subject: [PATCH 19/24] Fixed a tooling error. --- platformio.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio.ini b/platformio.ini index f671faf48..8ecbbbe78 100644 --- a/platformio.ini +++ b/platformio.ini @@ -110,6 +110,7 @@ platform_packages = ; framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.2 ; runs real slow ; framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.1 ; Has general issues ; framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.0 ; SD card not stable on cam card +board_build.arduino.upstream_packages = no ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; ; Build targets (environments) ; From 3c7cac17e105b19ed172eaddd61750d326aafe91 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 24 May 2023 13:27:11 -0400 Subject: [PATCH 20/24] Removed trigger channel from conifiguration Made most trigger fields advanced mode only --- html/index.html | 21 +++++++++------------ html/script.js | 2 -- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/html/index.html b/html/index.html index 8d403feae..428072ffc 100644 --- a/html/index.html +++ b/html/index.html @@ -637,27 +637,24 @@
-
- Triggered Effect + diff --git a/html/script.js b/html/script.js index d32d31f65..34ecc49be 100644 --- a/html/script.js +++ b/html/script.js @@ -920,7 +920,6 @@ function ProcessInputConfig() { $('#ecb_enable').prop("checked", Input_Config.ecb.enabled); $('#ecb_gpioid').val(Input_Config.ecb.id); $('#ecb_polarity').val(Input_Config.ecb.polarity); - $('#ecb_chanid').val(Input_Config.ecb.channels); $('#ecb_longPress').val(Input_Config.ecb.long); } // ProcessInputConfig @@ -1445,7 +1444,6 @@ function submitDeviceConfig() { Input_Config.ecb.enabled = $('#ecb_enable').is(':checked'); Input_Config.ecb.id = $('#ecb_gpioid').val(); Input_Config.ecb.polarity = $("#ecb_polarity").val(); - Input_Config.ecb.channels = $("#ecb_chanid").val(); Input_Config.ecb.long = $("#ecb_longPress").val(); ExtractChannelConfigFromHtmlPage(Output_Config.channels, "output"); From 8d2eda7731ae44dd47f15168fa41aaca50c68076 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 25 May 2023 06:27:39 -0400 Subject: [PATCH 21/24] Added flash min intensity levels --- html/effects.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/html/effects.html b/html/effects.html index 5bcb91e26..aaa7ee1a2 100644 --- a/html/effects.html +++ b/html/effects.html @@ -63,8 +63,8 @@ - '; - '; + '; + '; '; '; '; From 86f5aacca899fe569818f8da8407733e389b1655 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 25 May 2023 06:28:08 -0400 Subject: [PATCH 22/24] Increased the button debounce count --- ESPixelStick/src/input/externalInput.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ESPixelStick/src/input/externalInput.h b/ESPixelStick/src/input/externalInput.h index 8198c3fba..17e231272 100644 --- a/ESPixelStick/src/input/externalInput.h +++ b/ESPixelStick/src/input/externalInput.h @@ -74,7 +74,7 @@ class fsm_ExternalInput_state virtual void Init(c_ExternalInput& pExternalInput) = 0; virtual ~fsm_ExternalInput_state() {}; private: -#define MIN_INPUT_STABLE_VALUE 5 +#define MIN_INPUT_STABLE_VALUE 50 }; // fsm_ExternalInput_state From 5c88d33a5d005a06bd48b6557ca7b6d67505b155 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 25 May 2023 06:28:39 -0400 Subject: [PATCH 23/24] Fixed a build warning --- ESPixelStick/src/input/InputEffectEngine.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ESPixelStick/src/input/InputEffectEngine.cpp b/ESPixelStick/src/input/InputEffectEngine.cpp index 732f30b0a..bd1767957 100644 --- a/ESPixelStick/src/input/InputEffectEngine.cpp +++ b/ESPixelStick/src/input/InputEffectEngine.cpp @@ -250,7 +250,7 @@ void c_InputEffectEngine::NextEffect () // DEBUG_START; // DEBUG_V ("Find the current effect"); - int CurrentEffectIndex = 0; + uint32_t CurrentEffectIndex = 0; for (const EffectDescriptor_t currentEffect : ListOfEffects) { // DEBUG_V (String ("currentEffect.name: ") + currentEffect.name); @@ -443,6 +443,12 @@ bool c_InputEffectEngine::SetConfig (ArduinoJson::JsonObject& jsonConfig) setFromJSON (FlashInfo.MinDurationMS, jsonConfig, "FlashMinDur"); setFromJSON (FlashInfo.MaxDurationMS, jsonConfig, "FlashMaxDur"); + // make sure max is really max + if(FlashInfo.MinIntensity >= FlashInfo.MaxIntensity) + { + FlashInfo.MinIntensity = FlashInfo.MaxIntensity; + } + if(jsonConfig.containsKey(CN_transitions)) { TransitionColorTable.clear(); From f409aaf157f197cce201ecf5e0a7b31c1c902654 Mon Sep 17 00:00:00 2001 From: Martin Date: Thu, 25 May 2023 06:29:38 -0400 Subject: [PATCH 24/24] Added information about additional platform support. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d0248e8ff..d070b49ff 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ If you would like to compile the project yourself and modify the source code, go ## Hardware -Being open source, you are free to use the ESPixelStick firmware on the device of your choice. The code however is written specifically for the [ESPixelStick](http://forkineye.com/espixelstick). The ESPixelStick V3 utilizes a Wemos D1 Mini module and provides high current connectors, fusing, power filtering, reverse polarity protection, a differential output driver, SD card reader and proper logic level buffering. The ESPixelStick V3 is available for purchase from [Forkineye](https://forkineye.com/product/espixelstick-v3/) and if you're in the US, it is available via [Amazon](https://amzn.to/3kVb7tq) as well. The proceeds go towards things like keeping my wife happy so I can work on this project :) The ESP32 version of the firmware is targeted for the Lolin D32 Pro. At this time, there is not a pre-made ESP32 controller so it is up to the user to roll their own buffer for the WS281x output and add appropriate power connectors. It does however have a SD card reader. +Being open source, you are free to use the ESPixelStick firmware on the device of your choice. The code however is written specifically for the [ESPixelStick](http://forkineye.com/espixelstick). The ESPixelStick V3 utilizes a Wemos D1 Mini module and provides high current connectors, fusing, power filtering, reverse polarity protection, a differential output driver, SD card reader and proper logic level buffering. The ESPixelStick V3 is available for purchase from [Forkineye](https://forkineye.com/product/espixelstick-v3/) and if you're in the US, it is available via [Amazon](https://amzn.to/3kVb7tq) as well. The proceeds go towards things like keeping my wife happy so I can work on this project :) The ESP32 version of the firmware is targeted for the Lolin D32 Pro. At this time, there is not a pre-made ESP32 controller so it is up to the user to roll their own buffer for the WS281x output and add appropriate power connectors. It does however have a SD card reader. A wide variety of additional platforms have been added to the supported devices list (28 as of this writting). All of which have artifacts created every build. ## Build Requirements