millis() Bug controlling LED's with sound input

Hi there,
a few month ago I've started a new Arduino project. My goal was to have indirect lighting behind my shelf wich is sound-responsive. I've realized this by feeding one channel of my analog audio cable from my PC into the Arduino. The Arduino then simply reads out the gain, processes it and controls the LEDs (WS2812b). So far im really satisfied with the outcome. At this point I have 4 sound responsive modes and 6 other (non sound responsive) modes. A few days ago I wanted to create another "Party" mode. This Mode should determine a random time, color and mode, and then run this mode with the color until the time is over.

void partyModeColorChooser(int r) {
  switch (r) {
    case 0: partyColor = CRGB::Red; break;
    case 1: partyColor = CRGB::OrangeRed; break;
    case 2: partyColor = CRGB::DarkViolet; break;
    case 3: partyColor = CRGB::SeaGreen; break;
    case 4: partyColor = CRGB::DarkCyan; break;
    default: partyColor = CRGB::Green; break;
  }
}

void partyLightAnimationChooser(int lightModeSwitch) {
  switch (lightModeSwitch) {
    case 0: volumeBreath(partyColor, partyColor); break;
    case 1: soundmeter(partyColor, partyColor, CRGB::Blue); break;
    case 2: sparkle(partyColor); break;
    case 3: soundshooter(partyColor); break;
    case 4: randcolorstep();
    case 5: inout(partyColor, partyColor); break;
  }
}

void partymode() {
  unsigned long currentTime = millis();
  Serial.print("Time: ");
  Serial.print(currentTime);
  Serial.print(" - ");
  Serial.print(startTime);
  Serial.print(" > ");
  Serial.println(partyLightModeDuration);

  if (currentTime - startTime > partyLightModeDuration) {
    startTime = currentTime;
    fill_solid(led, NUM_LEDS, CRGB::Black);
    int r = random(0, 5);
    partyLightMode = random(0, 6);
    partyLightModeDuration = random(10000, 60000);
    partyModeColorChooser(r);
    resetRandStep();
  }
  partyLightAnimationChooser(partyLightMode);
}

My Problem is now that every time when the lightmode is volumeBreath (sound responsive) and the gain is high enough to light the LEDs, millis() gets reseted back to 0. (see log)

Time: 6457 - 0 > 10000
Time: 6488 - 0 > 10000
Time: 6518 - 0 > 10000
Time: 283 - 0 > 10000       --> here the LEDs light up
Time: 283 - 0 > 10000
Time: 283 - 0 > 10000
...
Time: 1244 - 0 > 10000
Time: 1275 - 0 > 10000
Time: 284 - 0 > 10000      --> here the LEDs light up
Time: 282 - 0 > 10000
...
Time: 1047 - 0 > 10000
Time: 282 - 0 > 10000     --> here the LEDs light up
etc.

This bug prevents the system to change Modes as long music is playing. Thats really strange because I dont use any time related functions in volumeBreath. Thats why i can't seem to find the bug.

void volumeBreath(CRGB::HTMLColorCode color1, CRGB::HTMLColorCode color2) {
  int gain = maxOf_From_Samples(3, 4);

  if (gain > 450) {
    fill_gradient_RGB(led, 0, color1, NUM_LEDS, color2);
    delay(20);
  } else {
    for (int i = 0; i < NUM_LEDS; i++)
      led[i].fadeLightBy(24);
  }
  FastLED.show();
}

Here are the functions that are responsible for reading out the gain (average of some samples and max of a number of averages)

int gainReadout(int anz) {
  float sum = 0;
  for (int i = 0; i < anz; i++) {
    sum += (float)analogRead(LEFT_ANALOG_AUDIO_IN) / (float)anz;

    delay(1);
  }
  return (int)sum;
}

int maxOf_From_Samples(int anz, int samples) {
  int maxi = 0;
  int temp;

  for (int i = 0; i < anz; i++) {
    temp = gainReadout(samples);
    if (temp > maxi)
      maxi = temp;
  }
  return maxi;
}

Like I already said I cant seem to find the bug. It's also worth mentioning that other sound responsive functions like soundmeter doesn't have this problem. Maybe it has something to do with the FastLED library?

I hope you have some ideas. Thanks in advance.

shelfmodes_refractored.ino (11.8 KB)

millis() gets reseted back to 0

I am willing to bet that it doesn't
You are printing the value of currentTime, not the value of millis(). Try printing millis() instead

Have you by any chance got 2 (or more) different variables named currentTime each with their own scope ?

UKHeliBob:
Have you by any chance got 2 (or more) different variables named currentTime each with their own scope ?

No, currentTime is only used in partymode.

UKHeliBob:
I am willing to bet that it doesn't
You are printing the value of currentTime, not the value of millis(). Try printing millis() instead

Code is now..

void partymode() {
  
  Serial.print(millis());
  Serial.print("  :  ");
  unsigned long currentTime = millis();
  
  Serial.print(currentTime);
  Serial.print(" - ");
  Serial.print(startTime);
  Serial.print(" > ");
  Serial.println(partyLightModeDuration);

  if (currentTime - startTime > partyLightModeDuration) {
    startTime = currentTime;
    fill_solid(led, NUM_LEDS, CRGB::Black);
    int r = random(0, 5);
    partyLightMode = random(0, 6);
    partyLightModeDuration = random(10000, 60000);
    partyModeColorChooser(r);
    resetRandStep();
  }
  partyLightAnimationChooser(partyLightMode);
}

Log is:

3865  :  3865 - 0 > 10000
3887  :  3888 - 0 > 10000
284  :  284 - 0 > 10000
307  :  307 - 0 > 10000
...
1025  :  1025 - 0 > 10000
282  :  282 - 0 > 10000
...
1386  :  1386 - 0 > 10000
283  :  283 - 0 > 10000
etc.

Damn, I thought that could be the solution

If millis() is really going back to 0 at certain times then presumably it's because the Arduino is being reset. Maybe you're doing something like trying to power the LED strip from the Arduino 5V pin instead of a sensible external power supply?

Unfortunately because you've provided little useful information, no complete program, no circuit diagram, no details of the power supply or the LEDs being used, it's not easy to guess what might be going on.

Steve

Please humour me

Change

  unsigned long currentTime = millis();

to

  currentTime = millis();

Does the code compile ?

slipstick:
If millis() is really going back to 0 at certain times then presumably it's because the Arduino is being reset. Maybe you're doing something like trying to power the LED strip from the Arduino 5V pin instead of a sensible external power supply?

I've now attached my code above. It's a state machine. That means that if the arduino gets reseted the entire state machine gets reseted and the arduino would not be in the function partymode anymore in which it is.

slipstick:
Unfortunately because you've provided little useful information, no complete program, no circuit diagram, no details of the power supply or the LEDs being used, it's not easy to guess what might be going on.

The LED strip is powered using a 5V/20A Power suply. The Arduino itself is powered by a AC Adapter. Pin 6 is used for the strips data cable and Pin A1 is for the analog audio input. I'm controlling the state machine with a JoyStick connected to A4 and A5.

UKHeliBob:
Please humour me

Change

  unsigned long currentTime = millis();

to

  currentTime = millis();

Does the code compile ?

Nope, it's not compiling.

Having seen you full code I can confirm that

However, if you put

 partymode();
  Serial.println("done");
  while (true);

at the end of setup() you will see that something is resetting the Arduino in the partymode() function or a function called by it

UKHeliBob:
Having seen you full code I can confirm that

However, if you put

 partymode();

Serial.println("done");
 while (true);



at the end of setup() you will see that something is resetting the Arduino in the partymode() function or a function called by it

Thanks, I finally found the bug. Because millis() was reseted everytime the LEDs were lit while being in function volumeBreath() I could be shure that the bug occurs only in the if case. Since only delay () and fill_gradient_RGB() were present and delay should be good because its a standard function I changed

fill_gradient_RGB(led, 0, color1, NUM_LEDS, color2);

at line 58 to

fill_solid(led, NUM_LEDS, color1);

and voila it works.
Apparently fill_gradient_RGB() bugged my code. But that's a bit strange because I'm using this function in other function called by partymode() to and there it seems to work..

Thank you, however, first for your help