Problemas al encender LEDs con Millis. [SOLUCIONADO]

Hola buen día, mi problema es el siguiente: "Encienda 3 leds con un pulsador, la secuencia es; encender led 1 luego espera 3 segundos, enciende led 2 espera 3 segundos, enciende led 3, la secuencia se puede detener en cualquier momento usando un segundo pulsador", ya use millis pero, a la hora de encender el tercer led, no lo hace, y no entiendo por que no, según mi logica todo esta correcto, hasta probe en usar un segundo tiempo para que el tercer retardo tenga un tiempo aparte de 6s y entre luego de que 3s se haya encendido el led 2.
Espero puedan me puedan ayudar.. :confused:

Adjunte el codigo.

int led1 = 4;
int led2 = 5;
int led3 = 6;
int inicio = 2;
int paro = 3;
int a,b,c,d,e,f;
int estado1=0, estado2=0, estado3=0;
long tiempoantes=0;
long intervalo=3000;

void setup() {
  pinMode(inicio, INPUT);
  pinMode(paro, INPUT);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  
}

void loop() {
a = digitalRead(inicio);
b = digitalRead(paro);
unsigned long tiempoactual = millis();

if(b==0){
  if(a==1){
    estado1=1;
    tiempoantes=tiempoactual; //Iguale el tiempo aquí porque, millis sobrepasaria el tiempo antes de pulsar el botón.
    }
  if(tiempoactual-tiempoantes>=intervalo && estado1==1){
    estado2=1;
    tiempoantes=tiempoactual;
    }
  if(tiempoactual-tiempoantes>=intervalo && estado2==1){
    estado3=1;
    tiempoantes=tiempoactual;
    }
  }
 else if(b==1){
  estado1=0;
  estado2=0;
  estado3=0;
  }

  digitalWrite(led1, estado1);
  digitalWrite(led2, estado2);
  digitalWrite(led3, estado3);

}

Si nos fijamos esta parte del programa...

  if(tiempoactual-tiempoantes>=intervalo && estado1==1){
    estado2=1;
    tiempoantes=tiempoactual;
    }
  if(tiempoactual-tiempoantes>=intervalo && estado2==1){
    estado3=1;
    tiempoantes=tiempoactual;
    }

... en el primer if se está verificando si ha transcurrido el tiempo necesario y si estado1 está activo. Si es así se activa estdo2 y "se pone a cero" el tiempo transcurrido al hacer que tiempoantes sea igual a tiempoactual. Acto seguido se evalúa el siguente if, que trata de ver si ha transcurido el tiempo necesario y si estado2 está activo. Recordemos que justo antes se ha "puesto a cero" el tiempo transcurrido porque ya había pasado ese tiempo y estado1 estaba activo, activándose a su vez estado2 aunque ya estuviera activo. Con lo que nunca se va a cumplir el segundo if porque siempre se evalúa antes el primero y "pondrá a cero" el tiempo transcurrido justo cuando se necesita para que se cumpla el segundo condicional.

Una posible solución es añadir otra premisa al primer condicional para que se cumpla sólo si estado2 no está activo. Quedando esa parte del pragrama así:

 if(tiempoactual-tiempoantes>=intervalo && estado1==1 && estado2 != 1){
    estado2=1;
    tiempoantes=tiempoactual;
    }
  if(tiempoactual-tiempoantes>=intervalo && estado2==1){
    estado3=1;
    tiempoantes=tiempoactual;
    }

Otra posible solución es invertir los if. Quedando esa parte del programa así:

  if(tiempoactual-tiempoantes>=intervalo && estado2==1){
    estado3=1;
    tiempoantes=tiempoactual;
    }
  if(tiempoactual-tiempoantes>=intervalo && estado1==1){
    estado2=1;
    tiempoantes=tiempoactual;
    }

Pero la solución más segura es tener una variable estado para controlar el "estado del conjunto" ("máquina de estados"). Que, por ejemplo, valga 0 para indicar que no hay nada encendido, 1 para indicar que sólo está encendido el primer LED, 2 para cuando están encendidos los dos primeros y 3 para indicar que están encendidos los tres. Si lo hicieras así, además de otros cambios, esa parte del código debería de ser algo tal que así:

  if(tiempoactual-tiempoantes>=intervalo && estado==1){
    estado=2; // Cambiamos de estado
    estado2=1; // El LED 2 ha de estar encendido
    tiempoantes=tiempoactual;
    }
  if(tiempoactual-tiempoantes>=intervalo && estado==2){
    estado=3; // Cambiamos de estado
    estado3=1; // El LED 3 ha de estar encendido
    tiempoantes=tiempoactual;
    }

El uso de esa nueva variable te permitiría incluso programar fácilmente seguencias más complejas. Por ejemplo: que una vez encendidos los tres, se fueran apagando uno a uno cada tres segundos. 4 indicaría que se ha apagado el primero, 5 que se han apagado dos. Y 0 que vuelven a estar todos apagados.

Nota: creo que el programa, tal cual lo tienes ahora, si mantienes presionado el primer pulsador, transcurridos los tres segundos, no se enciende el segundo LED. Han de transcurrir tres segundos desde que sueltas el pulsador y se enciende el segundo LED.

Muchas gracias,me funcionaron tus 3 soluciones, me quedo claro, el porque pasaba eso..., ademas gracias por tu idea de "maquina de estados", me ayudara mucho con proyectos mas complejos que tenga que hacer :slight_smile: .