Running a neopixel in a Task

Hi everybody, this is my first time running freeRTOS, so excuse my noobishness.
I made 2 Tasks, one that writes over the serial interface a “Hello world” string, and the other drives a neopixel. Over the serial interface I see the output. But the neopixel doesn’t light up.

This is the neopixel Task:

void TaskRGBLed(void *pvParameters __attribute__((unused))) // This is a Task.
{
  Adafruit_NeoPixel neoPixel = Adafruit_NeoPixel(1, 2, NEO_GRB + NEO_KHZ800);
  neoPixel.clear();

  for (;;) // A Task shall never return or exit.
  {
    for (int pixel = 0; pixel < 1; pixel++)
    {                                                           // for each pixel
      neoPixel.setPixelColor(pixel, neoPixel.Color(0, 0, 255)); // it only takes effect if pixels.show() is called
      neoPixel.show();
      vTaskDelay(100);
    }
    //vTaskDelay(100);

    for (int pixel = 0; pixel < 1; pixel++)
    {
      neoPixel.setPixelColor(pixel, neoPixel.Color(0, 255, 0));
      neoPixel.show();
      vTaskDelay(100);
    }
  }
}

I use an arudino nano, and I have tested the code in an arduino enviroment. Please let me know what am I missing…

Stack overflow ? Depending on how big an Adafruit_NeoPixel object is… you could retry with an increased task stack size or make it static for testing.
You should enable configASSERT and stack overflow checking for development if you didn’t.

I have added a Serial println to the TaskRGBLed to check if the task is being processed at all. And yes I get an additional output on the serial terminal.
Yet the neopixel doesn’t even turn on.

void TaskRGBLed(void *pvParameters __attribute__((unused))) // This is a Task.
{
  Adafruit_NeoPixel neoPixel = Adafruit_NeoPixel(1, 2, NEO_GRB + NEO_KHZ800);
  neoPixel.clear();

  for (;;) // A Task shall never return or exit.
  {
    for (int pixel = 0; pixel < 1; pixel++)
    { // for each pixel
      neoPixel.clear();
      neoPixel.setPixelColor(pixel, neoPixel.Color(0, 0, 255)); // it only takes effect if pixels.show() is called
      neoPixel.show();
      vTaskDelay(1000 / portTICK_PERIOD_MS); // one tick delay (15ms) in between reads for stability
    }
    // vTaskDelay(1000 / portTICK_PERIOD_MS); // one tick delay (15ms) in between reads for stability
    
    Serial.println("TaskRGBLed");//serial print happens successfully here....

    for (int pixel = 0; pixel < 1; pixel++)
    {
      neoPixel.clear();
      neoPixel.setPixelColor(pixel, neoPixel.Color(0, 255, 0));
      neoPixel.show();
      vTaskDelay(1000 / portTICK_PERIOD_MS); // one tick delay (15ms) in between reads for stability
    }
  }
}

What part exactly do you mean that you want to make static…

I mean static Adafruit_NeoPixel neoPixel = to avoid allocation on stack for testing.
However, did you enable FreeRTOS - stacks and stack overflow checking and defined configASSERT as recommended ?
BTW which FreeRTOS version do you use ?

I’m using the following version of freeRTOS on github: feilipu/Arduino_FreeRTOS_Library
I have kinda unserstood the concept of configASSERT, but do I simply throw the line in the #define area:
#define configASSERT ( x ) if( ( x ) == 0 ) vAssertCalled( FILE, LINE )

and then define the function vAssertCalled?

Yes, you could do that this way. Finally you should stop the app to allow halting the target with the debugger and check the call stack etc.
Or simply use a simple macro like this:

#define configASSERT( x ) if( ( x ) == pdFALSE ) { taskDISABLE_INTERRUPTS(); for( ;; ); }

While we are at it. Is the neopixel HW basically working ? I mean did it already work for you e.g. when used in main before starting tasks or even without FreeRTOS ?

Before starting at freeRTOS, I made sure that my code for driving the neopixel works as well the hardware.
Here is my code from my arduino project that only drives the neopixel:

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>  // Required for 16 MHz Adafruit Trinket
#endif

#define PIN_NEO_PIXEL 2     // Arduino pin that connects to NeoPixel
#define NUM_PIXELS 1        // The number of LEDs (pixels) on NeoPixel
#define DELAY_INTERVAL 250  // 250ms pause between each pixel

#define outputA 6
#define outputB 7
#define key 10
#define BAUD_RATE 115200

int red = 255, green = 0, blue = 0;
int pixelIndex = 0;
bool switchStateIsOff = true;
Adafruit_NeoPixel neoPixel = Adafruit_NeoPixel(NUM_PIXELS, PIN_NEO_PIXEL, NEO_GRB + NEO_KHZ800);

void setup() {
  neoPixel.begin();
  Serial.begin(BAUD_RATE);
}

void loop() {
  for (int pixel = 0; pixel < NUM_PIXELS; pixel++) {           // for each pixel
    neoPixel.setPixelColor(pixel, neoPixel.Color(0, 0, 255));  // it only takes effect if pixels.show() is called
    neoPixel.show();
    delay(250);  // pause between each pixel
  }
  for (int pixel = 0; pixel < NUM_PIXELS; pixel++) {
    neoPixel.setPixelColor(pixel, neoPixel.Color(0, 255, 0));
    neoPixel.show();
    delay(250);
  }
}

There are some lines that wouldn’t make sense, but that is because i was from previous experimentation before deciding to start off with freeRTOS.

Back to my freeRTOS project, these lines are from the #include and define lines:

#include <Arduino.h>
#include <Arduino_FreeRTOS.h>
#include <Adafruit_NeoPixel.h>
#include <semphr.h>

#define configASSERT( x ) if( ( x ) == pdFALSE ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
#define PIN_NEO_PIXEL 2    // Arduino pin that connects to NeoPixel
#define NUM_PIXELS 1       // The number of LEDs (pixels) on NeoPixel
#define DELAY_INTERVAL 250
#define BAUD_RATE 9600

I’m not familiar with Adafruit but maybe you simply missed

in your FreeRTOS version ?
BTW #define configASSERT should be in your FreeRTOSConfig.h file containing all the FreeRTOS - The Free RTOS configuration constants and configuration options - FREE Open Source RTOS for small real time embedded systems

Thank you for your sharp eye. That was the thing that I was missing that made my neopixel that didn’t work.