Here's the trick:
int number = &ledSequencer-ledSequencers; // Finds the index of the current element
And in the code:
#define usl unsigned long // I´m lazy to type
constexpr int LedPins[] {9, 10, 11};
struct LEDSEQUENCER
{
usl span;
int pattern[sizeof(LedPins) / sizeof(LedPins[0])];
usl now;
int control;
};
LEDSEQUENCER ledSequencers[]
{
{ 500, 0, 0, 0, 0, HIGH},
{ 1000, 1, 0, 0, 0, LOW},
{ 500, 0, 0, 0, 0, LOW},
{ 1000, 0, 1, 0, 0, LOW},
{ 500, 0, 0, 0, 0, LOW},
{ 1000, 0, 0, 1, 0, LOW},
{ 500, 0, 0, 0, 0, LOW},
{ 1000, 0, 0, 1, 0, LOW},
// add pattern if needed
};
void setup()
{
for (auto LedPin : LedPins)
{
pinMode ( LedPin, OUTPUT);
digitalWrite(LedPin, HIGH);
delay(1000);
digitalWrite(LedPin, LOW);
delay(1000);
}
}
void loop()
{
usl currentMillis = millis();
for (auto &ledSequencer : ledSequencers)
{
if (currentMillis - ledSequencer.now >= ledSequencer.span && ledSequencer.control)
{
int number = &ledSequencer-ledSequencers;
int element = 0;
ledSequencer.control = LOW;
number = (number + 1) % (sizeof(ledSequencers) / sizeof(ledSequencers[0]));
ledSequencers[number].control = HIGH;
ledSequencers[number].now = currentMillis;
for (auto LedPin : LedPins) digitalWrite(LedPin, ledSequencers[number].pattern[element++]);
}
}
}
On the other hand, if there's only one sequence active at a time, and it's index in recorded in number
you could move static int number
out to the top level of loop and instead of looking at the whole list sequencers with for(...)
, you could look at only the active one:
#define usl unsigned long // I´m lazy to type
constexpr int LedPins[] {9, 10, 11};
constexpr int nLedPins = sizeof(LedPins) / sizeof(LedPins[0]);
struct LEDSEQUENCER
{
usl span; // ms of time in state
int pattern[nLedPins]; // Settings of the LEDs in this state
usl now; // Timestamp of last change
int control; // whether active or not
};
LEDSEQUENCER ledSequencers[]
{
{ 500, 0, 0, 0, 0, LOW},
{ 1000, 1, 0, 0, 0, LOW},
{ 500, 0, 0, 0, 0, LOW},
{ 1000, 0, 1, 0, 0, LOW},
{ 500, 0, 0, 0, 0, HIGH}, // start with this one
{ 1000, 0, 0, 1, 0, LOW},
{ 500, 0, 0, 0, 0, LOW},
{ 1000, 0, 0, 1, 0, LOW},
// add pattern if needed
};
constexpr int nLedSequencers = sizeof(ledSequencers) / sizeof(ledSequencers[0]);
static int number = 0;
void setup()
{
for (auto LedPin : LedPins) // setup and excercise the ledPins
{
pinMode ( LedPin, OUTPUT);
digitalWrite(LedPin, HIGH);
delay(1000);
digitalWrite(LedPin, LOW);
delay(1000);
}
Serial.begin(115200);
for (auto &ledSequencer : ledSequencers) { // find the index of the last HIGH
if (ledSequencer.control == HIGH) {
number = &ledSequencer - ledSequencers;
}
}
}
void loop()
{
usl currentMillis = millis(); // remember the current time
auto &ledSequencer = ledSequencers[number]; // Uses a reference & because we need to modify data
if (currentMillis - ledSequencer.now >= ledSequencer.span && ledSequencer.control)
{
int element = 0;
ledSequencer.control = LOW;
number = (number + 1) % nLedSequencers;
ledSequencers[number].control = HIGH;
ledSequencers[number].now = currentMillis;
for (auto LedPin : LedPins) digitalWrite(LedPin, ledSequencers[number].pattern[element++]);
}
}