Random switch case with delay

Hello fellow arduino fans.

The project that I am currently stuck on is a sign with a border. The code that I have written is working great so far. My question is, How can I have a random case statement run for x amount of time before the next random case statement is called? So far I have 2 different patterns written, and I would like to have the first random one run for 10 seconds, then choose another random case, and have it run each case for 10 seconds. here is my code so far.

int pattern = 0;
int b1 = 10;  //sets pin names
int b2 = 11;
int b3 = 12;
int b4 = 13;
int t1 = 2;
int t2 = 3;
int t3 = 4;
int t4 = 5;
int pinArray[] = {10, 11, 12, 13, 2, 3, 4, 5};
int pinArraytop[] = {2, 3, 4, 5};
int pinArraybottom[] = {10, 11, 12, 13};
int count = 0;
int timer = 30;


void setup () {
  pinMode(b1, OUTPUT);   // sets pins as outputs.
  pinMode(b2, OUTPUT);
  pinMode(b3, OUTPUT);
  pinMode(b4, OUTPUT);
  pinMode(t1, OUTPUT);
  pinMode(t2, OUTPUT);
  pinMode(t3, OUTPUT);
  pinMode(t4, OUTPUT);
  for (count=0;count<8;count++) {
    pinMode(pinArray[count], OUTPUT);
  }
   
}  
  
  void loop() {
  int pattern = random(2);
    
  switch (pattern){
    
  case 0://CHASE
  for (count=0;count<4;count++) {
   digitalWrite(pinArraytop[count], HIGH);
   digitalWrite(pinArraybottom[count], HIGH);
   delay(timer);
   digitalWrite(pinArraybottom[count + 1], HIGH);
   digitalWrite(pinArraytop[count + 1], HIGH);
   delay(timer);
   digitalWrite(pinArraytop[count], LOW);
   digitalWrite(pinArraybottom[count], LOW);
  }
  break;
  
  
  case 1: //fill then empty
  digitalWrite(b1, HIGH);
  digitalWrite(t1, HIGH);
  delay(100);
  digitalWrite(b2, HIGH);
  digitalWrite(t2, HIGH);
  delay(100);
  digitalWrite(b3, HIGH);
  digitalWrite(t3, HIGH);
  delay(100);
  digitalWrite(b4, HIGH);
  digitalWrite(t4, HIGH);
  delay(100);
  digitalWrite(b1, LOW);
  digitalWrite(t1, LOW);
  delay(100);
  digitalWrite(b2, LOW);
  digitalWrite(t2, LOW);
  delay(100);
  digitalWrite(b3, LOW);
  digitalWrite(t3, LOW);
  delay(100);
  digitalWrite(b4, LOW);
  digitalWrite(t4, LOW);
  delay(100);
  break;  
  }
}

Set a variable as a timer record
Set timer to current millis()
Generate a random integer between 1 and the number of patterns
Do your Case statement to determine Which pattern to use
On each loop() check if the difference between current millis() and your timer is more than 10s
If greater than 10s then reset timer record and generate a new random number

I am confused as to how to do this? Can anyone point me in the right direction?

I am confused as to how to do this? Can anyone point me in the right direction?

tack listed several steps. Which one is causing you confusion? What have you tried?

The blink without delay example will explain how to use millis. You want a different interval, and different action when the interval is up, but it's a starting point.

Thank you Tack and Paul.S.... I think I have it figured out. Or at least it is working the way I had pictured in my head. I added a new for statement in the code, and it seems to be doing the delay I was looking for. here is the new code with the change.

int pattern = 0;
int a = 5000;
int b1 = 10;
int b2 = 11;
int b3 = 12;
int b4 = 13;
int t1 = 2;
int t2 = 3;
int t3 = 4;
int t4 = 5;
int pinArray[] = {10, 11, 12, 13, 2, 3, 4, 5};
int pinArraytop[] = {2, 3, 4, 5};
int pinArraybottom[] = {10, 11, 12, 13};
int count = 0;
int timer = 30;


void setup () {
  pinMode(b1, OUTPUT);
  pinMode(b2, OUTPUT);
  pinMode(b3, OUTPUT);
  pinMode(b4, OUTPUT);
  pinMode(t1, OUTPUT);
  pinMode(t2, OUTPUT);
  pinMode(t3, OUTPUT);
  pinMode(t4, OUTPUT);
  for (count=0;count<8;count++) {
    pinMode(pinArray[count], OUTPUT);
  }
   
}  
  
  void loop() {
  int pattern = random(2);
  for (int nextRandom = 1; nextRandom <=10; nextRandom++)  //a dealy that has each case run 10 times before switching.
  switch (pattern){
    
  case 0://CHASE
    for (count=0;count<4;count++) {
   digitalWrite(pinArraytop[count], HIGH);
   digitalWrite(pinArraybottom[count], HIGH);
   delay(timer);
   digitalWrite(pinArraybottom[count + 1], HIGH);
   digitalWrite(pinArraytop[count + 1], HIGH);
   delay(timer);
   digitalWrite(pinArraytop[count], LOW);
   digitalWrite(pinArraybottom[count], LOW);
  }
   break;
  
   case 1: //fill then empty
  digitalWrite(b1, HIGH);
  digitalWrite(t1, HIGH);
  delay(100);
  digitalWrite(b2, HIGH);
  digitalWrite(t2, HIGH);
  delay(100);
  digitalWrite(b3, HIGH);
  digitalWrite(t3, HIGH);
  delay(100);
  digitalWrite(b4, HIGH);
  digitalWrite(t4, HIGH);
  delay(100);
  digitalWrite(b1, LOW);
  digitalWrite(t1, LOW);
  delay(100);
  digitalWrite(b2, LOW);
  digitalWrite(t2, LOW);
  delay(100);
  digitalWrite(b3, LOW);
  digitalWrite(t3, LOW);
  delay(100);
  digitalWrite(b4, LOW);
  digitalWrite(t4, LOW);
  delay(100);
  break;  
  }
}

Does that look like what you guys were talking about? Or did i go off in a whole different direction?

Does that look like what you guys were talking about?

Not even a little bit.

Or did i go off in a whole different direction?

Completely.

daveydav27:
How can I have a random case statement run for x amount of time before the next random case statement is called?

I can see two ways to approach this:

In the blocking approach, you generate a random number and use that to select a random case from a switch statement, and you put code in the case which loops (doing something which you haven't told us about) until 'x amount of time' has passed - however you want to define that.

In the non-blocking approach, you define a global variable containing your random number, and use the global variable to select a case from a switch statement that does the thing you haven't told us about - just does it once. As loop is called repeatedly, the same case gets executed repeatedly until you change the global variable. Also within loop() you include some code similar to 'blink without delay' which generates a new random number each time 'x amount of time' has passed.

Personally I prefer the non-blocking approach since it enables you to control multiple activities concurrently, but the blocking approach is simpler to code and may be sufficient if your sketch doesn't need to do anything else independently of the behaviour you described above.