@@ -138,21 +138,21 @@ void effectTask(void* pvParameters) {
138138 // Copy previous frame (channelsD) to working buffer (channelsE)
139139 memcpy (layerP.lights .channelsE , layerP.lights .channelsD , layerP.lights .header .nrOfChannels );
140140
141+ xSemaphoreTake (monitorMutex, portMAX_DELAY); // don't change channelsE while the monitor display data is sent
141142 layerP.loop ();
142143
143144 if (millis () - last20ms >= 20 ) {
144145 last20ms = millis ();
145146 layerP.loop20ms ();
146147 }
148+ xSemaphoreGive (monitorMutex);
147149
148150 // Atomic swap channels
149151 xSemaphoreTake (swapMutex, portMAX_DELAY);
150- xSemaphoreTake (monitorMutex, portMAX_DELAY);
151152 uint8_t * temp = layerP.lights .channelsD ;
152153 layerP.lights .channelsD = layerP.lights .channelsE ;
153154 layerP.lights .channelsE = temp;
154155 newFrameReady = true ;
155- xSemaphoreGive (monitorMutex);
156156 xSemaphoreGive (swapMutex);
157157 }
158158
@@ -190,16 +190,17 @@ void driverTask(void* pvParameters) {
190190 if (layerP.lights .useDoubleBuffer ) {
191191 if (newFrameReady) {
192192 newFrameReady = false ;
193- esp32sveltekit.lps ++;
194193 // Double buffer: release lock, then send
195194 xSemaphoreGive (swapMutex);
196195
196+ esp32sveltekit.lps ++;
197197 layerP.loopDrivers (); // ✅ No lock needed
198198 } else {
199199 xSemaphoreGive (swapMutex);
200200 }
201201 } else {
202202 // Single buffer: keep lock while sending
203+ esp32sveltekit.lps ++;
203204 layerP.loopDrivers (); // ✅ Protected by lock
204205 xSemaphoreGive (swapMutex);
205206 }
0 commit comments