Hi all. I'm having great success with my fastLED project and I really at

Hi all. I’m having great success with my fastLED project and I really at the end of the development stage, need some “arduino” guidance, perhaps more than with the fast led library.

My project: I am making led dog collars where I have programmed the option for the user to select between several set color pallets, and also between 3 brightness levels.

On my last revision to my custom PCB, I added a function to use analog 0 (A0) to monitor battery voltage, and send an output to a discrete LED on PIN 5.

Here is the problem, and I know what is happening, just looking for options… When the voltage I monitor is above 3.7V, pin 5 goes high and lights the led, when it falls below that, I programmed a flashing subfunction, for the led on 600ms, off 600ms, repeat. My intent is to advise the owner that at the end of their dog walk if the battery is getting “sort-of” low, to recharge.

My problem: when I am in the low battery subroutine, the flashing timer function takes away from the fast LED counts, and if the customer is running one of the animation pallets, the pattern display slows down (obviously doesn’t happen in solid-color, non moving pallets).

Not a fault of Fast LED, but can someone offer some ideas on how I can fix this beside adding a seperate low battery led and have it always on when low and not do any timing counts?

My code:

#include <buttons.h>
#include <FastLED.h>

// define the LEDs
#define LED_PIN 12 //pin the LEDs are connected to
#define NUM_LEDS 10 //16 LEDs in a small collar 23 LEDs in a medium collar 29 LEDs in a large collar
#define MAX_BRIGHTNESS 255 //maximum brightness - useful if running off battery
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB

//THIS IS THE START OF THE CODE THAT MONITORS THE VOLTAGE
// number of analog samples to take per reading
//#define NUM_SAMPLES 10 original statement
#define NUM_SAMPLES 1
int sum = 0; // sum of samples taken
unsigned char sample_count = 0; // current sample number
float voltage = 0.0; // calculated voltage
const int ledPin = 5;
//THIS IS THE END OF THE CODE THAT MONITORS THE VOLTAGE

struct CRGB leds[NUM_LEDS];
//#define UPDATES_PER_SECOND standard is 125
//int updatesPerSecond = 125;

CRGBPalette16 currentPalette;
TBlendType currentBlending;

extern CRGBPalette16 myRedWhiteBluePalette;
extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM;

// define the buttons that we’ll use.
// one to control brightness and one to select palette.
Button paletteButton, brightnessButton;

// some counters to keep state
int paletteCounter = 1;
int brightnessCounter = 99;
int updatesPerSecond = 125;

void setup() {
Serial.begin(9600);
delay( 500 ); // power-up safety delay - DO NOT REMOVE

FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
FastLED.setBrightness(99); // start off 1/3 brightness

FastLED.clear();

// set up buttons
paletteButton.setMode(OneShot);
brightnessButton.setMode(OneShot);

// pin 2 = palette button
// pin 3 = brightness button
brightnessButton.assign(3);
paletteButton.assign(2);
}

void loop() {
switch (brightnessButton.check()) { // which button is pressed
case ON:
// 3 brightness levels starting at 99 above, then 176(+77), then 253(+77)
brightnessCounter += 77; // brightness = 0-255, so steps of 3
if (brightnessCounter >= MAX_BRIGHTNESS) {
brightnessCounter = 99; // we roll over to 1/3 bright
}
break;
default:
break;
}

switch (paletteButton.check()) {
case ON:
paletteCounter++;
if (paletteCounter > 8) { // adjust if you have more or less than 9 palettes
paletteCounter = 0;
}
break;
default:
break;
}

ChangePalettePeriodically();
static uint8_t startIndex = 0;

startIndex = startIndex + 1;

FillLEDsFromPaletteColors(startIndex);
FastLED.show();
//FastLED.delay(1000 / UPDATES_PER_SECOND);
if ( paletteCounter == 4) {
updatesPerSecond = 400; // custom speed for this one palette
}
else {
updatesPerSecond = 125;
}
FastLED.delay(1000 / updatesPerSecond );

//THIS IS WHERE THE CODE STARTS TO MONITOR THE VOLTAGE
{
// take a number of analog samples and add them up
while (sample_count < NUM_SAMPLES) {
sum += analogRead(A0);
sample_count++;
delay(10);
}
// calculate the voltage
// use 5.0 for a 5.0V ADC reference voltage
// 5.015V is the calibrated reference voltage
voltage = ((float)sum / (float)NUM_SAMPLES * 5.0) / 1024.0;
// send voltage for display on Serial Monitor
// voltage multiplied by 11 when using voltage divider that
// divides by 11. 11.132 is the calibrated voltage divide
// value
if (voltage > 3.7) {
digitalWrite(ledPin, HIGH);}

//THIS IS SPECIFICALLY THE TROUBLE AREA WITH THE DELAYS OF THE FLASHING LED CAUSE THE LIBRARY TO SLOW
if (voltage < 3.6999) {
digitalWrite (ledPin, LOW);
delay(500);
digitalWrite (ledPin, HIGH);
delay (500);
}
{Serial.print(voltage * 1);
Serial.println (" V");
sample_count = 0;
sum = 0;
}}

//THIS IS WHERE THE CODE TO MONITOR VOLTAGE ENDS
//FROM HERE I DIDN’T PASTE IN THE FASTLED EXAMPLES
//BECAUSE THEY ARE STANDARD FROM THE LIBRARY AND
//NOT RELEVANT TO THE QUESTION.

As you pointed out yourself in your comments, those delay() functions are killing the rest of the code. Write it without using any delay() calls. Read the Blink without Delay tutorial on the Arduino web site.

Also, Serial outputs cause a lot of delays as well.

Thanks Ashley, that REALLY helped. One tiny problem, and if its not fixable I doubt the customer would notice: When the voltage is above 3.7V, the led is ON as it should be but there is an almost unnoticeable flicker on the voltage state LED (pin 5). When the voltage drops it correctly goes into the 1 second blink mode and it DOES NOT affect fast LED! woo hoo!

I REMd out all the delays unrelated to fast LED, do you see something lurking in the code that might cause that flicker?

#include <buttons.h>
#include <FastLED.h>

// define the LEDs
#define LED_PIN 12 //pin the LEDs are connected to
#define NUM_LEDS 10 //16 LEDs in a small collar 23 LEDs in a medium collar 29 LEDs in a large collar
#define MAX_BRIGHTNESS 255 //maximum brightness - useful if running off battery
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB

//THIS STARTS THE ADDED CODE TO MONITOR VOLTAGE INCLUDING THE NEW BLINKING CODE
// number of analog samples to take per reading
#define NUM_SAMPLES 1
unsigned long previousMillis = 0; // will store last time LED was updated
// constants won’t change :
const long interval = 1000; // interval at which to blink (milliseconds)
int sum = 0; // sum of samples taken
unsigned char sample_count = 0; // current sample number
float voltage = 0.0; // calculated voltage
const int ledPin = 5;
int ledState = LOW; // ledState used to set the LED

//END OF THE SETUP CODE FOR MONITORING THE VOLTAGE

struct CRGB leds[NUM_LEDS];

//#define UPDATES_PER_SECOND 125
//int updatesPerSecond = 125;

CRGBPalette16 currentPalette;
TBlendType currentBlending;

extern CRGBPalette16 myRedWhiteBluePalette;
extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM;

// define the buttons that we’ll use.
// one to control brightness and one to select palette.
Button paletteButton, brightnessButton;

// some counters to keep state
int paletteCounter = 1;
int brightnessCounter = 99;
int updatesPerSecond = 125;

void setup() {
//Serial.begin(9600);
pinMode(ledPin, OUTPUT);
delay( 500 ); // power-up safety delay - DO NOT REMOVE

FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
FastLED.setBrightness(99); // start off 1/3 brightness

FastLED.clear();

// set up buttons
paletteButton.setMode(OneShot);
brightnessButton.setMode(OneShot);

// pin 2 = palette button
// pin 3 = brightness button
brightnessButton.assign(3);
paletteButton.assign(2);

}

void loop() {

switch (brightnessButton.check()) { // which button is pressed
case ON:
// 3 brightness levels starting at 99 above, then 176(+77), then 253(+77)
brightnessCounter += 77; // brightness = 0-255, so steps of 3
if (brightnessCounter >= MAX_BRIGHTNESS) {
brightnessCounter = 99; // we roll over to 1/3 bright
}
break;
default:
break;
}

switch (paletteButton.check()) {
case ON:
paletteCounter++;
if (paletteCounter > 8) { // adjust if you have more or less than 9 palettes
paletteCounter = 0;
}
break;
default:
break;

}

ChangePalettePeriodically();
static uint8_t startIndex = 0;

startIndex = startIndex + 1;

FillLEDsFromPaletteColors(startIndex);
FastLED.show();
//FastLED.delay(1000 / UPDATES_PER_SECOND);
if ( paletteCounter == 4) {
updatesPerSecond = 400; // custom speed for this one palette
}
else {
updatesPerSecond = 125;
}
FastLED.delay(1000 / updatesPerSecond );

//START OF MONITOR CODE IN THE LOOP
{
// take a number of analog samples and add them up
while (sample_count < NUM_SAMPLES) {
sum += analogRead(A0);
sample_count++;
//delay(10);
}
// calculate the voltage
// use 5.0 for a 5.0V ADC reference voltage
// 5.015V is the calibrated reference voltage
voltage = ((float)sum / (float)NUM_SAMPLES * 5.0) / 1024.0;
// send voltage for display on Serial Monitor
// voltage multiplied by 11 when using voltage divider that
// divides by 11. 11.132 is the calibrated voltage divide
// value
if (voltage > 3.7) {
digitalWrite(ledPin, HIGH);}

if (voltage < 3.6999) {
//digitalWrite (ledPin, LOW);
//delay(600);
//digitalWrite (ledPin, HIGH);
//delay (600);
}
{
//Serial.print(voltage * 1);
//Serial.println (" V");
sample_count = 0;
sum = 0;
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;

// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
  ledState = HIGH;
} else {
  ledState = LOW;
}

// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);     

}}
}

//END OF MONITOR CODE
//FAST LED CODE BELOW IS NOT PASTED HERE FOR SPACE REASONS

Here is a link to a sort video I took showing the flicker

You are constantly writing it high, completely unnecessary. Set a state, keep it that way. And don’t change it to the voltage drops. Basically, in pseudo code:
If (voltage is high enough) {
If (led is not high) {
Set led high;
}
} else {
Voltage is too low, blink led
}

Also, your ledState can easily be flip-flopped without an if statement:
ledState = !ledState;

And as a second “also”, please use pastebin for code. It’s really hard to read in this format. You can put the pastebin link to your code here.