Trying to have random led light up on multiple strips

Hello!

I'm am running a tinkercad simulation of an arduino uno. The goal is to have several LED strips that each light up (twinkle) a single led at random. If I run the same code to all strips the the same LED lights up on each strip. If I try to break it apart it runs one strip and then the next. (Which is what is happening in the code below.) I'm sure I'm missing something basic here. Any help would be appreciated!

Thanks!
~Pinky

#include <Adafruit_NeoPixel.h>

#define NUM_LEDS 8
Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(NUM_LEDS, 5, NEO_GRB + NEO_KHZ800);

#define NUM_LEDS 8
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(NUM_LEDS, 6, NEO_GRB + NEO_KHZ800);
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 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)


void setup() {
  strip1.begin();
  strip1.show(); // Initialize all pixels to 'off'
  
  strip2.begin();
  strip2.show(); // Initialize all pixels to 'off'
}

void loop() 
{  
  Twinkle1(0xff, 0, 0, 8, 200, true);
  Twinkle2(0xff, 0, 0, 8, 200, true);
}

void Twinkle1(byte red, byte green, byte blue, int Count, int SpeedDelay, boolean OnlyOne) {
  setAll(0,0,0);
 
  for (int i=0; i<Count; i++) {
     setPixel(random(NUM_LEDS),red,green,blue);
     strip1.show();
     delay(SpeedDelay);
     if(OnlyOne) {
       setAll(0,0,0);       
     }
   }
}

void Twinkle2(byte red, byte green, byte blue, int Count, int SpeedDelay, boolean OnlyOne) {
  setAll(0,0,0);
 
  for (int i=0; i<Count; i++) {
     setPixel(random(NUM_LEDS),red,green,blue);
     strip2.show();  
     delay(SpeedDelay);
     if(OnlyOne) {
       setAll(0,0,0);       
     }
   }
  
  delay(SpeedDelay);
}

void showStrip() {
 #ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip1.show();
   strip2.show();
 #endif

}

void setPixel(int Pixel, byte red, byte green, byte blue) {
 #ifdef ADAFRUIT_NEOPIXEL_H
   // NeoPixel
   strip1.setPixelColor(Pixel, strip1.Color(red, green, blue));
   strip2.setPixelColor(Pixel, strip2.Color(red, green, blue));
 #endif
}

void setAll(byte red, byte green, byte blue) {
  for(int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue);
  }
  showStrip();
}

I'm sure I'm missing something basic here.

What you are seeing is exactly what you have programmed the Arduino to do. Because of the show and delay in the for loop, it can’t do the second strip until it has done the first.

You need to implement the animation as a state machine. I have posted this many times here but I am on my iPad so I can’t at the moment.

Look at the blink without delay example in the IDE. You have to eliminate all delays and for loops. Do them by “hand”.

I just had this problem. I used a global index property to iterate through the strips, accompanied by an if statement in the setpixel and showstrip functions that determines which strip to command.

void showStrip() {
 #ifdef ADAFRUIT_NEOPIXEL_H 
   // NeoPixel
   if(stripToCommand[idx] == 1){
    ws1.show();
   }
   else if(stripToCommand[idx] == 2){
    ws2.show();
   }
   else if(stripToCommand[idx] == 3){
    ws3.show();
    
   }
   else if(stripToCommand[idx] == 4){
    ws4.show();
    
   }
   else if(stripToCommand[idx] == 5){
    ws5.show();
    
   }
  else{/*Serial.println("no matches1");*/}
 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H
   // FastLED
   FastLED.show();
 #endif
}

void setPixel(int Pixel, byte red, byte green, byte blue) {
 #ifdef ADAFRUIT_NEOPIXEL_H 
   // NeoPixel
   if(stripToCommand[idx] == 1){
    ws1.setPixelColor(Pixel, ws1.Color(red, green, blue));
   }
   else if(stripToCommand[idx] == 2){
    ws2.setPixelColor(Pixel, ws2.Color(red, green, blue));
   }
   else if(stripToCommand[idx] == 3){
    ws3.setPixelColor(Pixel, ws3.Color(red, green, blue));
   }
   else if(stripToCommand[idx] == 4){
    ws4.setPixelColor(Pixel, ws4.Color(red, green, blue));
   }
   else if(stripToCommand[idx] == 5){
    ws5.setPixelColor(Pixel, ws5.Color(red, green, blue));
   }
   else{/*Serial.println("no matches2");*/}

 #endif
 #ifndef ADAFRUIT_NEOPIXEL_H 
   // FastLED
//   leds[Pixel].r = red;
//   leds[Pixel].g = green;
//   leds[Pixel].b = blue;
 #endif
}

I do end up having to use an array to hold my values, because it takes user input to trigger my patterns and timing. And you may have to have a global property to hold however many random numbers you need, while using the same index for placing them. I hope this helps.