Matryca 8x32 z MAX7219 ...

Taka nowość z uC RP2040 Dual CORE ARM Cortex M0+ pędzącym 133MHz
ODPOWIEDZ
Awatar użytkownika
SunRiver
Użytkownik
Posty: 1511
Rejestracja: 08 paź 2017, 11:27
Lokalizacja: Festung Oppeln
Kontakt:

Matryca 8x32 z MAX7219 ...

Post autor: SunRiver »

W sumie to taki sobie dowcip .... bowiem oglądając zasoby Aliexpress znalazłem całkiem fajną klawiaturę

Obrazek

cena jak na aliexpress .... no cóż 1 056,39zł ---- ale sami zobaczcie filmik prezentujący jest ładna
i matrix robi robotę

https://pl.aliexpress.com/item/1005007771843412.html

Więc pomyślałem że mam 4x 8x8 zielone wiec dlaczego by nie zrobić takiego efektu ??
No więc zrobiłem :)

Język C, Raspberry SDK, RP2040 ...
Miłej zabawy ...
  1.  
  2. #include "pico/stdlib.h"
  3. #include "hardware/spi.h"
  4. #include <string.h>
  5.  
  6. #define SPI_PORT spi0
  7. #define PIN_CS   17
  8. #define PIN_SCK  18
  9. #define PIN_MOSI 19
  10.  
  11. // Font 6x6 - każda litera ma 6 bajtów szerokości (margines 1px góra/dół)
  12. const uint8_t font6x6[11][6] = {
  13.     { 0x7E, 0x08, 0x08, 0x08, 0x08, 0x7E }, // H (0)
  14.     { 0x7C, 0x12, 0x12, 0x12, 0x12, 0x7C }, // A (1)
  15.     { 0x02, 0x02, 0x7E, 0x02, 0x02, 0x00 }, // T (2)
  16.     { 0x44, 0x4A, 0x4A, 0x4A, 0x4A, 0x30 }, // S (3)
  17.     { 0x3E, 0x40, 0x40, 0x40, 0x40, 0x3E }, // U (4)
  18.     { 0x7E, 0x04, 0x08, 0x10, 0x20, 0x7E }, // N (5)
  19.     { 0x7E, 0x4A, 0x4A, 0x4A, 0x4A, 0x42 }, // E (6)
  20.     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Spacja (7)
  21.     { 0x7E, 0x04, 0x08, 0x04, 0x08, 0x7E }, // M (8)
  22.     { 0x42, 0x42, 0x7E, 0x42, 0x42, 0x00 }, // I (9)
  23.     { 0x7E, 0x08, 0x14, 0x22, 0x42, 0x00 }  // K (10)
  24. };
  25.  
  26. const int char_map[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 4 };
  27. #define MAP_SIZE 12
  28.  
  29. uint8_t frame_buffer[32];
  30.  
  31. void max7219_cmd(uint8_t reg, uint8_t data) {
  32.     uint8_t buf[2] = { reg, data };
  33.     gpio_put(PIN_CS, 0);
  34.     for (int i = 0; i < 4; i++) spi_write_blocking(SPI_PORT, buf, 2);
  35.     gpio_put(PIN_CS, 1);
  36. }
  37.  
  38. void send_row_all(uint8_t row, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4) {
  39.     uint8_t reg = row + 1;
  40.     uint8_t data_to_send[8] = { reg, d1, reg, d2, reg, d3, reg, d4 };
  41.     gpio_put(PIN_CS, 0);
  42.     spi_write_blocking(SPI_PORT, data_to_send, 8);
  43.     gpio_put(PIN_CS, 1);
  44. }
  45.  
  46. void update_display() {
  47.     for (int row = 0; row < 8; row++) {
  48.         uint8_t b[4] = { 0, 0, 0, 0 };
  49.         for (int col = 0; col < 32; col++) {
  50.             if (frame_buffer[col] & (1 << row)) {
  51.                 int m_idx = col / 8;
  52.                 int l_col = col % 8;
  53.                 b[m_idx] |= (1 << (7 - l_col));
  54.             }
  55.         }
  56.         send_row_all(row, b[0], b[1], b[2], b[3]);
  57.     }
  58. }
  59.  
  60. void clear_buffer() { memset(frame_buffer, 0, 32); }
  61.  
  62. // Pomocnicza funkcja do umieszczania znaku na konkretnej matrycy (0-3)
  63. void draw_char(int matrix_idx, int char_idx) {
  64.     int start_col = matrix_idx * 8 + 1;               // +1 daje margines z lewej
  65.     for (int i = 0; i < 6; i++) {
  66.         frame_buffer[start_col + i] = font6x6[char_idx][i];
  67.     }
  68. }
  69.  
  70. void init_spi() {
  71.     spi_init(SPI_PORT, 5000 * 1000);
  72.     gpio_set_function(PIN_SCK, GPIO_FUNC_SPI);
  73.     gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI);
  74.     gpio_init(PIN_CS);
  75.     gpio_set_dir(PIN_CS, GPIO_OUT);
  76.     gpio_put(PIN_CS, 1);
  77.     max7219_cmd(0x0c, 1); max7219_cmd(0x09, 0);
  78.     max7219_cmd(0x0b, 7); max7219_cmd(0x0a, 2);
  79.     clear_buffer(); update_display();
  80. }
  81.  
  82. int main() {
  83.     stdio_init_all();
  84.     init_spi();
  85.  
  86.     while (true) {
  87.         // Zewnętrzne do środka (Wiersz 1 i 8)
  88.         clear_buffer();
  89.         for (int i = 0; i < 16; i++) {
  90.             frame_buffer[i] |= 0x81;
  91.             frame_buffer[31 - i] |= 0x81;
  92.             update_display();
  93.             sleep_ms(30);
  94.         }
  95.  
  96.         // Do środka (zostawiamy linie na wierszach 4 i 5 - środek)
  97.         sleep_ms(200);
  98.         for (int step = 0; step < 3; step++) {
  99.             // NIE czyścimy całego bufora, tylko nadpisujemy maskę
  100.             uint8_t mask = (1 << (1 + step)) | (1 << (6 - step));
  101.             for (int j = 0; j < 32; j++) frame_buffer[j] = mask;
  102.             update_display();
  103.             sleep_ms(150);
  104.         }
  105.  
  106.         //Pionowe linie od środka na zewnątrz - WYGASZANIE
  107.         for (int i = 0; i < 16; i++) {
  108.             // NIE dajemy clear_buffer(), żeby poziome linie zostały
  109.             // Rysujemy pionowe linie (0xFF)
  110.             if (15 - i >= 0) frame_buffer[15 - i] = 0xFF;
  111.             if (16 + i < 32) frame_buffer[16 + i] = 0xFF;
  112.        
  113.             update_display();
  114.             sleep_ms(40);
  115.                     // Po wyświetleniu pionowej linii, "gasimy" kolumnę,
  116.             // którą właśnie minęliśmy, żeby sprzątnąć ekran pod napis
  117.             if (15 - i >= 0) frame_buffer[15 - i] = 0x00;
  118.             if (16 + i < 32) frame_buffer[16 + i] = 0x00;
  119.         }
  120.  
  121.         //Przewijanie napisu  HATSUNE MIKU
  122.         uint8_t text_full[120];
  123.         int total_px = 0;
  124.         memset(text_full, 0, 120);
  125.  
  126.         for (int i = 0; i < MAP_SIZE; i++) {
  127.             for (int c = 0; c < 6; c++) text_full[total_px++] = font6x6[char_map[i]][c];
  128.             total_px += 2;  // Odstęp między literami
  129.         }
  130.  
  131.         for (int shift = 0; shift < total_px + 32; shift++) {
  132.             clear_buffer();
  133.             for (int x = 0; x < 32; x++) {
  134.                 int pos = shift + x - 32;
  135.                 if (pos >= 0 && pos < total_px) {
  136.                     frame_buffer[x] = text_full[pos];
  137.                 }
  138.             }
  139.             update_display();
  140.             sleep_ms(45);
  141.         }
  142.  
  143.         // Efekt Migania napisu MIKU (ostanie 4 znaki z mapy)
  144.         for (int blink = 0; blink < 5; blink++) {
  145.             // Zgaś
  146.             clear_buffer();
  147.             update_display();
  148.             sleep_ms(200);
  149.             // Zapal MIKU
  150.             draw_char(0, 8);  // M
  151.             draw_char(1, 9);  // I
  152.             draw_char(2, 10); // K
  153.             draw_char(3, 4);  // U
  154.             update_display();
  155.             sleep_ms(200);
  156.         }
  157.        
  158.     //ANIMACJA KOŃCOWA: Odwrotność początku
  159.         for (int i = 0; i < 16; i++) {
  160.             // Rysujemy pionowe linie wpadające do środka
  161.             if (i < 16) frame_buffer[i] = 0xFF;
  162.             if (31 - i >= 16) frame_buffer[31 - i] = 0xFF;
  163.             update_display();
  164.             sleep_ms(30);
  165.             // Zostawiamy tylko poziome linie na środku (wiersze 3 i 4)
  166.             frame_buffer[i] = 0x18;
  167.             frame_buffer[31 - i] = 0x18;
  168.         }
  169.  
  170.         // Teraz poziome linie rozszerzają się ze środka do brzegów (góra/dół) i znikają
  171.         for (int step = 2; step >= 0; step--) {
  172.             uint8_t mask = (1 << (1 + step)) | (1 << (6 - step));
  173.             for (int j = 0; j < 32; j++) frame_buffer[j] = mask;
  174.             update_display();
  175.             sleep_ms(150);
  176.         }
  177.  
  178.         // Ostatni błysk brzegów i czysty ekran
  179.         clear_buffer();
  180.         for (int j = 0; j < 32; j++) frame_buffer[j] = 0x81; // Wiersz 0 i 7
  181.         update_display();
  182.         sleep_ms(150);
  183.        
  184.         clear_buffer();
  185.         update_display();
  186.        
  187.         sleep_ms(2000);
  188.    
  189.     }
  190.        
  191. }
  192.  
ODPOWIEDZ

Wróć do „Raspberry Pi Pico”