Neopixel chase and Millis timing

I have attached my code. The first 2 functions behave as expected. I am having diffuculty with the third. The "NacLed" function. I would like to use Neopixel jewel to appear like a rotating motor. I have found several tutorials on "moving" the pixels with the same color but not with "locked in" individual colors. I have placed what I am attempting to do in the code. Still a newbie and have almost given up.

//=======for the Neopixel Jewel=========

#include <FastLED.h>// include library
#define NUM_LEDS 7 // number of leds
#define DATA_PIN 5 //signal pin of board
#define MASTER_BRIGHTNESS 10
CRGB leds[NUM_LEDS];//setup individual led array







//======for the Standard LEDS======

const unsigned long StrobeOnMillis = 100;
const unsigned long NavOnMillis = 1000;
const unsigned long StrobeBaseInterval = 900;
const unsigned long NavBaseInterval = 500;
unsigned long StrobeInterval = StrobeBaseInterval;
unsigned long NavInterval = NavBaseInterval;
byte StrobeLedstate = HIGH;
byte NavLedstate = HIGH;
unsigned long prevStrobeLedMillis;
unsigned long prevNavLedMillis;
unsigned long currentMillis = millis(); //used for all functions
const byte Strobepin = 13;
const byte Navpin = 10;

//=======for the Neopixel========
#include <FastLED.h>// include library
#define NUM_LEDS 7 // number of leds
#define DATA_PIN 5 //signal pin of board
#define MASTER_BRIGHTNESS 10
//CRGB leds[NUM_LEDS];//setup individual led array
unsigned long NacOnMillis = 100; //each pixel on time
unsigned long prevNacLedMillis;
unsigned long NacBaseInterval = 50; //each pixel off time
unsigned long NacInterval = NacBaseInterval; //not clear if this is needed for NEOpixel timng
byte NacLedstate = HIGH;

void setup() {
  pinMode (Strobepin, OUTPUT);
  pinMode (Navpin, OUTPUT);
  digitalWrite(Strobepin, HIGH);
  digitalWrite(Navpin, HIGH);
  FastLED.setBrightness(MASTER_BRIGHTNESS);
  // start the strip and blank it out
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS); //declare LED strip


  //Select led colors. these will not require random changing
  //leds[0] = CRGB::Red;      this may not be the proper area to define the colors
  //leds[1] = CRGB::Blue;       but should give the idea on waht i am trying to achieve
  //leds[2] = CRGB::Yellow;
  //leds[3] = CRGB::Green;
  //leds[4] = CRGB::Orange;
  //leds[5] = CRGB::Magenta;
  //leds[6] = CRGB::Violet;


}

void loop() {
  currentMillis = millis();
  StrobeLed();
  NavLed();
  NacLed();
}

void StrobeLed() {
  if (currentMillis - prevStrobeLedMillis >= StrobeInterval) {
    prevStrobeLedMillis += StrobeInterval;
    StrobeLedstate = ! StrobeLedstate;
    if (StrobeLedstate == HIGH) {
      StrobeInterval = StrobeOnMillis;
    }
    else {
      StrobeInterval = StrobeBaseInterval;
    }
    digitalWrite(Strobepin, StrobeLedstate);
  }

}

void NavLed() {
  if (currentMillis - prevNavLedMillis >= NavInterval) {
    prevNavLedMillis += NavInterval;
    NavLedstate = ! NavLedstate;
    if (NavLedstate == HIGH) {
      NavInterval = NavOnMillis;
    }
    else {
      NavInterval = NavBaseInterval;
    }
    digitalWrite(Navpin, NavLedstate);
  }


}
//not sure where to go here
// i want pixel zero to be high for 100ms-low for 50ms, pixel 1 hinh for 100ms-low for 50ms etc.
// each pixel having a set indivdual color
void NacLed() {
  if (currentMillis - prevNacLedMillis >= NacInterval) {
    prevNacLedMillis += NacInterval;
    NacLedstate = ! NacLedstate;
    if (NacLedstate == HIGH) {
      NacInterval = NacOnMillis;
    }
    else {
      NacInterval = NacBaseInterval;
    }
    //neopixel code here?


  }
}

i'm not sure if I alteady understand what you want to do.
In my own words:
Ten Leds
switch on Led1 for 100ms
switch led1 off
after 50 milliseconds
switch on led2 for 100 ms
swicht led2 off
after 50 ms
switch on led3
etc.
is this correct?
if not you have to provide such a detailed description which clearly says how many leds
numbering all leds
saying all on-times
saying all off-times

one way of programming a light-pattern over time us to use a loop that executes every 10 ms or 50ms or whatever the shortest timeperiod is.
And then count up a variable by one in each iteration of the loop
and then code if-conditions
if (Counter == 3)
switch on led5 switch of led 17

if counter == 5 ....
if counter == 11 ..
etc.
best regards Stefan

To answer your first part yes. I have 7 led pixels on a neopixel light strip that I want to light sequentially 0on, 0off ,1on, 1off etc until all have completed and keep repeating the loop. I want to have the RGB pixels different colors but each one always the same color. Pixels by index number 0 pixel blue,1 pixel green,2 pixel red etc. I have been trying to utilize the fastled library

I think you know millis(), but the sketch can use a few improvements:

  • Don't use the same defines twice. For example: NUM_LEDS, DATA_PIN, MASTER_BRIGHTNESS.
  • Don't use the prevMillis += interval. It can be dangerous and you don't need it. Use the normal prevMillis = currentMillis.
  • Please don't use the logical "not" with a variable that is HIGH or LOW. I know it works, but it is not nice. For example: StrobeLedstate = ! StrobeLedstate;

An array with colors is needed for the led colors. Once you have that array, then all you need is a counter or index that cycles through the array (and a millis-timer with different "on" and "off" times of course).

I did not carefully check this code, I just wrote it down without thinking:

const unsigned long nacOnTime = 100; //each pixel on time
const unsigned long nacOffTime = 50; //each pixel off time
unsigned long nacInterval = nacOffTime;
unsigned long nacPreviousMillis;
bool nacState;
int nacCount;

CRGB fixedColor[NUM_LEDS] =
{
  CRGB::Red,
  CRGB::Blue,
  CRGB::Yellow,
  CRGB::Green,
  CRGB::Orange,
  CRGB::Magenta,
  CRGB::Violet,
};

void NacLed() 
{
  if( currentMillis - nacPreviousMillis >= nacInterval) 
  {
    nacPreviousMillis = currentMillis;

    if( nacState)
    {
      // Turn the led off by making it black.
      leds[nacCount] = CRGB::Black;

      nacState = false;
      nacInterval = nacOffTime;

      // Done with this led, set the next led
      nacCount++;
      if( nacCount >= NUM_LEDS)
        nacCount = 0;
    }
    else
    {
      leds[nacCount] = fixedColor[nacCount];  // set this led to its own color
      nacState = true;
      nacInterval = nacOnTime;
    }
    FastLED.show();
  }
}

The sketch with this addition in Wokwi:

If you want to synchronize the Strobe-led with the Neopixels, then you have to use a single millis-timer for that. Is the Nav-led also synchronized with the Neopixels in some way ? Then you have to add that to the same millis-timer as well.

If everything is synchronized with each other, then you need a single millis-timer as a "umbrella" and every sub-process is under that umbrella.

More than one millis-timer is only used when the processes are completely independent of each other.

Thanks that is what I am looking for. starting to come together. I want the strobes and NAV lights separate timing. To add another "wrinkle". If i were to add a second strip in series with the other how would i run leds 0-6 clockwise and 7-13 counter clockwise? I intend on using an ATTINY85 on the board and want to preserve a pin for project expansion. I tried changing for( int i=0; i<NUM_LEDS; i++) to for( int i=0; i<NUM_LEDS; i--) but had the effect of lighting led 1 at a constant state. Also is synchronizing led 0 and 7, led 1 and 11,led 2 and10 etc. see below. ignore the pixel colors on the drawing
image

did you carefully count the number of pins you need?
An AtTiny85 has only 5 IO-pins.
How about using a Seeeduino XIAO? which has 10 IO-pins?

Or a Arduino Nano?

best regards Stefan

If your pixels really are in series, then you now have 1 strip with twice as many LEDs so NUM_LEDS will be twice as large are before. If that is correct, then you want your for () loop to only count up to NUM_LEDS / 2 and then calculate the index of the other strip. E.g.

for ( int i=0; i < NUM_LEDS/2; ++i ) {
  int index2 = NUM_LEDS - i - 1;
  // do something with index 'i'
  // do something with index 'index2'
...

As the design is so far i will be using (3) pins for leds and (1) for a pushbutton in the future. other lights connected on/off independant of the arduino board. Main reason of using the Attiny is i have 10 of them laying around in parts bin along with 5 devleopment boards. I have several Atmega328 as well but thought that would be overkill.

I think I am a bit closer. I tried the code on WOKWI as jewels are a real pain to connect without soldering. the simulation runs although the lights seem to have no obvious order until about 30 seconds or so into simulation. the goal is 0-6 running clockwise and 7-13 running counter clockwise. code below.

//=======for the Neopixel Jewel=========

#include <FastLED.h>// include library
#define NUM_LEDS 14 // number of leds
#define DATA_PIN 5 //signal pin of board
#define MASTER_BRIGHTNESS 50
CRGB leds[NUM_LEDS];//setup individual led array



//=======for the Neopixel========
const unsigned long nacOnTime = 100; //each pixel on time
const unsigned long nacOffTime = 50; //each pixel off time
unsigned long nacInterval = nacOffTime;
unsigned long nacPreviousMillis;
unsigned long currentMillis = millis();
bool nacState;
int nacCount;

CRGB fixedColor[NUM_LEDS] =
{
  CRGB::Red,//led 0
  CRGB::Blue,//led 1
  CRGB::Yellow,//led 2
  CRGB::Green,//led 3
  CRGB::Orange,//led 4
  CRGB::Magenta,//led 5
  CRGB::Violet,//led 6
   CRGB::Red,//led 0
  CRGB::Blue,//led 1
  CRGB::Yellow,//led 2
  CRGB::Green,//led 3
  CRGB::Orange,//led 4
  CRGB::Magenta,//led 5
  CRGB::Violet,//led 6

};


void setup() {
  
//  FastLED.setBrightness(MASTER_BRIGHTNESS);   // full brighness is better for Wokwi
  // start the strip and blank it out
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS); //declare LED strip

  //Select led colors. these will not require random changing
  for( int i=0; i<NUM_LEDS/2; i++){
    int index2 = NUM_LEDS-i-1;
    leds[i] = fixedColor[i];
    leds[index2]=fixedColor[i];
  FastLED.show();
  delay( 2000);
  FastLED.clear();
}}

void loop() {
  currentMillis = millis();
  NacLed();
}

// not sure where to go here
// i want pixel zero to be high for 100ms-low for 50ms, pixel 1 hinh for 100ms-low for 50ms etc.
// each pixel having a set indivdual color
void NacLed() 
{
  if( currentMillis - nacPreviousMillis >= nacInterval) 
  {
    nacPreviousMillis = currentMillis;

    if( nacState)
    {
      // Turn the led off by making it black.
      leds[nacCount] = CRGB::Black;

      nacState = false;
      nacInterval = nacOffTime;

      // Done with this led, set the next led
      nacCount++;
      if( nacCount >= NUM_LEDS)
        nacCount = 0;
    }
    else
    {
      leds[nacCount] = fixedColor[nacCount];  // set this led to its own color
      nacState = true;
      nacInterval = nacOnTime;
    }
    FastLED.show();
  }
}

start with something simpler

//=======for the Neopixel Jewel=========

#include <FastLED.h>// include library
const byte NUM_LEDS = 14; // number of leds
const byte HALF_LEDS = NUM_LEDS / 2;

#define DATA_PIN 5 //signal pin of board
#define MASTER_BRIGHTNESS 50
CRGB leds[NUM_LEDS];//setup individual led array

//=======for the Neopixel========
const unsigned long nacOnTime = 100; //each pixel on time
const unsigned long nacOffTime = 50; //each pixel off time
unsigned long nacInterval = nacOffTime;

int startIdx = 0;

CRGB fixedColor[HALF_LEDS] =
{
  CRGB::Red,//led 0
  CRGB::Blue,//led 1
  CRGB::Yellow,//led 2
  CRGB::Green,//led 3
  CRGB::Orange,//led 4
  CRGB::Magenta,//led 5
  CRGB::Violet,//led 6
};


void setup() {

  //  FastLED.setBrightness(MASTER_BRIGHTNESS);   // full brighness is better for Wokwi
  // start the strip and blank it out
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS); //declare LED strip
}

void loop() {
  for ( int i = 0; i < HALF_LEDS; i++) {
    int index1 = (startIdx + i) % HALF_LEDS;
    int index2 = (startIdx + NUM_LEDS - i - 1) % HALF_LEDS;
    leds[index1] = fixedColor[i];
    leds[index2] = fixedColor[i];
    FastLED.show();
    delay(nacOnTime);
    FastLED.clear();
    FastLED.show();
    delay(nacOffTime);
  }
  startIdx++;
  if ( startIdx >= HALF_LEDS ) startIdx = 0;
}

I am using millies timing as this is going to be in a larger sketch with other things functioning. I have tried this sketch and it only functions on the pixels 0-6 and does not run on pixels 7-13. Not sure why

What do pixels 7-13 look like? Are they lighting up at all? not moving CCW or ????

7-13 are not lighting at all. 0-6 are running in a "jumble" looks like random flashing. Like getting confuse on LED number. It is really strange.

I have switched gears a bit. As Stefan eluded to things have changed and I have run out of pins. So I have decided to use 2 pins for the lighting effect here. I have both running but both are in the clockwise direction. code below. I sincerely appreciate the help

//=======for the Neopixel Jewel=========

#include <FastLED.h>// include library
#define NUM_LEDS 7 // number of leds
#define DATA_PIN 5 //signal pin of board
#define DATA_PIN2 3
#define MASTER_BRIGHTNESS 50
CRGB leds[NUM_LEDS];//setup individual clockwise led array
CRGB ledsR[NUM_LEDS];//setup individual counterclockwise led array



//=======for the Neopixel========
const unsigned long nacOnTime = 100; //each pixel on time
const unsigned long nacOffTime = 50; //each pixel off time
unsigned long nacInterval = nacOffTime;
unsigned long nacPreviousMillis;
unsigned long currentMillis = millis();
bool nacState;
int nacCount;

CRGB fixedColor[NUM_LEDS] =
{
  CRGB::Red,//led 0
  CRGB::Blue,//led 1
  CRGB::Yellow,//led 2
  CRGB::Green,//led 3
  CRGB::Orange,//led 4
  CRGB::Magenta,//led 5
  CRGB::Violet,//led 6
};

CRGB fixedColor2[NUM_LEDS] =
{
  CRGB::Red,//led 0
  CRGB::Blue,//led 1
  CRGB::Yellow,//led 2
  CRGB::Green,//led 3
  CRGB::Orange,//led 4
  CRGB::Magenta,//led 5
  CRGB::Violet,//led 6
};


void setup() {

  //  FastLED.setBrightness(MASTER_BRIGHTNESS);   // full brighness is better for Wokwi
  // start the strip and blank it out
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS); //declare first LED strip
  FastLED.addLeds<NEOPIXEL, DATA_PIN2>(leds, NUM_LEDS); //declare first LED strip
  //Select led colors. these will not require random changing
  for ( int i = 0; i < NUM_LEDS; i++) {
    CRGB ledsR[NUM_LEDS - 1 - i] = leds[i];
    leds[i] = fixedColor[i];
    //ledsR[i]= fixedColor2[i]; (this line caused the full strips to light and stay on)
  }

  FastLED.show();
  delay( 2000);
  FastLED.clear();
}

void loop() {
  currentMillis = millis();
  NacLed();
}

// not sure where to go here
// i want pixel zero to be high for 100ms-low for 50ms, pixel 1 hinh for 100ms-low for 50ms etc.
// each pixel having a set indivdual color
void NacLed()
{
  if ( currentMillis - nacPreviousMillis >= nacInterval)
  {
    nacPreviousMillis = currentMillis;

    if ( nacState)
    {
      // Turn the led off by making it black.
      leds[nacCount] = CRGB::Black;

      nacState = false;
      nacInterval = nacOffTime;

      // Done with this led, set the next led
      nacCount++;
      if ( nacCount >= NUM_LEDS)
        nacCount = 0;
    }
    else
    {
      leds[nacCount] = fixedColor[nacCount];  // set this led to its own color
      nacState = true;
      nacInterval = nacOnTime;
    }
    FastLED.show();
  }
}

and I believe this is the problem section.

void setup() {

  //  FastLED.setBrightness(MASTER_BRIGHTNESS);   // full brighness is better for Wokwi
  // start the strip and blank it out
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS); //declare first LED strip
  FastLED.addLeds<NEOPIXEL, DATA_PIN2>(leds, NUM_LEDS); //declare first LED strip
  //Select led colors. these will not require random changing
  for ( int i = 0; i < NUM_LEDS; i++) {
    CRGB ledsR[NUM_LEDS - 1 - i] = leds[i];
    leds[i] = fixedColor[i];
    //ledsR[i]= fixedColor2[i]; (this line caused the full strips to light and stay on)
  }

  FastLED.show();
  delay( 2000);
  FastLED.clear();
}

index2 is not being correctly calculated. It produces 0-6 instead of 7-13

 int index2 = (startIdx + NUM_LEDS - i - 1) % HALF_LEDS + HALF_LEDS;

You might also want to extend your on/off times so a human eye can track it. Maybe something like 500ms ON, 250ms OFF

Probably too late at this juncture, but things might be better manageable with a couple of arrays.
const byte leftWheel [7] = (0,1,2,3,4,5,6};
const byte rightWheel [7] = {13,12,11,10,9,8,7};

Given --
const unsigned long nacOffTime = 50; //each pixel off time
unsigned long nacInterval = nacOffTime;
then
nacInterval is unnecessary → just plug-in nacOffTime.

Thanks. I still have not figured out a solution. Can you give me a “push” on how to incorporate this into the existing code? Or better off starting from scratch?

I haven't used FastLED.h yet. This sketch doesn't use millis(), but it compiles. I think it should work - and get my point across. One wheel has a Red circulating and the other has a Green circulating. Change the #defines etc. to suit your set-up.

#include "FastLED.h"

#define NUM_LEDS 14
#define DATA_PIN 3
#define CLOCK_PIN 13

const byte L_Wheel [7] = {0,1,2,3,4,5,6};
const byte R_Wheel [7] = {13,12,11,10,9,8,7};

CRGB leds[NUM_LEDS];

void setup() 
{ 
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
}

void loop() 
{ 
  for(byte iter = 0; iter < 7; iter ++)
  {
    leds[L_Wheel[iter]] = CRGB::Red;
    leds[R_Wheel[iter]] = CRGB::Green;
    FastLED.show();
    delay(500);
    // Now turn the LED off, then pause
    leds[L_Wheel[iter]] = CRGB::Black;
    leds[R_Wheel[iter]] = CRGB::Black;
    FastLED.show();
  }
}