2D Array sequence timing error

Hi
Would anyone be able to help with some errors i have with an array sequence using 2 separate led arrays with separate interval and off times.
The program works but not quite as expected, At startup the 2 separate arrays seems to start from position 2 not 1 so iv'e added extra rows for this and at the end of each sequence there is a a few second delay until it start over again where i want it to go from sequence 6 say after off time straight onto sequence 1, i don'Use code tags to format code for the forumt think this is the most efficient way to run 2 separate arrays but any help would be appreciated. Thanks

//initialize Global variables
unsigned long CurrentMillis = 0; // mari current millis
unsigned long PreviousMillis = 0; // mari previous millis
unsigned long CurrentMillis1 = 0; // CLS current millis
unsigned long PreviousMillis1 = 0; // CLS previous millis
int TimeState = 0;  // Mari Timestates: 0 waiting, 1 open all relays, 2 wait for off perio, 3 set relays
int TimeState1 = 0; // CLS timestates: 0 waiting, 1 open all relays, 2 wait for off perio, 3 set relays
int Mari_interval = 4000; // Mari interval time
int Cls_interval = 7000; // Cls interval time
int Mari_OffTime = 700; // Mari all led Off time when incrementing to the next led
int Cls_OffTime = 700; // CLS all led Off time when incrementing to the next led
int Mari_Seq = 0; // sequence location
int Cls_Seq = 0; // sequence location
int Mari_crossing = 0; // Mari transitio time after reaching max count and srting at the beginning again.
int Cls_crossing = 0; // CLS transitio time after reaching max count and srting at the beginning again.
int Mari_Index = 0; // Mari index position
int Cls_Index = 0; // CLS index position

int MariPins[6] = { 2, 3, 4, 5, 6, 7 }; // Mari on D2,3,4,5,6,7
int ClsPins[3] = {8, 9, 10 }; // CLS on D8,9,10

//7 rows and 9 columns
int Mari_Array[8][6] = {

  //1  2  3  4  5  6 
  { 0, 0, 0, 0, 0, 0,}, //0 first row is Zero no aspects will be set
  { 0, 0, 0, 0, 0, 0,}, // start at Row 1
  { 1, 0, 0, 0, 0, 0,}, //2
  { 0, 1, 0, 0, 0, 0,}, //3
  { 0, 0, 1, 0, 0, 0,}, //4
  { 0, 0, 0, 1, 0, 0,}, //5
  { 0, 0, 0, 0, 1, 0,}, //6
  { 0, 0, 0, 0, 0, 1,}, //7
};

int Cls_Array[5][3] = {
  // columns
  //1  2  3  
  { 0, 0, 0 }, //0 first row is Zero no aspects will be set
  { 0, 0, 0 }, //1 start at row 1
  { 1, 0, 0,}, //2 the code seems to sart here at startup instead of 1 so an extra row has been added to counteract this.
  { 0, 1, 0 }, //3
  { 0, 0, 1 }, //4

};

// Timer Functions
void Mari_Timers() { // mari timers
  CurrentMillis = millis();

  if (PreviousMillis > CurrentMillis)  //timer roll over condition
  {
    PreviousMillis = 0;
  }

  if (TimeState == 0)  // if the timer is waiting to roll over
  {
    if (CurrentMillis - PreviousMillis >= Mari_interval) {
      PreviousMillis = CurrentMillis;
      Mari_crossing = Mari_crossing + 1;
      if (Mari_crossing > 5) {
        Mari_crossing = 0;
      }
      TimeState = 1;  // open all relays
    }
  }

  if (TimeState == 2)  // waiting for the relay off period to expire
  {
    if (CurrentMillis - PreviousMillis >= Mari_OffTime) {
      PreviousMillis = CurrentMillis;
      TimeState = 3;  // off time has expired so close selected relays, currently active low
    }
  }
}


void Cls_Timers() { // Cls timers with the led states for on off times  
  CurrentMillis1 = millis();

  if (PreviousMillis1 > CurrentMillis1)  //timer roll over condition
  {
    PreviousMillis1 = 0;
  }

  if (TimeState1 == 0)  // if the timer is waiting to roll over
  {
    if (CurrentMillis1 - PreviousMillis1 >= Cls_interval) {
      PreviousMillis1 = CurrentMillis1;
      Cls_crossing = Cls_crossing + 1;
      if (Cls_crossing > 5) {
        Cls_crossing = 0;
      }
      TimeState1 = 1;  // open all relays
    }
  }
  if (TimeState1 == 2)  // waiting for the relay off period to expire
  {
    if (CurrentMillis1 - PreviousMillis1 >= Cls_OffTime) {
      PreviousMillis1 = CurrentMillis1;
      TimeState1 = 3;  // off time has expired so close selected relays, currently active low
    }
  }
}



void Mari_Relays() {

  for (int i = 0; i < 6; i++) {
    if (TimeState == 2) {
      digitalWrite(MariPins[i], HIGH);  // turn off all relays during off cycle as the relay board is active low inputs
    } else {
      digitalWrite(MariPins[i], !Mari_Array[Mari_Index][i]);  // set the required relay outputs LOW, currently active Low with used relay boards
    }
  }
}


void Cls_Relays() {

  for (int i = 0; i < 3; i++) {
    if (TimeState1 == 2) {
      digitalWrite(ClsPins[i], HIGH);  // turn off relays during off cycle
    } else {
      digitalWrite(ClsPins[i], !Cls_Array[Cls_Index][i]);  // set the required relays, currently active Low with used relay boards
    }
  }
}


void setup() {
  //Setup Relay Output Pins
  for (int i = 0; i < 6; i++) pinMode(MariPins[i], OUTPUT);    // set array pins as outputs
  for (int i = 0; i < 6; i++) digitalWrite(MariPins[i], HIGH);  // set all array outputs low AT STARTUP
  Mari_Index = 0;

  for (int i = 0; i < 3; i++) pinMode(ClsPins[i], OUTPUT);    // set array pins as outputs
  for (int i = 0; i < 3; i++) digitalWrite(ClsPins[i], HIGH);  // set all array outputs low AT STARTUP
  Cls_Index = 0;
}


void loop() {

  Mari_Timers();  // Auto sequence structure below for the Mari Timer Manager

  if (TimeState == 1)  // time interval has passed open all relays
  {
    Mari_Index = 0;
    Mari_Relays();
    TimeState = 2;
  }
  if (TimeState == 3)  // time interval has passed set required relays
  {
    Mari_Seq = Mari_Seq + 1;
    if (Mari_Seq >= 7)  //max count required
    {
      Mari_Seq = 0;
    }
    {
      Mari_Index = Mari_Seq + 1; // increment sequence
    }

    Mari_Relays();
    TimeState = 0;
  }


  Cls_Timers();  // Auto sequence structure below for the Cls Timer Manager

  if (TimeState1 == 1)  // time interval has passed open all relays
  {
    Cls_Index = 0; // cls index
    Cls_Relays();
    TimeState1 = 2;
  }
  if (TimeState1 == 3)  // time interval has passed set required relays
  {
    Cls_Seq = Cls_Seq + 1;
    if (Cls_Seq >= 4)  //max count required
    {
      Cls_Seq = 0;
    }
    {
      Cls_Index = Cls_Seq + 1; // increment sequence
    }

    Cls_Relays();
    TimeState1 = 0;
  }

}


// works but only starts at 2 i the array and after the last count of 6 example then there is a delay of the given delay time.

edit your post and remove this text

Hi Will do, i thought i had used the tag icon and pasted the code.

can you describe what this program should do? focus on small Cls array and write down how animation should look from outside.

Did you miss out an 'else'?

@southtyne

Please do that. I've been running your code with some debug prints added, and I can't work out what you pattern you want from Cls_Seq, Cls_Index, Mari_Seq and Mari_Index.
The pattern isn't consistent:

Time:   0.0000 Seq / Index updated
*** Cls_Seq =0 Cls_Index=0          // 0,0
*** Mari_Seq=0 Mari_Index=0         //    0,0
Time:   0.0003 Exiting setup()
Time:   4.0717 Seq / Index updated
*** Cls_Seq =0 Cls_Index=0
*** Mari_Seq=1 Mari_Index=2         //    1,2
Time:   9.0417 Seq / Index updated
*** Cls_Seq =1 Cls_Index=2          // 1,2
*** Mari_Seq=2 Mari_Index=3         //    2,3 
Time:  14.0117 Seq / Index updated
*** Cls_Seq =1 Cls_Index=2
*** Mari_Seq=3 Mari_Index=4         //    3,4
Time:  18.0818 Seq / Index updated
*** Cls_Seq =2 Cls_Index=3          // 2,3
*** Mari_Seq=4 Mari_Index=5         //    4,5
Time:  23.0518 Seq / Index updated
*** Cls_Seq =3 Cls_Index=4          // 3,4
*** Mari_Seq=5 Mari_Index=6         //    5,6
Time:  28.0218 Seq / Index updated
*** Cls_Seq =3 Cls_Index=4
*** Mari_Seq=6 Mari_Index=7         //    6,7
////////////////////////////////////////////////////////// Reset seq / index
Time:  32.0921 Seq / Index updated
*** Cls_Seq =0 Cls_Index=1          // 0,1       <- not had 0,1 before now
*** Mari_Seq=0 Mari_Index=1         //    0,1    <- not had 0,1 before now
Time:  37.0617 Seq / Index updated
*** Cls_Seq =0 Cls_Index=1
*** Mari_Seq=1 Mari_Index=2         //    1,2
Time:  42.0317 Seq / Index updated
*** Cls_Seq =1 Cls_Index=2          // 1,2
*** Mari_Seq=2 Mari_Index=3         //    2,3
Time:  47.0017 Seq / Index updated
*** Cls_Seq =2 Cls_Index=3          // 2,3
*** Mari_Seq=3 Mari_Index=4         //    3,4
Time:  51.0718 Seq / Index updated
*** Cls_Seq =2 Cls_Index=3        
*** Mari_Seq=4 Mari_Index=5         //    4,5
Time:  56.0418 Seq / Index updated
*** Cls_Seq =3 Cls_Index=4          // 3,4
*** Mari_Seq=5 Mari_Index=6         //    5,6
Time:  61.0117 Seq / Index updated
*** Cls_Seq =3 Cls_Index=0          // 3,0       <- not had 3,0 before now
*** Mari_Seq=6 Mari_Index=7         //    6,7
////////////////////////////////////////////////////////// Reset seq / index
Time:  65.0821 Seq / Index updated  
*** Cls_Seq =0 Cls_Index=1          // 0,1
*** Mari_Seq=0 Mari_Index=1         //    0,1
Time:  70.0517 Seq / Index updated
*** Cls_Seq =1 Cls_Index=2          // 1,2  
*** Mari_Seq=1 Mari_Index=2         //    1,2
Time:  75.0217 Seq / Index updated
*** Cls_Seq =1 Cls_Index=2
*** Mari_Seq=2 Mari_Index=3         //    2,3
Time:  79.0918 Seq / Index updated
*** Cls_Seq =2 Cls_Index=3          // 2,3
*** Mari_Seq=3 Mari_Index=4         //    3,4
Time:  84.0618 Seq / Index updated
*** Cls_Seq =2 Cls_Index=0          // 2,0       <- not had 2,0 before
*** Mari_Seq=4 Mari_Index=5         //    4,5
Time:  89.0318 Seq / Index updated
*** Cls_Seq =3 Cls_Index=4          // 3,4
*** Mari_Seq=5 Mari_Index=6         //    5,6
////////////////////////////////////////////////////////// Reset only Cls seq / index
Time:  94.0017 Seq / Index updated
*** Cls_Seq =0 Cls_Index=1          // 0,1
*** Mari_Seq=6 Mari_Index=7         //    6,7
////////////////////////////////////////////////////////// Reset only Mari seq / index
Time:  98.0721 Seq / Index updated
*** Cls_Seq =0 Cls_Index=1
*** Mari_Seq=0 Mari_Index=1         //    0,1
Time: 103.0417 Seq / Index updated
*** Cls_Seq =1 Cls_Index=2          // 1,2
*** Mari_Seq=1 Mari_Index=2         //    1,2
Time: 108.0118 Seq / Index updated
*** Cls_Seq =2 Cls_Index=3          // 2,3
*** Mari_Seq=2 Mari_Index=3         //    2,3
Time: 112.0818 Seq / Index updated
*** Cls_Seq =2 Cls_Index=3
*** Mari_Seq=3 Mari_Index=4         //    3,4
Time: 117.0518 Seq / Index updated
*** Cls_Seq =3 Cls_Index=4          // 3,4
*** Mari_Seq=4 Mari_Index=5         //    4,5
Time: 122.0217 Seq / Index updated
*** Cls_Seq =3 Cls_Index=4
*** Mari_Seq=5 Mari_Index=6         //    5,6 
Time: 126.0917 Seq / Index updated
////////////////////////////////////////////////////////// Reset only Cls seq / index
*** Cls_Seq =0 Cls_Index=1          // 0,1
*** Mari_Seq=6 Mari_Index=7         //    6,7
////////////////////////////////////////////////////////// Reset only Mari seq / index
Time: 131.0640 Seq / Index updated
*** Cls_Seq =1 Cls_Index=2          // 1,2
*** Mari_Seq=0 Mari_Index=1         //    0,1
....ETC....

Let me know if you want me to post the code with those (and other) debug prints in it. I also tidied up your global variables. Some aren't variables (use const) and some don't need to be global.

Hi Dave

Thanks for your help looking at this.

the two arrays just sequence the led's from outputs D2 to D7 with intervals of the time set for the mari interval but between the transitions to the next sequence all outputs in that array turn off for the off time duration so they cycle from 1-6 down the array and start at 1 again but there seems to be a delay at the start and also only starts at array row 2 instead of 1 but after the first sequence pass its ok, and also there's a delay from the 6th sequence to starting at 1 again. thanks

Hi
The idea is at startup the array table scrolls down from top to bottom using the index then restarts from 1-6 again and the same for the cls array, all the 1s in the table are relay/led outputs I'm using then they are turned on or off from the relay manager based on what sequence/index its at.
any help with fixes is appreciated and will test. thanks

is so ok?

for (byte i = 2; i <= 7; i++){
  digitalWrite(i, ACTIVE);
  delay(duration);
  digitalWrite(i, OFF);
  delay(offtime);
}

Hi, Yes that's roughly what it is to do sequence outputs 1-6 with off times so as we go to the next sequence down the array the outputs are all off for that particular array, i maybe didnt need to use arrays to do this. The code seems to work but it starts the array at row 2 instead of row 1 and there is a delay before it even does that.

Why do you have two variables for each of Cls and Mari?
It seems like _Seq is always supposed to be = _Index-1.
Did you introduce that code because you were having problems indexing the arrays?
Can you write out the required timing sequence?
For example, like this, but with the correct sequence of output states and delay times?


Those times like "After 4000ms" don't need to be absolute times, e.g. the next row might say "After 4000ms" meaning "After another 4000ms". There's no need to know the absolute value of millis for each delay.

Hi
i needed two sequences running simultaneously at two different speeds with off times mostly to ensure the previous output is off for at least 500mS before the next output turns on. the idea was the sequence = the index then whatever sequence then program was at the index could turn the relay outputs on or off with the array table contents. Thanks

Where I've underlined pin numbers, should all of D2-D6 be off for 700ms?


What are the requirements for D7 (I thought it was asssociated with D2 to D6) because there's a comment in the code "Mari on D2,3,4,5,6,7"
Can you do a similar diagram for D8 to D10?
With those two diagrams I (or someone else following this thread) could quite quickly write some code that would do what you want to do.

1 Like
const byte MariPins[6] = { 2, 3, 4, 5, 6, 7 }; // Mari on D2,3,4,5,6,7
const byte  ClsPins[3] = {8, 9, 10 }; // CLS on D8,9,10
#define ACTIVE LOW
#define OFF HIGH

void Mari_Timers() { // mari timers
  const int Mari_interval = 4000; // Mari interval time
  const int Mari_OffTime = 700; // Mari all led Off time when incrementing to the next led
  static unsigned long PreviousMillis = 5; // mari previous millis
  static byte  TimeState = 0;  // Mari Timestates: 0 next LED ready, 1 LED on, 2 LED off 
  static byte Mari_Index = 0; // Mari index position

  switch (TimeState) {
    case 0:
      digitalWrite(MariPins[Mari_Index], ACTIVE);
      PreviousMillis = millis();
      TimeState++;
      break;

    case 1:
      if (millis() - PreviousMillis >= Mari_interval)
      {
        PreviousMillis += Mari_interval;
        digitalWrite(MariPins[Mari_Index], OFF);
        Mari_Index++;
        Mari_Index %= sizeof(MariPins);
        TimeState++;
      }
      break;

    case 2:
      if (millis() - PreviousMillis >= Mari_OffTime)
      {
        PreviousMillis += Mari_OffTime;
        TimeState = 0;
      }
      break;
  }
}
void Cls_Timers() { // Cls timers with the led states for on off times
  const int Cls_interval = 7000; // Cls interval time
  const int Cls_OffTime = 700; // CLS all led Off time when incrementing to the next led
  static unsigned long PreviousMillis1 = 0; // CLS previous millis
  static byte  TimeState1 = 0; // CLS timestates
  static byte  Cls_Index = 0; // CLS index position

  switch (TimeState1) {
    case 0:
      digitalWrite(ClsPins[Cls_Index], ACTIVE);
      PreviousMillis1 = millis();
      TimeState1++;
      break;

    case 1:
      if (millis() - PreviousMillis1 >= Cls_interval)
      {
        PreviousMillis1 += Cls_interval;
        digitalWrite(ClsPins[Cls_Index], OFF);
        Cls_Index++;
        Cls_Index %= sizeof(ClsPins);
        TimeState1++;
      }
      break;

    case 2:
      if (millis() - PreviousMillis1 >= Cls_OffTime)
      {
        PreviousMillis1 += Cls_OffTime;
        TimeState1 = 0;
      }
      break;
  }
}

void setup() {
  for (int i = 0; i < sizeof(MariPins); i++) {
    digitalWrite(MariPins[i], OFF);
    pinMode(MariPins[i], OUTPUT);
  }
  for (int i = 0; i < sizeof(ClsPins); i++) {
    digitalWrite(ClsPins[i], OFF);
    pinMode(ClsPins[i], OUTPUT);
  }
}

void loop() {
  Mari_Timers();
  Cls_Timers();
}
2 Likes

Sorry it is from D2-D7 i missed the D7 off the illustration.
The CLS is the same just different on time/sequence time of 7000mS and only 3 outputs D8-D10. Thanks

Hi
Thanks very much for this, i will take a good look and give this a try.

You can put pins and timing into arrays. Here is an example, including a timing chart...

2 Likes

Hi

Thanks so much for this, it works perfectly and exactly how i wanted it to work, I've had a couple of iterations with this and got the sequencing to work but getting the off times upon transition was more tricky but your version works perfectly so thanks again for this, much appreciated.

Hi thanks for this i will take a good look at it.

Hi dave Thanks very much for your help, much appreciated, Kolaha wrote some code and does exactly what i was trying to achieve. thanks again

1 Like