Condição de parada pra função

Bom dia Galera!
estou desenvolvendo um programa pra acender luzes conforme uma sequencia e mudando a forma de piscar através de um botão apenas, porem quando vou mudar a sequencia e pressiono o botão, ele não muda, notei que só muda se eu pressionar somente ao finalizar a minha função que esta executando no momento. então conclui que o erro esta no fato que o void loop fica executando a função, e ele não escuta o pressionar do botão se estiver executando outra coisa, alguém sabe me dizer alguma forma de quando eu pressionar o botão, imediatamente ele pare a função que esta fazendo e execute a próxima?

segue meu código:

int led1 = 13;
int led2 = 12;
int led3 = 8;
int led4 = 7;
int buttonPin = 3;
int pressButton = 0;
int estado = 0;

void setup() {
Serial.begin(9600);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(buttonPin, INPUT);
}

void loop() {
Serial.println(estado);
pressButton = digitalRead(buttonPin);

escolha();
}

void escolha() {
if (pressButton == HIGH) {
estado++;
}
if (estado == 4) {
estado = 0;
delay(1000);
}
if (estado == 0) {
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
digitalWrite(led4, LOW);
}
if (estado == 1) {
pisca1();
}
if (estado == 2) {
pisca2();
}
if (estado == 3) {
pisca3();
}
}

void pisca1() {
digitalWrite(led1, HIGH);
delay(500);
digitalWrite(led2, HIGH);
delay(500);
digitalWrite(led3, HIGH);
delay(500);
digitalWrite(led4, HIGH);
delay(300);

digitalWrite(led1, LOW);
delay(500);
digitalWrite(led2, LOW);
delay(500);
digitalWrite(led3, LOW);
delay(500);
digitalWrite(led4, LOW);
}

void pisca2() {
digitalWrite(led1, HIGH);
digitalWrite(led4, HIGH);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
delay(200);
digitalWrite(led2, HIGH);
digitalWrite(led3, HIGH);
digitalWrite(led1, LOW);
digitalWrite(led4, LOW);
delay(200);
}

void pisca3() {
digitalWrite(led1, HIGH);
digitalWrite(led2, HIGH);
digitalWrite(led3, LOW);
digitalWrite(led4, LOW);
delay(200);
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, HIGH);
digitalWrite(led4, HIGH);
delay(200);
}

Vê o exemplo Blink without delay e retira todos os delay() do teu código e vais ver que funciona.

Obrigado!! me botasse no caminho certo. o/

Não to conseguindo fazer vários leds piscar em tempos diferentes com essas funções que você me indicou.

Como fizeste o código? Admito que não é simples fazer este tipo de sincronização com millis, mas não é impossível.

Coloca aqui o código e eu vejo o que estará a faltar.

Segue o código, não sei como vou fazer pra calcular dois tempos diferentes usando o blink without delay

const int pinoLed1 = 13;
const int pinoLed2 = 12;
const int pinoLed3 = 8;
const int pinoLed4 = 7;
const int pinoBotao = 3;
const long intervalo = 300;
const long intervalo2 = 500;
const long intervalo3 = 1000;
unsigned long tempoAnterior = 0;
int estado = 0;
int pressionado;

unsigned long tempo;

int ledEstado = LOW;

void setup() {
Serial.begin(9600);
pinMode(pinoLed1, OUTPUT);
pinMode(pinoLed2, OUTPUT);
pinMode(pinoLed3, OUTPUT);
pinMode(pinoLed4, OUTPUT);
pinMode(pinoBotao, INPUT);
}

void loop() {
tempo = millis();
pressionado = digitalRead(pinoBotao);
Serial.println(estado);

escolha();
}

void escolha() {
if (pressionado == HIGH) {
estado++;
delay(300);
}
if (estado == 0) {
digitalWrite(pinoLed1, LOW);
digitalWrite(pinoLed2, LOW);
digitalWrite(pinoLed3, LOW);
digitalWrite(pinoLed4, LOW);
}
if (estado == 1) {
pisca1();
}
/if (estado == 2) {
pisca2();
}
if (estado == 3) {
pisca3();
}
/
if (estado == 4) {
estado = 0;
}
}

void pisca1() {
if (tempo - tempoAnterior >= intervalo) {
tempoAnterior = tempo;
digitalWrite(pinoLed1, HIGH);
}
}

/*void pisca2() {
digitalWrite(led1, HIGH);
digitalWrite(led4, HIGH);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
delay(200);
digitalWrite(led2, HIGH);
digitalWrite(led3, HIGH);
digitalWrite(led1, LOW);
digitalWrite(led4, LOW);
delay(200);
}

void pisca3() {
digitalWrite(led1, HIGH);
digitalWrite(led2, HIGH);
digitalWrite(led3, LOW);
digitalWrite(led4, LOW);
delay(200);
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, HIGH);
digitalWrite(led4, HIGH);
delay(200);
}*/

Com várias variáveis??

void pisca1() {
  if (tempo - tempoPisca1 >= intervalo) {
    tempoPisca1 = tempo;
    digitalWrite(pinoLed1, HIGH);
  }
}


void pisca2() {
  if (tempo - tempoPisca2 >= intervalo) {
    tempoPisca2 = tempo;
    digitalWrite(pinoLed2, HIGH);
  }
}

Beleza, vou tentar no sábado e retorno, muito obrigado por estar tirando teu tempo pra tentar me ajudar,

Outra sugestão é abolir todos os delays
Para programas em tempo real como esta fazendo não se deve usar.
Sempre use medir o tempo desde a ultima vez.
Por exemplo para o botão que seleciona use algo similar a isso:

unsigned long tempoUltimaLeituraBotaoProcesso = 0;

void lerBotaoProcesso() {
if (millis() - tempoUltimaLeituraBotaoProcesso >= 300 && digitalRead(pinoBotao) == LOW) {
tempoUltimaLeituraBotaoProcesso = millis();
estado++;
if (estado > 3)
estado = 0;
}
}

Para piscar os leds o mesmo, por exemplo.
void piscarLed2() {
if (millis() - tempoUltimaVariacaoLed >= 200) {
tempoUltimaVariacaoLed = millis();
led = 1 - led;
if (led == 1) {
digitalWrite(led1, HIGH);
digitalWrite(led4, HIGH);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
}
if (led == 0) {
digitalWrite(led2, HIGH);
digitalWrite(led3, HIGH);
digitalWrite(led1, LOW);
digitalWrite(led4, LOW);
}
}
}

Algo nessas linhas acho que ficaria melhor para vc.