From 5002f58fac7fa8a91c5b1b0d1a2e92070a0394f7 Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Sun, 17 Oct 2021 18:46:36 -0400 Subject: [PATCH 1/8] Expanded sync adjustment range. --- html/fpp_remote.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/html/fpp_remote.html b/html/fpp_remote.html index 05ee1a138..c572524b0 100644 --- a/html/fpp_remote.html +++ b/html/fpp_remote.html @@ -7,7 +7,7 @@
- +
\ No newline at end of file From ee560d2b6fb4100035f1d278bfd1d71cb4dc84df Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Sun, 17 Oct 2021 20:08:15 -0400 Subject: [PATCH 2/8] Fixed issue with floating point comparison in json read. --- ESPixelStick/src/ESPixelStick.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/ESPixelStick/src/ESPixelStick.h b/ESPixelStick/src/ESPixelStick.h index 4e2016094..635d3ec21 100644 --- a/ESPixelStick/src/ESPixelStick.h +++ b/ESPixelStick/src/ESPixelStick.h @@ -80,6 +80,24 @@ extern bool IsBooting; extern bool ResetWiFi; static const String ConfigFileName = "/config.json"; +template +bool setFromJSON (float & OutValue, J& Json, N Name) +{ + bool HasBeenModified = false; + + if (true == Json.containsKey (Name)) + { + float temp = Json[Name]; + if (fabs (temp - OutValue) > 0.000005F) + { + OutValue = temp; + HasBeenModified = true; + } + } + + return HasBeenModified; +}; + template bool setFromJSON (T& OutValue, J& Json, N Name) { From 08596fa274e72092841b18fe019f45a91a1073ae Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Sun, 17 Oct 2021 20:14:45 -0400 Subject: [PATCH 3/8] Added save to sd card of synch offset at the end of playing a file to allow the value to persist over reboots. --- .../src/input/InputFPPRemotePlayFile.cpp | 122 +++++++++++++++--- .../src/input/InputFPPRemotePlayFile.hpp | 11 +- .../src/input/InputFPPRemotePlayFileFsm.cpp | 16 ++- 3 files changed, 123 insertions(+), 26 deletions(-) diff --git a/ESPixelStick/src/input/InputFPPRemotePlayFile.cpp b/ESPixelStick/src/input/InputFPPRemotePlayFile.cpp index 6582d1f27..bfe380b42 100644 --- a/ESPixelStick/src/input/InputFPPRemotePlayFile.cpp +++ b/ESPixelStick/src/input/InputFPPRemotePlayFile.cpp @@ -26,7 +26,6 @@ c_InputFPPRemotePlayFile::c_InputFPPRemotePlayFile (c_InputMgr::e_InputChannelId c_InputFPPRemotePlayItem (InputChannelId) { // DEBUG_START; - fsm_PlayFile_state_Idle_imp.Init (this); // DEBUG_END; @@ -86,6 +85,7 @@ void c_InputFPPRemotePlayFile::Poll (uint8_t * Buffer, size_t BufferSize) { // DEBUG_START; + InitTimeCorrectionFactor (); pCurrentFsmState->Poll (Buffer, BufferSize); // DEBUG_END; @@ -218,19 +218,19 @@ bool c_InputFPPRemotePlayFile::ParseFseqFile () // #define DUMP_FSEQ_HEADER #ifdef DUMP_FSEQ_HEADER - DEBUG_V (String (" dataOffset: ") + String (fsqParsedHeader.dataOffset)); - DEBUG_V (String (" minorVersion: ") + String (fsqParsedHeader.minorVersion)); - DEBUG_V (String (" majorVersion: ") + String (fsqParsedHeader.majorVersion)); - DEBUG_V (String (" VariableHdrOffset: ") + String (fsqParsedHeader.VariableHdrOffset)); - DEBUG_V (String (" channelCount: ") + String (fsqParsedHeader.channelCount)); - DEBUG_V (String ("TotalNumberOfFramesInSequence: ") + String (fsqParsedHeader.TotalNumberOfFramesInSequence)); - DEBUG_V (String (" stepTime: ") + String (fsqParsedHeader.stepTime)); - DEBUG_V (String (" flags: ") + String (fsqParsedHeader.flags)); - DEBUG_V (String (" compressionType: 0x") + String (fsqParsedHeader.compressionType, HEX)); - DEBUG_V (String (" numCompressedBlocks: ") + String (fsqParsedHeader.numCompressedBlocks)); - DEBUG_V (String (" numSparseRanges: ") + String (fsqParsedHeader.numSparseRanges)); - DEBUG_V (String (" flags2: ") + String (fsqParsedHeader.flags2)); - DEBUG_V (String (" id: 0x") + String ((unsigned long)fsqParsedHeader.id, HEX)); + // DEBUG_V (String (" dataOffset: ") + String (fsqParsedHeader.dataOffset)); + // DEBUG_V (String (" minorVersion: ") + String (fsqParsedHeader.minorVersion)); + // DEBUG_V (String (" majorVersion: ") + String (fsqParsedHeader.majorVersion)); + // DEBUG_V (String (" VariableHdrOffset: ") + String (fsqParsedHeader.VariableHdrOffset)); + // DEBUG_V (String (" channelCount: ") + String (fsqParsedHeader.channelCount)); + // DEBUG_V (String ("TotalNumberOfFramesInSequence: ") + String (fsqParsedHeader.TotalNumberOfFramesInSequence)); + // DEBUG_V (String (" stepTime: ") + String (fsqParsedHeader.stepTime)); + // DEBUG_V (String (" flags: ") + String (fsqParsedHeader.flags)); + // DEBUG_V (String (" compressionType: 0x") + String (fsqParsedHeader.compressionType, HEX)); + // DEBUG_V (String (" numCompressedBlocks: ") + String (fsqParsedHeader.numCompressedBlocks)); + // DEBUG_V (String (" numSparseRanges: ") + String (fsqParsedHeader.numSparseRanges)); + // DEBUG_V (String (" flags2: ") + String (fsqParsedHeader.flags2)); + // DEBUG_V (String (" id: 0x") + String ((unsigned long)fsqParsedHeader.id, HEX)); #endif // def DUMP_FSEQ_HEADER if (fsqParsedHeader.majorVersion != 2 || fsqParsedHeader.compressionType != 0) @@ -292,17 +292,17 @@ bool c_InputFPPRemotePlayFile::ParseFseqFile () LargestBlock = max (LargestBlock, CurrentSparseRange.DataOffset + CurrentSparseRange.ChannelCount); #ifdef DUMP_FSEQ_HEADER - DEBUG_V (String (" RangeChannelCount: ") + String (CurrentSparseRange.ChannelCount)); - DEBUG_V (String (" RangeDataOffset: 0x") + String (CurrentSparseRange.DataOffset, HEX)); + // DEBUG_V (String (" RangeChannelCount: ") + String (CurrentSparseRange.ChannelCount)); + // DEBUG_V (String (" RangeDataOffset: 0x") + String (CurrentSparseRange.DataOffset, HEX)); #endif // def DUMP_FSEQ_HEADER ++SparseRangeIndex; } #ifdef DUMP_FSEQ_HEADER - DEBUG_V (String (" TotalChannels: ") + String (TotalChannels)); - DEBUG_V (String (" LargestOffset: ") + String (LargestOffset)); - DEBUG_V (String (" LargestBlock: ") + String (LargestBlock)); + // DEBUG_V (String (" TotalChannels: ") + String (TotalChannels)); + // DEBUG_V (String (" LargestOffset: ") + String (LargestOffset)); + // DEBUG_V (String (" LargestBlock: ") + String (LargestBlock)); #endif // def DUMP_FSEQ_HEADER if (0 == TotalChannels) { @@ -345,3 +345,87 @@ bool c_InputFPPRemotePlayFile::ParseFseqFile () return Response; } // ParseFseqFile + +//----------------------------------------------------------------------------- +void c_InputFPPRemotePlayFile::InitTimeCorrectionFactor () +{ + // DEBUG_START; + + do // once + { + if (INVALID_TIME_CORRECTION_FACTOR != SavedTimeCorrectionFactor) + { + break; + } + + // only do this once after boot. + TimeCorrectionFactor = SavedTimeCorrectionFactor = INITIAL_TIME_CORRECTION_FACTOR; + + String FileData; + FileMgr.ReadSdFile (String (CN_time), FileData); + + if (0 == FileData.length ()) + { + // DEBUG_V ("No data in file"); + break; + } + + // DEBUG_V (String ("FileData: ") + FileData); + + DynamicJsonDocument jsonDoc (64); + DeserializationError error = deserializeJson (jsonDoc, FileData); + if (error) + { + logcon (CN_Heap_colon + String (ESP.getFreeHeap ())); + logcon (String (F ("Time Factor Deserialzation Error. Error code = ")) + error.c_str ()); + } + // DEBUG_V (""); + + JsonObject JsonData = jsonDoc.as (); + + // extern void PrettyPrint (JsonObject & jsonStuff, String Name); + // PrettyPrint (JsonData, String ("InitTimeCorrectionFactor")); + + setFromJSON (TimeCorrectionFactor, JsonData, CN_time); + SavedTimeCorrectionFactor = TimeCorrectionFactor; + // DEBUG_V (String ("TimeCorrectionFactor: ") + String (TimeCorrectionFactor, 10)); + + } while (false); + + // DEBUG_END; + +} // InitTimeCorrectionFactor + +//----------------------------------------------------------------------------- +void c_InputFPPRemotePlayFile::SaveTimeCorrectionFactor () +{ + // DEBUG_START; + + do // once + { + if (fabs (SavedTimeCorrectionFactor - TimeCorrectionFactor) < 0.000005F ) + { + // DEBUG_V ("Nothing to save"); + break; + } + + DynamicJsonDocument jsonDoc (64); + JsonObject JsonData = jsonDoc.createNestedObject ("x"); + // JsonObject JsonData = jsonDoc.as (); + + JsonData[CN_time] = TimeCorrectionFactor; + SavedTimeCorrectionFactor = TimeCorrectionFactor; + + // extern void PrettyPrint (JsonObject & jsonStuff, String Name); + // PrettyPrint (JsonData, String ("SaveTimeCorrectionFactor")); + + String JsonFileData; + serializeJson (JsonData, JsonFileData); + // DEBUG_V (String ("JsonFileData: ") + JsonFileData); + FileMgr.SaveSdFile (String(CN_time), JsonFileData); + + } while (false); + + // DEBUG_END; + +} // SaveTimeCorrectionFactor diff --git a/ESPixelStick/src/input/InputFPPRemotePlayFile.hpp b/ESPixelStick/src/input/InputFPPRemotePlayFile.hpp index ed65ac56f..0df906bc7 100644 --- a/ESPixelStick/src/input/InputFPPRemotePlayFile.hpp +++ b/ESPixelStick/src/input/InputFPPRemotePlayFile.hpp @@ -36,11 +36,17 @@ class c_InputFPPRemotePlayFile : public c_InputFPPRemotePlayItem virtual void Poll (uint8_t* Buffer, size_t BufferSize); virtual void GetStatus (JsonObject & jsonStatus); virtual bool IsIdle () { return (pCurrentFsmState == &fsm_PlayFile_state_Idle_imp); } - + uint32_t GetLastFrameId () { return LastPlayedFrameId; } float GetTimeCorrectionFactor () { return TimeCorrectionFactor; } private: +#define INVALID_TIME_CORRECTION_FACTOR -1.0 +#define INITIAL_TIME_CORRECTION_FACTOR 1.0 + + void InitTimeCorrectionFactor (); + void SaveTimeCorrectionFactor (); + friend class fsm_PlayFile_state_Idle; friend class fsm_PlayFile_state_Starting; friend class fsm_PlayFile_state_PlayingFile; @@ -62,7 +68,8 @@ class c_InputFPPRemotePlayFile : public c_InputFPPRemotePlayItem time_t FrameStepTimeMS = 1; uint32_t TotalNumberOfFramesInSequence = 0; uint32_t StartTimeMS = 0; - float TimeCorrectionFactor = 1.0; + double TimeCorrectionFactor = INITIAL_TIME_CORRECTION_FACTOR; + double SavedTimeCorrectionFactor = INVALID_TIME_CORRECTION_FACTOR; uint32_t SyncCount = 0; uint32_t SyncAdjustmentCount = 0; diff --git a/ESPixelStick/src/input/InputFPPRemotePlayFileFsm.cpp b/ESPixelStick/src/input/InputFPPRemotePlayFileFsm.cpp index 0ef854000..3c3496df1 100644 --- a/ESPixelStick/src/input/InputFPPRemotePlayFileFsm.cpp +++ b/ESPixelStick/src/input/InputFPPRemotePlayFileFsm.cpp @@ -42,9 +42,15 @@ void fsm_PlayFile_state_Idle::Init (c_InputFPPRemotePlayFile* Parent) p_InputFPPRemotePlayFile = Parent; Parent->pCurrentFsmState = &(Parent->fsm_PlayFile_state_Idle_imp); - p_InputFPPRemotePlayFile->PlayItemName = String (""); - p_InputFPPRemotePlayFile->LastPlayedFrameId = 0; - p_InputFPPRemotePlayFile->RemainingPlayCount = 0; + p_InputFPPRemotePlayFile->PlayItemName = String (""); + p_InputFPPRemotePlayFile->LastPlayedFrameId = 0; + p_InputFPPRemotePlayFile->RemainingPlayCount = 0; + p_InputFPPRemotePlayFile->LastRcvdSyncFrameId = 0; + p_InputFPPRemotePlayFile->DataOffset = 0; + p_InputFPPRemotePlayFile->ChannelsPerFrame = 0; + p_InputFPPRemotePlayFile->FrameStepTimeMS = 1; + p_InputFPPRemotePlayFile->TotalNumberOfFramesInSequence = 0; + p_InputFPPRemotePlayFile->StartTimeMS = 0; // DEBUG_END; @@ -433,7 +439,7 @@ void fsm_PlayFile_state_Stopping::Poll (uint8_t* Buffer, size_t BufferSize) FileMgr.CloseSdFile (p_InputFPPRemotePlayFile->FileHandleForFileBeingPlayed); p_InputFPPRemotePlayFile->FileHandleForFileBeingPlayed = 0; p_InputFPPRemotePlayFile->PlayItemName = String (""); - + p_InputFPPRemotePlayFile->SaveTimeCorrectionFactor (); p_InputFPPRemotePlayFile->fsm_PlayFile_state_Idle_imp.Init (p_InputFPPRemotePlayFile); if (FileName != "") @@ -443,7 +449,7 @@ void fsm_PlayFile_state_Stopping::Poll (uint8_t* Buffer, size_t BufferSize) // DEBUG_END; -} // fsm_PlayFile_state_PlayingFile::Poll +} // fsm_PlayFile_state_Stopping::Poll //----------------------------------------------------------------------------- void fsm_PlayFile_state_Stopping::Init (c_InputFPPRemotePlayFile* Parent) From 54ef47782e2331501f6c9f0b94b43a7b15bb5fff Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Mon, 18 Oct 2021 10:07:19 -0400 Subject: [PATCH 4/8] Added a unified feed WDT function. Added additional instances of feed WdT. --- ESPixelStick/ESPixelStick.ino | 31 +++++++++++++++++++------------ ESPixelStick/src/ESPixelStick.h | 1 + 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/ESPixelStick/ESPixelStick.ino b/ESPixelStick/ESPixelStick.ino index 9bcf306a7..fda41f7b5 100644 --- a/ESPixelStick/ESPixelStick.ino +++ b/ESPixelStick/ESPixelStick.ino @@ -161,7 +161,8 @@ void setup() FPPDiscovery.begin (); #ifdef ARDUINO_ARCH_ESP8266 - ESP.wdtEnable (2000); + // * ((volatile uint32_t*)0x60000900) &= ~(1); // Hardware WDT OFF + ESP.wdtEnable (2000); // 2 seconds #else esp_task_wdt_init (5, true); #endif @@ -482,11 +483,9 @@ String serializeCore(bool pretty) /** Arduino based main loop */ void loop() { -#ifdef ARDUINO_ARCH_ESP32 - esp_task_wdt_reset (); -#else - ESP.wdtFeed (); -#endif // def ARDUINO_ARCH_ESP32 + // DEBUG_START; + + FeedWDT (); // Keep the WiFi Open WiFiMgr.Poll (); @@ -500,17 +499,14 @@ void loop() WebMgr.Process (); // need to keep the rx pipeline empty - size_t BytesToDiscard = min (1000, LOG_PORT.available ()); + size_t BytesToDiscard = min (100, LOG_PORT.available ()); while (0 < BytesToDiscard) { + FeedWDT (); + // DEBUG_V (String("BytesToDiscard: ") + String(BytesToDiscard)); BytesToDiscard--; LOG_PORT.read(); -#ifdef ARDUINO_ARCH_ESP32 - esp_task_wdt_reset (); -#else - ESP.wdtFeed (); -#endif // def ARDUINO_ARCH_ESP32 } // end discard loop // Reboot handler @@ -523,11 +519,13 @@ void loop() if (ConfigLoadNeeded) { + FeedWDT (); loadConfig (); } if (ConfigSaveNeeded) { + FeedWDT (); SaveConfig (); } @@ -554,3 +552,12 @@ void _logcon (String & DriverName, String Message) LOG_PORT.println ("[" + String (Spaces) + DriverName + "] " + Message); LOG_PORT.flush (); } // logcon + +void FeedWDT () +{ +#ifdef ARDUINO_ARCH_ESP32 + esp_task_wdt_reset (); +#else + ESP.wdtFeed (); +#endif // def ARDUINO_ARCH_ESP32 +} diff --git a/ESPixelStick/src/ESPixelStick.h b/ESPixelStick/src/ESPixelStick.h index 635d3ec21..04a54ac74 100644 --- a/ESPixelStick/src/ESPixelStick.h +++ b/ESPixelStick/src/ESPixelStick.h @@ -79,6 +79,7 @@ extern bool reboot; extern bool IsBooting; extern bool ResetWiFi; static const String ConfigFileName = "/config.json"; +extern void FeedWDT (); template bool setFromJSON (float & OutValue, J& Json, N Name) From db29cb85723f1f4f69cad833a599cccbe699feed Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Mon, 18 Oct 2021 10:07:55 -0400 Subject: [PATCH 5/8] Removed REST interface stubs --- ESPixelStick/src/WebMgr.hpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/ESPixelStick/src/WebMgr.hpp b/ESPixelStick/src/WebMgr.hpp index 8ea37035e..82158c652 100644 --- a/ESPixelStick/src/WebMgr.hpp +++ b/ESPixelStick/src/WebMgr.hpp @@ -46,6 +46,7 @@ class c_WebMgr void handleFileUpload (AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final); void NetworkStateChanged (bool NewNetworkState); void GetDriverName (String & Name) { Name = "WebMgr"; } + private: EFUpdate efupdate; @@ -70,7 +71,7 @@ class c_WebMgr }; void init (); - void onWsEvent (AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len); + void onWsEvent (AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len); void ProcessVseriesRequests (AsyncWebSocketClient * client); void ProcessGseriesRequests (AsyncWebSocketClient * client); void ProcessReceivedJsonMessage (DynamicJsonDocument & webJsonDoc, AsyncWebSocketClient * client); @@ -91,13 +92,6 @@ class c_WebMgr void GetInputOptions (); void GetOutputOptions (); -#ifdef USE_REST - void RestProcessGET (AsyncWebServerRequest* request); - void RestProcessPOST (AsyncWebServerRequest* request); - void RestProcessFile (AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final); - void RestProcessBody (AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total); -#endif // def USE_REST - protected: }; // c_WebMgr From 942e3cab6ec5b9f2b2422a3c6d1d31bfebf34087 Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Mon, 18 Oct 2021 10:08:41 -0400 Subject: [PATCH 6/8] Removed un-needed block on calling FSM poll. --- ESPixelStick/src/service/FPPDiscovery.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ESPixelStick/src/service/FPPDiscovery.cpp b/ESPixelStick/src/service/FPPDiscovery.cpp index 330966757..7fbadb85b 100644 --- a/ESPixelStick/src/service/FPPDiscovery.cpp +++ b/ESPixelStick/src/service/FPPDiscovery.cpp @@ -154,11 +154,7 @@ void c_FPPDiscovery::ReadNextFrame (uint8_t * CurrentOutputBuffer, uint16_t Curr { // DEBUG_START; - if (PlayingFile()) - { - // DEBUG_V (""); - InputFPPRemotePlayFile.Poll (CurrentOutputBuffer, CurrentOutputBufferSize); - } + InputFPPRemotePlayFile.Poll (CurrentOutputBuffer, CurrentOutputBufferSize); // DEBUG_END; } // ReadNextFrame From e2149f59b582fc8e60999b99831c18f3acbd998c Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Mon, 18 Oct 2021 10:10:53 -0400 Subject: [PATCH 7/8] Added WDT feeds on possibly long operations. Removed REST stubs. Created a permanent json buffer to reduce swiss cheese effect on heap --- ESPixelStick/src/WebMgr.cpp | 115 ++++-------------------------------- 1 file changed, 10 insertions(+), 105 deletions(-) diff --git a/ESPixelStick/src/WebMgr.cpp b/ESPixelStick/src/WebMgr.cpp index 4a122560b..145326949 100644 --- a/ESPixelStick/src/WebMgr.cpp +++ b/ESPixelStick/src/WebMgr.cpp @@ -46,6 +46,7 @@ static Espalexa espalexa; static EFUpdate efupdate; /// EFU Update Handler static AsyncWebServer webServer (HTTP_PORT); // Web Server static AsyncWebSocket webSocket ("/ws"); // Web Socket Plugin +static DynamicJsonDocument webJsonDoc (3 * WebSocketFrameCollectionBufferSize); //----------------------------------------------------------------------------- void PrettyPrint (JsonArray& jsonStuff, String Name) @@ -187,31 +188,6 @@ void c_WebMgr::init () FPPDiscovery.ProcessFPPJson(request); }); -#ifdef USE_REST - // URL's needed for FPP Connect fseq uploading and querying - webServer.on ("/rest", HTTP_GET, - [this](AsyncWebServerRequest* request) - { - RestProcessGET (request); - }); - - webServer.on ("/rest", HTTP_POST | HTTP_PUT, - [this](AsyncWebServerRequest* request) - { - RestProcessPOST (request); - }, - - [this] (AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final) - { - RestProcessFile (request, filename, index, data, len, final); - }, - - [this] (AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) - { - RestProcessBody (request, data, len, index, total); - }); -#endif // def USE_REST - // Static Handlers webServer.serveStatic ("/UpdRecipe", LittleFS, "/UpdRecipe.json"); // webServer.serveStatic ("/static", LittleFS, "/www/static").setCacheControl ("max-age=31536000"); @@ -362,8 +338,7 @@ void c_WebMgr::GetConfiguration () extern void GetConfig (JsonObject & json); // DEBUG_START; - DynamicJsonDocument webJsonDoc (4096); - + webJsonDoc.clear (); JsonObject JsonSystemConfig = webJsonDoc.createNestedObject (CN_system); GetConfig (JsonSystemConfig); // DEBUG_V (""); @@ -388,7 +363,7 @@ void c_WebMgr::GetDeviceOptions () // DEBUG_START; #ifdef SUPPORT_DEVICE_OPTION_LIST // set up a framework to get the option data - DynamicJsonDocument webJsonDoc (2048); + webJsonDoc.clear (); if (0 == webJsonDoc.capacity ()) { @@ -482,6 +457,8 @@ void c_WebMgr::onWsEvent (AsyncWebSocket* server, AsyncWebSocketClient * client, // DEBUG_V (WebSocketFrameCollectionBuffer); // message is all here. Process it + FeedWDT (); + if (WebSocketFrameCollectionBuffer[0] == 'X') { // DEBUG_V (""); @@ -507,7 +484,7 @@ void c_WebMgr::onWsEvent (AsyncWebSocket* server, AsyncWebSocketClient * client, // convert the input data into a json structure (use json read only mode) size_t docSize = strlen ((const char*)(&WebSocketFrameCollectionBuffer[0])) * 3; - DynamicJsonDocument webJsonDoc (docSize); + webJsonDoc.clear (); DeserializationError error = deserializeJson (webJsonDoc, (const char *)(&WebSocketFrameCollectionBuffer[0])); // DEBUG_V (""); @@ -551,6 +528,8 @@ void c_WebMgr::onWsEvent (AsyncWebSocket* server, AsyncWebSocketClient * client, } } // end switch (type) + FeedWDT (); + // DEBUG_V (CN_Heap_colon + String (ESP.getFreeHeap ())); // DEBUG_END; @@ -626,7 +605,7 @@ void c_WebMgr::ProcessXARequest (AsyncWebSocketClient* client) { // DEBUG_START; - DynamicJsonDocument webJsonDoc (1024); + webJsonDoc.clear (); JsonObject jsonAdmin = webJsonDoc.createNestedObject (F ("admin")); jsonAdmin[CN_version] = VERSION; @@ -656,7 +635,7 @@ void c_WebMgr::ProcessXJRequest (AsyncWebSocketClient* client) { // DEBUG_START; - DynamicJsonDocument webJsonDoc (2048); + webJsonDoc.clear (); JsonObject status = webJsonDoc.createNestedObject (CN_status); JsonObject system = status.createNestedObject (CN_system); @@ -1183,80 +1162,6 @@ void c_WebMgr::Process () } } // Process - -#ifdef USE_REST -void printRequest (AsyncWebServerRequest* request) -{ - // DEBUG_V (String (" version: '") + String (request->version ()) + "'"); - // DEBUG_V (String (" method: '") + String (request->method ()) + "'"); - // DEBUG_V (String (" url: '") + String (request->url ()) + "'"); - // DEBUG_V (String (" host: '") + String (request->host ()) + "'"); - // DEBUG_V (String (" contentType: '") + String (request->contentType ()) + "'"); - // DEBUG_V (String ("contentLength: '") + String (request->contentLength ()) + "'"); - // DEBUG_V (String (" multipart: '") + String (request->multipart ()) + "'"); - - //List all collected headers - int headers = request->headers (); - int i; - for (i = 0; i < headers; i++) - { - AsyncWebHeader* h = request->getHeader (i); - // DEBUG_V (String (" HEADER: '") + h->name () + "', '" + h->value () + "'"); - } - -} // printRequest -//----------------------------------------------------------------------------- -void c_WebMgr::RestProcessGET (AsyncWebServerRequest* request) -{ - // DEBUG_START; - printRequest (request); - - // request->send (200, "text/json", WebSocketFrameCollectionBuffer); - - - request->send (200, CN_textSLASHplain, "Hello"); - - // DEBUG_END; - -} // RestProcessPOST - -//----------------------------------------------------------------------------- -void c_WebMgr::RestProcessPOST (AsyncWebServerRequest* request) -{ - // DEBUG_START; - printRequest (request); - - request->send (404, CN_textSLASHplain, "Page Not found"); - - // DEBUG_END; - -} // RestProcessGET - -//----------------------------------------------------------------------------- -void c_WebMgr::RestProcessFile (AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final) -{ - // DEBUG_START; - printRequest (request); - - request->send (404, CN_textSLASHplain, "Page Not found"); - - // DEBUG_END; - -} // RestProcessFile - -//----------------------------------------------------------------------------- -void c_WebMgr::RestProcessBody (AsyncWebServerRequest* request, uint8_t* data, size_t len, size_t index, size_t total) -{ - // DEBUG_START; - printRequest (request); - - request->send (404, CN_textSLASHplain, "Page Not found"); - - // DEBUG_END; - -} // RestProcessBody -#endif // def USE_REST - //----------------------------------------------------------------------------- // create a global instance of the WEB UI manager c_WebMgr WebMgr; From 1fe9bfd8ca3fee61fc3ccc1a997a1907c3edce28 Mon Sep 17 00:00:00 2001 From: Martin Mueller Date: Mon, 18 Oct 2021 12:47:02 -0400 Subject: [PATCH 8/8] Added support for millis wrap around which also resolves a startup issue with playing an fseq file in remote mode that started playing before we booted. --- .../src/input/InputFPPRemotePlayFile.cpp | 20 ++++++++++++-- .../src/input/InputFPPRemotePlayFileFsm.cpp | 26 ++++++------------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/ESPixelStick/src/input/InputFPPRemotePlayFile.cpp b/ESPixelStick/src/input/InputFPPRemotePlayFile.cpp index bfe380b42..6dfe7effa 100644 --- a/ESPixelStick/src/input/InputFPPRemotePlayFile.cpp +++ b/ESPixelStick/src/input/InputFPPRemotePlayFile.cpp @@ -20,6 +20,7 @@ #include "InputFPPRemotePlayFile.hpp" #include "../service/FPPDiscovery.h" +#include "../service/fseq.h" //----------------------------------------------------------------------------- c_InputFPPRemotePlayFile::c_InputFPPRemotePlayFile (c_InputMgr::e_InputChannelIds InputChannelId) : @@ -143,7 +144,14 @@ uint32_t c_InputFPPRemotePlayFile::CalculateFrameId (time_t now, int32_t SyncOff { // DEBUG_START; - time_t CurrentPlayTime = now - StartTimeMS; + time_t CurrentPlayTime = now - StartTimeMS; + + // has the counter wrapped? + if (now < StartTimeMS) + { + CurrentPlayTime = now + (0 - StartTimeMS); + } + time_t AdjustedPlayTime = CurrentPlayTime + SyncOffsetMS; time_t AdjustedFrameStepTimeMS = time_t (float (FrameStepTimeMS) * TimeCorrectionFactor); uint32_t CurrentFrameId = AdjustedPlayTime / AdjustedFrameStepTimeMS; @@ -159,7 +167,15 @@ void c_InputFPPRemotePlayFile::CalculatePlayStartTime () { // DEBUG_START; - StartTimeMS = millis () - uint32_t ((float (FrameStepTimeMS) * TimeCorrectionFactor) * float (LastPlayedFrameId)); + time_t now = millis (); + time_t StartOffset = time_t ((float (FrameStepTimeMS) * TimeCorrectionFactor) * float (LastPlayedFrameId)); + StartTimeMS = now - StartOffset; + // DEBUG_V (String (" now: ") + String (now)); + // DEBUG_V (String (" StartOffset: ") + String (StartOffset)); + // DEBUG_V (String (" FrameStepTimeMS: ") + String (FrameStepTimeMS)); + // DEBUG_V (String ("TimeCorrectionFactor: ") + String (TimeCorrectionFactor)); + // DEBUG_V (String (" LastPlayedFrameId: ") + String (LastPlayedFrameId)); + // DEBUG_V (String (" StartTimeMS: ") + String (StartTimeMS)); // DEBUG_END; diff --git a/ESPixelStick/src/input/InputFPPRemotePlayFileFsm.cpp b/ESPixelStick/src/input/InputFPPRemotePlayFileFsm.cpp index 3c3496df1..d3db686bb 100644 --- a/ESPixelStick/src/input/InputFPPRemotePlayFileFsm.cpp +++ b/ESPixelStick/src/input/InputFPPRemotePlayFileFsm.cpp @@ -20,7 +20,6 @@ #include "InputFPPRemotePlayFile.hpp" #include "InputMgr.hpp" -#include "../service/fseq.h" //----------------------------------------------------------------------------- void fsm_PlayFile_state_Idle::Poll (uint8_t * Buffer, size_t BufferSize) @@ -200,8 +199,9 @@ void fsm_PlayFile_state_PlayingFile::Poll (uint8_t* Buffer, size_t BufferSize) } else { - // DEBUG_V (String ("CurrentFrame: ") + String(CurrentFrame)); - // DEBUG_V (String ("Done Playing:: FileName: '") + p_InputFPPRemotePlayFile->GetFileName () + "'"); + // DEBUG_V (String ("TotalNumberOfFramesInSequence: ") + String (p_InputFPPRemotePlayFile->TotalNumberOfFramesInSequence)); + // DEBUG_V (String (" CurrentFrame: ") + String (CurrentFrame)); + // DEBUG_V (String (" Done Playing:: FileName: '") + p_InputFPPRemotePlayFile->GetFileName () + "'"); Stop (); break; } @@ -294,11 +294,10 @@ void fsm_PlayFile_state_PlayingFile::Init (c_InputFPPRemotePlayFile* Parent) if (!p_InputFPPRemotePlayFile->ParseFseqFile ()) { - Stop (); + p_InputFPPRemotePlayFile->fsm_PlayFile_state_Stopping_imp.Init (p_InputFPPRemotePlayFile); break; } - p_InputFPPRemotePlayFile->LastPlayedFrameId = 0; p_InputFPPRemotePlayFile->CalculatePlayStartTime (); // DEBUG_V (String (" LastPlayedFrameId: ") + String (p_InputFPPRemotePlayFile->LastPlayedFrameId)); @@ -325,19 +324,9 @@ void fsm_PlayFile_state_PlayingFile::Start (String& FileName, uint32_t FrameId, // DEBUG_V (String ("TotalNumberOfFramesInSequence: ") + String (p_InputFPPRemotePlayFile->TotalNumberOfFramesInSequence)); // DEBUG_V (String ("RemainingPlayCount: ") + p_InputFPPRemotePlayFile->RemainingPlayCount); - if (FileName == p_InputFPPRemotePlayFile->GetFileName ()) - { - // Keep playing the same file - // p_InputFPPRemotePlayFile->LastPlayedFrameId = FrameId; - // p_InputFPPRemotePlayFile->LastRcvdSyncFrameId = FrameId; - // p_InputFPPRemotePlayFile->RemainingPlayCount = PlayCount - 1; - // p_InputFPPRemotePlayFile->CalculatePlayStartTime (); - } - else - { - Stop (); - p_InputFPPRemotePlayFile->Start (FileName, FrameId, PlayCount); - } + Stop (); + p_InputFPPRemotePlayFile->Start (FileName, FrameId, PlayCount); + // DEBUG_END; } // fsm_PlayFile_state_PlayingFile::Start @@ -415,6 +404,7 @@ bool fsm_PlayFile_state_PlayingFile::Sync (String& FileName, uint32_t TargetFram p_InputFPPRemotePlayFile->TimeCorrectionFactor -= TimeOffsetStep; } + p_InputFPPRemotePlayFile->LastPlayedFrameId = TargetFrameId-1; // p_InputFPPRemotePlayFile->CalculatePlayStartTime (); response = true;