#include <Wire.h> // Inclui a biblioteca para comunicação I2C
#include <LiquidCrystal_I2C.h> // Inclui a biblioteca para controle do display LCD
LiquidCrystal_I2C lcd(0x27, 16, 2); // Incia o LCD (endereço 0x27)
// Definição dos pinos para os LEDs do semáforo dos veículos
#define VermelhoCarro 13
#define AmareloCarro 12
#define VerdeCarro 11
// Definição dos pinos para os LEDs do semáforo dos pedestres
#define VermelhoPedestre 10
#define VerdePedestre 9

#define BotaoPedestre 2 // Define o pino para o botão do semáforo dos pedestres
#define Buzzer 6 // Define o pino para o buzzer
#define BotaoMulta 3 // Define o pino para o botão da multa
unsigned long UltimaAbertura = 0; // Variável para armazenar a última vez que o semáforo de pedestres foi aberto


void setup() {
  Serial.begin(115200); 
  // Configura os pinos como entrada ou saída
  pinMode(VermelhoCarro, OUTPUT);
  pinMode(AmareloCarro, OUTPUT);
  pinMode(VerdeCarro, OUTPUT);
  pinMode(VermelhoPedestre, OUTPUT);
  pinMode(VerdePedestre, OUTPUT);
  pinMode(BotaoPedestre, INPUT_PULLUP);
  pinMode(Buzzer, OUTPUT);
  pinMode(BotaoMulta, INPUT_PULLUP);

  // Ajuste do display
  lcd.init(); // Inicia a comunicação com o display 
  lcd.backlight(); // Liga a luz de fundo 
  lcd.clear(); // Limpa o display
  lcd.setCursor(0, 0); // Ajusta a posição do cursor para a coluna 0 e a linha 0

  // Inicia o semáforo no estado verde para os veículos e vermelho para os pedestres
  digitalWrite(VermelhoCarro, LOW);
  digitalWrite(AmareloCarro, LOW);
  digitalWrite(VerdeCarro, HIGH);
  digitalWrite(VermelhoPedestre, HIGH);
  digitalWrite(VerdePedestre, LOW);
}


void loop() {
  EstadoDoSemaforo(); // Função para atualizar o estado do semáforo
  BotaoDoPedestre(); // Função responsável por verificar se o botão do pedestre foi pressionado
  ContaMultas(); // Função que atualiza a contagem de multas
}

void EstadoDoSemaforo() {
  static unsigned long tempoSinal = 0; // Variável para armazenar o tempo do último estado do semáforo 
  if (millis() - tempoSinal >= 30000) { // Se passaram 30 segundos desde o ultimo estado do semáforo 
    tempoSinal = millis(); // Atualiza o tempo do ultimo estado do semáforo

    //Semáforo no amarelo para os veículos e vermelho para os pedestres
    digitalWrite(VermelhoCarro, LOW);
    digitalWrite(AmareloCarro, HIGH);
    digitalWrite(VerdeCarro, LOW);
    digitalWrite(VermelhoPedestre, HIGH);
    digitalWrite(VerdePedestre, LOW);
    delay(6000); // Espera 6 segundos 

    //Semáforo no vermelho para os veículos e verde para os pedestres
    digitalWrite(VermelhoCarro, HIGH);
    digitalWrite(AmareloCarro, LOW);
    digitalWrite(VerdeCarro, LOW);
    digitalWrite(VermelhoPedestre, LOW);
    digitalWrite(VerdePedestre, HIGH);

   // Emite um som no buzzer com frequência variável durante 30 segundos
    unsigned long temposom = millis(); // Variável para armazenar o tempo atual
    while (millis() - temposom < 30000) { // Enquanto a diferença entre o tempo atual e o tempo inicial for menor que 30 segundos
      for (int i = 500; i <= 2000; i += 100) { // Varia a frequênica do sinal
        tone(Buzzer, i, 100); // Emite um som no buzzer 
        delay(100); // Espera 0.1 segundos
      }
    }
    noTone(Buzzer); // Para o som do buzzer

    //Semáforo no verde para os veículos e vermelho para os pedestres
    digitalWrite(VermelhoCarro, LOW);
    digitalWrite(AmareloCarro, LOW);
    digitalWrite(VerdeCarro, HIGH);
    digitalWrite(VermelhoPedestre, HIGH);
    digitalWrite(VerdePedestre, LOW);
    delay(30000); // Espera 30 segundos
  }
}
void BotaoDoPedestre() {
  unsigned long TempoAtual = millis(); // Variável que obtém o tempo atual

  // Se o botão estiver pressionado e o tempo desde a última abertura estiver entre 10 segundos e 3 minutos
  if (!digitalRead(BotaoPedestre) && (TempoAtual - UltimaAbertura >= 10000) && (TempoAtual - UltimaAbertura <= 180000)) {
    UltimaAbertura = TempoAtual; // Atualiza a última vez que o semáforo dos pedestres foi aberto
    tone(Buzzer, 1000); // Emite um som para confirmar a solicitação
    delay(100); // Aguarda 0.1 segundos
    noTone(Buzzer); // Para o som do buzzer
  }
  else if (!digitalRead(BotaoPedestre)) {
    tone(Buzzer, 1000, 100); // Emite um som quando o botão dos pedestres é pressionado
  }
}

void ContaMultas() {
  static int Multa = 0; // Variável para o número de multas
  static int Foto = 0; // Variável para o número de multas
  static unsigned long Repique = 0; // Variável para armazenar o último repique 
  static bool Apertou = digitalRead(BotaoMulta); //Váriavel para armazenar o estado do botão
  
  // Se o botão for apertado e o tempo do último repique for maior que 0.3 segundos
  if (Apertou && !digitalRead(BotaoMulta) && ((millis() - Repique) > 300)) { 
    Multa++; // Variável para o número de multas
    Foto++; // Variável para a quantidade de fotos tiradas
    Repique = millis();
  }
  lcd.setCursor(0, 0); // Ajusta a posição do cursor para a coluna 0 e a linha 0
  lcd.print("Fotos: " + String(Foto)); // Exibe o número de fotos tiradas no display
  lcd.setCursor(0, 1); // Ajusta a posição do cursor para a coluna 0 e a linha 1
  lcd.print("Multas: " + String(Multa)); // Exibe o número de multas tiradas no display
}
$abcdeabcde151015202530fghijfghij