0

My LED controller has a color fader mode that I am making. The controller's loop() function grabs incoming serial data to set the amount of colors, fade speed, mode, and other info then runs the correct mode with the colors that it read from the serial port

When in color fader mode, the controller "freezes" at a certain color and becomes unresponsive to further input until I unplug it and plug it back in or reupload the code (the latter means that it still responds to something).

For testing purposes I am using red, green, and blue in that order. This stopping color can happen anywhere from in the middle of the transition from red to green in the first cycle to going through multiple cycles and stopping on blue depending on the fade speed. This only became a problem after I switched from using delay() to millis(). Why is that and what can I do to fix it?

The reason I switched to using millis is because the delays would stack infinitely and the arduino would become unresponsive to commands

Here is my relevant code:

#include <Adafruit_DotStar.h>
#include <SPI.h>

#define NUMPIXELS 60
#define DATAPIN    4
#define CLOCKPIN   5

Adafruit_DotStar strip(NUMPIXELS, DOTSTAR_BRG);

// Variables
int mode;
int numColors;
int fadeSpeed;
int BBCC;
int R[100];
int G[100];
int B[100];
int Bright[100];

int currColor;

void setup() {

#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000L)
  clock_prescale_set(clock_div_1); // Enable 16 MHz on Trinket
#endif
  strip.begin(); // Initialize pins for output
  strip.show();  // Turn all LEDs off ASAP

  currColor = 0;
}

void loop() {
  strip.show();                     // Refresh strip
  delay(20);                        // Pause 20 milliseconds (~50 FPS)

  getData();


  switch (mode)
  {
    case 1:                  // Mode 1: Solid Color
    {
      for (int i = 0; i < NUMPIXELS; i++)
      {
        if (i % 2 == 0)
          strip.setPixelColor(i, G[0], R[0], B[0]);// Sets whole strip to Color 1
      }
      strip.setBrightness(Bright[0]);
      strip.show();
      break;
    }
    case 2:                  // Mode 2: Multi Color Fader
    {
      colorFade();
      break;
    }
    case 3:                  // Mode 3: Multi Color Pattern
    {
      int j = 0;
      for (int i = 0; i < NUMPIXELS; i++)
      {
        if (i % 2 == 0)
        {
          strip.setPixelColor(i, G[j], R[j], B[j]); // sets a repeating pattern 
          if (j == (numColors - 1))
            j = 0;
          else
            j++;
        }
      }
      strip.setBrightness(Bright[0]);
      strip.show();
      break;
    }
    case 4:                  // Mode 4: Music-Reactive Wave Form
    {

      break;
    }
    case 5:                  // Mode 5: Music-Reactive Color Jump
    {

      break;
    }
    default:                 // Default Mode: Incandecent Simulation
    {
      for (int i = 0; i < NUMPIXELS; i++)
      {
        if (i % 2 == 0)
          strip.setPixelColor(i, 150, 200, 40); // Sets whole strip to default value
      }
      strip.setBrightness(255);
      strip.show();
      break;
    }
  }

}


void colorFade()
{
  int del = 100;     // 100 milisecond
  if (currColor >= numColors - 1)
  {

    int steps = fadeSpeed * del;
    int Rdiff, Gdiff, Bdiff, BrightDiff;

    Rdiff = R[0] - R[currColor];
    Gdiff = G[0] - G[currColor];
    Bdiff = B[0] - B[currColor];
    BrightDiff = Bright[0] - Bright[currColor];

    for (int i = 0; i <= steps + 5; i++)
    {
      for (int j = 0; j < NUMPIXELS; j++)
      {
        if (j % 2 == 0)
          strip.setPixelColor(j, (G[currColor] - (Gdiff * i)), (R[currColor] - (Rdiff * i)), (B[currColor] - (Bdiff * i))); // Sets whole strip to value
      }
      //strip.setBrightness((Bright[currColor] - (BrightDiff * i)));
      strip.show();    
      //delay(del);
      int timer = millis() + del;
      while(millis() < timer)
      {

      }
    }
    currColor = 0;
  }
  else
  {
    int steps = fadeSpeed * del;
    int Rdiff, Gdiff, Bdiff, BrightDiff;

    Rdiff = R[currColor + 1] - R[currColor];
    Gdiff = G[currColor + 1] - G[currColor];
    Bdiff = B[currColor + 1] - B[currColor];
    BrightDiff = Bright[currColor + 1] - Bright[currColor];

    for (int i = 0; i <= steps + 5; i++)
    {
      for (int j = 0; j < NUMPIXELS; j++)
      {
        if (j % 2 == 0)
          strip.setPixelColor(j, (G[currColor] - (Gdiff * i)), (R[currColor] - (Rdiff * i)), (B[currColor] - (Bdiff * i))); // Sets whole strip to value
      }
      //strip.setBrightness((Bright[currColor] - (BrightDiff * i)));
      strip.show();    
      //delay(del);

      int timer = millis() + del;
      while(millis() < timer)
      {

      }
    }
    currColor++;
  }
}
6
  • start debugging by running only the fade selection ... preset mode to 2 .... comment out getData(); in loop()
    – jsotola
    Aug 17, 2019 at 19:45
  • how would I debug this in arduino IDE? I can't find any command for breakpoints and I don't know what I would need to look at if i used serial.println() to read values
    – BoatHouse
    Aug 17, 2019 at 21:56
  • There is no debugging in the normal embedded firmware sense WRT Arduino programming. That is why you need to start small and not add anything more complex until the small thing works.
    – st2000
    Aug 17, 2019 at 23:17
  • it is not "Arduino" ... it is "C++" .... insert mode = 2; in setup() ... replace getData(); with // getData();
    – jsotola
    Aug 18, 2019 at 0:19
  • 1
    @BoatHouse Please write an answer to your question, so that others can profit from it. Thank you
    – chrisl
    Aug 18, 2019 at 21:02

1 Answer 1

0

The problem with the above code lies with overflow. timer should be an unsigned long, because millis() outputs an unsigned long. This causes the freeze because after timer hits its upper limit, This setup works better:

unsigned long timer = (unsigned long)millis() + del;
      while((unsigned long)millis() < timer)
      {
        //wait for as long as del says to
      }

This setup should be able to run for a long time without overflowing

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.