Trying to simulate an led travel along an led strip without using delay

Hi all,

Let me begin by saying that I am new to both the Arduino hardware and programing. I have been working on it for about a month now to understand and expand my knowledge a bit and I believe I can at least grasp the basic concepts.

I'm using an Arduino Uno board together with some individually addressable LED strips to create a series of independent "paths" where one led would look like it's traveling along its path.

So if we were to look at it in simple "pseudo code" it would be something like:

Blink led 0 once;
Blink led 1 once;
Blink led 2 once;
...
Restart after reaching the last led

So I managed to code this pretty easily using delay, see below.

#include <Adafruit_NeoPixel.h> //Library in use; needs to be compatible with the LED strip

#define S01PIN 3     // Data pin for strip01
#define S01NUNLEDS 8 // Number of leds for strip01

Adafruit_NeoPixel strip01(S01NUNLEDS, S01PIN, NEO_RGBW + NEO_KHZ800); //strip01 DEFINITIONS

//travel(); DEFINITIONS
#define TLEDON 500 //TIME EACH LED IS ON; IN MILLISECONDS
#define TLEDOFF 0  //TIME BETWEEN ONE LED TURNS OFF AND THE NEXT ONE LIGHTS UP; IN MILLISECONDS

void setup() {
  // put your setup code here, to run once:
  strip01.begin(); // Initializes the strip
  strip01.clear(); // Clears the strip of any previous data
}

void loop() {
  // put your main code here, to run repeatedly:
  travel();
}

void travel() {
  for (int i = 0; i < S01NUNLEDS; i++) {

    //This section turns the led ON
    strip01.setPixelColor(i, 255, 0, 0);
    strip01.show();

    delay(TLEDON);

    //This section turns the led OFF
    strip01.setPixelColor(i, 0, 0, 0);
    strip01.show();

    delay(TLEDOFF);
  }
}

The problem comes when I want to use other strips, with different lengths, to have the same effect. For this I can't really use delay (and i've read why you shouldn't be using delay anyway, makes sense really). So, I looked up Demonstration code for several things at the same time and tried to adapt it to my project using the code below.

#include <Adafruit_NeoPixel.h>

//---CONSTANTS
#define PIN 3
#define NUNLEDS 8
Adafruit_NeoPixel strip(NUNLEDS, PIN, NEO_RGBW + NEO_KHZ800);

const int travelSpeed = 1000; //Time each led should be ON
const int interval = 500;     //Interval between one led turning OFF and the next one turning ON

//---VARIABLES

boolean going = false; //Virtual switch

unsigned long currentMillis = 0;        // Stores the value of millis() in each iteration of loop()
unsigned long previousPixelMillis = 0;  // will store last time the LED was updated



void setup() {
  // put your setup code here, to run once:
  
  strip.begin();
  strip.clear();
}

void loop() {
  // put your main code here, to run repeatedly:


  currentMillis = millis();
  state();
  travel();

}

void state() {
  if (going == false) {
    if (currentMillis - previousPixelMillis >= interval) {
      going = true;
      previousPixelMillis += interval;
    }
  }
  else {
    if (going == true) {
      if (currentMillis - previousPixelMillis >= travelSpeed) {

        going = false;
        previousPixelMillis += travelSpeed;
      }
    }
  }
}

void travel() {
  for (int i = 0; i < NUNLEDS; i++) {
    if (going) {
      strip.setPixelColor(i, 0, 255, 0);
      strip.show();
    }
    else {
      strip.setPixelColor(i, 0, 0, 0);
      strip.show();
    }
  }
}

But this makes the whole strip blink and I haven't been able to figure out to create the same effect.

Any help will be greatly appreciated.
Thanks,

So it looks like to me that in your loop() you get current millis, then run the state function, then run the travel function. The execution of travel does not seem to be dependent on the state of your timer at all. It seems to me that you are calling travel() on each loop and then in travel it is going to loop over each LED turning each successive one on. Since this would happen super fast it possibly makes it look like it all turns on at once. Then once your state changes via the timer, you loop through and set them all to black, making it look like they all turned off at once. Then you wait for state to change again. Thus blinking.

The main issue is that the FOR loop within the travel() function runs completely each time you call travel(). You really need to check a timer each time to see it is time to increment to the next LED.

@mmitchellmoss

Thanks for your answer.

I understand what you are saying. I suspected that's what was happening with my FOR loop within travel().
It still melts my head understanding all the different logical statements and how to use them together, but I'll give it a go tomorrow and update the here after.

Thanks again