State Machine with LEDs

Hi,
Im trying to flash 14 LEDs in 3 different sequences using a push button. To control those LEDs im using 2 shift registers working independently.
Im new in programming and im trying to use the principles of state machines to switch between those different sequences, but what happpens is that when i push the button it basically goes right to the last of those 3 states (it runs all the states but the two first states lasts only milliseconds).
Can you help?
thanks in advance.

const int buttonLed_Pin = 12;

int latchPin1 = 2;                  //SHIFT REGISTERS
int clockPin1 = 3;
int dataPin1 = 4;
int latchPin2 = 5;
int clockPin2 = 6;
int dataPin2 = 7;

int array1[8] = {1,2,4,8,16,32,64,128};  // LED Sequences
int array2[8] = {1,2,4,8,16,32,64,128};
int array3[8] = {128,64,32,16,8,4,2,1};
int array4[8] = {128,64,32,16,8,4,2,1};
int array5[8] = {128,64,32,16,8,4,2,1};
int array6[8] = {1,2,3,8,16,32,64,128};


const int buttonInterval = 300;
unsigned long currentMillis = 0;
unsigned long previousButtonMillis = 0;
int ledState = 0;
int oldSeq = 0;

void setup() {
Serial.begin(9600);

  pinMode(buttonLed_Pin, INPUT);
  pinMode(latchPin1, OUTPUT);
  pinMode(clockPin1, OUTPUT);
  pinMode(dataPin1, OUTPUT);
  
  pinMode(latchPin2, OUTPUT);
  pinMode(clockPin2, OUTPUT);
  pinMode(dataPin2, OUTPUT);

}

void loop() {
  // put your main code here, to run repeatedly:
currentMillis = millis();
checkButtons();
ledSequences();
Serial.println(ledState);
}

void checkButtons() {

 if (millis() - previousButtonMillis >= buttonInterval) {
  if (digitalRead(buttonLed_Pin) == HIGH){
     ledState = oldSeq +1;
     previousButtonMillis += buttonInterval;
 }
}
}

void ledSequences(){

 switch (ledState) {
  case 1:
  for(int i = 0; i < 8; i++)
    {
    digitalWrite(latchPin1, LOW);
    digitalWrite(latchPin2, LOW);
    
    shiftOut(dataPin1, clockPin1, MSBFIRST, array1[i]);
    shiftOut(dataPin2, clockPin2, MSBFIRST, array2[i]);
    
    digitalWrite(latchPin1, HIGH);
    digitalWrite(latchPin2, HIGH);
    oldSeq = ledState;
    
 }

 break;
 case 2:
  for(int i = 0; i < 8; i++)
    {
    digitalWrite(latchPin1, LOW);
    digitalWrite(latchPin2, LOW);
    
    shiftOut(dataPin1, clockPin1, MSBFIRST, array3[i]);
    shiftOut(dataPin2, clockPin2, MSBFIRST, array4[i]);
    
    digitalWrite(latchPin1, HIGH);
    digitalWrite(latchPin2, HIGH);
}
 oldSeq = ledState;
 break;

  case 3 :
  for(int i = 0; i < 8; i++)
    {
    digitalWrite(latchPin1, LOW);
    shiftOut(dataPin1, clockPin1, MSBFIRST, array5[i]);
    digitalWrite(latchPin1, HIGH);
    delay(100);
    digitalWrite(latchPin2, LOW);
    shiftOut(dataPin2, clockPin2, MSBFIRST, array6[i]);
    digitalWrite(latchPin2, HIGH);
    }
    oldSeq = 0;
    break;
   }
}

You need to change the state when the switch TRANSITIONS from inactive to active (what that is depends on whether there is a pullup or not). The key is that you are looking for the change in the switch, not what the switch is currently.

Remember your processor goes through loop() many of thousands of times each second.

oh you're right.. Thanks, im going to try that.

hi, im trying to control 16 leds using 2 shift registers by pressing a button that will chenge the sequence that flash the leds. I can do it using delay but i to use this code in my project i cant use delay.. so my doubt is how can i do it.. I've been trying but it doesnt work how it is supossed to ..
Here goes the code :

const int buttonLed_Pin = 12;

int latchPin1 = 2;                  //SHIFT REGISTERS
int clockPin1 = 3;
int dataPin1 = 4;
int latchPin2 = 5;
int clockPin2 = 6;
int dataPin2 = 7;

int array1[8] = {1,2,4,8,16,32,64,128};  // LEDS SEQUENCES
int array2[8] = {1,2,4,8,16,32,64,128};
int array3[8] = {128,64,32,16,8,4,2,1};
int array4[8] = {128,64,32,16,8,4,2,1};
int array5[8] = {128,64,32,16,8,4,2,1};
int array6[8] = {1,2,3,8,16,32,64,128};


const int ledsInterval = 100; 
const int buttonLedInterval = 300;
unsigned long currentMillis = 0;
unsigned long previousLedMillis = 0;
unsigned long previousButtonMillis1 = 0;

int buttonPushCounter1 = 0;
int buttonState1=0;
int lastButtonState1 = 0;
int lastPushCounter1 = 0;

void setup() {
Serial.begin(9600);

  pinMode(buttonLed_Pin, INPUT);
  pinMode(latchPin1, OUTPUT);
  pinMode(clockPin1, OUTPUT);
  pinMode(dataPin1, OUTPUT);
  
  pinMode(latchPin2, OUTPUT);
  pinMode(clockPin2, OUTPUT);
  pinMode(dataPin2, OUTPUT);

}

void loop() {
  // put your main code here, to run repeatedly:
currentMillis = millis();
checkStates();
checkButtons();
ledSequences();
Serial.println(buttonPushCounter1); 
}

void checkStates(){
  buttonState1= digitalRead(buttonLed_Pin);
}

void checkButtons() {

 if (millis() - previousButtonMillis1 >= buttonLedInterval) {
  if (buttonState1!= lastButtonState1){
    if (buttonState1 ==HIGH) {
     buttonPushCounter1 = lastPushCounter1 +1;
     previousButtonMillis1 += buttonLedInterval;
 }
}
lastButtonState1 = buttonState1;
}
}

void ledSequences(){

 switch (buttonPushCounter1) {
  case 1:

  if( currentMillis - previousLedMillis >= ledsInterval){
    for(int i = 0; i < 8; i++)
    {
    digitalWrite(latchPin1, LOW);
    digitalWrite(latchPin2, LOW);
    
   
    shiftOut(dataPin1, clockPin1, MSBFIRST, array1[i]);
    shiftOut(dataPin2, clockPin2, MSBFIRST, array2[i]);
  
    digitalWrite(latchPin1, HIGH);
    digitalWrite(latchPin2, HIGH);
    }
    previousLedMillis += ledsInterval;
    lastPushCounter1 = buttonPushCounter1;
  }

 break;
 case 2:
  for(int i = 0; i < 8; i++)
    {
    digitalWrite(latchPin1, LOW);
    digitalWrite(latchPin2, LOW);
   
    shiftOut(dataPin1, clockPin1, MSBFIRST, array3[i]);
    shiftOut(dataPin2, clockPin2, MSBFIRST, array4[i]);
   
    digitalWrite(latchPin1, HIGH);
    digitalWrite(latchPin2, HIGH);
    delay(200);
}
 lastPushCounter1 = buttonPushCounter1;
 break;

  case 3 :
  for(int i = 0; i < 8; i++)
    {
    digitalWrite(latchPin1, LOW);
    shiftOut(dataPin1, clockPin1, MSBFIRST, array5[i]);
    digitalWrite(latchPin1, HIGH);
    delay(100);
    digitalWrite(latchPin2, LOW);
    shiftOut(dataPin2, clockPin2, MSBFIRST, array6[i]);
    digitalWrite(latchPin2, HIGH);
    }
    lastPushCounter1 = 0;
    break;
   }
}

Case 1 is how im trying to do it without delay.. case 2 and 3 are using delays which im trying to delete. Leds are supposed to flash one at a time.
Any help is appreciated, thanks in advance.

Hi. I have reported this topic to the moderators. You are cross-posting which is against forum rules. The moderators will merge the topics. Be careful not to do this again.

Please perform auto-format on your code before you post it again.

To perform your animations without delay(), you must remove the for() loop. Instead of the loop control variable 'i', you must make some new global variable which replaces 'i'. You could name it 'animationStep' for example. When the time arrives to update the LEDs, increment animationStep and then check to see if it has exceeded the maximum value, and if so, set it to the minimum value.

Question: why are you not chaining your shift registers so that only one data, one clock and one latch pin is required?

When you call ledSequences() you need to update the LEDs only one step. For this you need to store the current step in a global variable and update it only when the time is up.

int ledidx = 0;

void ledSequences(){

 switch (buttonPushCounter1) {
  case 1:

  if( currentMillis - previousLedMillis >= ledsInterval){
    ledidx++;
    if (ledidx >= 8) {
        ledidx  = 0;
    }
    
    digitalWrite(latchPin1, LOW);
    digitalWrite(latchPin2, LOW);
   
   
    shiftOut(dataPin1, clockPin1, MSBFIRST, array1[ledidx]);
    shiftOut(dataPin2, clockPin2, MSBFIRST, array2[ledidx]);
 
    digitalWrite(latchPin1, HIGH);
    digitalWrite(latchPin2, HIGH);

    previousLedMillis += ledsInterval;
    lastPushCounter1 = buttonPushCounter1;
  }

 break;