Skip to content

Commit

Permalink
Merge pull request #635 from MartinMueller2003/main
Browse files Browse the repository at this point in the history
Added new button support and Marquee effect
  • Loading branch information
forkineye committed Jun 5, 2023
2 parents ae3e177 + f409aaf commit 615e493
Show file tree
Hide file tree
Showing 16 changed files with 357 additions and 313 deletions.
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

0 comments on commit 615e493

Please sign in to comment.