Queue returns unexpected objects

Hello there,

I'm new to Arduino&C++, so it is probably a newby problem.
I try to synchronize LEDs on a LED-strip to the music beat: Every time, there is a new beat, a new LED turns on and afterwards it will fade out.
To controll the Fading-process I programmed a Fader class, which can give a less brighter colour of the start colour depending on the time. To controll multiple LEDs I use a queue, which should handle the appropriate faders.
But I recognized, that this queue does not work properly in my main sketch, so I wrote a shorter example sketch:

#include <cppQueue.h>
#include "Fader.h"

Fader f1;
int i = 0;
Queue faders(sizeof(Fader(0,0,0, CRGB::Black)), 80, FIFO, false);

void setup() {
  Serial.begin(9600);
  Serial.println("Hello World!");
}

void loop() {
  if (random(100) > 90) {
    f1 = Fader(i, millis(), random(500, 2001), CRGB::HotPink);
    faders.push(&f1);
    Serial.println("Push: " + String(int(&f1)));
    i = (i + 1) % 80;
  }

  Serial.println("i: " + String(i));

  if (faders.pop(&f1)) {
    Serial.println("Pop: " + String(int(&f1)) + " ledNumber: " + String(f1.ledNumber));
    CRGB curColour = f1.getColour(millis());
    Serial.println("Red: " + String(curColour.r) + " Green: " + String(curColour.g) + " Blue: " + String(curColour.b));
    if (curColour) { //curColour is not black
      faders.push(&curColour);
      Serial.println("Push " + String(int(&f1)));
    }
  }
}

I expected the queue to pop only items, which were pushed into it before. But insted, I get this output:

Hello World!
i: 0
i: 0
i: 0
i: 0
i: 0
i: 0
i: 0
i: 0
i: 0
i: 0
i: 0
i: 0
Push: 369
i: 1
Pop: 369 ledNumber: 0
Red: 246 Green: 101 Blue: 173
Push 369
i: 1
Pop: 369 ledNumber: 246
Red: 219 Green: 213 Blue: 105
Push 369
i: 1
Pop: 369 ledNumber: 219
Red: 41 Green: 49 Blue: 49
Push 369
i: 1
Pop: 369 ledNumber: 41
Red: 44 Green: 34 Blue: 126
Push 369
i: 1
Pop: 369 ledNumber: 44
Red: 11 Green: 26 Blue: 103
Push 369
i: 1
Pop: 369 ledNumber: 11
Red: 4 Green: 13 Blue: 48
Push 369
i: 1
...
Pop: 369 ledNumber: 1
Red: 215 Green: 89 Blue: 152
Push 369

So from time to time, there are expected items, but not always.

My question is now, how to make the queue act as it is planned?

Thank you!

P.S.: This is the code of the Fader class:

#include "Arduino.h"
#include <FastLED.h>

class Fader{
  public:
    Fader(uint8_t ledNumber, uint32_t starTime, uint16_t duration, CRGB startColour);
    Fader(){};
    CRGB getColour(uint32_t curTime);
    uint8_t ledNumber; //1 Byte
  private:
    uint32_t startTime; //4 Bytes
    uint16_t duration; //2 Bytes
    CRGB startColour;  //3Bytes
               // = 10 Bytes
};
Fader::Fader(uint8_t pLedNumber, uint32_t pStarTime, uint16_t pDuration, CRGB pStartColour){
  ledNumber = pLedNumber;
  startTime = pStarTime;
  duration = pDuration;
  startColour = pStartColour;
}


CRGB Fader::getColour(uint32_t curTime){
  if(curTime >= (startTime + duration))
    return CRGB::Black;
  float tPhase = (float(curTime) - float(startTime))/float(duration);
  uint8_t brightness = int(-256.0*tPhase + 256.0); 
  CRGB returnColour = CRGB(startColour);
  returnColour %= brightness;
  return returnColour;
}

Thank you for using code tags. :slight_smile:

You are passing a pointer to a local object to a static queue. The local object goes out of scope immediately after pushing it onto the FIFO, and then the pointer saved in the buffer is no longer valid.
You would have to use dynamic memory allocation to do it that way.

However, that's not the optimal solution, especially not on a microcontroller with very limited resources.
You only have a fixed number of LEDs in your design, so it wouldn't be a good idea to 'create' LED objects dynamically.

Start with a static array of N LEDs, and manipulate their internal state to turn them on/of and to fade them, rather than using external logic to do that.

Pieter

Edit: That queue library seems to copy the records, so it doesn't matter that the original object goes out of scope. At any rate, it's still not a great solution in my eyes.
Please specify what kind of behavior you'd like for your LEDs.

Also, you don't have to create an object to get the size of a fader. Doing this:

int s = sizeof(Fader);
Serial.println(s);

shows the expected value of 10.

Why are you pushing a CRGB object onto a queue of faders?!? That's going to cause all sorts of mess when you pop that into a Fader object!

    CRGB curColour = f1.getColour(millis());
    Serial.println("Red: " + String(curColour.r) + " Green: " + String(curColour.g) + " Blue: " + String(curColour.b));
    if (curColour) { //curColour is not black
      faders.push(&curColour);