#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "ws2818b.pio.h"
#include "hardware/uart.h" // Biblioteca para manipulação de UART
#include "hardware/i2c.h" // Biblioteca para manipulação de I2C
#include "ssd1306.h" // Biblioteca para controlar o display SSD1306
// Definindo os pinos dos componentes
#define BOTAO_A 5 // Pino do Botão A
#define BOTAO_B 6 // Pino do Botão B
#define BLUE 11 // Pino do LED azul
#define GREEN 12 // Pino do LED verde
#define RED 13 // Pino do LED vermelho
#define pinSDA 14 // Pino GPIO para SDA (comunicação I2C)
#define pinSCL 15 // Pino GPIO para SCL (comunicação I2C)
#define I2C_PORT i2c0
int num_eventos = 2; // Número de eventos para alternar entre os botões
int atualizar = 0; // Estado atual do sistema (0 - Desliga, 1 - Chuva)
// Tempo mínimo entre interrupções para debouncing
#define DEBOUNCE_DELAY 300 // Milissegundos
// Variáveis para controlar o debouncing
volatile uint32_t last_irq_time_A = 0;
volatile uint32_t last_irq_time_B = 0;
//Inicializar os pinos do led RGB
void iniciar_rgb() {
gpio_init(RED);
gpio_init(GREEN);
gpio_init(BLUE);
gpio_set_dir(RED, GPIO_OUT);
gpio_set_dir(GREEN, GPIO_OUT);
gpio_set_dir(BLUE, GPIO_OUT);
}
// Função para iniciar os leds RGB dos pinos 11, 12 e 13 e configurar o tempo ligado
void state(bool rr, bool gg, bool bb) {
iniciar_rgb();
gpio_put(RED, rr);
gpio_put(GREEN, gg);
gpio_put(BLUE, bb);
}
#define PINO_MATRIZ 7 // Pino de controle da matriz de LEDs
#define NUM_LEDS 25 // Número total de LEDs na matriz
// Função para converter as posições (x, y) da matriz para um índice do vetor de LEDs
int getIndex(int x, int y) {
if (x % 2 == 0) {
return 24 - (x* 5 + y);
} else {
return 24 - (x * 5 + (4 - y));
}
}
//Controlando o brilho para 30%
uint8_t BRILHO = 255*1;
// 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 bf() {
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 controle(uint pino) {
uint offset = pio_add_program(pio0, &ws2818b_program);
np_pio = pio0;
sm = pio_claim_unused_sm(np_pio, true);
ws2818b_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;
}
bf();
}
// Função para configurar a cor de um LED específico
void 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;
}
void desliga() {
for (uint i = 0; i < NUM_LEDS; ++i) {
cor(i, 0, 0, 0);
}
bf();
}
// Funções para os diferentes efeitos
void number0() {
int mat1[5][5][3] = {
{{0, 0, 0}, {BRILHO, 0, 0}, {BRILHO, 0, 0}, {BRILHO, 0, 0},{0, 0, 0}},
{{0, 0, 0}, {BRILHO, 0, 0}, {0, 0, 0}, {BRILHO, 0, 0}, {0, 0, 0}},
{{0, 0, 0}, {BRILHO, 0, 0}, {0, 0, 0}, {BRILHO, 0, 0}, { 0, 0, 0}},
{{0, 0, 0}, {BRILHO, 0, 0}, {0, 0, 0}, {BRILHO, 0, 0}, {0, 0, 0}},
{{0, 0, 0}, {BRILHO, 0, 0}, {BRILHO, 0, 0}, {BRILHO, 0, 0},{0, 0, 0}}
};
for (int linha = 0; linha < 5; linha++) {
for (int cols = 0; cols < 5; cols++) {
int posicao = getIndex(linha, cols);
cor(posicao, mat1[linha][cols][0], mat1[linha][cols][1], mat1[linha][cols][2]);
}
}
bf();
}
void number1() {
int mat1[5][5][3] = {
{{0, 0, 0}, {0, 0, 0}, {0, BRILHO, 10}, {0, 0, 0}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, 0}, {0, BRILHO, 10}, {0, 0, 0}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, 0}, {0, BRILHO, 10}, {0, 0, 0}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, 0}, {0, BRILHO, 10}, {0, 0, 0}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, 0}, {0, BRILHO, 10}, {0, 0, 0}, {0, 0, 0}}
};
// Exibir a primeira matriz
for (int linha = 0; linha < 5; linha++) {
for (int cols = 0; cols < 5; cols++) {
int posicao = getIndex(linha, cols);
cor(posicao, mat1[linha][cols][0], mat1[linha][cols][1], mat1[linha][cols][2]);
}
}
bf();
}
void number2() {
int mat1[5][5][3] = {
{{0, 0, 0}, {0, 0, BRILHO}, {0, 0, BRILHO}, {0, 0, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, BRILHO}, {0, 0, BRILHO}, {0, 0, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, BRILHO}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, BRILHO}, {0, 0, BRILHO}, {0, 0, BRILHO}, {0, 0, 0}}
};
// Exibir a primeira matriz
for (int linha = 0; linha < 5; linha++) {
for (int cols = 0; cols < 5; cols++) {
int posicao = getIndex(linha, cols);
cor(posicao, mat1[linha][cols][0], mat1[linha][cols][1], mat1[linha][cols][2]);
}
}
bf();
}
void number3() {
int mat1[5][5][3] = {
{{0, 0, 0}, {100, BRILHO, 0}, {100, BRILHO, 0}, {100, BRILHO, 0}, {0, 0, 0 }},
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {100, BRILHO, 0}, {0, 0, 0}},
{{0, 0, 0}, {100, BRILHO, 0}, {100, BRILHO, 0}, {100, BRILHO, 0}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {100, BRILHO, 0}, {0, 0, 0}},
{{0, 0, 0}, {100, BRILHO, 0}, {100, BRILHO, 0}, {100, BRILHO, 0}, {0, 0, 0}}
};
// Exibir a primeira matriz
for (int linha = 0; linha < 5; linha++) {
for (int cols = 0; cols < 5; cols++) {
int posicao = getIndex(linha, cols);
cor(posicao, mat1[linha][cols][0], mat1[linha][cols][1], mat1[linha][cols][2]);
}
}
bf();
}
void number4() {
int mat1[5][5][3] = {
{{0, 0, 0}, {0, 0, BRILHO}, {0, 0, 0}, {0, 0, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, BRILHO}, {0, 0, 0}, {0, 0, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, BRILHO}, {0, 0, BRILHO}, {0, 0, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, BRILHO}, {0, 0, 0}}
};
// Exibir a primeira matriz
for (int linha = 0; linha < 5; linha++) {
for (int cols = 0; cols < 5; cols++) {
int posicao = getIndex(linha, cols);
cor(posicao, mat1[linha][cols][0], mat1[linha][cols][1], mat1[linha][cols][2]);
}
}
bf();
}
void number5() {
int mat1[5][5][3] = {
{{0, 0, 0}, {0, BRILHO, 0}, {0, BRILHO, 0}, {0, BRILHO, 0}, {0, 0, 0}},
{{0, 0, 0}, {0, BRILHO, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
{{0, 0, 0}, {0, BRILHO, 0}, {0, BRILHO, 0}, {0, BRILHO, 0}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, BRILHO, 0}, {0, 0, 0}},
{{0, 0, 0}, {0, BRILHO, 0}, {0, BRILHO, 0}, {0, BRILHO, 0}, {0, 0, 0}}
};
// Exibir a matriz
for (int linha = 0; linha < 5; linha++) {
for (int cols = 0; cols < 5; cols++) {
int posicao = getIndex(linha, cols);
cor(posicao, mat1[linha][cols][0], mat1[linha][cols][1], mat1[linha][cols][2]);
}
}
bf();
}
void number6() {
int mat1[5][5][3] = {
{{0, 0, 0}, {0, 0, BRILHO}, {0, 0, BRILHO}, {0, 0, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, BRILHO}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, BRILHO}, {0, 0, BRILHO}, {0, 0, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, BRILHO}, {0, 0, 0}, {0, 0, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, BRILHO}, {0, 0, BRILHO}, {0, 0, BRILHO}, {0, 0, 0}}
};
// Exibir a matriz
for (int linha = 0; linha < 5; linha++) {
for (int cols = 0; cols < 5; cols++) {
int posicao = getIndex(linha, cols);
cor(posicao, mat1[linha][cols][0], mat1[linha][cols][1], mat1[linha][cols][2]);
}
}
bf();
}
void number7() {
int mat1[5][5][3] = {
{{0, 0, 0}, {0, BRILHO, BRILHO}, {0, BRILHO, BRILHO}, {0, BRILHO, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, BRILHO, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, BRILHO, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, BRILHO, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, BRILHO, BRILHO}, {0, 0, 0}}
};
// Exibir a matriz
for (int linha = 0; linha < 5; linha++) {
for (int cols = 0; cols < 5; cols++) {
int posicao = getIndex(linha, cols);
cor(posicao, mat1[linha][cols][0], mat1[linha][cols][1], mat1[linha][cols][2]);
}
}
bf();
}
void number8() {
int mat1[5][5][3] = {
{{0, 0, 0}, {BRILHO, 0, BRILHO}, {BRILHO, 0, BRILHO}, {BRILHO, 0, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {BRILHO, 0, BRILHO}, {0, 0, 0}, {BRILHO, 0, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {BRILHO, 0, BRILHO}, {BRILHO, 0, BRILHO}, {BRILHO, 0, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {BRILHO, 0, BRILHO}, {0, 0, 0}, {BRILHO, 0, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {BRILHO, 0, BRILHO}, {BRILHO, 0, BRILHO}, {BRILHO, 0, BRILHO}, {0, 0, 0}}
};
// Exibir a matriz
for (int linha = 0; linha < 5; linha++) {
for (int cols = 0; cols < 5; cols++) {
int posicao = getIndex(linha, cols);
cor(posicao, mat1[linha][cols][0], mat1[linha][cols][1], mat1[linha][cols][2]);
}
}
bf();
}
void number9() {
int mat1[5][5][3] = {
{{0, 0, 0}, {BRILHO, BRILHO, BRILHO}, {BRILHO, BRILHO, BRILHO}, {BRILHO, BRILHO, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {BRILHO, BRILHO, BRILHO}, {0, 0, 0}, {BRILHO, BRILHO, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {BRILHO, BRILHO, BRILHO}, {BRILHO, BRILHO, BRILHO}, {BRILHO, BRILHO, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {BRILHO, BRILHO, BRILHO}, {0, 0, 0}},
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {BRILHO, BRILHO, BRILHO}, {0, 0, 0}}
};
// Exibir a matriz
for (int linha = 0; linha < 5; linha++) {
for (int cols = 0; cols < 5; cols++) {
int posicao = getIndex(linha, cols);
cor(posicao, mat1[linha][cols][0], mat1[linha][cols][1], mat1[linha][cols][2]);
}
}
bf();
}
// CONFIGURANDO O DISPLAY
// Função para inicializar a UART
void uart_init_custom() {
uart_init(uart0, 115200); // Inicializa a UART com taxa de 115200
gpio_set_function(0, GPIO_FUNC_UART); // Configura o pino 0 para UART
gpio_set_function(1, GPIO_FUNC_UART); // Configura o pino 1 para UART
}
void config_i2c() {
// Configuração do barramento I2C
i2c_init(I2C_PORT, 400 * 1000); // Configura o I2C com taxa de 400 kHz
gpio_set_function(pinSDA, GPIO_FUNC_I2C); // Configura o pino SDA
gpio_set_function(pinSCL, GPIO_FUNC_I2C); // Configura o pino SCL
gpio_pull_up(pinSDA); // Ativa o pull-up no pino SDA
gpio_pull_up(pinSCL); // Ativa o pull-up no pino SCL
}
void display() {
// Inicialização do display SSD1306
ssd1306_init(I2C_PORT); // Inicializa o display
ssd1306_clear(); // Limpa o display
}
void comando(char atualizar) {
switch (atualizar) {
case '0':
number0();
break;
case '1':
number1();
break;
case '2':
number2();
break;
case '3':
number3();
break;
case '4':
number4();
break;
case '5':
number5();
break;
case '6':
number6();
break;
case '7':
number7();
break;
case '8':
number8();
break;
case '9':
number9();
break;
case 'd':
state(0,0,0);
break;
default:
desliga();
printf("Comando inválido! \n");
break;
}
}
void debounce_botao(uint pino, volatile uint32_t *last_irq_time, int direcao) {
uint32_t tempo_atual = to_ms_since_boot(get_absolute_time());
if (tempo_atual - *last_irq_time > DEBOUNCE_DELAY) {
*last_irq_time = tempo_atual;
if (pino == BOTAO_A) {
// Quando o Botão A for pressionado, acende o LED vermelho
state(1, 0, 0); // LED vermelho aceso, verde e azul apagados
//gpio_put(RED, !gpio_get(RED));
}
if (pino == BOTAO_B) {
// Quando o Botão B for pressionado, acende o LED verde
state(0, 1, 0); // LED verde aceso, vermelho e azul apagados
//gpio_put(GREEN, !gpio_get(GREEN));
}
}
}
disp() {
sleep_ms(10); // Aguarda 1 segundo
printf("Sistema iniciado, para ligar pressione ON...\n"); // Mensagem inicial via UART
// Configuração do barramento I2C
i2c_init(I2C_PORT, 400 * 1000); // Configura o I2C com taxa de 400 kHz
gpio_set_function(pinSDA, GPIO_FUNC_I2C); // Configura o pino SDA
gpio_set_function(pinSCL, GPIO_FUNC_I2C); // Configura o pino SCL
gpio_pull_up(pinSDA); // Ativa o pull-up no pino SDA
gpio_pull_up(pinSCL); // Ativa o pull-up no pino SCL
// Inicialização do display SSD1306
ssd1306_init(I2C_PORT); // Inicializa o display
ssd1306_clear(); // Limpa o display
}
void iniciar_botoes() {
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);
// Interrupção para o botão A
gpio_set_irq_enabled_with_callback(BOTAO_A, GPIO_IRQ_EDGE_FALL, true, &debounce_botao);
// Interrupção para o botão B
gpio_set_irq_enabled_with_callback(BOTAO_B, GPIO_IRQ_EDGE_FALL, true, &debounce_botao);
}
// Função main
int main() {
stdio_init_all();
uart_init_custom(); // Configura a UART para comunicação com o terminal
controle(PINO_MATRIZ);
iniciar_botoes();
char atualizar;
while (1) {
if (!gpio_get(BOTAO_B)) debounce_botao(BOTAO_B, &last_irq_time_B, -1);
if (!gpio_get(BOTAO_A)) debounce_botao(BOTAO_A, &last_irq_time_A, +1);
printf("Digite um caractere: ");
if (scanf(" %c", &atualizar) == 1) {
comando(atualizar);
printf("%c\n", atualizar);
}
sleep_ms(10);
}
return (0);
}