Acho que sua lógica de fluxo deveria ser um pouco diferente, por exemplo em vez de delay usar a função millis() e checar o botão a cada ciclo (procura nos exemplos, blink without delay).
Acho que deveria ser tipo:
Checa botão -> checa timer -> botão pressionado? S:seta variavel. -> timer atingido? S:(variavel setada? N: proxima cor, S:vai para semaforo de pedestres) -> volta ao inicio.
Entenda que checa botao e checa timer devem rodar a cada clock do uControlador, por isso é importante não usar a função delay. Durante a rotina do semaforo de pedestres pode ter delay normal