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++;
 }
}
asked Aug 17, 2019 at 18:46
6
  • start debugging by running only the fade selection ... preset mode to 2 .... comment out getData(); in loop() Commented 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 Commented 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. Commented Aug 17, 2019 at 23:17
  • it is not "Arduino" ... it is "C++" .... insert mode = 2; in setup() ... replace getData(); with // getData(); Commented Aug 18, 2019 at 0:19
  • 1
    @BoatHouse Please write an answer to your question, so that others can profit from it. Thank you Commented 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

answered Aug 19, 2019 at 14:54

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.