Semaforo con boton- que solo tenga que apretar una vez

Tengo que realizar un programa para un semáforo coordinado con otro de paso de peatón.
Hay que poner un tiempo mínimo de paso de coches antes de activar el paso de peatones mediante un botón.
El tema es que si aprieto el botón antes de ese tiempo mínimo de paso no me guarda el estado y tengo que volverlo a apretar al pasar el tiempo mínimo de semáforo de coche en verde.

/*  SEMAFORO -Projecto: Semáforo interactivo para paso de peatones
Cuando se encuentre el semáforo en Rojo, el paso de peatones estará en verde. 
Cuando se aproxime el momento finalizar el estado rojo del semáforo, el paso de peatón parpadeará en verde pasándose finalmente a rojo, y con una pequeña latencia, 
el semáforo de vehículos pasará a verde, iniciando un nuevo bucle al pulsar un botón con la condición de que tengamos siempre un mínimo del paso de vehículos abierto . */

/** Definiciones **/
// Semaforo automóviles
int rojoCar = 13 ;
int amarilloCar = 12;
int verdeCar = 11;
// Semaforo peatón
int rojoPe = 10;
int verdePe = 9;
// Boton
int button = 2; // asignación del pin 2 variable botón accionamiento peatones.

/* Variables*/
int SafetyLatence = 1500; // (ms) Tiempo en el que ambos pasos (vehículos y peatón) permanecen en rojo.
int TimeMinVerdeCar = 5000; // (ms) Tiempo mínimo en el que el paso de vehículos se encuentra en verde.
int TiempoCruce = 5000; // (ms)tiempo permitido para que el peatón cruce. 
unsigned long previousMillis; // tiempo de cambio: variable para guardar el tiempo desde que hemos activado el paso para peatones.
int estado = false;

/* Programa */
void setup(){
 
  pinMode(rojoCar, OUTPUT);
  pinMode(amarilloCar, OUTPUT);
  pinMode(verdeCar, OUTPUT);
  pinMode(rojoPe, OUTPUT);
  pinMode(verdePe, OUTPUT);
  pinMode(button, INPUT);
 // Arranca el ciclo, estados activos (HIGH) de luz verde para vehículos y roja para peatones
  digitalWrite(verdeCar, HIGH);
  digitalWrite(rojoPe, HIGH);
}
 
void loop() {
 
  estado = digitalRead(button);
 
  if (estado == HIGH && (millis() - previousMillis) > TimeMinVerdeCar){
   cambioLuces();
  }
}
 
void cambioLuces() {
  delay (2000);
  digitalWrite(verdeCar,LOW);
  digitalWrite(amarilloCar, HIGH);
  delay(2000);
 
  digitalWrite(amarilloCar, LOW);
  digitalWrite(rojoCar, HIGH);
  delay(SafetyLatence);
 
  digitalWrite(rojoPe, LOW);
  digitalWrite(verdePe, HIGH);
  delay(TiempoCruce);
 
  for (int x=0; x<10; x++) { // El bucle for enciende el led verde de forma intermitente n veces
  digitalWrite(verdePe, HIGH);
  delay(250);
  digitalWrite(verdePe, LOW);
  delay(250);
 
  }
 
  digitalWrite(rojoPe, HIGH);
  delay(500); // Retraso de encendio del semáforo verde del auto con respecto al rojo del peatón
  digitalWrite(rojoCar, LOW);
  delay(1000);
 
  digitalWrite(verdeCar, HIGH);
 
  previousMillis = millis();
}

He estado mirando la documentación de millis() en el foro y he modificado un poco el programa.
Ahora me va. Le he añadido un segundo if.
Tengo que revisar bien lo del botón que me cuentas, pues no lo entiendo muy bien.

/*  SEMAFORO REQUERIMIENTO 3 -Projecto: Semáforo interactivo para paso de peatones
Semáforo con paso peatón: Igual que en el paso previo pero en cuanto se encuentre el semáforo en Rojo, el paso de peatones estárá en verde. 
Cuando se aproxime el momento finalizar el estado rojo del semáforo, el paso de peatón parpadeará en verde pasándose finalmente a rojo, y con una pequeña latencia, 
el semáforo de vehículos pasará a verde, iniciando un nuevo bucle. */

/** Definiciones **/
// Semaforo automóviles
int rojoCar = 13 ;
int amarilloCar = 12;
int verdeCar = 11;
// Semaforo peatón
int rojoPe = 10;
int verdePe = 9;
// Boton
int button = 2; // asignación del pin 2 variable botón accionamiento peatones.

/* Variables*/
int SafetyLatence = 1500; // (ms) Tiempo en el que ambos pasos (vehículos y peatón) permanecen en rojo.
int TiempoCruce = 5000; // (ms)tiempo permitido para que el peatón cruce.

unsigned long TimeMinVerdeCar = 5000; // (ms) Tiempo mínimo en el que el paso de vehículos se encuentra en verde.
unsigned long startTime; // variable para guardar el tiempo desde que acaba el paso para peatones y empieza el verde coches.
unsigned long finishTime; // (ms)Tiempo de fin semaforo coches verde inicio del cambio de luces.
int switchState = 0;

/* Programa */
void setup(){
 
  pinMode(rojoCar, OUTPUT);
  pinMode(amarilloCar, OUTPUT);
  pinMode(verdeCar, OUTPUT);
  pinMode(rojoPe, OUTPUT);
  pinMode(verdePe, OUTPUT);
  pinMode(button, INPUT);
 // Arranca el ciclo, estados activos (HIGH) de luz verde para vehículos y roja para peatones
  digitalWrite(verdeCar, HIGH);
  digitalWrite(rojoPe, HIGH);
}
 
void loop() {
  finishTime = millis ();
  switchState = digitalRead(button);
 
 if (switchState == HIGH && (finishTime - startTime) > TimeMinVerdeCar){
   cambioLuces();
  }
 if (switchState == HIGH && (finishTime - startTime) < TimeMinVerdeCar){
   delay (TimeMinVerdeCar);
   cambioLuces();
  } 
}
 
void cambioLuces() {
  delay (2000);
  digitalWrite(verdeCar,LOW);
  digitalWrite(amarilloCar, HIGH);
  delay(2000);
 
  digitalWrite(amarilloCar, LOW);
  digitalWrite(rojoCar, HIGH);
  delay(SafetyLatence);
 
  digitalWrite(rojoPe, LOW);
  digitalWrite(verdePe, HIGH);
  delay(TiempoCruce);
 
  for (int x=0; x<10; x++) { // El bucle for enciende el led verde de forma intermitente 9 veces
  digitalWrite(verdePe, HIGH);
  delay(250);
  digitalWrite(verdePe, LOW);
  delay(250);
  }
 
  digitalWrite(rojoPe, HIGH);
  delay(500); // Retraso de encendio del semáforo verde del auto con respecto al rojo del peatón
  digitalWrite(rojoCar, LOW);
  delay(1000);

  digitalWrite(verdeCar, HIGH); 
  startTime = millis();
}

montaje.png

Moderador: Imagen editada para que sea visible en el post

Voy a modificar lo de la resistencia para evitar devounce.
Lo de los timers por cada led ...ni idea. He estado leyendo varios artículos aquí y allá y no lo acabo de pillar. Como utilizar los timers. Yo se que algún compañero de curso hizo las interrupciones con la libreria TimerOne.
Un saludo y muchas.

no sé porque hay tanto empeño con el MEGA, cuando DUE tiene de todo.

porque el MEGA es 5V y el DUE 3.3V y la gente todavía duda de usar 3.3V. Todos los tutos son con 5V y muy pocos con 3.3V.

No se para que se habla de interrupciones en algo que solo activará algunos LEDs. Haciendo una buena máquina de estados con millis() no requieres de ninguna interrupción.
Lo sugerido por ArduMyth esta mas que bien.

Solo dire que puedes usar interrupciones aunque no vale la pena en cada pin del UNO/NANO/Mega y el que sea.
Pero no tiene sentido acá.

Todo el proyecto para mi esta mal encarado.
Si no usas maquina de estados en este caso tienes que pensar en trucos como el de las interrupciones.
Puedes aprender a programar correctamente con máquina de estados y verás que dejarás las interrupciones para otras situaciones y no esta.

Estoy de acuerdo con ArduMyth que si las tienes tmb puedes usarlas. En fin, es tu decisión

En Documentación => Indice de temas tutoriales => Maquina de estados tienes una buena introducción y luego en los comentarios hay un ejemplo de como pasar de una situación como lal tuya a otra usando millis() y máquina de estados.

El enfoque es muy diferente al uso de delay, asi que te tomará un tiempo entenderlo.

Pero imagina que el programa fluye de tal manera que le toma menos de 1mseg dar un cliclo completo. Es decir no hay delays. Ni uno solo!!!
Asi que no puedes pensar que se haga algo y luego espero a lo otro, eso ya no va.
Tienes que pensarlo como que son tareas distintas.
Veamos tu situación de las luces

Solo este parte del código para ubicarte en tema

void cambioLuces() {
  delay (2000);
  digitalWrite(verdeCar,LOW);
  digitalWrite(amarilloCar, HIGH);
  delay(2000);
 
  digitalWrite(amarilloCar, LOW);
  digitalWrite(rojoCar, HIGH);
  delay(SafetyLatence);

En este código, no hay modo de que tu arduino preste atención al peatón que presiona el botón
Porque cuando llega el cambio de luces que hace?
demoras 2 seg tal vez inutilmente.
luego Luz Verde OFF, Amarilla ON
demoras 2 seg
Amarillo OFF
ROJO ON
delay(tiempo SafetyLatence)

Okay esto mismo con algo que fluye usando maquina de estados sería asi

arrancas con un estado definido por el valor de una variable que llamemos status con el valor inicial 0
defines antes como global status = 0;

void cambioLuces() {
    swiwtch(status) {
      case 0: if (millis()-start > 2000UL) {
                  digitalWrite(verdeCar,LOW);
                  digitalWrite(amarilloCar, HIGH);
                  estado = 1;                       // cuando pasen 2 seg cambio de estado
                  start = millis();
              }
              break;
      case 1: if (millis()-start > 2000UL) {
                  digitalWrite(amarilloCar, LOW);
                  digitalWrite(rojoCar, HIGH);
                  estado = 2;
                  start = millis();
              }
              break;
      case 2: if (millis() - start > SafetyLatence) {
                  digitalWrite(rojoPe, LOW);
                  digitalWrite(verdePe, HIGH);
                  estado = 3;
                  start = millis();
              }
              break;
      case 3: if (millis() - start > TiempoCruce) {
                  // El bucle for enciende el led verde de forma intermitente 9 veces
              }
              break;
              // sigue

    }
}

Esto es una implementación parcial de tu necesidad como para que con la teoria y este empujón puedas seguir.