I have a couple of pattern functions and one task (Task1) which runs on core 1. I receive data (pattern no.) from BLE in core 0. Depending on the data, I create the task above with the task function as the chosen pattern.

Problem comes when I want to switch patterns. What I do is delete the already running task handle (Task1) and recreate the same Task1 handle with the new pattern function. Sometimes the switch between patterns is flawless. But most times, the switch happens but the leds don't get updated. In the background I can see the new task has been created and the pattern looping as expected but the leds just don't get updated. They are stuck on the colors from the previous deleted task.

The switch of patterns: `

TaskHandle_t Task1;

// if a new pattern no. has been read
if (command.startsWith("p"))
        {
            if (Task1 != NULL)
            {
                vTaskDelete(Task1);
            }


            xTaskCreatePinnedToCore(
                switchPattern(command.substring(1).toInt()), /* Returns a task function. */
                "Task1",                                     /* name of task. */
                20000,                                       /* Stack size of task */
                NULL,                                        /* parameter of the task */
                1,                                           /* priority of the task */
                &Task1,                                      /* Task handle to keep track of created task */
                1);                                          /* pin task to core 1 */

            mode = 1; // switch to patterns mode
            preferences.putInt("mode", mode);
        }

**Example pattern function:**

void BPM(void *)
{
    while (1)
    {
        // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
        uint8_t BeatsPerMinute = 62;
        CRGBPalette16 palette = PartyColors_p;
        uint8_t beat = beatsin8(BeatsPerMinute, 64, 255);
        for (int i = 0; i < NUM_LEDS; i++)
        { // 9948
            led[i] = ColorFromPalette(palette, (i * 2), beat + (i * 10));
        }
        FastLED.show();
    }
}

` If you know the fault or know a better way to do this, throw it at me. Any help is appreciated!

I really can't find similar questions online so I haven't tried much. I have tried not deleting the task at all, but that just adds more tasks to the core 1 hence showing multiple patterns at once, though FASTLED continues working normally. But this is not the expected result of course.

I expect the changing of patterns to be smooth. Maybe I'm missing something.

1

There are 1 best solutions below

7
Tarmo On

Creating a new task for a simple control flow branch is a nuclear overkill :) I suspect you don't need to create any threads whatsoever, as FastLED doesn't seem to require it in any way (didn't look too deep).

Assuming you have a LED blinking task, just signal to it which option you want. It can be done quite simply.

typedef enum {
    LED_PATTERN_BPM,
    LED_PATTERN_Y,
    LED_PATTERN_Z
} led_pattern_t;

// "volatile" keyword required for any variable accessed in different threads
volatile led_pattern_t _led_pattern = LED_PATTERN_BPM;

// Single iteration of a flash pattern, no while(1) loop
void flash_pattern_BPM()
{
    // colored stripes pulsing at a defined Beats-Per-Minute (BPM)
    uint8_t BeatsPerMinute = 62;
    CRGBPalette16 palette = PartyColors_p;
    uint8_t beat = beatsin8(BeatsPerMinute, 64, 255);
    for (int i = 0; i < NUM_LEDS; i++)
    { // 9948
        led[i] = ColorFromPalette(palette, (i * 2), beat + (i * 10));
    }
    FastLED.show();
}

void flash_pattern_Z_interruptible() {
    while (_led_pattern == LED_PATTERN_Z) {
        // Fill the pattern, show it
    }
}

// Task code for flashing the LEDs
void led_task(void* param) {
    while (true) {
        switch(_led_pattern) {
        case LED_PATTERN_BPM:
            flash_pattern_BPM();
            break;
        case LED_PATTERN_Y:
            // Flash pattern Y
            break;
        case LED_PATTERN_Z:
            flash_pattern_Z_interruptible();
            break;
        }
    }
}

xTaskCreatePinnedToCore(led_task, "LED task", 20000, NULL, 1, &Task1, 1);

... 
// Somewhere in your code where a new pattern is required
_led_pattern = LED_PATTERN_Z;