// Definição de pinos dos semáforos
int semaforo1_verde = 4;
int semaforo1_amarelo = 5;
int semaforo1_vermelho = 6;
int semaforo2_verde = 7;
int semaforo2_amarelo = 8;
int semaforo2_vermelho = 9;
// Pinos das botoeiras (usados em interrupções)
const int botoeira12 = 2; // Botoeiras 1 e 2 (Interrupt 0)
const int botoeira34 = 3; // Botoeiras 3 e 4 (Interrupt 1)
// Controle de tempo sem usar delay()
unsigned long tempoInicioFase;
int duracaoFase[] = {12, 4, 10, 12, 4, 10}; // Agora, as fases de travessia duram 10 segundos
volatile bool interrupcao_ocorrida = false;
volatile int novaFase = -1; // Indica se houve uma solicitação de mudança de fase
int faseAtual = 0;
bool faseEspecial = false; // Se verdadeiro, significa que estamos em uma fase de travessia
void setup() {
Serial.begin(9600);
// Configuração dos semáforos
pinMode(semaforo1_verde, OUTPUT);
pinMode(semaforo1_amarelo, OUTPUT);
pinMode(semaforo1_vermelho, OUTPUT);
pinMode(semaforo2_verde, OUTPUT);
pinMode(semaforo2_amarelo, OUTPUT);
pinMode(semaforo2_vermelho, OUTPUT);
// Configuração das botoeiras com interrupções
pinMode(botoeira12, INPUT_PULLUP);
pinMode(botoeira34, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(botoeira12), solicitarTravessia12, FALLING);
attachInterrupt(digitalPinToInterrupt(botoeira34), solicitarTravessia34, FALLING);
tempoInicioFase = millis();
atualizarSemaforos();
}
void loop() {
// Se houve uma interrupção, muda a fase imediatamente
if (interrupcao_ocorrida) {
interrupcao_ocorrida = false;
faseAtual = novaFase;
novaFase = -1; // Reset da variável para evitar mudanças indesejadas
tempoInicioFase = millis();
faseEspecial = true; // Marca que estamos em uma fase especial (travessia)
atualizarSemaforos();
}
// Se estamos em uma fase especial, garantir que ela dure pelo tempo necessário antes de continuar
if (faseEspecial) {
if (millis() - tempoInicioFase >= duracaoFase[faseAtual] * 1000) {
faseEspecial = false; // Volta ao ciclo normal após a travessia
avancarFase();
}
return; // Evita que o código continue rodando desnecessariamente
}
// Avança para a próxima fase após o tempo definido
if (millis() - tempoInicioFase >= duracaoFase[faseAtual] * 1000) {
avancarFase();
}
}
// Interrupções ativadas ao pressionar as botoeiras
void solicitarTravessia12() {
Serial.println("🚦 Botão B1/B2 pressionado!"); // Para depuração
if (faseAtual == 0 || faseAtual == 1) {
novaFase = 2; // Ir para fase 2 (Travessia B1/B2)
interrupcao_ocorrida = true;
}
}
void solicitarTravessia34() {
Serial.println("🚦 Botão B3/B4 pressionado!"); // Para depuração
if (faseAtual == 3 || faseAtual == 4) {
novaFase = 5; // Ir para fase 5 (Travessia B3/B4)
interrupcao_ocorrida = true;
}
}
// Avança para a próxima fase do ciclo normal
void avancarFase() {
switch (faseAtual) {
case 0: faseAtual = 1; break;
case 1: faseAtual = 2; break;
case 2: faseAtual = 3; break;
case 3: faseAtual = 4; break;
case 4: faseAtual = 5; break;
case 5: faseAtual = 0; break;
}
tempoInicioFase = millis();
atualizarSemaforos();
}
// Atualiza os semáforos conforme a fase atual
void atualizarSemaforos() {
Serial.print("Fase Atual: ");
Serial.println(faseAtual + 1);
switch (faseAtual) {
case 0: // Fase 1: Semáforo 1 Verde, Semáforo 2 Vermelho
definirSemaforos(HIGH, LOW, LOW, LOW, LOW, HIGH);
break;
case 1: // Fase 2: Semáforo 1 Amarelo, Semáforo 2 Vermelho
definirSemaforos(LOW, HIGH, LOW, LOW, LOW, HIGH);
break;
case 2: // Fase 3: Ambos Vermelhos (Travessia de B1/B2)
definirSemaforos(LOW, LOW, HIGH, LOW, LOW, HIGH);
break;
case 3: // Fase 4: Semáforo 1 Vermelho, Semáforo 2 Verde
definirSemaforos(LOW, LOW, HIGH, HIGH, LOW, LOW);
break;
case 4: // Fase 5: Semáforo 1 Vermelho, Semáforo 2 Amarelo
definirSemaforos(LOW, LOW, HIGH, LOW, HIGH, LOW);
break;
case 5: // Fase 6: Ambos Vermelhos (Travessia de B3/B4)
definirSemaforos(LOW, LOW, HIGH, LOW, LOW, HIGH);
break;
}
}
// Define os estados dos semáforos
void definirSemaforos(int s1v, int s1a, int s1r, int s2v, int s2a, int s2r) {
digitalWrite(semaforo1_verde, s1v);
digitalWrite(semaforo1_amarelo, s1a);
digitalWrite(semaforo1_vermelho, s1r);
digitalWrite(semaforo2_verde, s2v);
digitalWrite(semaforo2_amarelo, s2a);
digitalWrite(semaforo2_vermelho, s2r);
}