void s1_routine();
void s2_routine();
void s3_routine();
void sem_state(int estado);
void IRAM_ATTR s1_change();
void IRAM_ATTR s2_change();
void IRAM_ATTR s3_change();
void bt_verify();
enum {
SEM_A_R = 23,
SEM_A_Y = 22,
SEM_A_G = 21,
SEM_B_R = 19,
SEM_B_Y = 18,
SEM_B_G = 5,
SEM_C_R = 4,
SEM_C_G = 0,
SEM_D_R = 2,
SEM_D_G = 15,
S1 = 34,
S2 = 32,
S3 = 35
};
enum {
GR, //Semaforo A = Green, e semaforo B = Red
YR, //Semaforo A = Yellow, e semaforo B = Red
RG, //Semaforo A = Red, e semaforo B = Green
RY //Semaforo A = Red, e semaforo B = Yellow
}; //os demais leds/semaforos acendem de acordo com o padrão
volatile bool s1_flag = LOW;
volatile bool s2_flag = LOW;
volatile bool s3_flag = LOW;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(SEM_A_R, OUTPUT);
pinMode(SEM_A_Y, OUTPUT);
pinMode(SEM_A_G, OUTPUT);
pinMode(SEM_B_R, OUTPUT);
pinMode(SEM_B_Y, OUTPUT);
pinMode(SEM_B_G, OUTPUT);
pinMode(SEM_C_R, OUTPUT);
pinMode(SEM_C_G, OUTPUT);
pinMode(SEM_D_R, OUTPUT);
pinMode(SEM_D_G, OUTPUT);
pinMode(S1, INPUT);
attachInterrupt(digitalPinToInterrupt(S1), s1_change, RISING);
pinMode(S2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(S2), s2_change, FALLING);
pinMode(S3, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(S3), s3_change, FALLING);
/*
digitalWrite(SEM_A_R, HIGH);
digitalWrite(SEM_A_Y, HIGH);
digitalWrite(SEM_A_G, HIGH);
digitalWrite(SEM_B_R, HIGH);
digitalWrite(SEM_B_Y, HIGH);
digitalWrite(SEM_B_G, HIGH);
digitalWrite(SEM_C_R, HIGH);
digitalWrite(SEM_C_G, HIGH);
digitalWrite(SEM_D_R, HIGH);
digitalWrite(SEM_D_G, HIGH);
delay(5000);
*/
}
void loop() {
//para cada estado foi usado um for de 1 em 1 segundo
//para verificar o estado dos botões no meio da interação
for(int i = 0; i < 16; i++){
sem_state(GR);
delay(500);
bt_verify();
}
for(int i = 0; i < 4; i++){
sem_state(YR);
delay(500);
bt_verify();
}
for(int i = 0; i < 16; i++){
sem_state(RG);
delay(500);
bt_verify();
}
for(int i = 0; i < 4; i++){
sem_state(RY);
delay(500);
bt_verify();
}
}
//função que acende os semaforos dependendo do padrão escolhido
void sem_state(int estado){
Serial.print("mudando estado do semafaro para: ");
digitalWrite(SEM_A_R, LOW);
digitalWrite(SEM_A_Y, LOW);
digitalWrite(SEM_A_G, LOW);
digitalWrite(SEM_B_R, LOW);
digitalWrite(SEM_B_Y, LOW);
digitalWrite(SEM_B_G, LOW);
digitalWrite(SEM_C_R, LOW);
digitalWrite(SEM_C_G, LOW);
digitalWrite(SEM_D_R, LOW);
digitalWrite(SEM_D_G, LOW);
switch(estado){
case 0:
Serial.print("GR (A para verde, B para vermelho)\n");
digitalWrite(SEM_A_G, HIGH);
digitalWrite(SEM_B_R, HIGH);
digitalWrite(SEM_C_R, HIGH);
digitalWrite(SEM_D_G, HIGH);
break;
case 1:
Serial.print("YR (A para amarelo, B para vermelho)\n");
digitalWrite(SEM_A_Y, HIGH);
digitalWrite(SEM_B_R, HIGH);
digitalWrite(SEM_C_R, HIGH);
digitalWrite(SEM_D_G, HIGH);
break;
case 2:
Serial.print("RG (A para vermelho, B para verde)\n");
digitalWrite(SEM_A_R, HIGH);
digitalWrite(SEM_B_G, HIGH);
digitalWrite(SEM_C_G, HIGH);
digitalWrite(SEM_D_R, HIGH);
break;
case 3:
Serial.print("RY (A para vermelho, B para amarelo)\n");
digitalWrite(SEM_A_R, HIGH);
digitalWrite(SEM_B_Y, HIGH);
digitalWrite(SEM_C_G, HIGH);
digitalWrite(SEM_D_R, HIGH);
break;
}
}
void s1_routine(){
//apaga todos os leds exceto os amarelos
int s1_state;
Serial.print("rotina 1\n");
digitalWrite(SEM_A_R, LOW);
digitalWrite(SEM_B_R, LOW);
digitalWrite(SEM_A_G, LOW);
digitalWrite(SEM_B_G, LOW);
digitalWrite(SEM_C_R, LOW);
digitalWrite(SEM_C_G, LOW);
digitalWrite(SEM_D_R, LOW);
digitalWrite(SEM_D_G, LOW);
do{ //pisca os leds amarelos de 1 em 1 segundo até o swich s1 ser desativado
digitalWrite(SEM_A_Y, HIGH);
digitalWrite(SEM_B_Y, HIGH);
delay(1000);
digitalWrite(SEM_A_Y, LOW);
digitalWrite(SEM_B_Y, LOW);
delay(1000);
s1_state = digitalRead(S1);
} while(s1_state == HIGH);
}
//rotina para o botão s2
void s2_routine(){
//(vai travar o semaforo no estado anterior independente de qual seja)
Serial.print("rotina 2\n");
delay(4000);
sem_state(RG);
delay(5000);
sem_state(RY);
}
//rotina para o botão s3
void s3_routine(){
//(vai travar o semaforo no estado anterior independente de qual seja)
Serial.print("rotina 3\n");
delay(4000);
sem_state(GR);
delay(5000);
sem_state(YR);
}
//função que verifica o estado dos botões e chama
//a respectiva rotina se algum estiver pressionado
void IRAM_ATTR s1_change(){
s1_flag = HIGH;
}
void IRAM_ATTR s2_change(){
s2_flag = HIGH;
}
void IRAM_ATTR s3_change(){
s3_flag = HIGH;
}
void bt_verify(){
if(s1_flag){
s1_routine();
s1_flag = s2_flag = s3_flag = LOW; //reseta todas as flags
return;
}
if(s2_flag){
s2_routine();
s2_flag = LOW;
}
if(s3_flag){
s3_routine();
s3_flag = LOW;
}
}