Светодиодная матрица и управление ей в Arduino
Материал по статье автор Виталий Чубатый
Светодиодная матрица – удобное средство для отображения информации: во-первых, она ярче обычных TFT-дисплеев, во-вторых, больше по размеру, что в ряде случаев имеет преимущества (если нам не надо отображать фотографии).
При желании без особых затруднений можно найти готовую сборку – матрица 1088 (или любая подобная, 8×8 светодиодов) и в комплекте с ней контроллер MAX7219. Эта небольшая микросхема способна самостоятельно управлять не только отображением светодиодов, но и менять их яркость (для всей матрицы, а не по светодиодам), а также она «знает», как вывести цифры на семисегментный индикатор. Это означает, что разработчику будет меньше работы. Управление достаточно простое, по интерфейсу SPI по трём проводам – выбор устройства, данные и синхронизация.
Также часто такие сборки объединяют в блоки по 4 последовательно, получается мини-дисплей размером 32×8 пикселей, что достаточно удобно – можно отобразить слово длиной до 5 букв. Стоит отметить, что эта сборка умеет передавать данные дальше по цепочке, и 4 штуки последовательно – не предел. Я объединял 4 блока по 4 такие сборки, получался дисплей 128×8 (также можно получить 64×16 при соответствующей программной настройке, это просто), работавший без торможения и обновляющийся 50 раз в секунду. Хотя, в отличие от схемы в прошлом материале, здесь программное обновление не нужно – за вывод информации отвечает контроллер на плате, дело программиста – указать, что выводить, а не как.
Для работы с такими сборками есть специальная библиотека для Arduino – Max72xxPanel, доступная на GitHub. Для её корректной работы также требуется подключение библиотек SPI и Adafruit_GFX, но это не проблема. Первая библиотека присутствует по умолчанию в дистрибутиве Arduino IDE, вторая доступна на GitHub.
Инициализируем матрицу
Для начала попробуем инициализировать нашу матрицу. Выводы питания VCC и GND соединяем с аналогичными на плате Arduino, DIN подключаем к выводу 11, CS – 9, CLK – 13. Учтите, что эта нумерация верна для платы Arduino UNO, для других моделей интерфейс SPI может находиться на выводах с другими номерами.
С этой сборкой удобнее работать, «повернув» её программно на 90 градусов. Фактически, у нас есть 4 блока по вертикали и 1 по горизонтали, но отображать будем, как будто она ориентирована горизонтально. Причина простая – 1 столбец занимает ровно 1 байт, удобнее строить изображение.
Пишем начальный программный код для инициализации:
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>
#include <Adafruit_SPITFT.h>
#include <Max72xxPanel.h>
int pinCS = 9;
int hBlocks = 1;
int vBlocks = 4;
byte brightness = 1;
Max72xxPanel matrix = Max72xxPanel(pinCS, hBlocks, vBlocks);
void setup() {
matrix.setIntensity(brightness);
matrix.setRotation(0);
matrix.fillScreen(LOW);
matrix.write();
}
void loop() {
}
Нажимаем Ctrl+U, загружаем скетч в плату и смотрим на результат, точнее, на полностью погасший дисплей.
Так и должно быть, мы просто очистили его. Попробуйте сами изменить строку 18 следующим образом:
matrix.fillScreen(HIGH);
В результате получим полностью светящуюся матрицу. Если светится тускло, увеличивайте яркость в строке 11, только постепенно и осторожно – у меня уже при значении 3 при взгляде на светодиоды ощущается дискомфорт и болят глаза. Так что с яркостью стоит начинать с минимума и плавно увеличивать.
Простейшую операцию мы выполнили, теперь давайте попробуем что-то написать.
Вывод статического изображения
Для примера возьмём слово из пяти букв, чтобы максимально заполнить матрицу. Можно, конечно, вывести по одному символу на матрицу, но для любой буквы хватает места 5*7 символов, поэтому с учётом интервала получится до 5 букв. Для примера возьмём слово «Старт».
Формируем изображение:
И модифицируем программный код, добавив туда массив с данными для включения определённых светодиодов (приводить не буду, скетч можно скачать для ознакомления по ссылке внизу). Рисовать будем по вертикали, старший бит – верхний ряд. Кроме этого, из кода можно исключить начальное заполнение матрицы, поскольку все светодиоды будут определены явно:
void setup() {
byte x, y;
matrix.setIntensity(brightness);
matrix.setRotation(0);
for (y = 0; y < 32; y++) {
for (x = 0; x < 8; x++) {
matrix.drawPixel(x, y, leds[y] & (1< }
}
matrix.write();
}
Компилируем скетч, загружаем в плату и смотрим на результат:
В следующий раз сделаем на матрице бегущую строку и выведем надпись, которая не помещается по длине.