#include "pico/stdlib.h" // Biblioteca padrão do Pico para GPIO, timers, etc.
#include "hardware/timer.h" // Biblioteca para timers de hardware
// Definição dos pinos
const uint LED_PIN = 12; // Pino GPIO para o LED
const uint BUTTON_A_PIN = 5; // Pino GPIO para o botão A
const uint BUTTON_B_PIN = 9; // Pino GPIO para o botão B
// Constantes de configuração
const int CLICKS_REQUIRED = 5; // Número de cliques consecutivos necessários para ativar o LED
const int DEBOUNCE_DELAY_MS = 50; // Atraso em milissegundos para debounce do botão
const int MAX_CLICK_INTERVAL_MS = 500; // Tempo máximo em milissegundos entre cliques consecutivos
const int FREQ_1HZ_INTERVAL = 1000; // Intervalo em ms para frequência de 1 Hz
const int FREQ_10HZ_INTERVAL = 100; // Intervalo em ms para frequência de 10 Hz
// Variáveis de estado
bool led_on = false; // Indica se o LED está ligado ou desligado
bool led_active = false; // Indica se o LED está no estado de pisca-pisca
absolute_time_t end_time; // Armazena o tempo em que o LED deve parar de piscar
struct repeating_timer blink_timer; // Timer para controlar o pisca-pisca do LED
int click_count = 0; // Contador de cliques consecutivos
absolute_time_t last_click_time; // Armazena o tempo do último clique detectado
int blink_interval_ms = FREQ_10HZ_INTERVAL; // Intervalo do pisca-pisca (inicializado com 10Hz)
// Função de callback do timer do pisca-pisca
bool blink_timer_callback(struct repeating_timer *t) {
if (led_active) { // Verifica se o LED está no modo pisca-pisca
if (absolute_time_diff_us(get_absolute_time(), end_time) <= 0) { // Verifica se o tempo de pisca-pisca acabou
gpio_put(LED_PIN, false); // Desliga o LED
led_on = false; // Define o estado do LED como desligado
led_active = false; // Define que o LED não está mais piscando
cancel_repeating_timer(&blink_timer); // Cancela o timer do pisca-pisca
printf("LED desligado.\n"); // Imprime mensagem no console informando que o LED desligou
return false; // Indica ao timer que ele deve ser cancelado
}
led_on = !led_on; // Inverte o estado do LED
gpio_put(LED_PIN, led_on); // Atualiza o estado do LED no pino GPIO
}
return true; // Indica ao timer que ele deve continuar executando
}
// Função para iniciar o pisca-pisca
void start_blinking() {
led_on = true; // Define o estado do LED como ligado
led_active = true; // Define que o LED está no modo pisca-pisca
end_time = make_timeout_time_ms(10000); // Define o tempo para o LED piscar por 10 segundos
add_repeating_timer_ms(blink_interval_ms, blink_timer_callback, NULL, &blink_timer); // Inicia o timer do pisca-pisca com a frequência atual
printf("LED piscando na frequência de %d Hz.\n", 1000 / blink_interval_ms); // Imprime mensagem informando a frequência
}
// Função para alternar a frequência do pisca-pisca
void update_blink_frequency() {
if (blink_interval_ms == FREQ_10HZ_INTERVAL) { // Verifica se a frequência atual é 10Hz
blink_interval_ms = FREQ_1HZ_INTERVAL; // Altera para 1Hz
printf("Frequência do LED alterada para 1 Hz.\n"); // Imprime mensagem informando a alteração para 1Hz
} else {
blink_interval_ms = FREQ_10HZ_INTERVAL; // Altera para 10Hz
printf("Frequência do LED alterada para 10 Hz.\n"); // Imprime mensagem informando a alteração para 10Hz
}
if (led_active) { // Verifica se o LED está ativo (piscando)
cancel_repeating_timer(&blink_timer); // Cancela o timer atual
add_repeating_timer_ms(blink_interval_ms, blink_timer_callback, NULL, &blink_timer); // Reinicia o timer com a nova frequência
}
}
int main() {
stdio_init_all(); // Inicializa a comunicação serial para usar printf
gpio_init(LED_PIN); // Inicializa o pino do LED
gpio_set_dir(LED_PIN, GPIO_OUT); // Define o pino do LED como saída
gpio_init(BUTTON_A_PIN); // Inicializa o pino do botão A
gpio_set_dir(BUTTON_A_PIN, GPIO_IN); // Define o pino do botão A como entrada
gpio_pull_up(BUTTON_A_PIN); // Ativa o resistor de pull-up interno no pino do botão A
gpio_init(BUTTON_B_PIN); // Inicializa o pino do botão B
gpio_set_dir(BUTTON_B_PIN, GPIO_IN); // Define o pino do botão B como entrada
gpio_pull_up(BUTTON_B_PIN); // Ativa o resistor de pull-up interno no pino do botão B
last_click_time = nil_time; // Inicializa o tempo do último clique como nulo
while (true) { // Loop principal do programa
// Lógica do Botão A
if (gpio_get(BUTTON_A_PIN) == 0) { // Verifica se o botão A foi pressionado (nível lógico baixo)
sleep_ms(DEBOUNCE_DELAY_MS); // Aguarda o tempo de debounce para evitar cliques espúrios
if (gpio_get(BUTTON_A_PIN) == 0) { // Verifica novamente se o botão A está pressionado após o debounce
absolute_time_t now = get_absolute_time(); // Obtém o tempo atual
// Verifica se o clique está dentro do tempo limite (clique consecutivo)
if (is_nil_time(last_click_time) || absolute_time_diff_us(last_click_time, now) <= MAX_CLICK_INTERVAL_MS * 1000) {
click_count++; // Incrementa o contador de cliques
} else {
click_count = 1; // Reseta o contador se o tempo entre cliques for muito longo
}
last_click_time = now; // Atualiza o tempo do último clique
// Verifica se o número de cliques atingiu o limite e o LED não está ativo
if (click_count >= CLICKS_REQUIRED && !led_active) {
start_blinking(); // Inicia o pisca-pisca do LED
click_count = 0; // Reseta o contador de cliques
}
}
}
// Lógica do Botão B
if (gpio_get(BUTTON_B_PIN) == 0) { // Verifica se o botão B foi pressionado (nível lógico baixo)
sleep_ms(DEBOUNCE_DELAY_MS); // Aguarda o tempo de debounce para evitar cliques espúrios
if (gpio_get(BUTTON_B_PIN) == 0) { // Verifica novamente se o botão B está pressionado após o debounce
update_blink_frequency(); // Altera a frequência do pisca-pisca
}
}
sleep_ms(10); // Pequeno atraso para não sobrecarregar a CPU
}
return 0; // Nunca será alcançado (loop infinito)
}