Need Help with LED Coding to multiple Pins on board

Ok, so needing a bit of help with the coding on this project. :confused:

I have 2 current codes that both work as is (both being just modified sample codes):
1. An LED lit sign that runs a scrolling rainbow effect.
2. Plus 2 large resin sword props as you see exampled in the pic. (They pulse a slow fade)

Both codes run great as independent projects. Both are using adafruit neopixel leds. The swords have Trinket boards that are battery powered so that they work in-hand, and the sign is wired to an adafruit metro board.

I'm going to post both independent codes - as well as my in-progress merged version... That's where I need the help. I'd like to run both of of the same metro board while mounted on our wall. I can't for the life of me figure out how to get each code loop to run off of different data pins on the board. (I have a VERY basic knowledge with writing these scripts, very basic) I've tried researching, but seem to get even more lost... If someone could help straighten this out for me I'd GREATLY appreciate it!!!

Hardwiring everything and managing that portion is more so my forte. There I have no issues.

This is the current mess of me trying to follow along what I've found online for running multiple strips from 1 board on different pins. I made an elementary attempt to merge... but need guidance to test a working version.
I'd like to have sword code running on pin 7 - and then be able to follow the corrected version you all help me with to add other items down the road for other props. (once i get a test working anyways, i have a few others ready to try as well)
I've read that I have to remove delays etc, but I believe i'm failing at getting any of the setup right first...

// A basic everyday NeoPixel strip test program.

// NEOPIXEL BEST PRACTICES for most reliable operation:
// - Add 1000 uF CAPACITOR between NeoPixel strip's + and - connections.
// - MINIMIZE WIRING LENGTH between microcontroller board and first pixel.
// - NeoPixel strip's DATA-IN should pass through a 300-500 OHM RESISTOR.
// - AVOID connecting NeoPixels on a LIVE CIRCUIT. If you must, ALWAYS
//   connect GROUND (-) first, then +, then data.
// - When using a 3.3V microcontroller with a 5V-powered NeoPixel strip,
//   a LOGIC-LEVEL CONVERTER on the data line is STRONGLY RECOMMENDED.
// (Skipping these may work OK on your workbench but can fail in the field)

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

// have 2 independent NEO_RGBW

NEO_RGBW leds1[118]
NEO_RGBW leds3[120]

// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1:
#define LED_PIN    

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 120

// Declare our NeoPixel strip object:
Adafruit_NeoPixel led1(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)


// setup() function -- runs once at startup --------------------------------

void setup() {
  // These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
  // Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // END of Trinket-specific code.
  
  LED_PIN.addLeds<NEO_RGBW, 6>(leds1, 118);
  LED_PIN.addLeds<NEO_RGBW, 7>(leds3, 120);

  leds1.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  leds1.show();            // Turn OFF all pixels ASAP
  leds1.setBrightness(250); // Set BRIGHTNESS to about 1/5 (max = 255)
  
  leds3.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  leds3.show();            // Turn OFF all pixels ASAP
  leds3.setBrightness(255); // Set BRIGHTNESS to about 1/5 (max = 255)
}


// loop() function -- runs repeatedly as long as board is on ---------------

void loop() {  

  // render the first animation into leds1
  animationA();
  
  // render the second animation into leds3
  animationC();

  
  leds1.show();
  leds13.show();
}

void animationA() {
  rainbow(5);             // Flowing rainbow cycle along the whole strip
}


// Some functions of our own for creating animated effects -----------------

// Rainbow cycle along whole strip. Pass delay time (in ms) between frames.
void rainbow(int wait) {
  // Hue of first pixel runs 5 complete loops through the color wheel.
  // Color wheel has a range of 65536 but it's OK if we roll over, so
  // just count from 0 to 5*65536. Adding 256 to firstPixelHue each time
  // means we'll make 5*65536/256 = 1280 passes through this outer loop:
  for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
    for(int i=0; i<leds1.numPixels(); i++) { // For each pixel in strip...
      // Offset pixel hue by an amount to make one full revolution of the
      // color wheel (range of 65536) along the length of the strip
      // (leds1.numPixels() steps):
      int pixelHue = firstPixelHue + (i * 65536L / leds1.numPixels());
      // leds1.ColorHSV() can take 1 or 3 arguments: a hue (0 to 65535) or
      // optionally add saturation and value (brightness) (each 0 to 255).
      // Here we're using just the single-argument hue variant. The result
      // is passed through leds1.gamma32() to provide 'truer' colors
      // before assigning to each pixel:
      leds1.setPixelColor(i, leds1.gamma32(leds1.ColorHSV(pixelHue)));
    }
    leds1.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
    }
  }
  
void animationC() 
{
  float MinBrightness = 0;
  float MaxBrightness = 255 - MinBrightness;
  float SpeedFactor = 0.01;
  float wait = 4;

  for(int b=0;b<65535;b++) 
  {
    float intensity = MaxBrightness/2.0*(1.0+sin(SpeedFactor*b)) + MinBrightness;
    leds3.setBrightness(intensity);
    for (uint8_t i=0;i<strip.numPixels();i++)
    {
      leds3.setPixelColor(i, 0, 200, 255, 0);
    }
    leds3.show();
    delay(wait);
  }
}

This is the original working code for the swords on Adafruit Trinket boards:

// NeoPixel test program showing use of the WHITE channel for RGBW
// pixels only (won't look correct on regular RGB NeoPixel strips).

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1:
#define LED_PIN     6

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT  120

// NeoPixel brightness, 0 (min) to 255 (max)
#define BRIGHTNESS 255

#define TOTAL_LEDS 120

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)

void setup() {
  // These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
  // Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // END of Trinket-specific code.

  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(255); // Set BRIGHTNESS to about 1/5 (max = 255)
}

void loop() 
{
  float MinBrightness = 0;
  float MaxBrightness = 255 - MinBrightness;
  float SpeedFactor = 0.01;
  float wait = 4;

  for(int b=0;b<65535;b++) 
  {
    float intensity = MaxBrightness/2.0*(1.0+sin(SpeedFactor*b)) + MinBrightness;
    strip.setBrightness(intensity);
    for (uint8_t i=0;i<strip.numPixels();i++)
    {
      strip.setPixelColor(i, 0, 200, 255, 0);
    }
    strip.show();
    delay(wait);
  }
}

And this is the original working code for the LED lit sign working on pin 6 of the Metro board I'm wanting to use for the whole display wall:

// A basic everyday NeoPixel strip test program.

// NEOPIXEL BEST PRACTICES for most reliable operation:
// - Add 1000 uF CAPACITOR between NeoPixel strip's + and - connections.
// - MINIMIZE WIRING LENGTH between microcontroller board and first pixel.
// - NeoPixel strip's DATA-IN should pass through a 300-500 OHM RESISTOR.
// - AVOID connecting NeoPixels on a LIVE CIRCUIT. If you must, ALWAYS
//   connect GROUND (-) first, then +, then data.
// - When using a 3.3V microcontroller with a 5V-powered NeoPixel strip,
//   a LOGIC-LEVEL CONVERTER on the data line is STRONGLY RECOMMENDED.
// (Skipping these may work OK on your workbench but can fail in the field)

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1:
#define LED_PIN    6

// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 120

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)


// setup() function -- runs once at startup --------------------------------

void setup() {
  // These lines are specifically to support the Adafruit Trinket 5V 16 MHz.
  // Any other board, you can remove this part (but no harm leaving it):
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif
  // END of Trinket-specific code.

  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(250); // Set BRIGHTNESS to about 1/5 (max = 255)
}


// loop() function -- runs repeatedly as long as board is on ---------------

void loop() {
  rainbow(5);             // Flowing rainbow cycle along the whole strip
}


// Some functions of our own for creating animated effects -----------------

// Rainbow cycle along whole strip. Pass delay time (in ms) between frames.
void rainbow(int wait) {
  // Hue of first pixel runs 5 complete loops through the color wheel.
  // Color wheel has a range of 65536 but it's OK if we roll over, so
  // just count from 0 to 5*65536. Adding 256 to firstPixelHue each time
  // means we'll make 5*65536/256 = 1280 passes through this outer loop:
  for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
    for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
      // Offset pixel hue by an amount to make one full revolution of the
      // color wheel (range of 65536) along the length of the strip
      // (strip.numPixels() steps):
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      // strip.ColorHSV() can take 1 or 3 arguments: a hue (0 to 65535) or
      // optionally add saturation and value (brightness) (each 0 to 255).
      // Here we're using just the single-argument hue variant. The result
      // is passed through strip.gamma32() to provide 'truer' colors
      // before assigning to each pixel:
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
    }
  }
  LED_PIN.addLeds<NEO_RGBW, 6>(leds1, 118);
  LED_PIN.addLeds<NEO_RGBW, 7>(leds3, 120);

These are declaration used by the FastLED.h library, not the neopixel.h . You should use one or the other, both can address pins several strips on several pins.
If you decide on Neopixel.h (which it appears you have done) then your strip declarations should look something like this.

// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2(LED_COUNT2, LED_PIN2, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip3(LED_COUNT3, LED_PIN3, NEO_GRB + NEO_KHZ800);

and you don't need to declare these arrays

LED_PIN.addLeds<NEO_RGBW, 6>(leds1, 118);
  LED_PIN.addLeds<NEO_RGBW, 7>(leds3, 120);

Neopixel has the buffer as part of the object.

I've read that I have to remove delays etc

Yes you will have to start using millis() for timing or 1 of the patterns will hold up the processing of the others.

And this is the original working code for the LED lit sign working on pin 6 of the Metro board I'm wanting to use for the whole display wall:

Great you posted within </>-code tags, but you code is more comments than code. please remove any excess comments for the sake of readability.

Thanks a ton! I’ll give that a try.

And yes sorry, the comments were all a part of the original samples. Not something I added myself - and I didn’t touch in fear of messing something up further.

Yes my libraries are neopixel - thanks for pointing out that there was a mixup.

Re-visiting this for some further guidance...

The combined sketches each now function on the single metro board pins 6 and 7, just how how I want them too.

My 'animationA' rainbow effect starts right away ('animationC' does not).
It runs for about 12-15 sec before it sticks as a frozen rainbow (no scrolling effect) and the 'animationC' blue pulse starts on the other strip.

That pulsing continues in an endless loop, with the other staying motionless.

From what i've been able to find in my research - i'm not correctly coding millis into this equation somehow. I want both effects to run simultaneously.

I was trying to find a way following samples from these links - but haven't been able to successfully convert to my application. Thanks for any help!

https://paulmurraycbr.github.io/ArduinoTheOOWay.html#ShowMeTheCode

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h>
#endif

#define LED_PIN 6   
#define LED_PIN3 7

#define LED_COUNT 117
#define LED_COUNT3 120

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip3(LED_COUNT3, LED_PIN3, NEO_RGBW + NEO_KHZ800);

void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif

  strip.begin();
  strip.show();
  strip.setBrightness(250);
  
  strip3.begin();
  strip3.show();
  strip3.setBrightness(255);
}

void loop() {
  
  // render the first animation into strip
  animationA();
  // render the second animation into strip3
  animationC();
}

void animationA()
{  
  rainbow(5);
}
void rainbow(int wait) {
  for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
    for(int i=0; i<strip.numPixels(); i++) { 
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show();
    }
}
 
void animationC()
{
  float MinBrightness = 0;
  float MaxBrightness = 255 - MinBrightness;
  float SpeedFactor = 0.01;
  float wait = 4;

  for(int b=0;b<65535;b++) 
  {
    float intensity = MaxBrightness/2.0*(1.0+sin(SpeedFactor*b)) + MinBrightness;
    strip3.setBrightness(intensity);
    for (uint8_t i=0;i<strip3.numPixels();i++)
    {
      strip3.setPixelColor(i, 0, 200, 255, 0);
    }
    strip3.show();
    }
  }

Int on Arduino is 16 bits. It can hold a value between -32768 and +32767.
When you add one to +32767 it wraps around to -32768....

 for(int b=0;b<65535;b++)

...thus b is ALWAYS less than 65535.

Try “unsigned int” (or better uint16_t so you don’t forget it’s 16 bits) or long (or int32_t) if you really need signed (you don’t here, as far as I can see).

Edit: Neither of these effects use delay. They both run flat out. That makes it tricky to use millis() since there is no waiting required.
You can make it do one step of each animation each time, and do that as fast as possible. The overall speed of the individual animations will be reduced though.

To do that...
Remove the outer loops.
Create global variables in place of the loop variables.
After you’ve done a step of each loop, increment the global variable, check if it up has reached the end condition of the original loop. If it has reset the loop variable for the next time “around the loop”.

Example...

for(uint16_t b=0;b<65535;b++) 
{
  //do something
}

Becomes...

//global
uint16_t b = 0;

//loop
//do something
b++;
if (b >= 65535) b = 0;

5*65536same here the literal is overflowing the variable. Anyway you should not have to use such large numbers as your counters.

for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
    for(int i=0; i<strip.numPixels(); i++) {

From what i've been able to find in my research - i'm not correctly coding millis into this equation somehow. I want both effects to run simultaneously.

You are correct, the first loop still 'blocks' the continuation of the program. instead try something like

void rainbow() {
  static unsigned long firstPixelHue = 0;
    for(int i=0; i<strip.numPixels(); i++) {
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show();
   firstPixelHue += 256;
  if  (firstPixelHue >= 5*65536UL) firstPixelHue = 0;
}

But where did you implement millis() ?

I haven't found a way to implement millis, just removed delay() from each program.

(I didn't realize the issue was in those values either. Both original scripts were just from the test programs of NeoPixel with some slight modifications to colors/speed rates)

I'll try making some of the adjustments suggested!

Thanks!!!

sir i want code for ultrasonic sensor hand detection for sanitizer spray for 3 seconds. relay should be on for 3 sec
after three seconds relay should be off, even if u didnot remove ur hand code please help me.

Deva_Rishi:
5*65536same here the literal is overflowing the variable. Anyway you should not have to use such large numbers as your counters.

for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {

for(int i=0; i<strip.numPixels(); i++) {


You are correct, the first loop still 'blocks' the continuation of the program. instead try something like 

void rainbow() {
  static unsigned long firstPixelHue = 0;
    for(int i=0; i<strip.numPixels(); i++) {
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show();
  firstPixelHue += 256;
  if  (firstPixelHue >= 5*65536UL) firstPixelHue = 0;
}

Thank you so much! This allowed the rainbow effect to run, but i was still having issues with the pulse script. I tested the function i wanted to achieve by applying the rainbow to each strip, which ran simultaneously like I wanted it to. Then modified the pulse script to match the global variables in the same manner that was working for 'rainbow'.

It now works perfect! :smiley: With myself understanding the code enough to be able to add additional programs to this display later on! (Millis were not ended up needed at all as you pointed out) :confused:

pcbbc:
Int on Arduino is 16 bits. It can hold a value between -32768 and +32767.
When you add one to +32767 it wraps around to -32768....
...thus b is ALWAYS less than 65535.

Try “unsigned int” (or better uint16_t so you don’t forget it’s 16 bits) or long (or int32_t) if you really need signed (you don’t here, as far as I can see).

Edit: Neither of these effects use delay. They both run flat out. That makes it tricky to use millis() since there is no waiting required.
You can make it do one step of each animation each time, and do that as fast as possible. The overall speed of the individual animations will be reduced though.

To do that...
Remove the outer loops.
Create global variables in place of the loop variables.
After you’ve done a step of each loop, increment the global variable, check if it up has reached the end condition of the original loop. If it has reset the loop variable for the next time “around the loop”.

Thank you for the explanation as it help me understand this all a bit more.

Here is the final code that works:

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h>
#endif

#define LED_PIN 6   
#define LED_PIN3 7

#define LED_COUNT 117
#define LED_COUNT3 120

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip3(LED_COUNT3, LED_PIN3, NEO_GRBW + NEO_KHZ800);

void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
#endif

  strip.begin();
  strip.show();
  strip.setBrightness(250);
  
  strip3.begin();
  strip3.show();
  strip3.setBrightness(255);
}

void loop() {
  
  // render the first animation into strip
  animationA();
  // render the second animation into strip3
  animationC();
}

void animationA()
{  
  rainbow();
}
void rainbow() {
  static unsigned long firstPixelHue = 0;
    for(int i=0; i<strip.numPixels(); i++) {
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show();
   firstPixelHue += 256;
  if  (firstPixelHue >= 5*65536UL) firstPixelHue = 0;
}
 
void animationC()
{
  pulse();
}
void pulse(){
  float MinBrightness = 0;
  float MaxBrightness = 255 - MinBrightness;
  float SpeedFactor = 0.02;
  float wait = 4;

  static unsigned long b=0;
  {
    float intensity = MaxBrightness/2.0*(1.0+sin(SpeedFactor*b)) + MinBrightness;
    strip3.setBrightness(intensity);
    for (uint8_t i=0;i<strip3.numPixels();i++)
    {
      strip3.setPixelColor(i, 0, 200, 255, 0);
    }
    strip3.show();
    b++;
    if (b >= 65535) b=0;
  }
}

Well the pattern(s) are just running at full speed now, but to implement millis() is fairly straightforward

void animationA()
{
  static uint32_t lastChg = 0;
  if (millis() - lastChg < WAIT_TIME) return;
  lastChg = millis(); 
  rainbow();
}

Deva_Rishi:
Well the pattern(s) are just running at full speed now, but to implement millis() is fairly straightforward

void animationA()

{
  static uint32_t lastChg = 0;
  if (millis() - lastChg < WAIT_TIME) return;
  lastChg = millis();
  rainbow();
}

How I understand what you're showing: that would prevent other events from ever holding up that specific script? (In this case 'rainbow') Since it would be checking against millis passed during startup anyways? Right?

Benefit being that I could time starts/stops to the specific events versus them all just running non-stop? That's how millis had been explained to me before - but I could never get a clear grasp on how to code with it. Clearly I could use some 101 coursework on this all since i don't grasp a lot of it lol...

Being as that this project is for a wall of illuminated props, I only need it to continually run - but good to know for future applications. Gaining an understanding of basics for this to work in a single arduino script was the first step i needed to overcome for the project!

YouTube clip of the running project

^Here's a short 15 sec clip of the running project! Thanks again for all the help - the coding here is NOT our specialty! :sweat_smile:

It wasn't nearly as much of a struggle to have any of them funding on their own and portable! Lol. But wanted to find a neat way to display this stuff "on"

How I understand what you're showing: that would prevent other events from ever holding up that specific script? (In this case 'rainbow') Since it would be checking against millis passed during startup anyways? Right?

Yes, of course there is no need to continually holding up the rainbow, if WAIT_TIME is something like 10 (ms) it would just slow the rainbow effect down, making 10ms have passed before the next step in the sequence is taken.

Benefit being that I could time starts/stops to the specific events versus them all just running non-stop?

as i said, not exactly, you could have different pattern running at different speeds, without their slowing affecting each other (it is a little in the explanation and how to phrase it possibly)