Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added new button support and Marquee effect #635

Merged
merged 25 commits into from
Jun 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f1e681b
Fixed warnings on float calculation
MartinMueller2003 May 17, 2023
36899ff
Refactoring for clarity
MartinMueller2003 May 17, 2023
4f0ab21
Removed input trigger settings
MartinMueller2003 May 17, 2023
83f6b94
Added ecb_channel selector
MartinMueller2003 May 17, 2023
10e16c7
Adjusted trigger event settings
MartinMueller2003 May 17, 2023
473eeea
Added virtual function to handle button events.
MartinMueller2003 May 17, 2023
3f71dea
Made button processing distributed.
MartinMueller2003 May 17, 2023
0291173
Added stub for button processing
MartinMueller2003 May 17, 2023
6fe9036
Fixed detection FSM
MartinMueller2003 May 18, 2023
548f2bb
Got ECB working
MartinMueller2003 May 18, 2023
15bee93
Made process button actions public.
MartinMueller2003 May 20, 2023
4cf0cf2
Updated for latest API with external Input
MartinMueller2003 May 20, 2023
7393c94
Converted to an event driven API towards the input manager
MartinMueller2003 May 20, 2023
4601dc3
Updated for latest API with external Input
MartinMueller2003 May 20, 2023
4ee0dd9
Merge branch 'main' of https://github.com/MartinMueller2003/ESPixelStick
MartinMueller2003 May 20, 2023
eaf9673
Build a vector list of the files on the SD card.
MartinMueller2003 May 23, 2023
ffc7f6b
Added support for cycleing through fseq files in response to a button…
MartinMueller2003 May 23, 2023
a90cd52
Upgraded to Arduion ESP version 2.0.9
MartinMueller2003 May 23, 2023
66b509f
Moved ECB to a common space since it is shared by input modes.
MartinMueller2003 May 23, 2023
fa19731
Fixed a tooling error.
MartinMueller2003 May 23, 2023
3c7cac1
Removed trigger channel from conifiguration
MartinMueller2003 May 24, 2023
8d2eda7
Added flash min intensity levels
MartinMueller2003 May 25, 2023
86f5aac
Increased the button debounce count
MartinMueller2003 May 25, 2023
5c88d33
Fixed a build warning
MartinMueller2003 May 25, 2023
f409aaf
Added information about additional platform support.
MartinMueller2003 May 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions ESPixelStick/src/FileMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,55 @@ void c_FileMgr::GetListOfSdFiles (String & Response)

} // GetListOfFiles

//-----------------------------------------------------------------------------
void c_FileMgr::GetListOfSdFiles (std::vector<String> & 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)
{
Expand Down
2 changes: 2 additions & 0 deletions ESPixelStick/src/FileMgr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
# include <SD.h>
#endif // def SUPPORT_SD_MMC
#include <map>
#include <vector>

#ifdef ARDUINO_ARCH_ESP32
# ifdef SUPPORT_SD_MMC
Expand Down Expand Up @@ -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<String> & Response);
size_t GetSdFileSize (const String & FileName);
size_t GetSdFileSize (const FileId & FileHandle);
void GetDriverName (String& Name) { Name = "FileMgr"; }
Expand Down
1 change: 1 addition & 0 deletions ESPixelStick/src/input/InputCommon.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 ProcessButtonActions(c_ExternalInput::InputValue_t value) {};

c_InputMgr::e_InputChannelIds GetInputChannelId () { return InputChannelId; }
c_InputMgr::e_InputType GetInputType () { return ChannelType; }
Expand Down
47 changes: 40 additions & 7 deletions ESPixelStick/src/input/InputEffectEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ c_InputEffectEngine::c_InputEffectEngine () :
// DEBUG_END;

} // c_InputEffectEngine

//-----------------------------------------------------------------------------
c_InputEffectEngine::~c_InputEffectEngine ()
{
Expand Down Expand Up @@ -249,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);
Expand All @@ -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;
Expand Down Expand Up @@ -341,32 +342,58 @@ void c_InputEffectEngine::Process ()
}
// DEBUG_V ("Init OK");

if (0 == PixelCount)
if ((0 == PixelCount) || (StayDark))
{
break;
}
// DEBUG_V ("Pixel Count OK");

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::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("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)
{
Expand Down Expand Up @@ -416,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();
Expand Down Expand Up @@ -1278,7 +1311,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) });
Expand Down
3 changes: 3 additions & 0 deletions ESPixelStick/src/input/InputEffectEngine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 ProcessButtonActions(c_ExternalInput::InputValue_t value);

// Effect functions
uint16_t effectSolidColor ();
Expand Down Expand Up @@ -145,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;
Expand Down Expand Up @@ -199,4 +201,5 @@ class c_InputEffectEngine : public c_InputCommon
FastTimer delaytimer;
FastTimer durationtimer;
} FlashInfo;

};
105 changes: 101 additions & 4 deletions ESPixelStick/src/input/InputFPPRemote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,87 @@ void c_InputFPPRemote::GetStatus (JsonObject& jsonStatus)

} // GetStatus

//-----------------------------------------------------------------------------
void c_InputFPPRemote::PlayNextFile ()
{
// DEBUG_START;
do // once
{
std::vector<String> 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<String>::iterator FileIterator = ListOfFiles.end();
std::vector<String>::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 ();
Expand All @@ -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)
{
Expand Down
9 changes: 7 additions & 2 deletions ESPixelStick/src/input/InputFPPRemote.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 ();
Expand All @@ -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
Expand Down
Loading