Введение
Хотите создать яркую вывеску, информационный экран или интерактивную арт-инсталляцию? Светодиодная RGB матрица идеально подходит для этих задач. Из этого руководства вы узнаете, как подключить матрицу к микроконтроллеру STM32, а программу напишем в среде разработке Arduino IDE.

Необходимые детали
| № | Компонент | Количество | Купить |
|---|---|---|---|
| 1 | Отладочная плата STM32F411 | 1 шт | Авито | AliExpress | RobotChip |
| 2 | Блок питания AC-DC, 5В, 3А | 1 шт | Авито | AliExpress | RobotChip |
| 3 | RGB матрица 64х32 | 1 шт | Авито | AliExpress | RobotChip |
| 4 | Провод DuPont | 16 шт | Авито | AliExpress | RobotChip |
Технические параметры
- Разрешение: 64×32;
- Цвет: RGB;
- Количество светодиодов «пикселей»: 2048;
- Тип светодиодов: SMD2121;
- Шаг пикселя: 4 мм;
- Номинальное напряжение: 5 В;
- Максимальный ток: до 4 А;
- Интерфейс матрицы: HUB75;
- Структура пикселя: 1R1G1B;
- Режим сканирования: 1/16;
- Яркость: ~1200 кд/м²;
- Углы обзора: 160°;
- Габариты: 256×128×15 мм.
Описание
Панель RGB матрицы представляет собой модуль, на котором распаяна сетка из множества светодиодов. Они выпускаются в различных форм-факторах с разным количеством пикселей (16×32, 32×32, 64×32 и другие), так-же разделяются по классу защиты IP для эксплуатации на улице или внутри зданий. В статье буду использовать стандартную матрицу для помещений, размером 64×32.


Давайте разберём матрицу подробнее: корпус выполнен из пластмассовой рамки. На передней части расположено 2048 RGB-светодиодов, которые закрыты пластиковой защитой. На обратной стороне расположен текстолит с радиодеталями и винтовые крепления М3 (по контуру).
Принцип работы прост: матрица разбита пополам на 16 верхних и 16 нижних строк. У каждой половины свои сигнальные выводы: для верхней это R1,G1,B1, для нижней — R2,G2,B2. Одновременно может гореть всего одна строка сверху и одна снизу. Контроллер очень быстро перебирает все 16 пар строк по очереди, обновляя картинку десятки раз в секунду — глаз этого не замечает и видит цельное изображение.
Чтобы включить определённый светодиод, сначала пинами A, B, C и D мы выбираем, какую именно пару строк будем сейчас отрисовывать. Затем сигналом LAT подготавливаем регистры к приёму данных. После этого быстрым потоком передаём биты цвета (R1, G1, B1, R2, G2, B2), подтверждая каждый байт тактовым сигналом CLK

Назначение контактов
Интерфейсный разъем:
Подключение к контроллеру осуществляется через пару стандартных 16-пиновых колодок HUB75. Крайне важно не перепутать направление передачи данных: кабель от контроллера всегда вставляется в разъём с маркировкой IN. Со второго разъёма (OUT) сигнал уходит на вход следующей матрицы.
- Входной разъём — DATA IN
- Выходной разъём — DATA OUT

Назначение каждого контакт:
| Вывод | Обозначение | Описание |
|---|---|---|
| 1 | R1 | Сигнал данных красного цвета для верхней половины матрицы |
| 2 | G1 | Сигнал данных зелёного цвета для верхней половины матрицы |
| 3 | B1 | Сигнал данных синего цвета для верхней половины матрицы |
| 4 | GND | Земля |
| 5 | R2 | Сигнал данных красного цвета для верхней половины матрицы |
| 6 | G2 | Сигнал данных зелёного цвета для верхней половины матрицы |
| 7 | B2 | Сигнал данных синего цвета для верхней половины матрицы |
| 8 | GND | Земля |
| 9 | A | Выбор строки |
| 10 | B | Выбор строки |
| 11 | C | Выбор строки |
| 12 | D | Выбор строки |
| 13 | CLK | Тактовый сигнал для согласования скорости передачи |
| 14 | LAT | Управляющий сигнал |
| 15 | OE | Пин контроля отображения свечения всего дисплея |
| 16 | GND | Земля |
Разъем питания:
Питание подаётся через четыре контакта: линии питания (VCC) и земли (GND), которые продублированы для увеличения нагрузочной способности по току
- VCC — питание матрицы 5В
- GND — земля матрицы

Каждая RGB матрица питается от источника постоянного тока напряжением 5 Вольт. При одновременном включении всех RGB-светодиодов на полной яркости матрица потребляет ток до 4 Ампер, нужно это учитывать при выборе блока питания.
Подключение
Давайте соберём схему подключения RGB матрицы 64×32 к плате STM32F411. Для этого необходимо соединить выводы A, B, C и D подключить к портам PB6, PB5, PB4 и PB3 соответственно; сигнал разрешения выхода nOE — к выводу PB0; тактовый сигнал CLK — к выводу PA0. Цветовые каналы нижнего регистра R1, G1 и B1 подключаются к выводам PA0, PA1 и PA2, а цветовые каналы верхнего регистра R2, G2 и B2 — к выводам PA3, PA4 и PA5. Питание самой матрицы следует подключить к источнику напряжения 5 Вольт.

Таблица подключения
| Вывод | STM32F411 | RGB матрица |
|---|---|---|
| 1 | R1 | PA0 |
| 2 | G1 | PA1 |
| 3 | B1 | PA2 |
| 4 | GND | GND |
| 5 | R2 | PA3 |
| 6 | G2 | PA4 |
| 7 | B2 | PA5 |
| 8 | GND | GND |
| 9 | A | PB6 |
| 10 | B | PB5 |
| 11 | C | PB4 |
| 12 | D | PB3 |
| 13 | CLK | PA0 |
| 14 | LAT | PB7 |
| 15 | OE | PA0 |
| 16 | GND | GND |
В данной статье я использую плату Black Pill на базе микроконтроллера STM32F411CEU6. После установки поддержки платы в Arduino IDE необходимо настроить параметры проекта во вкладке «Инструменты» следующим образом.

Установка библиотеки
Для работы, будем использовать библиотеку «DMD_STM32» скачать можно используя интегрированную среду разработки Arduino IDE», для этого откройте «Скетч → Подключение библиотеки → Менеджер библиотек…», так же выложу библиотеки в конце статьи или скачайте с GitHub.
В строке поиска введите «DMD_STM32» и нажмите «Установить »

Для работы библиотеки необходимо установить зависимые библиотеки, нажимаем «Установить все»

Программа для передатчика
Ниже приведён исходный код передатчика, переведен и удалено лишние (пример dmd_rgb из библиотеки), загрузите скетч в плату STM.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
#include "DMD_RGB.h" // Подключаем библиотеку DMD_RGB #include "st_fonts/UkrRusArial14.h" #pragma GCC diagnostic ignored "-Wnarrowing" #pragma GCC diagnostic ignored "-Woverflow" #include "gfx_fonts/GlametrixLight12pt7b.h" #include "gfx_fonts/GlametrixBold12pt7b.h" #pragma GCC diagnostic warning "-Wnarrowing" #pragma GCC diagnostic warning "-Woverflow" // Количество панелей по осям X и Y #define DISPLAYS_ACROSS 1 #define DISPLAYS_DOWN 1 // Включить буферизацию вывода #define ENABLE_DUAL_BUFFER false // Указываем, какие контакты A, B, C, D, E используется, все мультиплексорные контакты должны быть выбраны из одного порта. #define DMD_PIN_A PB6 #define DMD_PIN_B PB5 #define DMD_PIN_C PB4 #define DMD_PIN_D PB3 #define DMD_PIN_E PB8 // Добавление всех контактов в массив. uint8_t mux_list[] = {DMD_PIN_A , DMD_PIN_B , DMD_PIN_C , DMD_PIN_D , DMD_PIN_E}; // Указываем контакты, OE должен быть одним из PB0, PB1, PA6, PA7 #define DMD_PIN_nOE PB0 #define DMD_PIN_SCLK PB7 // Указываем, какие контакты R0, G0, B0, R1, G1, B1 используется, все мультиплексорные контакты должны быть выбраны из одного порта. // Добавление всех контактов в массив. uint8_t custom_rgbpins[] = {PA6, PA0, PA1, PA2, PA3, PA4, PA5}; // CLK, R0, G0, B0, R1, G1, B1 // Создаем объект DMD с параметрами матрицы. DMD_RGB <RGB64x32plainS16, COLOR_4BITS> dmd(mux_list, DMD_PIN_nOE, DMD_PIN_SCLK, custom_rgbpins, DISPLAYS_ACROSS, DISPLAYS_DOWN, ENABLE_DUAL_BUFFER); // <RGB32x16plainS8> - матрица 32x16 с 8 экранами // <RGB80x40plainS20> - матрица 80x40 с 20 экранами // <RGB64x64plainS32> - матрица 64x64 с 32 развертками // Глубина цвета - <COLOR_4BITS> или <COLOR_1BITS> // Настройка шрифтов DMD_Standard_Font UkrRusArial_F(UkrRusArial_14); DMD_GFX_Font GlametrixL((uint8_t*)&GlametrixLight12pt7b, (uint8_t*)&GlametrixLight12pt8b_rus, 0x80, 13); // Перекодировка символов в UTF8 int utf8_rus(char* dest, const unsigned char* src) { uint16_t i, j; for (i = 0, j = 0; src[i]; i++) { if ((src[i] == 0xD0) && src[i + 1]) { dest[j++] = src[++i] - 0x10; } else if ((src[i] == 0xD1) && src[i + 1]) { dest[j++] = src[++i] + 0x30; } else dest[j++] = src[i]; } dest[j] = '\0'; return j; } void setup(void) { dmd.init(); // Инициализация } void loop(void) { uint16_t col[] = {dmd.Color888(255,0, 0), dmd.Color888(0, 255, 0), dmd.Color888(0, 0, 255)}; // Задаем масив цвета uint16_t bg = 0; // Фон - черный int col_cnt = 3; // Rоличество цветов в массиве char s[] = "Привет RobotChip!"; // Текст отображаюшся на экране // Перекодировать сообщение в UTF для использования со шрифтами GFX char k[30]; utf8_rus(k, (const unsigned char*)s); char* m = s; // Выбераем стандартный шрифт с интервалом между символами 3 пикселя dmd.selectFont(&UkrRusArial_F,3); // Установите цвета фона и текста dmd.setTextColor(col[0], bg); // Шаги сдвига в пикселях для бегущего текста (положительный сдвиг вправо, отрицательный влево) int8_t step[] = { 1,-1,-2,2 }; // Текущий интервал сдвига текста uint32_t interval = 50; uint32_t prev_step = millis(); uint8_t col_ptr = 0; uint8_t i = 0, b = 0; uint8_t test = 255; uint8_t test_cnt = 4; dmd.setBrightness(200); // Бесконечный цикл для теста: // Перемещение текста по осям x и y с однократной и двойной скоростью // Перемещение текста по вертикальной прокруткой while (1) { if ((millis() - prev_step) > interval) { prev_step = millis(); if (test >= test_cnt) { test = 0; dmd.drawMarqueeX(m, -1 * (dmd.stringWidth(m)), 0); dmd.swapBuffers(true); } switch (test) { // Перемещение текста по оси x case 0: if (dmd.stepMarquee(step[i], 0) & 1) { // Если текст выходит за пределы экрана dmd.clearScreen(true); // Установить следующий цвет текста col_ptr++; if (col_ptr >= col_cnt) col_ptr = 0; dmd.setTextColor(col[col_ptr], bg); // Установить новую скорость ввода текста i++; // Если все перемещения завершены if (i > 3) { // Переход к следующему этапу i = 0; test++; dmd.drawMarqueeX(m, 0, (dmd.height() > 16)? 8 : 0); } else { if (step[i] < 0) dmd.drawMarqueeX(m, dmd.width() - 1, 0); else dmd.drawMarqueeX(m, -1 * dmd.stringWidth(m), 0); } } // Вывод буфера в матрицу dmd.swapBuffers(true); break; case 1: b++; dmd.setBrightness(b); if (b > 250) { test++; b = 80; i = 0; dmd.setBrightness(b); dmd.drawMarqueeX(m, 0, 0); } // Вывод буфера в матрицу dmd.swapBuffers(true); break; // перемещение текста по оси y case 2: if (dmd.stepMarquee(0, step[i]) & 1) { // Если текст выходит за пределы экрана // Очистите экран dmd.clearScreen(true); // Выберите новую скорость перемещения i++; // Если все перемещения завершены if (i > 3) { // Переход к следующему этапу test++; // Выберите шрифт GFX для вертикальной прокрутки dmd.selectFont(&GlametrixL); dmd.drawMarquee(k, strlen(k), dmd.width() - 1, (dmd.height() > 16)? 8 : 0, 1); } else { if (step[i] < 0) dmd.drawMarqueeX(m, 0, dmd.height()); else dmd.drawMarqueeX(m, 0, 0); } } // Вывод буфера в матрицу dmd.swapBuffers(true); break; // Вертикальная прокрутка case 3: dmd.stepMarquee(-1, 0, 1); dmd.swapBuffers(true); break; } } } } |
Не буду описывать весь код, добавил небольшое описание в самом коде, можно подключать несколько RGB матриц, для этого необходимо изменить два параметра.
1 2 |
#define DISPLAYS_ACROSS 1 #define DISPLAYS_DOWN 1 |
Полезные ссылки
| № | Описание | |
|---|---|---|
| 1 | Библиотека для работы с RGB матрицей «DMD_STM32_1.2.16» | Скачать |
| 2 | Библиотека «Adafruit GFX v.1.12.6» | Скачать |
| 2 | Библиотека «Adafruit_BusIO v.1.14.7» | Скачать |