/* Embarcatech: 21-01-2025
Autor: Marcio Barbosa
4 - Microcontroladores - Tarefa 1 - Firmware Embarcado
exerc_2. Na questão anterior, implemente o botão B para mudar a frequência do LED para 1 Hz.
Componentes:
https://wokwi.com/projects/420893132310212609
1 x Raspberry Pi Pico W,
1 x LED (preferencialmente de cor verde)
1 x Resistor de 330 ohms
2 x Botão de pressão (push button)
*/
#include <stdio.h>
#include "pico/stdlib.h"
#define BTN_A 5 // Botão A (verde) – usado para contagem (temporizador)
#define BTN_B 6 // Botão B (azul) – altera a frequência
#define LEDPIN 13 // Pino conectado ao LED
// Variáveis globais (volatile, pois são acessadas em interrupções)
volatile int countA = 0;
volatile int countB = 0;
volatile bool led_active = false;
volatile bool reduz_Freq = false; // false: 10 Hz; true: 1 Hz
volatile int valor_freq = 0;
// Função para debounce (considera ação para os botões)
bool debounce(uint gpio) {
static uint32_t last_timeA = 0;
static uint32_t last_timeB = 0;
uint32_t current_time = to_ms_since_boot(get_absolute_time());
if (gpio == BTN_A) {
if (current_time - last_timeA > 200) { // 200 ms de debounce
last_timeA = current_time;
printf("Botão pressionado A, %d \n", countA + 1);
return true; // Valida o pressionamento
}
} else if (gpio == BTN_B) {
if (current_time - last_timeB > 200) { // 200 ms de debounce
last_timeB = current_time;
printf("\n ## Botão pressionado B, frequencia alterada para: %d \n", valor_freq);
return true; // Valida o pressionamento
}
}
return false; // Caso contrário, ignora
}
// único para tratar interrupções de ambos os botões
void gpio_btn(uint gpio, uint32_t events) {
if (gpio == BTN_A) {
if (debounce(gpio)) {
countA++;
}
}
else if (gpio == BTN_B) {
if (debounce(gpio)) {
reduz_Freq = !reduz_Freq; // Alterna entre 10 Hz e 1 Hz
}
}
}
int main() {
stdio_init_all();
// Configuração do LED
gpio_init(LEDPIN);
gpio_set_dir(LEDPIN, GPIO_OUT);
// Configuração dos botões com pull-up interno
gpio_init(BTN_A);
gpio_set_dir(BTN_A, GPIO_IN);
gpio_pull_up(BTN_A);
gpio_init(BTN_B);
gpio_set_dir(BTN_B, GPIO_IN);
gpio_pull_up(BTN_B);
// Configura a interrupção para os botões usando um única chamada.
// A partir da primeira chamada o callback é registrado globalmente.
gpio_set_irq_enabled_with_callback(BTN_A, GPIO_IRQ_EDGE_FALL, true, &gpio_btn);
// Para os demais botões, use apenas gpio_set_irq_enabled:
gpio_set_irq_enabled(BTN_B, GPIO_IRQ_EDGE_FALL, true);
while (true) {
// Quando o botão A foi pressionado 5 vezes e o LED não está ativo
if (countA >= 5 && !led_active) {
// Reseta as contagens
countA = 0;
countB = 0;
led_active = true;
printf("## AGUARDE, LED acionado por 10 segundos \n");
uint32_t start_time = to_ms_since_boot(get_absolute_time());
uint32_t tempo = 0;
// Loop de piscar o LED durante 10 segundos
while (tempo < 10000) { // 10.000 ms = 10 segundos
// Determina a frequência conforme a variável global 'reduz_Freq'
// Se 'reduz_Freq' for true, a frequência será 1 Hz; caso contrário, 10 Hz.
int freq = (reduz_Freq ? 1 : 10);
valor_freq = 1000 / (freq * 2); // Calcula o tempo de meia onda
gpio_put(LEDPIN, 1);
sleep_ms(valor_freq);
gpio_put(LEDPIN, 0);
sleep_ms(valor_freq);
tempo = to_ms_since_boot(get_absolute_time()) - start_time;
}
led_active = false;
printf("\n ## ZERANDO AS VARIAVEIS PARA NOVO TESTE, Pressione Azul para mudar a frequencia e Pressione Verde mais 5 vezes \n");
}
}
return 0;
}