diff --git a/html/script.js b/html/script.js index df3d399a8..ad8d636cb 100644 --- a/html/script.js +++ b/html/script.js @@ -1,5 +1,6 @@ var StatusRequestTimer = null; var DiagTimer = null; +var ConfigSessionId = new Date().getTime(); // global data var AdminInfo = null; @@ -23,6 +24,111 @@ var ctx = canvas.getContext("2d"); ctx.font = "20px Arial"; ctx.textAlign = "center"; +const rssiToPercent = +[ + /* -100 */ 0, + /* -99 */ 0, + /* -98 */ 0, + /* -97 */ 0, + /* -96 */ 0, + /* -95 */ 0, + /* -94 */ 4, + /* -93 */ 6, + /* -92 */ 8, + /* -91 */ 11, + /* -90 */ 13, + /* -89 */ 15, + /* -88 */ 17, + /* -87 */ 19, + /* -86 */ 21, + /* -85 */ 23, + /* -84 */ 26, + /* -83 */ 28, + /* -82 */ 30, + /* -81 */ 32, + /* -80 */ 34, + /* -79 */ 35, + /* -78 */ 37, + /* -77 */ 39, + /* -76 */ 41, + /* -75 */ 43, + /* -74 */ 45, + /* -73 */ 46, + /* -72 */ 48, + /* -71 */ 50, + /* -70 */ 52, + /* -69 */ 53, + /* -68 */ 55, + /* -67 */ 56, + /* -66 */ 58, + /* -65 */ 59, + /* -64 */ 61, + /* -63 */ 62, + /* -62 */ 64, + /* -61 */ 65, + /* -60 */ 67, + /* -59 */ 68, + /* -58 */ 69, + /* -57 */ 71, + /* -56 */ 72, + /* -55 */ 73, + /* -54 */ 75, + /* -53 */ 76, + /* -52 */ 77, + /* -51 */ 78, + /* -50 */ 79, + /* -49 */ 80, + /* -48 */ 81, + /* -47 */ 82, + /* -46 */ 83, + /* -45 */ 84, + /* -44 */ 85, + /* -43 */ 86, + /* -42 */ 87, + /* -41 */ 88, + /* -40 */ 89, + /* -39 */ 90, + /* -38 */ 90, + /* -37 */ 91, + /* -36 */ 92, + /* -35 */ 93, + /* -34 */ 93, + /* -33 */ 94, + /* -32 */ 95, + /* -31 */ 95, + /* -30 */ 96, + /* -29 */ 96, + /* -28 */ 97, + /* -27 */ 97, + /* -26 */ 98, + /* -25 */ 98, + /* -24 */ 99, + /* -23 */ 99, + /* -22 */ 99, + /* -21 */ 100, + /* -20 */ 100, + /* -19 */ 100, + /* -18 */ 100, + /* -17 */ 100, + /* -16 */ 100, + /* -15 */ 100, + /* -14 */ 100, + /* -13 */ 100, + /* -12 */ 100, + /* -11 */ 100, + /* -10 */ 100, + /* -9 */ 100, + /* -8 */ 100, + /* -7 */ 100, + /* -6 */ 100, + /* -5 */ 100, + /* -4 */ 100, + /* -3 */ 100, + /* -2 */ 100, + /* -1 */ 100, + /* 0 */ 100, +]; + // Default modal properties $.fn.modal.Constructor.DEFAULTS.backdrop = 'static'; $.fn.modal.Constructor.DEFAULTS.keyboard = false; @@ -267,7 +373,7 @@ $(function () { let DeltaTime = (new Date().getTime() - FseqFileTransferStartTime.getTime()) / 1000; let rate = Math.floor((file.size / DeltaTime) / 1000); - console.debug("Final Transfer Rate: " + rate + "KBps"); + // console.debug("Final Transfer Rate: " + rate + "KBps"); }); this.on('addedfile', function (file, resp) { @@ -442,7 +548,7 @@ function MergeConfigTree(SourceTree, TargetTree, CurrentTarget, FullSelector) if(CurrentElementValue === undefined) { - console.info("target element is not properly formed"); + console.error("target element is not properly formed"); continue; } @@ -468,7 +574,7 @@ function MergeConfigTree(SourceTree, TargetTree, CurrentTarget, FullSelector) } else { - console.info("NOT Saving CurrentElement. Source value is Not in target tree."); + console.error("NOT Saving CurrentElement. Source value is Not in target tree."); } } } @@ -616,7 +722,9 @@ async function RequestConfigFile(FileName) { // console.log("RequestConfigFile FileName: " + FileName); - await $.getJSON("HTTP://" + target + "/conf/" + FileName, function(data) + var url = "HTTP://" + target + "/conf/" + FileName + '?t=' + ConfigSessionId; + // console.info("'GET' Config URL: '" + url + "'"); + await $.getJSON(url, function(data) { // console.log("RequestConfigFile: " + JSON.stringify(data)); ProcessReceivedJsonConfigMessage(data); @@ -1742,13 +1850,13 @@ function hexToRgb(hex) { function ExtractConfigFromHtmlPages(elementids, modeControlName, ChannelConfig) { - console.info("Preping config to send to ESP"); - console.info("num elementids: " + elementids.length); + // console.debug("Preping config to send to ESP"); + // console.debug("num elementids: " + elementids.length); elementids.forEach(function (elementid) { let SelectedElement = modeControlName + ' #' + elementid; - console.info("Element ID: " + $(SelectedElement).id) + // console.debug("Element ID: " + $(SelectedElement).id) if ($(SelectedElement).is(':checkbox')) { @@ -1756,7 +1864,7 @@ function ExtractConfigFromHtmlPages(elementids, modeControlName, ChannelConfig) } else if ($(SelectedElement).attr('type') === 'number') { - console.info("Found Number: " + $(SelectedElement).id) + // console.debug("Found Number: " + $(SelectedElement).id) ChannelConfig[elementid] = parseInt($(SelectedElement).val()); } else @@ -1805,6 +1913,7 @@ function submitDeviceConfig() { ExtractChannelConfigFromHtmlPage(Output_Config.channels, "output"); + ConfigSessionId = new Date().getTime(); ServerAccess.callFunction(SendConfigFileToServer, "output_config", JSON.stringify({'output_config': Output_Config})); ServerAccess.callFunction(SendConfigFileToServer, "input_config", JSON.stringify({'input_config': Input_Config})); submitNetworkConfig(); @@ -1930,19 +2039,19 @@ function ProcessReceivedJsonStatusMessage(JsonStat) { let Ethernet = Network.wifi; let rssi = Wifi.rssi; - let quality = 2 * (rssi + 100); + let quality = rssi + 100; if (rssi <= -100) { quality = 0; } - else if (rssi >= -50) { + else if (rssi >= 0) { quality = 100; } $('#w_connected').text((true === Wifi.connected) ? "Yes" : "No"); $('#w_hostname').text(Wifi.hostname); $('#w_rssi').text(rssi); - $('#w_quality').text(quality); + $('#w_quality').text(rssiToPercent[quality]); $('#w_ssid').text(Wifi.ssid); $('#w_ip').text(Wifi.ip); $('#w_subnet').text(Wifi.subnet); @@ -2222,4 +2331,5 @@ function reboot() { $('#confirm-reset .btn-ok').on("click", (function () { showReboot(); SendCommand('X7'); + ConfigSessionId = new Date().getTime(); })); diff --git a/include/output/OutputAPA102Spi.hpp b/include/output/OutputAPA102Spi.hpp index 7086cc618..696b6712d 100644 --- a/include/output/OutputAPA102Spi.hpp +++ b/include/output/OutputAPA102Spi.hpp @@ -3,7 +3,7 @@ * OutputAPA102Spi.h - APA102 driver code for ESPixelStick Spi Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2022 Shelby Merrick +* Copyright (c) 2015, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -46,7 +46,6 @@ class c_OutputAPA102Spi : public c_OutputAPA102 #if defined(ARDUINO_ARCH_ESP32) bool RmtPoll () {return false;} #endif // defined(ARDUINO_ARCH_ESP32) - void PauseOutput () {}; private: diff --git a/include/output/OutputCommon.hpp b/include/output/OutputCommon.hpp index f2941086c..7eda6113f 100644 --- a/include/output/OutputCommon.hpp +++ b/include/output/OutputCommon.hpp @@ -59,13 +59,15 @@ class c_OutputCommon virtual void SetOutputBufferSize (uint32_t NewOutputBufferSize) { OutputBufferSize = NewOutputBufferSize; }; virtual uint32_t GetNumOutputBufferBytesNeeded () = 0; virtual uint32_t GetNumOutputBufferChannelsServiced () = 0; - virtual void PauseOutput (bool State) {} + virtual void PauseOutput (bool NewState) {Paused = NewState;} virtual void ClearBuffer (); virtual void WriteChannelData (uint32_t StartChannelId, uint32_t ChannelCount, byte *pSourceData); virtual void ReadChannelData (uint32_t StartChannelId, uint32_t ChannelCount, byte *pTargetData); virtual bool ValidateGpio (gpio_num_t ConsoleTxGpio, gpio_num_t ConsoleRxGpio); virtual bool DriverIsSendingIntensityData() {return false;} virtual uint32_t GetFrameTimeMs() {return 1 + (ActualFrameDurationMicroSec / 1000); } + bool IsPaused() {return Paused;} + protected: gpio_num_t DataPin = gpio_num_t (-1); @@ -78,6 +80,7 @@ class c_OutputCommon uint8_t * pOutputBuffer = nullptr; uint32_t OutputBufferSize = 0; uint32_t FrameCount = 0; + bool Paused = false; virtual void ReportNewFrame (); diff --git a/include/output/OutputGECERmt.hpp b/include/output/OutputGECERmt.hpp index fe6e547d6..da8a0738c 100644 --- a/include/output/OutputGECERmt.hpp +++ b/include/output/OutputGECERmt.hpp @@ -3,7 +3,7 @@ * OutputGECERmt.h - GECE driver code for ESPixelStick RMT Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2022 Shelby Merrick +* Copyright (c) 2015, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -46,6 +46,7 @@ class c_OutputGECERmt : public c_OutputGECE #endif // defined(ARDUINO_ARCH_ESP32) void GetStatus (ArduinoJson::JsonObject& jsonStatus); void SetOutputBufferSize (uint32_t NumChannelsAvailable); + void PauseOutput (bool State); private: diff --git a/include/output/OutputGS8208Rmt.hpp b/include/output/OutputGS8208Rmt.hpp index f1971b420..02c8328df 100644 --- a/include/output/OutputGS8208Rmt.hpp +++ b/include/output/OutputGS8208Rmt.hpp @@ -3,7 +3,7 @@ * OutputGS8208Rmt.h - GS8208 driver code for ESPixelStick RMT Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2022 Shelby Merrick +* Copyright (c) 2015, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -47,6 +47,7 @@ class c_OutputGS8208Rmt : public c_OutputGS8208 #endif // defined(ARDUINO_ARCH_ESP32) void GetStatus (ArduinoJson::JsonObject& jsonStatus); void SetOutputBufferSize (uint32_t NumChannelsAvailable); + void PauseOutput (bool State); private: diff --git a/include/output/OutputGrinchSpi.hpp b/include/output/OutputGrinchSpi.hpp index 02fd81748..50bc450bb 100644 --- a/include/output/OutputGrinchSpi.hpp +++ b/include/output/OutputGrinchSpi.hpp @@ -3,7 +3,7 @@ * OutputGrinchSpi.h - GRINCH driver code for ESPixelStick Spi Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2024 Shelby Merrick +* Copyright (c) 2015, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -45,7 +45,6 @@ class c_OutputGrinchSpi : public c_OutputGrinch #if defined(ARDUINO_ARCH_ESP32) bool RmtPoll () {return false;} #endif // defined(ARDUINO_ARCH_ESP32) - void PauseOutput () {}; private: diff --git a/include/output/OutputRmt.hpp b/include/output/OutputRmt.hpp index 80d4f75a4..a384e0ce0 100644 --- a/include/output/OutputRmt.hpp +++ b/include/output/OutputRmt.hpp @@ -98,7 +98,7 @@ class c_OutputRmt uint32_t NumRmtSlotOverruns = 0; uint32_t MaxNumRmtSlotsPerInterrupt = (NUM_RMT_SLOTS/2); - rmt_item32_t SendBuffer[NUM_RMT_SLOTS]; + rmt_item32_t SendBuffer[NUM_RMT_SLOTS * 2]; uint32_t RmtBufferWriteIndex = 0; uint32_t SendBufferWriteIndex = 0; uint32_t SendBufferReadIndex = 0; @@ -109,7 +109,7 @@ class c_OutputRmt uint32_t TxIntensityDataStartingMask = 0x80; RmtDataBitIdType_t InterIntensityValueId = RMT_INVALID_VALUE; - inline void IRAM_ATTR ISR_TransferIntensityDataToRMT (); + inline void IRAM_ATTR ISR_TransferIntensityDataToRMT (uint32_t NumEntriesToTransfer); inline void IRAM_ATTR ISR_CreateIntensityData (); inline void IRAM_ATTR ISR_WriteToBuffer(uint32_t value); inline bool IRAM_ATTR ISR_MoreDataToSend(); @@ -129,7 +129,7 @@ class c_OutputRmt void Begin (OutputRmtConfig_t config, c_OutputCommon * pParent); bool StartNewFrame (); - bool StartNextFrame () { return (pParent) ? pParent->RmtPoll() : false; } + bool StartNextFrame () { return ((nullptr != pParent) & (!OutputIsPaused)) ? pParent->RmtPoll() : false; } void GetStatus (ArduinoJson::JsonObject& jsonStatus); void set_pin (gpio_num_t _DataPin) { OutputRmtConfig.DataPin = _DataPin; rmt_set_gpio (OutputRmtConfig.RmtChannelId, rmt_mode_t::RMT_MODE_TX, OutputRmtConfig.DataPin, false); } void PauseOutput (bool State); @@ -164,7 +164,6 @@ class c_OutputRmt uint32_t DataTaskcounter = 0; uint32_t ISRcounter = 0; uint32_t FrameStartCounter = 0; - uint32_t FrameEndISRcounter = 0; uint32_t SendBlockIsrCounter = 0; uint32_t RanOutOfData = 0; uint32_t UnknownISRcounter = 0; @@ -181,6 +180,7 @@ class c_OutputRmt uint32_t RmtEntriesTransfered = 0; uint32_t RmtXmtFills = 0; uint32_t RmtWhiteDetected = 0; + uint32_t FailedToSendAllData = 0; #define RMT_DEBUG_COUNTER(p) p diff --git a/include/output/OutputSerialRmt.hpp b/include/output/OutputSerialRmt.hpp index 18d00fe8d..b4e9b354f 100644 --- a/include/output/OutputSerialRmt.hpp +++ b/include/output/OutputSerialRmt.hpp @@ -3,7 +3,7 @@ * OutputSerialRmt.h - WS2811 driver code for ESPixelStick RMT Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2022 Shelby Merrick +* Copyright (c) 2015, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -44,7 +44,7 @@ class c_OutputSerialRmt : public c_OutputSerial bool RmtPoll (); void GetStatus (ArduinoJson::JsonObject& jsonStatus); void SetOutputBufferSize (uint32_t NumChannelsAvailable); - void PauseOutput(bool State) {Rmt.PauseOutput(State);} + void PauseOutput(bool State); private: void SetUpRmtBitTimes(); diff --git a/include/output/OutputSerialUart.hpp b/include/output/OutputSerialUart.hpp index 393b6500e..196f89548 100644 --- a/include/output/OutputSerialUart.hpp +++ b/include/output/OutputSerialUart.hpp @@ -2,7 +2,7 @@ /****************************************************************** * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel (And Serial!) driver -* Orginal ESPixelStickproject by 2015 Shelby Merrick +* Orginal ESPixelStickproject by 2015 - 2025 Shelby Merrick * *This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or(at your option) any later version. This program is distributed in the hope that it will be useful, @@ -47,6 +47,7 @@ class c_OutputSerialUart : public c_OutputSerial #if defined(ARDUINO_ARCH_ESP32) bool RmtPoll () {return false;} #endif // defined(ARDUINO_ARCH_ESP32) + void PauseOutput (bool NewState); private: c_OutputUart Uart; diff --git a/include/output/OutputTLS3001Rmt.hpp b/include/output/OutputTLS3001Rmt.hpp index 1a1eab98c..b89168b95 100644 --- a/include/output/OutputTLS3001Rmt.hpp +++ b/include/output/OutputTLS3001Rmt.hpp @@ -3,7 +3,7 @@ * OutputTLS3001Rmt.h - TLS3001 driver code for ESPixelStick RMT Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2022 Shelby Merrick +* Copyright (c) 2015, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -56,6 +56,7 @@ class c_OutputTLS3001Rmt : public c_OutputTLS3001 bool RmtPoll (); void GetStatus (ArduinoJson::JsonObject& jsonStatus); void SetOutputBufferSize (uint32_t NumChannelsAvailable); + void PauseOutput(bool State); private: diff --git a/include/output/OutputTM1814Rmt.hpp b/include/output/OutputTM1814Rmt.hpp index 93f308d8d..c2af9b0d4 100644 --- a/include/output/OutputTM1814Rmt.hpp +++ b/include/output/OutputTM1814Rmt.hpp @@ -3,7 +3,7 @@ * OutputTM1814Rmt.h - TM1814 driver code for ESPixelStick RMT Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2022 Shelby Merrick +* Copyright (c) 2015, 2024 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -44,6 +44,7 @@ class c_OutputTM1814Rmt : public c_OutputTM1814 bool RmtPoll (); void GetStatus (ArduinoJson::JsonObject& jsonStatus); void SetOutputBufferSize (uint32_t NumChannelsAvailable); + void PauseOutput(bool State); private: diff --git a/include/output/OutputUCS1903Rmt.hpp b/include/output/OutputUCS1903Rmt.hpp index b5ef7f5a9..1e1f70b8d 100644 --- a/include/output/OutputUCS1903Rmt.hpp +++ b/include/output/OutputUCS1903Rmt.hpp @@ -3,7 +3,7 @@ * OutputUCS1903Rmt.h - UCS1903 driver code for ESPixelStick RMT Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2022 Shelby Merrick +* Copyright (c) 2015, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -45,6 +45,7 @@ class c_OutputUCS1903Rmt : public c_OutputUCS1903 bool RmtPoll (); void GetStatus (ArduinoJson::JsonObject& jsonStatus); void SetOutputBufferSize (uint32_t NumChannelsAvailable); + void PauseOutput(bool State); private: diff --git a/include/output/OutputUCS8903Rmt.hpp b/include/output/OutputUCS8903Rmt.hpp index 50ae849c6..270666bf5 100644 --- a/include/output/OutputUCS8903Rmt.hpp +++ b/include/output/OutputUCS8903Rmt.hpp @@ -3,7 +3,7 @@ * OutputUCS8903Rmt.h - UCS8903 driver code for ESPixelStick RMT Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015 Shelby Merrick +* Copyright (c) 2015 - 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -45,6 +45,7 @@ class c_OutputUCS8903Rmt : public c_OutputUCS8903 bool RmtPoll (); void GetStatus (ArduinoJson::JsonObject& jsonStatus); void SetOutputBufferSize (uint32_t NumChannelsAvailable); + void PauseOutput(bool State); private: diff --git a/include/output/OutputWS2801Spi.hpp b/include/output/OutputWS2801Spi.hpp index 86762ed62..7c74983c7 100644 --- a/include/output/OutputWS2801Spi.hpp +++ b/include/output/OutputWS2801Spi.hpp @@ -3,7 +3,7 @@ * OutputWS2801Spi.h - WS2801 driver code for ESPixelStick Spi Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2022 Shelby Merrick +* Copyright (c) 2015, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -45,7 +45,6 @@ class c_OutputWS2801Spi : public c_OutputWS2801 #if defined(ARDUINO_ARCH_ESP32) bool RmtPoll () {return false;} #endif // defined(ARDUINO_ARCH_ESP32) - void PauseOutput () {}; private: diff --git a/include/output/OutputWS2811Rmt.hpp b/include/output/OutputWS2811Rmt.hpp index 692bb5aae..b95fcce8c 100644 --- a/include/output/OutputWS2811Rmt.hpp +++ b/include/output/OutputWS2811Rmt.hpp @@ -3,7 +3,7 @@ * OutputWS2811Rmt.h - WS2811 driver code for ESPixelStick RMT Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2022 Shelby Merrick +* Copyright (c) 2015, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -45,6 +45,7 @@ class c_OutputWS2811Rmt : public c_OutputWS2811 void GetStatus (ArduinoJson::JsonObject& jsonStatus); void SetOutputBufferSize (uint32_t NumChannelsAvailable); bool DriverIsSendingIntensityData() {return (Rmt.DriverIsSendingIntensityData() || false == canRefresh());} + void PauseOutput(bool State); private: diff --git a/platformio.ini b/platformio.ini index c946a21f4..f9b628640 100644 --- a/platformio.ini +++ b/platformio.ini @@ -50,6 +50,7 @@ build_flags = ; -D FTP_ADDITIONAL_DEBUG -D DISABLE_FS_H_WARNING=1 -I ./ESPixelStick/src + -I ./include lib_ignore = ESP Async WebServer ; force the use of the esphome version AsyncTCP ; force the use of the esphome version diff --git a/src/input/InputE131.cpp b/src/input/InputE131.cpp index 0bc0c20ad..a687f8e28 100644 --- a/src/input/InputE131.cpp +++ b/src/input/InputE131.cpp @@ -103,7 +103,7 @@ void c_InputE131::GetStatus (JsonObject & jsonStatus) // DEBUG_V (""); JsonArray e131UniverseStatus = e131Status[CN_channels].to (); - uint32_t TotalErrors = e131->stats.packet_errors; + uint32_t TotalErrors = 0; // e131->stats.packet_errors; for (auto & CurrentUniverse : UniverseArray) { JsonObject e131CurrentUniverseStatus = e131UniverseStatus.add (); diff --git a/src/input/InputMQTT.cpp b/src/input/InputMQTT.cpp index a02bfcd49..ffa1c5cf9 100644 --- a/src/input/InputMQTT.cpp +++ b/src/input/InputMQTT.cpp @@ -123,6 +123,8 @@ void c_InputMQTT::GetConfig (JsonObject & jsonConfig) // DEBUG_START; // Serialize Config + jsonConfig[CN_ip] = ip; + jsonConfig[CN_port] = port; jsonConfig[CN_user] = user; jsonConfig[CN_password] = password; jsonConfig[CN_topic] = topic; @@ -164,10 +166,14 @@ void c_InputMQTT::Process () pEffectsEngine->Process (); } - if (nullptr != pPlayFileEngine) + else if (nullptr != pPlayFileEngine) { pPlayFileEngine->Poll (); } + else + { + // DEBUG_V("No active data generation channel"); + } } // DEBUG_END; @@ -411,7 +417,7 @@ void c_InputMQTT::onMqttMessage( // if its a retained message and we want a clean session, ignore it if (properties.retain && CleanSessionRequired) { - // DEBUG_V (""); + // DEBUG_V ("Ignore retained session."); break; } diff --git a/src/input/InputMgr.cpp b/src/input/InputMgr.cpp index d8e102eee..6eed931db 100644 --- a/src/input/InputMgr.cpp +++ b/src/input/InputMgr.cpp @@ -2,7 +2,7 @@ * InputMgr.cpp - Input Management class * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -950,6 +950,7 @@ void c_InputMgr::SetBufferInfo (uint32_t BufferSize) void c_InputMgr::SetOperationalState (bool ActiveFlag) { // DEBUG_START; + // DEBUG_V(String("ActiveFlag: ") + String(ActiveFlag)); // pass through each active interface and set the active state for (auto & InputChannel : InputChannelDrivers) diff --git a/src/output/OutputGECERmt.cpp b/src/output/OutputGECERmt.cpp index af3e09d7c..856da8383 100644 --- a/src/output/OutputGECERmt.cpp +++ b/src/output/OutputGECERmt.cpp @@ -2,7 +2,7 @@ * OutputGECERmt.cpp - GECE driver code for ESPixelStick RMT Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2022 Shelby Merrick +* Copyright (c) 2015, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -162,4 +162,15 @@ bool c_OutputGECERmt::RmtPoll () } // Poll +//---------------------------------------------------------------------------- +void c_OutputGECERmt::PauseOutput (bool State) +{ + // DEBUG_START; + + c_OutputGECE::PauseOutput(State); + Rmt.PauseOutput(State); + + // DEBUG_END; +} // PauseOutput + #endif // defined(SUPPORT_OutputType_GECE) && defined(ARDUINO_ARCH_ESP32) diff --git a/src/output/OutputGS8208Rmt.cpp b/src/output/OutputGS8208Rmt.cpp index 1f4c7584d..a2fde2696 100644 --- a/src/output/OutputGS8208Rmt.cpp +++ b/src/output/OutputGS8208Rmt.cpp @@ -2,7 +2,7 @@ * OutputGS8208Rmt.cpp - GS8208 driver code for ESPixelStick RMT Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2022 Shelby Merrick +* Copyright (c) 2015, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -171,4 +171,15 @@ bool c_OutputGS8208Rmt::RmtPoll () } // Poll +//---------------------------------------------------------------------------- +void c_OutputGS8208Rmt::PauseOutput (bool State) +{ + // DEBUG_START; + + c_OutputGS8208::PauseOutput(State); + Rmt.PauseOutput(State); + + // DEBUG_END; +} // PauseOutput + #endif // defined(SUPPORT_OutputType_GS8208) && defined(ARDUINO_ARCH_ESP32) diff --git a/src/output/OutputMgr.cpp b/src/output/OutputMgr.cpp index fc77fc340..46d2dce93 100644 --- a/src/output/OutputMgr.cpp +++ b/src/output/OutputMgr.cpp @@ -2,7 +2,7 @@ * OutputMgr.cpp - Output Management class * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2021, 2024 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -1418,6 +1418,8 @@ void c_OutputMgr::UpdateDisplayBufferReferences (void) void c_OutputMgr::PauseOutputs(bool PauseTheOutput) { // DEBUG_START; + // DEBUG_V(String("PauseTheOutput: ") + String(PauseTheOutput)); + IsOutputPaused = PauseTheOutput; for (auto & CurrentOutput : OutputChannelDrivers) diff --git a/src/output/OutputRmt.cpp b/src/output/OutputRmt.cpp index ab37fc4e6..d12b478e6 100644 --- a/src/output/OutputRmt.cpp +++ b/src/output/OutputRmt.cpp @@ -39,30 +39,30 @@ static uint32_t FrameTimeouts = 0; //---------------------------------------------------------------------------- void RMT_Task (void *arg) { - unsigned long FrameStartTime = millis(); - unsigned long FrameEndTime = FrameStartTime; - TickType_t DelayTime = pdMS_TO_TICKS(25); + unsigned long FrameStartTimeMS = millis(); + unsigned long FrameEndTimeMS = FrameStartTimeMS; const uint32_t MinFrameTimeMs = 25; + TickType_t DelayTimeTicks = pdMS_TO_TICKS(MinFrameTimeMs); while(1) { - uint32_t DeltaTime = FrameEndTime - FrameStartTime; + uint32_t DeltaTimeMS = FrameEndTimeMS - FrameStartTimeMS; // did the timer wrap? - if (DeltaTime > MinFrameTimeMs) + if (DeltaTimeMS > MinFrameTimeMs) { // Timer has wrapped or // frame took longer than 25MS to run. // Dont wait a long time for the next one. - DelayTime = pdMS_TO_TICKS(1); + DelayTimeTicks = pdMS_TO_TICKS(1); } else { - DelayTime = pdMS_TO_TICKS( MinFrameTimeMs - DeltaTime ); + DelayTimeTicks = pdMS_TO_TICKS( MinFrameTimeMs - DeltaTimeMS ); } - vTaskDelay(DelayTime); + vTaskDelay(DelayTimeTicks); - FrameStartTime = millis(); + FrameStartTimeMS = millis(); // process all possible channels for (c_OutputRmt * pRmt : rmt_isr_ThisPtrs) { @@ -70,22 +70,24 @@ void RMT_Task (void *arg) if(nullptr != pRmt) { // invoke the channel - pRmt->StartNextFrame(); - uint32_t NotificationValue = ulTaskNotifyTake( pdTRUE, pdMS_TO_TICKS(25) ); - if(1 == NotificationValue) + if (pRmt->StartNextFrame()) { - // DEBUG_V("The transmission ended as expected."); - ++FrameCompletes; - } - else - { - ++FrameTimeouts; - // DEBUG_V("Transmit Timed Out."); + uint32_t NotificationValue = ulTaskNotifyTake( pdTRUE, pdMS_TO_TICKS(100) ); + if(1 == NotificationValue) + { + // DEBUG_V("The transmission ended as expected."); + ++FrameCompletes; + } + else + { + ++FrameTimeouts; + // DEBUG_V("Transmit Timed Out."); + } } } } // record the loop end time - FrameEndTime = millis(); + FrameEndTimeMS = millis(); } } // RMT_Task @@ -240,7 +242,7 @@ void c_OutputRmt::Begin (OutputRmtConfig_t config, c_OutputCommon * _pParent ) // reset the internal and external pointers to the start of the mem block ISR_ResetRmtBlockPointers (); RMT.conf_ch[OutputRmtConfig.RmtChannelId].conf1.apb_mem_rst = 0;/* Make sure the FIFO is not in reset */ - RMT.conf_ch[OutputRmtConfig.RmtChannelId].conf1.mem_owner = RMT_MEM_OWNER_TX; /* TX owns the memory */ + RMT.conf_ch[OutputRmtConfig.RmtChannelId].conf1.mem_owner = RMT_MEM_OWNER_TX; /* TX owns the memory */ RMT.apb_conf.fifo_mask = RMT_DATA_MODE_MEM; memset((void*)&RMTMEM.chan[OutputRmtConfig.RmtChannelId].data32[0], 0x0, sizeof(RMTMEM.chan[0].data32)); @@ -272,6 +274,8 @@ void c_OutputRmt::Begin (OutputRmtConfig_t config, c_OutputCommon * _pParent ) pParent = _pParent; rmt_isr_ThisPtrs[OutputRmtConfig.RmtChannelId] = this; + rmt_set_gpio(OutputRmtConfig.RmtChannelId, RMT_MODE_TX, OutputRmtConfig.DataPin, false); + HasBeenInitialized = true; } while (false); @@ -294,45 +298,45 @@ void c_OutputRmt::GetStatus (ArduinoJson::JsonObject& jsonStatus) debugStatus["conf1"] = String(RMT.conf_ch[OutputRmtConfig.RmtChannelId].conf1.val, HEX); debugStatus["tx_lim_ch"] = String(RMT.tx_lim_ch[OutputRmtConfig.RmtChannelId].limit); - debugStatus["FrameStartCounter"] = FrameStartCounter; - debugStatus["RawIsrCounter"] = RawIsrCounter; - debugStatus["ISRcounter"] = ISRcounter; - debugStatus["SendBlockIsrCounter"] = SendBlockIsrCounter; - debugStatus["FrameEndISRcounter"] = FrameEndISRcounter; - debugStatus["UnknownISRcounter"] = UnknownISRcounter; - debugStatus["RanOutOfData"] = RanOutOfData; - debugStatus["IntTxEndIsrCounter"] = IntTxEndIsrCounter; - debugStatus["IntTxThrIsrCounter"] = IntTxThrIsrCounter; debugStatus["ErrorIsr"] = ErrorIsr; - debugStatus["RxIsr"] = RxIsr; + debugStatus["FrameCompletes"] = String (FrameCompletes); + debugStatus["FrameStartCounter"] = FrameStartCounter; + debugStatus["FrameTimeouts"] = String (FrameTimeouts); + debugStatus["FailedToSendAllData"] = String (FailedToSendAllData); debugStatus["IncompleteFrame"] = IncompleteFrame; - debugStatus["RMT_INT_TX_END_BIT"] = "0x" + String (RMT_INT_TX_END_BIT, HEX); - debugStatus["RMT_INT_THR_EVNT_BIT"] = "0x" + String (RMT_INT_THR_EVNT_BIT, HEX); - uint32_t temp = RMT.int_ena.val; - debugStatus["Raw int_ena"] = "0x" + String (temp, HEX); - debugStatus["TX END int_ena"] = "0x" + String (temp & (RMT_INT_TX_END_BIT), HEX); - debugStatus["TX THRSH int_ena"] = "0x" + String (temp & (RMT_INT_THR_EVNT_BIT), HEX); - temp = RMT.int_st.val; - debugStatus["Raw int_st"] = "0x" + String (temp, HEX); - debugStatus["TX END int_st"] = "0x" + String (temp & (RMT_INT_TX_END_BIT), HEX); - debugStatus["TX THRSH int_st"] = "0x" + String (temp & (RMT_INT_THR_EVNT_BIT), HEX); debugStatus["IntensityValuesSent"] = IntensityValuesSent; debugStatus["IntensityValuesSentLastFrame"] = IntensityValuesSentLastFrame; debugStatus["IntensityBitsSent"] = IntensityBitsSent; debugStatus["IntensityBitsSentLastFrame"] = IntensityBitsSentLastFrame; + debugStatus["IntTxEndIsrCounter"] = IntTxEndIsrCounter; + debugStatus["IntTxThrIsrCounter"] = IntTxThrIsrCounter; + debugStatus["ISRcounter"] = ISRcounter; debugStatus["NumIdleBits"] = OutputRmtConfig.NumIdleBits; debugStatus["NumFrameStartBits"] = OutputRmtConfig.NumFrameStartBits; debugStatus["NumFrameStopBits"] = OutputRmtConfig.NumFrameStopBits; - debugStatus["SendInterIntensityBits"] = OutputRmtConfig.SendInterIntensityBits; - debugStatus["SendEndOfFrameBits"] = OutputRmtConfig.SendEndOfFrameBits; debugStatus["NumRmtSlotsPerIntensityValue"] = NumRmtSlotsPerIntensityValue; + debugStatus["OneBitValue"] = String (Intensity2Rmt[RmtDataBitIdType_t::RMT_DATA_BIT_ONE_ID].val, HEX); + debugStatus["RanOutOfData"] = RanOutOfData; + uint32_t temp = RMT.int_ena.val; + debugStatus["Raw int_ena"] = "0x" + String (temp, HEX); + temp = RMT.int_st.val; + debugStatus["Raw int_st"] = "0x" + String (temp, HEX); + debugStatus["RawIsrCounter"] = RawIsrCounter; + debugStatus["RMT_INT_TX_END_BIT"] = "0x" + String (RMT_INT_TX_END_BIT, HEX); + debugStatus["RMT_INT_THR_EVNT_BIT"] = "0x" + String (RMT_INT_THR_EVNT_BIT, HEX); debugStatus["RmtEntriesTransfered"] = RmtEntriesTransfered; + debugStatus["RmtWhiteDetected"] = String (RmtWhiteDetected); debugStatus["RmtXmtFills"] = RmtXmtFills; + debugStatus["RxIsr"] = RxIsr; + debugStatus["SendBlockIsrCounter"] = SendBlockIsrCounter; + debugStatus["SendInterIntensityBits"] = OutputRmtConfig.SendInterIntensityBits; + debugStatus["SendEndOfFrameBits"] = OutputRmtConfig.SendEndOfFrameBits; + debugStatus["TX END int_ena"] = "0x" + String (temp & (RMT_INT_TX_END_BIT), HEX); + debugStatus["TX END int_st"] = "0x" + String (temp & (RMT_INT_TX_END_BIT), HEX); + debugStatus["TX THRSH int_ena"] = "0x" + String (temp & (RMT_INT_THR_EVNT_BIT), HEX); + debugStatus["TX THRSH int_st"] = "0x" + String (temp & (RMT_INT_THR_EVNT_BIT), HEX); + debugStatus["UnknownISRcounter"] = UnknownISRcounter; debugStatus["ZeroBitValue"] = String (Intensity2Rmt[RmtDataBitIdType_t::RMT_DATA_BIT_ZERO_ID].val, HEX); - debugStatus["OneBitValue"] = String (Intensity2Rmt[RmtDataBitIdType_t::RMT_DATA_BIT_ONE_ID].val, HEX); - debugStatus["FrameCompletes"] = String (FrameCompletes); - debugStatus["FrameTimeouts"] = String (FrameTimeouts); - debugStatus["RmtWhiteDetected"] = String (RmtWhiteDetected); #ifdef IncludeBufferData { @@ -461,40 +465,42 @@ void IRAM_ATTR c_OutputRmt::ISR_Handler (uint32_t isrFlags) // //DEBUG_V(String(" RMT_INT_TX_END_BIT: 0x") + String(RMT_INT_TX_END_BIT, HEX)); // ClearRmtInterrupts; -#ifdef USE_RMT_DEBUG_COUNTERS - ++ISRcounter; - - if(isrFlags & RMT_INT_TX_END_BIT) + RMT_DEBUG_COUNTER(++ISRcounter); + if(OutputIsPaused) { - ++IntTxEndIsrCounter; + DisableRmtInterrupts; } - - if(isrFlags & RMT_INT_THR_EVNT_BIT ) + // did the transmitter stall? + else if (isrFlags & RMT_INT_TX_END_BIT ) { - ++IntTxThrIsrCounter; - } + RMT_DEBUG_COUNTER(++IntTxEndIsrCounter); + DisableRmtInterrupts; - if (isrFlags & RMT_INT_ERROR_BIT) - { - ErrorIsr++; - } + if(NumUsedEntriesInSendBuffer) + { + RMT_DEBUG_COUNTER(++FailedToSendAllData); + } - if (isrFlags & RMT_INT_RX_END_BIT) - { - RxIsr++; + // tell the background task to start the next output + vTaskNotifyGiveFromISR( SendFrameTaskHandle, &xHigherPriorityTaskWoken ); + // portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); } -#endif // def USE_RMT_DEBUG_COUNTERS - - if (isrFlags & RMT_ISR_BITS) + else if (isrFlags & RMT_INT_THR_EVNT_BIT ) { + RMT_DEBUG_COUNTER(++IntTxThrIsrCounter); + + // do we still have data to send? if(NumUsedEntriesInSendBuffer) { + // LOG_PORT.println(String("NumUsedEntriesInSendBuffer1: ") + String(NumUsedEntriesInSendBuffer)); RMT_DEBUG_COUNTER(++SendBlockIsrCounter); // transfer any prefetched data to the hardware transmitter - ISR_TransferIntensityDataToRMT(); + ISR_TransferIntensityDataToRMT( MaxNumRmtSlotsPerInterrupt ); + // LOG_PORT.println(String("NumUsedEntriesInSendBuffer2: ") + String(NumUsedEntriesInSendBuffer)); // refill the buffer ISR_CreateIntensityData(); + // LOG_PORT.println(String("NumUsedEntriesInSendBuffer3: ") + String(NumUsedEntriesInSendBuffer)); // is there any data left to enqueue? if (!ThereIsDataToSend && 0 == NumUsedEntriesInSendBuffer) @@ -502,28 +508,28 @@ void IRAM_ATTR c_OutputRmt::ISR_Handler (uint32_t isrFlags) RMT_DEBUG_COUNTER(++RanOutOfData); DisableRmtInterrupts; - // terminate the data stream - RMTMEM.chan[OutputRmtConfig.RmtChannelId].data32[RmtBufferWriteIndex].val = 0x0; - // tell the background task to start the next output vTaskNotifyGiveFromISR( SendFrameTaskHandle, &xHigherPriorityTaskWoken ); - portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + // portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); } } - else if (isrFlags & RMT_INT_TX_END_BIT ) - { - DisableRmtInterrupts; - RMT_DEBUG_COUNTER(++FrameEndISRcounter); - - // tell the background task to start the next output - vTaskNotifyGiveFromISR( SendFrameTaskHandle, &xHigherPriorityTaskWoken ); - portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); - } + // else ignore the interrupt and let the transmitter stall when it runs out of data } +#ifdef USE_RMT_DEBUG_COUNTERS else { RMT_DEBUG_COUNTER(++UnknownISRcounter); + if (isrFlags & RMT_INT_ERROR_BIT) + { + ErrorIsr++; + } + + if (isrFlags & RMT_INT_RX_END_BIT) + { + RxIsr++; + } } +#endif // def USE_RMT_DEBUG_COUNTERS // //DEBUG_END; } // ISR_Handler @@ -572,11 +578,11 @@ inline void IRAM_ATTR c_OutputRmt::ISR_StartNewDataFrame() } // StartNewDataFrame //---------------------------------------------------------------------------- -void IRAM_ATTR c_OutputRmt::ISR_TransferIntensityDataToRMT () +void IRAM_ATTR c_OutputRmt::ISR_TransferIntensityDataToRMT (uint32_t MaxNumEntriesToTransfer) { // //DEBUG_START; - uint32_t NumEntriesToTransfer = min((NUM_RMT_SLOTS/2), NumUsedEntriesInSendBuffer); + uint32_t NumEntriesToTransfer = min(NumUsedEntriesInSendBuffer, MaxNumEntriesToTransfer); #ifdef USE_RMT_DEBUG_COUNTERS if(NumEntriesToTransfer) @@ -585,7 +591,6 @@ void IRAM_ATTR c_OutputRmt::ISR_TransferIntensityDataToRMT () RmtEntriesTransfered = NumEntriesToTransfer; } #endif // def USE_RMT_DEBUG_COUNTERS - while(NumEntriesToTransfer) { RMTMEM.chan[OutputRmtConfig.RmtChannelId].data32[RmtBufferWriteIndex].val = SendBuffer[SendBufferReadIndex].val; @@ -594,6 +599,10 @@ void IRAM_ATTR c_OutputRmt::ISR_TransferIntensityDataToRMT () --NumEntriesToTransfer; --NumUsedEntriesInSendBuffer; } + + // terminate the data stream + RMTMEM.chan[OutputRmtConfig.RmtChannelId].data32[RmtBufferWriteIndex].val = uint32_t(0); + // //DEBUG_END; } // ISR_Handler_TransferBufferToRMT @@ -629,7 +638,7 @@ void c_OutputRmt::PauseOutput(bool PauseOutput) OutputIsPaused = PauseOutput; // //DEBUG_END; -} +} // PauseOutput //---------------------------------------------------------------------------- bool c_OutputRmt::StartNewFrame () @@ -643,13 +652,14 @@ bool c_OutputRmt::StartNewFrame () if(OutputIsPaused) { // DEBUG_V("Paused"); + DisableRmtInterrupts; + ClearRmtInterrupts; break; } if(InterrupsAreEnabled) { RMT_DEBUG_COUNTER(IncompleteFrame++); - break; } DisableRmtInterrupts; @@ -692,26 +702,19 @@ bool c_OutputRmt::StartNewFrame () // this fills the send buffer ISR_CreateIntensityData (); - // transfer 1st 32 entries of buffer data to the RMT hardware - ISR_TransferIntensityDataToRMT(); + // Fill the RMT Hardware buffer + ISR_TransferIntensityDataToRMT(NUM_RMT_SLOTS - 1); // this refills the send buffer ISR_CreateIntensityData (); - // transfer 2nd 32 entries of buffer data to the RMT hardware - ISR_TransferIntensityDataToRMT(); - - // top off the send buffer - ISR_CreateIntensityData (); - - // At this point we have 128 bits of data created and ready to send + // At this point we have 191 bits of data created and ready to send RMT.tx_lim_ch[OutputRmtConfig.RmtChannelId].limit = MaxNumRmtSlotsPerInterrupt; ClearRmtInterrupts; EnableRmtInterrupts; // DEBUG_V("start the transmitter"); - rmt_set_gpio(OutputRmtConfig.RmtChannelId, RMT_MODE_TX, OutputRmtConfig.DataPin, false); RMT.conf_ch[OutputRmtConfig.RmtChannelId].conf1.tx_start = 1; Response = true; diff --git a/src/output/OutputSerialRmt.cpp b/src/output/OutputSerialRmt.cpp index 46868a9d0..0bd3ab14e 100644 --- a/src/output/OutputSerialRmt.cpp +++ b/src/output/OutputSerialRmt.cpp @@ -2,7 +2,7 @@ * OutputSerialRmt.cpp - WS2811 driver code for ESPixelStick RMT Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015 Shelby Merrick +* Copyright (c) 2015 - 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -248,4 +248,15 @@ bool c_OutputSerialRmt::RmtPoll () } // Poll +//---------------------------------------------------------------------------- +void c_OutputSerialRmt::PauseOutput (bool State) +{ + // DEBUG_START; + + c_OutputSerial::PauseOutput(State); + Rmt.PauseOutput(State); + + // DEBUG_END; +} // PauseOutput + #endif // (defined(SUPPORT_OutputType_DMX) || defined(SUPPORT_OutputType_Serial) || defined(SUPPORT_OutputType_Renard)) && defined(ARDUINO_ARCH_ESP32) diff --git a/src/output/OutputSerialUart.cpp b/src/output/OutputSerialUart.cpp index 84b5e8322..c1689a015 100644 --- a/src/output/OutputSerialUart.cpp +++ b/src/output/OutputSerialUart.cpp @@ -1,7 +1,7 @@ /****************************************************************** * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel (And Serial!) driver -* Orginal ESPixelStickproject by 2015 Shelby Merrick +* Orginal ESPixelStickproject by 2015 - 2025 Shelby Merrick * *This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or(at your option) any later version. This program is distributed in the hope that it will be useful, @@ -116,7 +116,7 @@ uint32_t c_OutputSerialUart::Poll () Uart.StartNewFrame(); ReportNewFrame(); } - else + else { FrameLen = 0; } @@ -126,4 +126,15 @@ uint32_t c_OutputSerialUart::Poll () } // render +//---------------------------------------------------------------------------- +void c_OutputSerialUart::PauseOutput (bool State) +{ + // DEBUG_START; + + c_OutputSerial::PauseOutput(State); + Uart.PauseOutput(State); + + // DEBUG_END; +} // PauseOutput + #endif // defined(SUPPORT_OutputType_DMX) || defined(SUPPORT_OutputType_Serial) || defined(SUPPORT_OutputType_Renard) diff --git a/src/output/OutputTLS3001Rmt.cpp b/src/output/OutputTLS3001Rmt.cpp index 3d8f62268..b000b5845 100644 --- a/src/output/OutputTLS3001Rmt.cpp +++ b/src/output/OutputTLS3001Rmt.cpp @@ -2,7 +2,7 @@ * OutputTLS3001Rmt.cpp - TLS3001 driver code for ESPixelStick RMT Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2022 Shelby Merrick +* Copyright (c) 2015, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -163,6 +163,17 @@ bool c_OutputTLS3001Rmt::RmtPoll () } // Poll +//---------------------------------------------------------------------------- +void c_OutputTLS3001Rmt::PauseOutput (bool State) +{ + // DEBUG_START; + + c_OutputTLS3001::PauseOutput(State); + Rmt.PauseOutput(State); + + // DEBUG_END; +} // PauseOutput + //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- diff --git a/src/output/OutputTM1814Rmt.cpp b/src/output/OutputTM1814Rmt.cpp index 4bfc92989..5561e5121 100644 --- a/src/output/OutputTM1814Rmt.cpp +++ b/src/output/OutputTM1814Rmt.cpp @@ -2,7 +2,7 @@ * OutputTM1814Rmt.cpp - TM1814 driver code for ESPixelStick RMT Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2022 Shelby Merrick +* Copyright (c) 2015, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -176,5 +176,15 @@ bool c_OutputTM1814Rmt::RmtPoll () } // Poll +//---------------------------------------------------------------------------- +void c_OutputTM1814Rmt::PauseOutput (bool State) +{ + // DEBUG_START; + + c_OutputTM1814::PauseOutput(State); + Rmt.PauseOutput(State); + + // DEBUG_END; +} // PauseOutput #endif // defined (SUPPORT_OutputType_TM1814) && defined (ARDUINO_ARCH_ESP32) diff --git a/src/output/OutputUCS1903Rmt.cpp b/src/output/OutputUCS1903Rmt.cpp index a91984c55..ea8b4edb6 100644 --- a/src/output/OutputUCS1903Rmt.cpp +++ b/src/output/OutputUCS1903Rmt.cpp @@ -2,7 +2,7 @@ * OutputUCS1903Rmt.cpp - UCS1903 driver code for ESPixelStick RMT Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2022 Shelby Merrick +* Copyright (c) 2015, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -171,4 +171,15 @@ bool c_OutputUCS1903Rmt::RmtPoll () } // Poll +//---------------------------------------------------------------------------- +void c_OutputUCS1903Rmt::PauseOutput (bool State) +{ + // DEBUG_START; + + c_OutputUCS1903::PauseOutput(State); + Rmt.PauseOutput(State); + + // DEBUG_END; +} // PauseOutput + #endif // defined(SUPPORT_OutputType_UCS1903) && defined(ARDUINO_ARCH_ESP32) diff --git a/src/output/OutputUCS8903Rmt.cpp b/src/output/OutputUCS8903Rmt.cpp index c801b057b..aa5dc7b63 100644 --- a/src/output/OutputUCS8903Rmt.cpp +++ b/src/output/OutputUCS8903Rmt.cpp @@ -2,7 +2,7 @@ * OutputUCS8903Rmt.cpp - UCS8903 driver code for ESPixelStick RMT Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015 Shelby Merrick +* Copyright (c) 2015 - 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -175,4 +175,15 @@ bool c_OutputUCS8903Rmt::RmtPoll () } // Poll +//---------------------------------------------------------------------------- +void c_OutputUCS8903Rmt::PauseOutput (bool State) +{ + // DEBUG_START; + + c_OutputUCS8903::PauseOutput(State); + Rmt.PauseOutput(State); + + // DEBUG_END; +} // PauseOutput + #endif // defined(SUPPORT_OutputType_UCS8903) && defined(ARDUINO_ARCH_ESP32) diff --git a/src/output/OutputWS2811Rmt.cpp b/src/output/OutputWS2811Rmt.cpp index c4884abcd..db3516c60 100644 --- a/src/output/OutputWS2811Rmt.cpp +++ b/src/output/OutputWS2811Rmt.cpp @@ -2,7 +2,7 @@ * OutputWS2811Rmt.cpp - WS2811 driver code for ESPixelStick RMT Channel * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2022 Shelby Merrick +* Copyright (c) 2015, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -177,4 +177,15 @@ bool c_OutputWS2811Rmt::RmtPoll () } // Poll +//---------------------------------------------------------------------------- +void c_OutputWS2811Rmt::PauseOutput (bool State) +{ + // DEBUG_START; + + c_OutputWS2811::PauseOutput(State); + Rmt.PauseOutput(State); + + // DEBUG_END; +} // PauseOutput + #endif // defined(SUPPORT_OutputType_WS2811) && defined(ARDUINO_ARCH_ESP32) diff --git a/src/service/FPPDiscovery.cpp b/src/service/FPPDiscovery.cpp index 6519968c0..ba8701539 100644 --- a/src/service/FPPDiscovery.cpp +++ b/src/service/FPPDiscovery.cpp @@ -1,7 +1,7 @@ /* * c_FPPDiscovery.cpp -* Copyright (c) 2021, 2022 Shelby Merrick +* Copyright (c) 2021, 2025 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -816,6 +816,9 @@ void c_FPPDiscovery::ProcessFile ( StopPlaying(true); inFileUpload = true; UploadFileName = filename; + InputMgr.SetOperationalState(false); + OutputMgr.PauseOutputs(true); + memset(OutputMgr.GetBufferAddress(), 0x00, OutputMgr.GetBufferSize()); } // DEBUG_V(); @@ -833,6 +836,8 @@ void c_FPPDiscovery::ProcessFile ( // DEBUG_V("Allow file to play"); inFileUpload = false; UploadFileName = ""; + InputMgr.SetOperationalState(true); + OutputMgr.PauseOutputs(false); } } while (false);