#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Criação do objeto do display LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);
// ------------------------- Definição dos pinos -------------------------
#define CAR_VERDE 17 // LED verde dos carros
#define CAR_AMARELO 18 // LED amarelo dos carros
#define CAR_VERMELHO 19 // LED vermelho dos carros
#define PED_VERDE 5 // LED verde pedestre
#define PED_VERMELHO 4 // LED vermelho pedestre
#define BOTAO 16 // Botão pedestre
#define BUZZER 15 // Buzzer
#define LDR 33 // Sensor de luminosidade
#define POT 26 // Potenciômetro para ajuste de tempo
#define TRIGGER 14 // Sensor ultrassônico trigger
#define ECHO 27 // Sensor ultrassônico echo
#define LEDBR 25 // LED branco para sinalizar multa
// ------------------------- Variáveis de tempo -------------------------
unsigned long T_AMARELO = 30000; // Tempo do sinal amarelo
unsigned long T_VERMELHO; // Tempo do sinal vermelho (modo 3)
unsigned long T_Atual; // Tempo atual do loop
unsigned long Tempo = 0; // Variável auxiliar de tempo
unsigned long tchico = 0; // Auxiliar para atualização do LCD
// ------------------------- Controle de modos -------------------------
int modo = 0; // Modos do semáforo: 0=default, 1=aguarde, 2=amarelo, 3=pedestre
int i = 0; // Contagem de acionamentos do botão
// ------------------------- Modo 3 - Pedestres -------------------------
unsigned long T_Modo_3 = 40000; // Tempo fixo para atravessar
unsigned long iniciomodo3 = 0; // Momento em que o modo 3 inicia
unsigned long ultimosom = 0; // Auxiliar para beeps progressivos
bool buzzerligado = false; // Estado do buzzer
// ------------------------- Flags de inicialização -------------------------
bool iniciou0 = false; // Flag para iniciar modo 0
bool iniciou1 = false; // Flag para iniciar modo 2
bool iniciou2 = false; // Flag para iniciar modo 3
// ------------------------- Lógica de multas -------------------------
int CONTADOR_MULTAS = 0; // Contador de multas
bool MULTA = false; // Flag indicando se já multou
bool FLASH_ATIVO = false; // Flag do flash do LED branco
const unsigned long DURACAO_FLASH = 500; // Tempo de flash em ms
unsigned long TEMPO_FLASH = 0; // Marca o momento do flash
unsigned long T_Resto; // Tempo restante do modo
// ------------------------- Controle de contagem regressiva -------------------------
//int T_Resto = 0; // Segundos restantes para pedestres
unsigned long utss = 0; // Última atualização do contador de segundos
void setup() {
Serial.begin(115200);
//------------------------- Configuração de pinos -------------------------
pinMode(CAR_VERMELHO, OUTPUT);
pinMode(CAR_AMARELO, OUTPUT);
pinMode(CAR_VERDE, OUTPUT);
pinMode(PED_VERDE, OUTPUT);
pinMode(PED_VERMELHO, OUTPUT);
pinMode(BOTAO, INPUT_PULLUP); // Botão com pull-up interno
pinMode(BUZZER, OUTPUT);
pinMode(LDR, INPUT);
pinMode(TRIGGER, OUTPUT);
pinMode(ECHO, INPUT);
pinMode(LEDBR, OUTPUT);
randomSeed(analogRead(LDR)); // Inicializa gerador de números aleatórios com LDR
//------------------------- Inicialização do LCD -------------------------
lcd.init();
lcd.backlight();
}
void loop() {
float d; // Distância do sensor ultrassônico
float tchegada; // Tempo do pulso do sensor ultrassônico
static unsigned long tpulso = 0; // Auxiliar para pulso do sensor
static int passoupelosinal = 0; // Flag para detectar passagem do pedestre
static int passoupelosinall = 0; // Contagem auxiliar para evitar loop
delay(10); // Pequeno delay para estabilidade
//------------------------- Leitura do LDR -------------------------
int leituraLDR = analogRead(LDR);
int brilho = map(leituraLDR, 32, 4095, 50, 255); // Ajusta brilho dos LEDs
// -------------------- MODO 0: Default --------------------
if (modo == 0) {
analogWrite(CAR_VERDE, brilho); // Carros verdes
analogWrite(CAR_AMARELO, 0); // Carros amarelos desligados
analogWrite(CAR_VERMELHO, 0); // Carros vermelhos desligados
analogWrite(PED_VERDE, 0); // Pedestres verdes desligados
analogWrite(PED_VERMELHO, brilho); // Pedestres vermelhos ligados
analogWrite(LEDBR, 0); // LED branco desligado
// Mensagem inicial no LCD
if (!iniciou0) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Aperte o botao");
lcd.setCursor(0, 1);
lcd.print("para atravessar");
iniciou0 = true;
}
//-------------------- Leitura do botão --------------------
if (!digitalRead(BOTAO)) { // Se botão pressionado
unsigned long baseTempo = map(analogRead(POT), 32, 4095, 10000, 60000);
int variacao = random(-5000, 5000); // Pequena variação aleatória
T_AMARELO = constrain(baseTempo + variacao, 10000, 60000);
iniciou0 = false;
T_Atual = millis();
Tempo = T_Atual;
tone(BUZZER, 800, 100); // Beep curto
i++;
Serial.println("Botao acionado " + String(i) + " vezes");
modo = 1; // Avança para modo 1
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Aguarde");
}
}
// -------------------- MODO 1: Aguarde --------------------
else if (modo == 1) {
analogWrite(CAR_VERDE, brilho);
analogWrite(CAR_AMARELO, 0);
analogWrite(CAR_VERMELHO, 0);
analogWrite(PED_VERDE, 0);
analogWrite(PED_VERMELHO, brilho);
T_Atual = millis();
// Atualiza LCD a cada segundo
if (millis() - tchico > 1000) {
tchico = millis();
lcd.setCursor(0, 1);
lcd.print(String((T_AMARELO - (millis() - Tempo)) / 1000) + "s ");
}
if (T_Atual - Tempo > T_AMARELO) {
Tempo = T_Atual;
modo = 2; // Avança para modo 2
}
}
// -------------------- MODO 2: Amarelo --------------------
else if (modo == 2) {
analogWrite(CAR_VERDE, 0);
analogWrite(CAR_AMARELO, brilho);
analogWrite(CAR_VERMELHO, 0);
analogWrite(PED_VERDE, 0);
analogWrite(PED_VERMELHO, brilho);
if (!iniciou1) {
iniciou1 = true;
T_Atual = millis();
}
// Espera 2 segundos antes de liberar pedestres
if (millis() - T_Atual >= 2000) {
Tempo = T_Atual;
iniciomodo3 = T_Atual; // Marca início do modo 3
ultimosom = T_Atual;
buzzerligado = false;
iniciou1 = false;
modo = 3; // Avança para modo 3
}
}
// -------------------- MODO 3: Pedestres --------------------
else if (modo == 3) {
analogWrite(CAR_VERDE, 0);
analogWrite(CAR_AMARELO, 0);
analogWrite(CAR_VERMELHO, brilho); // Carros parados
analogWrite(PED_VERDE, brilho); // Pedestres atravessando
analogWrite(PED_VERMELHO, 0);
T_Atual = millis();
//-------------------- Inicialização do modo 3 --------------------
if (!iniciou2) {
iniciou2 = true;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Avance");
T_VERMELHO = map(analogRead(POT), 32, 4095, 40000, 10000);
int variacao = random(-5000, 5000);
T_VERMELHO = constrain(T_VERMELHO + variacao, 10000, 40000);
T_Resto = T_VERMELHO / 1000;
utss = T_Atual;
}
//-------------------- Atualização do LCD --------------------
if (T_Atual - utss >= 1000) {
utss = T_Atual;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Avance");
if (T_Resto > 0) T_Resto--;
lcd.setCursor(0, 1);
lcd.print(String(T_Resto) + "s Multas:" + String(CONTADOR_MULTAS));
}
//-------------------- Sensor Ultrassônico --------------------
digitalWrite(TRIGGER, 1);
if (micros() - tpulso >= 10) {
tpulso = micros();
digitalWrite(TRIGGER, 0);
}
tchegada = pulseIn(ECHO, 1);
d = (340.0 / 2) * (tchegada / 1000000.0);
//-------------------- Lógica de multas --------------------
if (passoupelosinal == 0 && (d < 2.01)) {
passoupelosinal = 1;
if (!FLASH_ATIVO && !MULTA) {
CONTADOR_MULTAS++;
MULTA = true;
analogWrite(LEDBR, brilho);
FLASH_ATIVO = true;
TEMPO_FLASH = millis();
Serial.println("Total de multas: " + String(CONTADOR_MULTAS));
}
passoupelosinall++;
} else if (passoupelosinal == 1 && d > 2.1) {
passoupelosinal = 0;
MULTA = false;
}
if (FLASH_ATIVO && (millis() - TEMPO_FLASH >= DURACAO_FLASH)) {
analogWrite(LEDBR, 0);
FLASH_ATIVO = false;
}
//-------------------- Beeps progressivos --------------------
unsigned long T_Total = T_Atual - iniciomodo3;
unsigned long intersom = map(T_Total, 0, T_VERMELHO, 800, 150);
if (!buzzerligado && T_Atual - ultimosom >= intersom) {
tone(BUZZER, 1000);
buzzerligado = true;
ultimosom = T_Atual;
}
if (buzzerligado && T_Atual - ultimosom >= 10) {
noTone(BUZZER);
buzzerligado = false;
}
//-------------------- Final do modo 3 --------------------
if (T_Total >= T_VERMELHO) {
iniciou2 = false;
modo = 0; // Retorna para modo 0
noTone(BUZZER);
buzzerligado = false;
analogWrite(LEDBR, 0); // Desliga LED branco
}
}
}