#include "pico/stdlib.h"
#include "hardware/pwm.h"
#include "hardware/clocks.h"
// Definição de pinos (GPIOs)
#define LED_VERDE_CARRO 0
#define LED_AMARELO_CARRO 1
#define LED_VERMELHO_CARRO 2
#define LED_VERDE_PEDESTRE 3
#define BUZZER 4
#define BOTAO 5
// Estado do semáforo
enum EstadoSemaforo {VERDE, AMARELO, VERMELHO};
enum EstadoSemaforo estado_atual = VERDE;
// Função para configurar o PWM no buzzer
void pwm_init_buzzer(uint pin) {
// Configura o pino como saída de PWM
gpio_set_function(pin, GPIO_FUNC_PWM);
// Obter o slice do PWM associado ao pino
uint slice_num = pwm_gpio_to_slice_num(pin);
// Configurar o PWM com frequência desejada
pwm_config config = pwm_get_default_config();
pwm_config_set_clkdiv(&config, clock_get_hz(clk_sys) / (1000 * 4096)); // Frequência de 1000 Hz
pwm_init(slice_num, &config, true);
// Iniciar o PWM no nível baixo
pwm_set_gpio_level(pin, 0);
}
// Função para emitir um beep com duração especificada
void beep(uint pin, uint duration_ms) {
// Obter o slice do PWM associado ao pino
uint slice_num = pwm_gpio_to_slice_num(pin);
// Configurar o duty cycle para 50% (ativo)
pwm_set_gpio_level(pin, 2048); // Duty cycle de 50%
// Temporização
sleep_ms(duration_ms);
// Desativar o sinal PWM (duty cycle 0)
pwm_set_gpio_level(pin, 0);
// Pausa entre os beeps
sleep_ms(100); // Pausa de 100ms
}
// Função de delay com verificação do botão
void esperar_com_botao(int segundos) {
for (int i = 0; i < segundos * 10; i++) {
if (gpio_get(BOTAO) == 0) { // Se o botão for pressionado
atravessar_pedestre(); // Interrompe ciclo e faz travessia
return; // Volta ao loop principal
}
sleep_ms(100);
}
}
// Função que controla o ciclo normal do semáforo
void ciclo_normal() {
switch (estado_atual) {
case VERDE:
gpio_put(LED_VERDE_CARRO, 1);
esperar_com_botao(8); // Verde por 8 segundos
gpio_put(LED_VERDE_CARRO, 0);
estado_atual = AMARELO;
// Não usa break para seguir diretamente ao próximo estado
case AMARELO:
gpio_put(LED_AMARELO_CARRO, 1);
esperar_com_botao(5); // Amarelo por 5 segundos
gpio_put(LED_AMARELO_CARRO, 0);
estado_atual = VERMELHO;
case VERMELHO:
gpio_put(LED_VERMELHO_CARRO, 1);
esperar_com_botao(10); // Vermelho por 10 segundos
gpio_put(LED_VERMELHO_CARRO, 0);
estado_atual = VERDE;
break;
}
}
// Função para travessia de pedestre quando o botão é pressionado
void atravessar_pedestre() {
// Desliga todos os LEDs de carro
gpio_put(LED_VERDE_CARRO, 0);
gpio_put(LED_AMARELO_CARRO, 0);
gpio_put(LED_VERMELHO_CARRO, 0);
// Acende o LED amarelo do carro por 5 segundos
gpio_put(LED_AMARELO_CARRO, 1);
sleep_ms(5000);
gpio_put(LED_AMARELO_CARRO, 0);
// Acende o vermelho do carro e verde do pedestre
gpio_put(LED_VERMELHO_CARRO, 1);
gpio_put(LED_VERDE_PEDESTRE, 1);
// Emite o som do buzzer
beep(BUZZER, 500); // Emite o som por 500ms
// Mantém o estado por 15 segundos com o buzzer ativo
for (int i = 0; i < 30; i++) { // Buzzer intermitente (ciclo de 250 ms)
beep(BUZZER, 250); // Emite o som do buzzer por 250ms
sleep_ms(250); // Pausa de 250ms
}
// Desliga tudo após 15 segundos
gpio_put(LED_VERDE_PEDESTRE, 0);
gpio_put(LED_VERMELHO_CARRO, 0);
}
int main() {
stdio_init_all();
// Inicialização dos pinos
gpio_init(LED_VERDE_CARRO);
gpio_init(LED_AMARELO_CARRO);
gpio_init(LED_VERMELHO_CARRO);
gpio_init(LED_VERDE_PEDESTRE);
gpio_init(BUZZER);
gpio_init(BOTAO);
gpio_set_dir(LED_VERDE_CARRO, GPIO_OUT);
gpio_set_dir(LED_AMARELO_CARRO, GPIO_OUT);
gpio_set_dir(LED_VERMELHO_CARRO, GPIO_OUT);
gpio_set_dir(LED_VERDE_PEDESTRE, GPIO_OUT);
gpio_set_dir(BUZZER, GPIO_OUT);
gpio_set_dir(BOTAO, GPIO_IN);
gpio_pull_up(BOTAO); // Ativa pull-up interno no botão
// Inicializar o PWM no pino do buzzer
pwm_init_buzzer(BUZZER);
// Loop infinito
while (1) {
ciclo_normal(); // Executa ciclo normal do semáforo
}
}