loop not calling function

Hello all

I am having trouble with a project I am working on. Basically, a single LED chases up and down a digital addressable neopixel strip and then the whole strip sweeps on and stays on. At least that's what i'm trying to achieve.
So far I can only get the single led to chase up and down the strip but the sweep wont happen. I have narrowed it down to the "Chaseback" part of my code that is causing problems as when i take this bit out of the loop the sweep works fine.

Does anybody know why the sweep wont happen when I include "chaseback" in the loop?

Thanks in advance

#include <Adafruit_NeoPixel.h>
 
#define PIN      6
#define N_LEDS 27
 
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_LEDS, PIN, NEO_GRBW + NEO_KHZ800);
 
void setup() {
  strip.begin();
}
 
void loop() {
  chase(strip.Color(255, 0, 0, 0)); // Red
  chaseback(strip.Color(255, 0, 0, 0)); // Red
sweep(strip.Color(255, 0, 0, 0));
}


static void chase(uint32_t c) {
  for(uint16_t i= 0 ; i<strip.numPixels()+4; i++) {
      strip.setPixelColor(i  , c); // Draw new pixel
      strip.setPixelColor(i - 2 , 0); // Erase pixel a few steps back
      strip.show();
      delay(25);
  }
}

static void chaseback(uint32_t c) {
for(uint16_t i=N_LEDS-1; i>=0; i--) {
      strip.setPixelColor(i  , c); // Draw new pixel
      strip.setPixelColor(i + 2 , 0); // Erase pixel a few steps back
      strip.show();
      delay(25);
  }
}


static void sweep (uint32_t c) {
  //Ascend strip
  for(uint16_t i= 0 ; i<strip.numPixels()+4; i++) {

  strip.setPixelColor(i, c); 
    
    strip.show();
    delay(10);
  }
 }
for(uint16_t i=N_LEDS-1; i>=0; i--) {

uint16_t can never be < 0

Suggestion:

static void chaseback(uint32_t c) {
for(uint16_t i=0; i < N_LEDS; i--) {
      strip.setPixelColor(N_LEDS - i  , c); // Draw new pixel
      strip.setPixelColor(N_LEDS - i - 2 , 0); // Erase pixel a few steps back
      strip.show();
      delay(25);
  }
}

Thanks for the reply, unfortunately it still doesn't work. Now the single led chases up the strip but then the wipe happens straight away before the led has chased back down the strip.
Also, I need the wipe to stay on but it is instantly wiping away after it has wiped on. I'm pretty sure this is due to the loop going back to the chase section which clears the LEDs behind it as it chases down the strip.

In short I need a single LED to chase up and back down the strip followed by a colour wipe that stays on until it is switched off. (I will be adding in the switches when the program is working correctly)

Any help is greatly appreciated :smiley:

Please post your updated code.

it still doesn't work.

You want us to guess what your code looks like now? I'll pass.

All I did was to stop the for-next loop from bugging the way it had to.

Something changed, right? Isn't that a good thing? It usually is for me when I'm debugging.
So you have to debug some more, expect that when writing new code.

Should this

      strip.setPixelColor(N_LEDS - i - 2 , 0); // Erase pixel a few steps back

Be this?

      strip.setPixelColor(N_LEDS - i + 2 , 0); // Erase pixel a few steps back

Likely not quite since N_LEDS - i + or - 2 goes out of the range of 0 to N_LEDS.
There should be different limits to that for-next loop or an if() inside to never write pixels outside of range.

Ooooops! Karma to you, Delta_G!

Unsigned index but not unsigned literal (2 instead of 2U) will the compiler force signed math?
No biggie, it's wrong as is either way.

Personally, I would temporarily add a delay of 50 in that loop. Then print i to the serial monitor so I know EXACTLY what is going on with that variable. Then work from there. I'm no Arduino guru and that sort of thing makes more sense to me when I can see it.

Now you're just making sense. Debug prints is what the old-heads and gurus often suggest.

I didn't repost the code because it's already on the original post... and the code that goforsmoke suggested didn't work so i've kept it as it was. I'm a proper amateur, I have probably spent less than 5 hours working with arduinos so PaulS if you don't plan on being constructive then do me a favour and don't bother commenting...

Here is the code with goforsmokes suggestion.

#include <Adafruit_NeoPixel.h>
 
#define PIN      6
#define N_LEDS 27
 
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_LEDS, PIN, NEO_GRBW + NEO_KHZ800);
 
void setup() {
  strip.begin();
}
 
void loop() {
  chase(strip.Color(255, 0, 0, 0)); // Red
  chaseback(strip.Color(255, 0, 0, 0)); // Red
indicator(strip.Color(255, 0, 0, 0));
}
static void chase(uint32_t c) {
  for(uint16_t i= 0 ; i<strip.numPixels()+4; i++) {
      strip.setPixelColor(i  , c); // Draw new pixel
      strip.setPixelColor(i - 2 , 0); // Erase pixel a few steps back
      strip.show();
      delay(25);
  }
}


static void chaseback(uint32_t c) {
for(uint16_t i=0; i < N_LEDS; i--) {
      strip.setPixelColor(N_LEDS - i  , c); // Draw new pixel
      strip.setPixelColor(N_LEDS - i - 2 , 0); // Erase pixel a few steps back
      strip.show();
      delay(25);
  }
}

static void indicator (uint32_t c) {
  //Ascend strip
  for(uint16_t i= 0 ; i<strip.numPixels()+4; i++) {

  strip.setPixelColor(i, c); 
    
    strip.show();
    delay(10);
  }
 }

In this code there is still a problem when N_LEDS - i - 2 would be less than 0.
Also it maybe shouldn't be - 2 but more like + 2 since the motion is supposed to be towards 0, steps back would be +.

static void chaseback(uint32_t c) 
{
  uint16_t  i;
  uint16_t  index;       // don't have to have (uses RAM) but makes the code more clear
  uint16_t  pixSteps;

  for( i = 0; i < N_LEDS; i++ ) 
  {
    index = N_LEDS - i; // goes from high to low
    strip.setPixelColor( index, c); // Draw new pixel

    pixSteps = N_LEDS - i;
    if ( pixSteps >= 2 )
    {
      pixSteps = 2;
      strip.setPixelColor(N_LEDS - i + pixSteps , 0); // Erase pixel 2 steps back
    }

    strip.show();
    delay(25);
  }

  strip.setPixelColor( 1 , 0); // Erase the next to last
  strip.show();
  delay( 25 );
  strip.setPixelColor( 0, 0); // Erase the last
  strip.show();
  delay( 25 );
}

This should be closer if not 100% right.
NORMALLY IF IT WAS MY PROJECT I'd be testing and debugging which I leave to the OP who has the rig.
I could make something parallel to this (print numbers instead of light leds) and debug that but I don't want to spend the extra hour.

Thank you for all your help goforsmoke. I have updated the code but there is still some problems. The LED strip does exactly what I want for the first loop. Single LED chases up then back down the strip and then the whole strip wipes on. However, after the strip has wiped on, the program then goes back to the single LED which chases back down the strip and then the whole strip wipes on again. This repeats over and over.

I need the strip to stay on after it has wiped on instead of the program continuing to loop everything.

Any suggestions?

#include <Adafruit_NeoPixel.h>
 
#define PIN      6
#define N_LEDS 27
 
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_LEDS, PIN, NEO_GRBW + NEO_KHZ800);
 
void setup() {
  strip.begin();
}
 
void loop() {
  chase(strip.Color(255, 0, 0, 0)); // Red
  chaseback(strip.Color(255, 0, 0, 0)); // Red
indicator(strip.Color(255, 0, 0, 0));
}

static void chase(uint32_t c) {
  for(uint16_t i= 0 ; i<strip.numPixels()+4; i++) {
      strip.setPixelColor(i  , c); // Draw new pixel
      strip.setPixelColor(i - 2 , 0); // Erase pixel a few steps back
      strip.show();
      delay(25);
  }
}


static void chaseback(uint32_t c) 
{
  uint16_t  i;
  uint16_t  index;       // don't have to have (uses RAM) but makes the code more clear
  uint16_t  pixSteps;

  for( i = 0; i < N_LEDS; i++ ) 
  {
    index = N_LEDS - i; // goes from high to low
    strip.setPixelColor( index, c); // Draw new pixel

    pixSteps = N_LEDS - i;
    if ( pixSteps >= 2 )
    {
      pixSteps = 2;
      strip.setPixelColor(N_LEDS - i + pixSteps , 0); // Erase pixel 2 steps back
    }

    strip.show();
    delay(25);
  }

  strip.setPixelColor( 1 , 0); // Erase the next to last
  strip.show();
  delay( 25 );
  strip.setPixelColor( 0, 0); // Erase the last
  strip.show();
  delay( 25 );
}


static void indicator (uint32_t c) {
  //Ascend strip
  for(uint16_t i= 0 ; i<strip.numPixels()+4; i++) {

  strip.setPixelColor(i, c); 
    
    strip.show();
    delay(10);
  }
 }

Move what you have in void loop() up into void setup(), leave void loop() empty.

What is in setup() runs -once-. What is in loop() runs over and over.

I can't put it in setup as i'm having the same strip do other things such as a car indicator function. Once the indicator is off I need the strip to revert back to all the LED's being on

A state machine in void loop() could do that.