/*
Autor: Atenilton Santos de Souza Júnior
*/
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "ws2812b.pio.h"
// Definindo os pinos dos componentes
#define PINO_MATRIZ 7 // Pino de controle da matriz de LEDs
#define NUM_LEDS 25 // Número total de LEDs na matriz
#define BOTAO_A 5 // Pino do Botão A
#define BOTAO_B 6 // Pino do Botão B
#define LED_AZUL 11 // Pino do LED azul
#define LED_VERDE 12 // Pino do LED verde
#define LED_VERMELHO 13 // Pino do LED vermelho
int num_eventos = 2; // Número de eventos para alternar entre os botões
int estado_atual = 0; // Estado atual do sistema
// Função para converter as posições (x, y) da matriz para um índice do vetor de LEDs
int obter_indice(int x, int y) {
if (y % 2 == 0) {
return 24 - (y * 5 + x);
} else {
return 24 - (y * 5 + (4 - x));
}
}
// Definição da estrutura de cor para cada LED
struct pixel_t {
uint8_t R, G, B;
};
typedef struct pixel_t npLED_t;
npLED_t leds[NUM_LEDS];
// PIO e state machine para controle dos LEDs
PIO np_pio;
uint sm;
// Função para atualizar os LEDs da matriz
void atualizar_leds() {
for (uint i = 0; i < NUM_LEDS; ++i) {
pio_sm_put_blocking(np_pio, sm, leds[i].R);
pio_sm_put_blocking(np_pio, sm, leds[i].G);
pio_sm_put_blocking(np_pio, sm, leds[i].B);
}
sleep_us(100);
}
// Função de controle inicial da matriz de LEDs
void inicializar_matriz(uint pino) {
uint offset = pio_add_program(pio0, &ws2812b_program);
np_pio = pio0;
sm = pio_claim_unused_sm(np_pio, true);
ws2812b_program_init(np_pio, sm, offset, pino, 800000.f);
for (uint i = 0; i < NUM_LEDS; ++i) {
leds[i].R = leds[i].G = leds[i].B = 0;
}
atualizar_leds();
}
// Função para configurar a cor de um LED específico
void definir_cor(const uint indice, const uint8_t r, const uint8_t g, const uint8_t b) {
leds[indice].R = r;
leds[indice].G = g;
leds[indice].B = b;
}
// Função para desligar todos os LEDs
void desligar_leds() {
for (uint i = 0; i < NUM_LEDS; ++i) {
definir_cor(i, 0, 0, 0);
}
atualizar_leds();
}
// Função de callback para o botão A
void botao_callback_A(uint gpio, uint32_t eventos) {
estado_atual = (estado_atual + 1) % num_eventos;
}
// Função de callback para o botão B
void botao_callback_B(uint gpio, uint32_t eventos) {
estado_atual = (estado_atual - 1 + num_eventos) % num_eventos; // Decremento circular
}
// Função para simular um efeito de chuva de LEDs
void efeito_chuva() {
int tempo_frame = 200;
int duracao_total = 10 * 1000; // 10 segundos
int total_frames = duracao_total / tempo_frame;
// Matriz para mapear as posições dos LEDs
int matriz[5][5] = {
{24, 23, 22, 21, 20},
{15, 16, 17, 18, 19},
{14, 13, 12, 11, 10},
{5, 6, 7, 8, 9},
{4, 3, 2, 1, 0}
};
// Efeito de chuva
for (int frame = 0; frame < total_frames; frame++) {
int chuva[5][5][3] = {0}; // Matriz para armazenar as cores da "chuva"
// Gerando gotas de chuva aleatórias
for (int coluna = 0; coluna < 5; coluna++) {
int linhaAleatoria = rand() % 5;
chuva[linhaAleatoria][coluna][0] = rand() % 256;
chuva[linhaAleatoria][coluna][1] = rand() % 256;
chuva[linhaAleatoria][coluna][2] = rand() % 256;
}
// Atualizando os LEDs com as cores geradas
for (int linha = 0; linha < 5; linha++) {
for (int coluna = 0; coluna < 5; coluna++) {
definir_cor(matriz[linha][coluna], chuva[linha][coluna][0], chuva[linha][coluna][1], chuva[linha][coluna][2]);
}
}
// Atualizando a matriz de LEDs
atualizar_leds();
sleep_ms(tempo_frame);
desligar_leds();
}
}
int main() {
// Inicializando o controle da matriz de LEDs
inicializar_matriz(PINO_MATRIZ);
// Inicializando os botões
gpio_init(BOTAO_A);
gpio_init(BOTAO_B);
gpio_set_dir(BOTAO_A, GPIO_IN);
gpio_set_dir(BOTAO_B, GPIO_IN);
gpio_pull_up(BOTAO_A);
gpio_pull_up(BOTAO_B);
gpio_set_irq_enabled_with_callback(BOTAO_A, GPIO_IRQ_EDGE_FALL, true, &botao_callback_A);
gpio_set_irq_enabled_with_callback(BOTAO_B, GPIO_IRQ_EDGE_FALL, true, &botao_callback_B);
while (1) {
switch (estado_atual) {
case 0:
desligar_leds();
break;
case 1:
efeito_chuva();
break;
}
sleep_ms(500);
}
}