#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/timer.h"
#define LED_R 13 // Vermelho
#define LED_G 11 // Verde
#define LED_B 12 // Não utilizado
#define BUTTON 5
#define SEMAPHORE_TIMER (uint8_t[]){10, 10, 3}
static char STATES[] = {'R', 'G', 'Y'};
volatile bool pedestrian_detected = false;
volatile bool printed_on_serial = false;
volatile bool timer_adjusted_pedestrian = false;
volatile bool color_change = true;
int timer_counter = 0;
int semaphore_counter = 0;
bool timer_callback(__unused repeating_timer_t *rt) {
if (pedestrian_detected && !timer_adjusted_pedestrian) {
color_change = true;
timer_counter = 0;
semaphore_counter = 2; // Muda para amarelo
timer_adjusted_pedestrian = true;
}
else {
// Contagem regressiva nos últimos 5s do vermelho (após botão)
if (semaphore_counter == 0 && timer_adjusted_pedestrian) {
if (timer_counter >= (SEMAPHORE_TIMER[0] - 5)) {
int time_remaining = SEMAPHORE_TIMER[0] - timer_counter;
printf("Contagem regressiva: %d\n", time_remaining);
}
}
timer_counter++;
if (timer_counter >= SEMAPHORE_TIMER[semaphore_counter]) {
timer_counter = 0;
// Transição de estados
if (timer_adjusted_pedestrian && semaphore_counter == 2) {
semaphore_counter = 0; // Volta para vermelho
pedestrian_detected = false;
gpio_set_irq_enabled(BUTTON, GPIO_IRQ_EDGE_FALL, true);
}
else {
semaphore_counter = (semaphore_counter >= 2) ? 0 : semaphore_counter + 1;
}
// Resetar flag ao entrar no verde
if (semaphore_counter == 1) {
timer_adjusted_pedestrian = false;
}
color_change = true;
}
}
return true;
}
void button_callback(uint gpio, uint32_t events) {
if (semaphore_counter == 1) { // Só funciona durante o verde
pedestrian_detected = true;
gpio_set_irq_enabled(BUTTON, GPIO_IRQ_EDGE_FALL, false);
}
}
int main() {
stdio_init_all();
sleep_ms(2000);
// Configuração dos LEDs
gpio_init(LED_R);
gpio_set_dir(LED_R, GPIO_OUT);
gpio_init(LED_G);
gpio_set_dir(LED_G, GPIO_OUT);
gpio_init(LED_B);
gpio_set_dir(LED_B, GPIO_OUT);
// Configuração do botão
gpio_init(BUTTON);
gpio_set_dir(BUTTON, GPIO_IN);
gpio_pull_up(BUTTON);
// Interrupção do botão
gpio_set_irq_enabled_with_callback(BUTTON, GPIO_IRQ_EDGE_FALL, true, &button_callback);
// Timer principal
struct repeating_timer timer;
add_repeating_timer_ms(-1000, timer_callback, NULL, &timer);
while (true) {
if (pedestrian_detected && !printed_on_serial) {
printf("Botão de Pedestres acionado\n");
printed_on_serial = true;
}
if (color_change) {
printf("Sinal: ");
switch (STATES[semaphore_counter]) {
case 'R':
printf("VERMELHO\n");
gpio_put(LED_R, 1);
gpio_put(LED_G, 0);
break;
case 'G':
printf("VERDE\n");
printed_on_serial = false;
gpio_put(LED_R, 0);
gpio_put(LED_G, 1);
break;
case 'Y':
printf("AMARELO\n");
gpio_put(LED_R, 1);
gpio_put(LED_G, 1);
break;
}
color_change = false;
}
sleep_ms(100);
}
}