WigWag Lighting - How to Delay Flasher Groups

I'm working on replacing a lighting system based on Mercury switches and I'm about 60% of the way there. I have my code working, but it's flashing all the LEDs at once rather than in groups like I need. I know why, but I can't seem to figure out how to insert a delay between each group of outputs. Ideally, I need b7a/b and b4a/b to start the sequence, followed 500 ms later by b6a/b and b3a/b, followed an additional 500 ms later by b5a/b and b2a/b, and finally completed 500 ms later by b1. The effect we're looking for is to have the lights trail one another, so by the time we get to b5/b2, b7/b4 turns back on to restart the trail. I used a tutorial from Adafruit to get this far, but I've hit a sticking point. I tried inserting a delay in the loop, but it didn't function like I was hoping it would. How would I go about delaying each group of outputs independently? My current code is below. Thanks for the assist.

class Flasher
{
    // Class Member Variables
    // These are intitialised at Startup
    int gpoPin;        // the number of gpo pin
    long OnTime;       // milliseconds of on-time
    long OffTime;      // milliseconds of off-time

    // These maintain the current state
    int gpoState;                        // gpoState used to set the GPO 
    unsigned long previousMillis;         // will store last time GPO was updated

    // Constructor - creates a flasher
    // and initializes the member variables and state
    public:
    Flasher(int pin, long on, long off)
    {
      gpoPin = pin;
      pinMode(gpoPin, OUTPUT);

      OnTime = on;
      OffTime = off;


      gpoState = LOW;
      previousMillis = 0;
    }

    void Update()
    {
      // check to see if it's time to change the state of the LED
      unsigned long currentMillis = millis();

      if ((gpoState == HIGH) && (currentMillis - previousMillis >= OnTime))
      {
        gpoState = LOW;  // Turn it Off
        previousMillis = currentMillis;  // Remember the Time
        digitalWrite(gpoPin, gpoState);  // Update the Actual GPO
      }
      else if ((gpoState == LOW) && (currentMillis - previousMillis >= OffTime))
      {
        gpoState = HIGH; // Turn it On
        previousMillis = currentMillis;  // Remember the Time
        digitalWrite(gpoPin, gpoState);  // Update the Actual GPO
      }
    }
};

Flasher b1(1, 1000, 1000);
Flasher b2a(2, 1000, 1000);
Flasher b2b(3, 1000, 1000);
Flasher b3a(4, 1000, 1000);
Flasher b3b(5, 1000, 1000);
Flasher b4a(6, 1000, 1000);
Flasher b4b(7, 1000, 1000);
Flasher b5a(8, 1000, 1000);
Flasher b5b(9, 1000, 1000);
Flasher b6a(10, 1000, 1000);
Flasher b6b(11, 1000, 1000);
Flasher b7a(12, 1000, 1000);
Flasher b7b(13, 1000, 1000);

void setup ()
{

}

void loop()
{
  b7b.Update();
  b7a.Update();
  b4b.Update();
  b4a.Update();
  b6b.Update();
  b6a.Update();
  b3b.Update();
  b3a.Update();
  b5b.Update();
  b5a.Update();
  b2b.Update();
  b2a.Update();
  b1.Update();
}

This sounds like you want four sequences to start and run simultaneously...

... followed by adding four more simultaneous sequences (eight simultaneous sequences)... adding... repeating..

This is how the loop() is working... "top-down"

Probably not solving your problem but you should not access hardware in a constructor; e.g. pinMode.

are you saying you want the following sequence?

       0    7 on
     500    6 on
    1000    5 on, 7 off
    1500    6 off
    2000    5 off

       0    4 on
     500    3 on
    1000    2 on, 4 off
    1500    1 on, 3 off
    2000    2 off
    2500    1 off

if so, does each pin need an offset time ?

Not that each pin needs an independent offset time, each group of Pins needs an offset time. Pins 6, 7, 12, and 13 go together, Pins 4, 5, 10, and 11 go together, Pins 2, 3, 8, and 9 go together, and Pin 1 goes alone. I know I could parallel the relays down the line to reduce my Pins since so many go together, but I'm keeping them independent with independent relays for redundancy.

Each of these flashers works independant from the others.

This contradictionary in itself. Or that is what your code already does.
Flash them all independently.

This means that the on/off-state depends from each other.

0 ms ed b7a/b and b4a/b ON
500 ms later b6a/b and b3a/b ON,
500 ms later b5a/b and b2a/b ON
500 ms later 500 ms b1 ON
then
b5/b2, b7/b4 ON

This is all what your description says

This is a non-suffcient description of what you really want because you wrote this

This means there has to be a switching OFF inbetween.

You should draw a timing diagram that shows at what time-distances which out-puts shall be on and when off. This timing diagram will save you hundreds of words.

You wrote that your LEDs shall flash.
Does flash mean switch one time on / off,
or
does it mean multiple times on/off? before advancing to the next group?

Is this some common kind of lighting device so that there might be a youtube-video that shows it in action?

each pin within a sequence needs an offset:
4, 5, 10, 11= 500 ms
2, 3, 8, 9 = 1000
1 = 1500

To close the loop here, we decided to just use a delay() instead of millis() because at the end of the day, controlling these relays is all this Arduino is ever going to do so having blocking code isn't an issue at all. Using delay() made things super simple in terms of sequencing so it's up and operational. Thanks all for the assistance.

is this the sequence you're looking for?

   msec pin
      0   6 On
      0   7 On
      0  12 On
      0  13 On
    500   4 On
    500   5 On
    500  10 On
    500  11 On
   1000   6 Off
   1000   2 On
   1000   7 Off
   1000   3 On
   1000  12 Off
   1000   8 On
   1000  13 Off
   1000   9 On
   1500   4 Off
   1500   1 On
   1500   5 Off
   1500  10 Off
   1500  11 Off
   1500   1 On
   2000   2 Off
   2000   3 Off
   2000   8 Off
   2000   9 Off
   2500   1 Off
   2500   1 Off

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.