Индикаторы в виде матриц из светодиодов отличаются высокой яркостью и контрастностью. В некоторых задачах, это делает их лучше тех же графических LCD, OLED или TFT дисплеев. Светодиодная матрица — недорогое устройство, которое позволяет показывать картинки с простой графикой — цифры, буквы, различные иконки.
В DIY роботах матрицы часто используют для имитации глаз, через которые можно выразить примитивные псевдоэмоции. То же самое подойдет и для cosplay костюмов. Из нескольких матриц можно собрать табло для бегущей строки, и выводить какую-нибудь полезную информацию или рекламу.
В одном из предыдущих уроков мы разбирались с устройством светодиодной матрицы. Тогда же мы узнали, что управлять матрицей не так то просто. Чтобы зажечь конкретный выбранный светодиод, нам необходимо применять специальный подход, называемый динамической индикацией. Этот самый подход — тяжелая работа для такого микроконтроллера как Atmega328, который как раз и применяется в Ардуино.
Для решения проблемы инженеры придумали различные специальные микросхемы, которые сами организуют динамическую индикацию, тем самым снижая нагрузку на микроконтроллер. В одном из уроков мы познакомились с одной из таких микросхем — MAX7219.
Сегодня мы будем учиться работать с модулем монохромной светодиодной матрицы с микросхемой HOLTEK16K33, который был разработан в лаборатории RobotClass.
Список необходимых компонентов
Для выполнения всех инструкций в данном уроке, кроме самого модуля матрицы, потребуется Ардуино-совместимый контроллер и немного распространённых компонентов. Необходимые компоненты можно добавить в корзину прямо здесь, и затем оформить заказ в нашем интернет-магазине.
Модуль матрицы 8×8 от RobotClass
Как и все прочие модули из линейки ROC, модуль выполнен в унифицированном форм-факторе с расстоянием между монтажными отверстиями кратным 9 мм. Такие модули легко прикреплять, например, на наших роботов.
Матрица на модуле монохромная, это означает, что точки матрицы могут светиться только одним цветом, в нашем случае — красным. Но существуют матрицы и других цветов, и даже многоцветные — RGB матрицы.
Характеристики модуля матрицы ROC:
- микроконтроллер: HOLTEK16K33;
- рабочее напряжение: от 3,3 до 5 В;
- цвет свечения: красный;
- размеры модуля: 32 x 23 мм;
- расстояние между монтажными отверстиями: 27 x 18 мм.
На обратной стороне модуля есть три перемычки (A0, A1, A2), которые позволяют менять адрес устройства. Это нужно для того, чтобы мы смогли подключить сразу несколько матриц к одной шине.
Изначально, все перемычки разомкнуты и адрес устройства равен 0x70. Таблица допустимых адресов выглядит следующим образом:
Перемычки | Адрес |
— | 0x70 |
A0 | 0x71 |
A1 | 0x72 |
A0,A1 | 0x73 |
A2 | 0x74 |
A0,A2 | 0x75 |
A1,A2 | 0x76 |
A0,A2,A3 | 0x77 |
Попробуем теперь подключить матрицу к самой простой плате Ардуино Уно и заставить её выводить разную полезную информацию.
Подключение светодиодной матрицы к Ардуино
Матрица работает по интерфейсу I2C, а это значит, что для подключения нам нужно соединить только контакты питания и два сигнальных контакта SCL и SDA:
Матрица 8×8 ROC | VCC | GND | SDA | SCL |
Ардуино Уно | +5V | GND | A4 | A5 |
Программа
Для управления матрицей нам понадобится библиотека Adafruit_LED_Backpack, инструкция по установке которой имеется в конце урока. С помощью этой библиотеки мы сможем выводить на матрицу точки, или по-другому «пиксели». Делается это с помощью функции drawPixel:
drawPixel(x, y, цвет);
где x и y — координаты точки, а цвет — её цвет. Для монохромной матрицы, которая используется в нашем модуле, цвет может принимать только значения 0 или 1.
Напишем программу, которая будет попиксельно рисовать квадрат размером 8×8 точек.
#include <Wire.h>
#include "Adafruit_LEDBackpack.h"
Adafruit_8x8matrix matrix = Adafruit_8x8matrix();
void setup() {
matrix.begin(0x70); // устанавливаем адрес модуля
delay(1000); // пауза 1 секунда, можно убрать
matrix.clear(); // очищаем буфер матрицы
// рисуем квадрат
for(byte i=0; i<8; i++){
matrix.drawPixel(i, 0, 1); // верхняя линия
matrix.drawPixel(i, 7, 1); // нижняя линия
matrix.drawPixel(0, i, 1); // левая линия
matrix.drawPixel(7, i, 1); // правая линия
}
// выводим буфер данных на матрицу
matrix.writeDisplay();
}
void loop() {
}
Загружаем программу на Ардуино и видим яркий красный квадрат!
Пример программы для вывода цифр и букв на матрицу ROC
Чтобы выводить на матрицу что-то ещё, кроме точек, нам потребуется уже известная по другим урокам библиотека Adafruit_GFX. Ссылка на неё имеется в конце урока.
Например, чтобы нарисовать тот же самый квадрат, можно использовать функцию drawRect:
drawRect(x, y, w, h);
где x и y — координаты левого верхнего угла, а w и h — ширина и высота прямоугольника соответственно.
Однако, наша задача — цифры. Напишем программу, которая будет выводить на матрицу обратный отсчет от 9 до 0! В этом нам поможет функция drawChar:
drawChar(x, y, символ, цвет, фон, размер);
где x и y — координаты верхнего левого угла символа, цвет — цвет начертания, фон — цвет фона, а размер — размер символа в пикселях.
А вот и программа:
#include <Wire.h>
#include "Adafruit_GFX.h"
#include "Adafruit_LEDBackpack.h"
Adafruit_8x8matrix matrix = Adafruit_8x8matrix();
void setup() {
matrix.begin(0x70); // устанавливаем адрес модуля
delay(1000); // пауза 1 секунда, можно убрать
}
void loop() {
// запускаем цикл от символа '9' до символа '0'
// что эквивалентно перебору чисел от 57 до 48
for( char c='9'; c>='0'; c--){
matrix.clear(); // очищаем буфер матрицы
matrix.drawChar(0, 0, c, 1, 0, 1);
matrix.writeDisplay(); // выводим буфер в матрицу
delay(1000); // пауза 1 секунда
}
}
Следующая задача — вывод картинки!
Пример программы для вывода картинки на матрицу ROC
Чтобы светодиодная матрица отобразила картинку, эту самую картинку нужно где-то хранить. Будем хранить её в массиве.
Для вывода картинки на матрицу используем функцию drawBitmap:
drawBitmap(x, y, кадр, w, h, цвет);
где x и y — координаты верхнего левого угла картинки, кадр — массив с картинкой, w и h — ширина и высота картинки, цвет — собственно, цвет начертания.
Чтобы программа была не совсем скучная, мы будем выводить не статичную картинку, а две сменяющиеся друг за другом. Для этого потребуется использовать двумерный массив!
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
Adafruit_8x8matrix matrix = Adafruit_8x8matrix();
// объявляем двумерный массив с картинками
static const uint8_t PROGMEM frames[2][8] = {
{ B00000000,
B01100110,
B11111111,
B11111111,
B01111110,
B00111100,
B00011000,
B00000000 },
{ B00000000,
B00100100,
B01111110,
B01111110,
B00111100,
B00011000,
B00000000,
B00000000 }
};
void setup() {
matrix.begin(0x70); // устанавливаем адрес модуля
}
void loop() {
matrix.clear(); // очищаем буфер матрицы
// заполняем буфер матрицы первой картинкой
matrix.drawBitmap(0, 0, frames[0], 8, 8, 1);
matrix.writeDisplay(); // выводим буфер в матрицу
delay(200); // пауза 200 мс
matrix.clear(); // очищаем буфер матрицы
// заполняем буфер матрицы второй картинкой
matrix.drawBitmap(0, 0, frames[1], 8, 8, 1);
matrix.writeDisplay(); // выводим буфер в матрицу
delay(500); // пауза 200 мс
}
Загружаем программу в Ардуино и получаем вот такой чудесный результат:
К размышлению
Как мы с вами убедились, светодиодная матрица — очень гибкий индикатор, на котором можно отображать любые графические объекты, будь то геометрическая фигура, текст или анимированное сердце.
Интерфейс I2C позволяет подключать на одну шину до 8 матриц одновременно, так что можно сделать из них злого робота с кучей глаз, полезную бегущую строку, или веселые игрушки для ёлки!
Приложение: установка библиотеки Adafruit LED Backpack
Стандартная библиотека Adafruit LED Backpack, которую мы используем для нашего модуля матрицы, в исходном своём виде будет работать неправильно. Решить эту проблему можно двумя способами.
Способ №1. Установить уже исправленную библиотеку. Скачать её можно по ссылке в конце урока.
Способ №2. Установить оригинальную библиотеку и внести в неё небольшое изменение. Для этого сначала устанавливаем LED Backpack через менеджер библиотек:
Затем ищем файл «Adafruit_LEDBackpack.cpp», который обычно находится в папке:
C:\Users\Master\Documents\Arduino\libraries\Adafruit_LED_Backpack_Library
Открываем файл в любом текстовом редакторе и ищем строки:
void Adafruit_8x8matrix::drawPixel(int16_t x, int16_t y, uint16_t color) { if ((y < 0) || (y >= 8)) return; if ((x < 0) || (x >= 8)) return;
Добавляем сразу после этих строк выражение:
x = 7 - x + 1;
Сохраняем файл. Библиотека готова к работе!
Русский шрифт
За генерацию изображения буквы отвечает библиотека Adafruit GFX. Пиксельное изображение каждого символа хранится в файле:
C:\Users\???\Documents\Arduino\libraries\Adafruit_GFX_Library\glcdfont.c
(вместо ??? нужно указать название личной папки текущего пользователя windows).
Чтобы подключить русский алфавит, заменим этот файл на модифицированный. Для этого скачаем по ссылке архив:
http://git.robotclass.ru/download/Arduino/utf8rus.zip
Распакуем его. Найдём внутри нужный файл и скопируем в папку Adafruit_GFX_Library поверх старого. Пишем в программе русский текст, компилируем и загружаем на контроллер. Готово!
Полезные ссылки
Модифицированная библиотека Adafruit_LED_Backpack:
http://git.robotclass.ru/download/Arduino/Adafruit_LED_Backpack_Library_ROC.zip
Библиотека Adafruit_GFX:
http://git.robotclass.ru/download/Arduino/Adafruit-GFX-Library-master.zip
Спасибо большое за ваши подробные и качественные статьи. Очень интересно!
Микросхема Holtek, а не Holtec.
Интересно было бы почитать именно об особенностях этих специализированных контроллеров. Конкретнее — как синхронизировать пару — если, скажем, не хватает разрядности. Индикатор (сегментный, неразборный) имеет организацию: 8(16) общих анодов (по одному выводу на каждую пару знакомест, всего знакомест 16) на 16 катодов (сегментов) . За одну итерацию индикатор может отобразить 2 знакоместа (старший и младший байты). Весь индикатор отображается за 8 итераций. HT16K33 хорошая микросхема — к ней можно подключить сразу две матрицы 8х8 и мой индикатор вроде бы подходит под нее, если бы не одно «но» — что ht16k33, что мах7219 — это все «общий катод» — а у меня «общий анод», а TM1637 имеет организацию 8х6 (слегка не хватает). Как без транзисторов, регистров, улнок оживить зверька?
Спасибо, поправил! Что касается чипа, то ведь он не единственный. Вам надо поискать подобные контроллеры других производителей, есть куда интереснее и компактнее. Даже у того же Holtek есть чип с 16 катодами.
здравствуйте, возник вопрос, как поменять пины сигналов. к примеру вместо а5 и а4, а0 и а5?