Использование светодиодной матрицы Arduino UNO R4 WiFi
Начните работу со встроенной светодиодной матрицей Arduino UNO R4 WiFi. Изучите различные техники управления ей, создавайте анимации, графику или даже игры.
Цели
Матрица и её API разработаны так, чтобы их можно было программировать несколькими различными способами, каждый из которых подходит для разных задач. Это руководство проведёт вас через основные концепции программирования LED-матрицы и поможет начать создавать собственные анимации, при этом продемонстрирует два различных способа управления светодиодами для создания анимаций и изображений. Это облегчит вам выбор метода, который лучше всего подходит для ваших нужд!
Светодиодная матрица UNO R4 WiFi
Необходимое оборудование и ПО
Пакет плат UNO R4 (последняя версия)
Инициализация матрицы
Для использования библиотеки LED Matrix необходимо добавить несколько вещей в ваш скетч, чтобы начать работу.
Сначала подключите библиотеку в начале вашего скетча, вот так:
#include "Arduino_LED_Matrix.h"
Затем вам нужно создать объект LED Matrix в вашем скетче, добавив следующую строку сразу после первой:
ArduinoLEDMatrix matrix;
И наконец, запустите LED Matrix, добавив эту строку в void setup():
matrix.begin();
Всё вместе должно выглядеть так:
#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix matrix;
void setup() {
Serial.begin(115200);
matrix.begin();
}
Как создать кадр
Библиотека LED Matrix для UNO R4 WiFi работает по принципу создания кадра и последующей загрузки его в буфер, который отображает этот кадр.
Кадр — это то, что мы называем «изображением», отображаемым в любой данный момент на матрице. Если анимация — это серия изображений, то кадр — одно из этих изображений в серии.
Для управления светодиодной матрицей 12x8 на UNO R4 WiFi вам нужно пространство в памяти размером не менее 96 бит. Библиотека предоставляет два способа сделать это.
Первый — просто создать двумерный массив байтов, вот так:
byte frame[8][12] = {
{ 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 },
{ 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0 },
{ 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
Этот вариант прост для понимания, потому что вы можете видеть изображение в паттерне массива, и его легко редактировать во время выполнения. Единицы в приведённом выше массиве образуют сердце, и именно это изображение вы увидите на экране.
Чтобы обратиться к отдельному пикселю, выберите его адрес и измените значение, помните, что нумерация начинается с 0. Таким образом, следующая строка обратится к третьему пикселю сверху и второму слева, а затем включит его:
frame[2][1] = 1;
matrix.renderBitmap(frame, 8, 12);
Однако этот метод использует больше памяти, чем необходимо. Хотя каждому светодиоду нужен всего один бит для хранения его состояния, вы используете восемь бит (байт). Более экономичный по памяти метод хранения кадра — использование массива 32-битных целых чисел.
В этом разделе мы пройдём через процесс и концепцию того, как вы можете создать один из таких кадров самостоятельно. Хотя мы разработали инструмент, который может сделать это за вас, так что вы можете перейти сюда, если хотите пропустить это упражнение.
Вот то же сердце в такой форме:
unsigned long frame[] = {
0x3184a444,
0x42081100,
0xa0040000
};
Переменная unsigned long содержит 32 бита, а 96/32 = 3, поэтому массив unsigned long — это эффективный способ хранения всех битов, необходимых для LED-матрицы.
Но как эти шестнадцатеричные значения соотносятся с позициями пикселей? Чтобы выяснить это, преобразуйте шестнадцатеричные значения в двоичные. Вот фрагмент кода, который это сделает:
for (int b = 0; b < 3; b++) {
Serial.println(frame[b], BIN);
}
Это выведет все битовые значения массива. Вывод будет выглядеть так:
110001100001001010010001000100
1000010000010000001000100000000
10100000000001000000000000000000
Однако этот метод не показывает все биты. Каждый элемент массива должен содержать 32 бита. Если добавить нули для отображения всех 32 бит каждого элемента, вы получите:
00110001100001001010010001000100
01000010000010000001000100000000
10100000000001000000000000000000
Теперь разделите это на группы по 12 бит, и вы снова получите сердце:
001100011000
010010100100
010001000100
001000001000
000100010000
000010100000
000001000000
000000000000
Подсказка
Вы можете увидеть сердце легче, если выделите все «1» на странице, нажав CTRL/Command + F и выполнив поиск по «1».
Если у вас есть несколько разных кадров, вы можете загрузить и отобразить их вот так:
const uint32_t happy[] = {
0x19819,
0x80000001,
0x81f8000
};
const uint32_t heart[] = {
0x3184a444,
0x44042081,
0x100a0040
};
matrix.loadFrame(happy);
delay(500);
matrix.loadFrame(heart);
delay(500);
Проверка работы
Давайте применим эти концепции с двумя базовыми скетчами, которые отображают разные кадры на вашей плате. Сначала создадим кадры из 3x32-битных целых чисел и загрузим их один за другим.
Вот скетч, который сначала загрузит смайлик на вашу матрицу, а затем сменит его на сердце.
#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix matrix;
void setup() {
Serial.begin(115200);
matrix.begin();
}
const uint32_t happy[] = {
0x19819,
0x80000001,
0x81f8000
};
const uint32_t heart[] = {
0x3184a444,
0x44042081,
0x100a0040
};
void loop(){
matrix.loadFrame(happy);
delay(500);
matrix.loadFrame(heart);
delay(500);
}
Скетч довольно простой, и всё же результат очень выразительный и может помочь вам легко отображать состояния ваших проектов.
Теперь давайте изменим подход и создадим растровое изображение, которое мы изменяем во время выполнения. Этот скетч включает несколько функций, каждая из которых рисует часть лица, а затем подмигивает левым глазом, выключая определённые пиксели.
#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix matrix;
void setup() {
Serial.begin(115200);
matrix.begin();
}
uint8_t frame[8][12] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
void leftEye(){
//Left eye
frame[1][3] = 1;
frame[1][4] = 1;
frame[2][3] = 1;
frame[2][4] = 1;
}
void wink(){
//Wink with the left eye
frame[1][3] = 0;
frame[1][4] = 0;
frame[2][3] = 1;
frame[2][4] = 1;
}
void rightEye(){
//Right eye
frame[1][8] = 1;
frame[1][9] = 1;
frame[2][8] = 1;
frame[2][9] = 1;
}
void mouth(){
//Mouth
frame[5][3] = 1;
frame[5][9] = 1;
frame[6][3] = 1;
frame[6][4] = 1;
frame[6][5] = 1;
frame[6][6] = 1;
frame[6][7] = 1;
frame[6][8] = 1;
frame[6][9] = 1;
}
void loop(){
leftEye();
rightEye();
mouth();
matrix.renderBitmap(frame, 8, 12);
delay(1000);
wink();
matrix.renderBitmap(frame, 8, 12);
delay(1000);
}
Ресурсы
Оставшаяся часть этой статьи — это коллекция ресурсов, таких как рабочие примеры, галерея кадров и инструменты, которые помогут вам начать работу с LED-матрицей различными способами.
Пример прокрутки текста
LED-матрица теперь поддерживает печать символов через библиотеку ArduinoGraphics. С её помощью вы можете:
Задать начальную позицию для текста через
matrix.beginText(x, y, 0xFFFFFF). Значение0xFFFFFFпредставляет цвет по умолчанию (красный). Поскольку библиотека ArduinoGraphics поддерживает другое оборудование с несколькими цветами, нам нужно его указать.Напечатать текст через
matrix.printText("Это сообщение напечатано")Завершить печать и (опционально) указать направление прокрутки с помощью
matrix.endText(direction)Поддерживаются
SCROLL_LEFTиSCROLL_RIGHT. Оставьте пустым, если прокрутка не нужна.
Приведённый ниже пример просто выводит «Hello World!» на матрице.
Важно
Для работы этого примера вам нужно установить библиотеку ArduinoGraphics для включения печати символов на LED-матрице с помощью менеджера библиотек.
// To use ArduinoGraphics APIs, please include BEFORE Arduino_LED_Matrix
#include "ArduinoGraphics.h"
#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix matrix;
void setup() {
Serial.begin(115200);
matrix.begin();
matrix.beginDraw();
matrix.stroke(0xFFFFFFFF);
// add some static text
// will only show "UNO" (not enough space on the display)
const char text[] = "UNO r4";
matrix.textFont(Font_4x6);
matrix.beginText(0, 1, 0xFFFFFF);
matrix.println(text);
matrix.endText();
matrix.endDraw();
delay(2000);
}
void loop() {
// Make it scroll!
matrix.beginDraw();
matrix.stroke(0xFFFFFFFF);
matrix.textScrollSpeed(50);
// add the text
const char text[] = " Hello World! ";
matrix.textFont(Font_5x7);
matrix.beginText(0, 1, 0xFFFFFF);
matrix.println(text);
matrix.endText(SCROLL_LEFT);
matrix.endDraw();
}
Галерея кадров
Мы разработали галерею кадров и анимаций, которые включены в библиотеку! Вы можете загрузить и отобразить их на вашем UNO R4 WiFi с помощью следующего фрагмента кода:
#include "Arduino_LED_Matrix.h" // Include the LED_Matrix library
ArduinoLEDMatrix matrix; // Create an instance of the ArduinoLEDMatrix class
void setup() {
Serial.begin(115200); // Initialize serial communication at a baud rate of 115200
matrix.begin(); // Initialize the LED matrix
}
void loop() {
// Load and display the basic emoji frame on the LED matrix
matrix.loadFrame(LEDMATRIX_EMOJI_BASIC);
}
Изменяя параметр в matrix.loadFrame() в цикле loop, вы можете выбирать среди доступных кадров, которые мы разработали.
Доступные кадры:
LEDMATRIX_BLUETOOTHLEDMATRIX_BOOTLOADER_ONLEDMATRIX_CHIPLEDMATRIX_CLOUD_WIFILEDMATRIX_DANGERLEDMATRIX_EMOJI_BASICLEDMATRIX_EMOJI_HAPPYLEDMATRIX_EMOJI_SADLEDMATRIX_HEART_BIGLEDMATRIX_HEART_SMALLLEDMATRIX_LIKELEDMATRIX_MUSIC_NOTELEDMATRIX_RESISTORLEDMATRIX_UNO
Альтернативно, воспроизведите одну из анимаций на LED-матрице вот так:
#include "Arduino_LED_Matrix.h" //Include the LED_Matrix library
// Create an instance of the ArduinoLEDMatrix class
ArduinoLEDMatrix matrix;
void setup() {
Serial.begin(115200);
// you can also load frames at runtime, without stopping the refresh
matrix.loadSequence(LEDMATRIX_ANIMATION_STARTUP);
matrix.begin();
matrix.play(true);
}
void loop() {
}
В этом случае вы меняете параметр matrix.loadSequence() в setup на один из доступных для отображения.
Доступные анимации:
LEDMATRIX_ANIMATION_STARTUPLEDMATRIX_ANIMATION_TETRIS_INTROLEDMATRIX_ANIMATION_ATMEGALEDMATRIX_ANIMATION_LED_BLINK_HORIZONTALLEDMATRIX_ANIMATION_LED_BLINK_VERTICALLEDMATRIX_ANIMATION_ARROWS_COMPASSLEDMATRIX_ANIMATION_AUDIO_WAVEFORMLEDMATRIX_ANIMATION_BATTERYLEDMATRIX_ANIMATION_BOUNCING_BALLLEDMATRIX_ANIMATION_BUGLEDMATRIX_ANIMATION_CHECKLEDMATRIX_ANIMATION_CLOUDLEDMATRIX_ANIMATION_DOWNLOADLEDMATRIX_ANIMATION_DVDLEDMATRIX_ANIMATION_HEARTBEAT_LINELEDMATRIX_ANIMATION_HEARTBEATLEDMATRIX_ANIMATION_INFINITY_LOOP_LOADERLEDMATRIX_ANIMATION_LOAD_CLOCKLEDMATRIX_ANIMATION_LOADLEDMATRIX_ANIMATION_LOCKLEDMATRIX_ANIMATION_NOTIFICATIONLEDMATRIX_ANIMATION_OPENSOURCELEDMATRIX_ANIMATION_SPINNING_COINLEDMATRIX_ANIMATION_TETRISLEDMATRIX_ANIMATION_WIFI_SEARCH
Генерация анимаций
Мы разработали инструмент, который используется для генерации кадров и анимаций для отображения на LED-матрице в вашем браузере. Этот инструмент является частью Arduino Labs и поэтому считается экспериментальным программным обеспечением.
Для использования инструмента вам нужно загрузить следующий скетч, позволяющий плате читать последовательные данные, отправляемые браузером.
Вы также можете найти скетч в File > Examples > LED_Matrix > LivePreview
#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix matrix;
void setup() {
Serial.begin(115200);
matrix.begin();
}
uint32_t frame[] = {
0, 0, 0, 0xFFFF
};
void loop() {
if(Serial.available() >= 12){
frame[0] = Serial.read() | Serial.read() << 8 | Serial.read() << 16 | Serial.read() << 24;
frame[1] = Serial.read() | Serial.read() << 8 | Serial.read() << 16 | Serial.read() << 24;
frame[2] = Serial.read() | Serial.read() << 8 | Serial.read() << 16 | Serial.read() << 24;
matrix.loadFrame(frame);
}
}
Нажмите здесь, чтобы перейти к инструменту LED Matrix.
Редактор LED-матрицы
После того как вы создали свои анимации, вы можете экспортировать их из инструмента в формате, который позволяет использовать их, как обсуждалось ранее.
Вы можете найти больше советов по использованию этого инструмента на его сайте.
API
Для написания более продвинутых скетчей самостоятельно вы можете использовать полный API библиотеки, приведённый ниже.
Метод |
Описание |
|---|---|
|
Основной класс для управления LED-матрицей. |
|
Устанавливает время в мс для отображения каждого кадра. |
|
Запускает LED-матрицу. |
|
Вручную переходит к следующему кадру в последовательности. |
|
Загружает новый одиночный кадр, не входящий в последовательность. |
|
Отрисовывает загруженный кадр. |
|
Загружает последовательность анимации в буфер, но не отображает её. |
|
Начинает воспроизведение последовательности кадров с возможностью бесконечного цикла или однократного воспроизведения. |
|
Проверяет, завершено ли воспроизведение последовательности. |
Описание методов
ArduinoLEDMatrix()
Создаёт новый объект LED-матрицы. Он будет использоваться для доступа к методам библиотеки.
ArduinoLEDMatrix LEDMatrix;
autoscroll()
Включает автоматическую прокрутку по кадрам в последовательности.
Параметры
interval_ms— устанавливает время в миллисекундах, которое должно быть потрачено на кадр перед переключением на следующий кадр в последовательности.
begin()
Запускает LED-матрицу.
LEDMatrix.begin()
next()
Вручную переходит к следующему кадру в последовательности.
LEDMatrix.next()
loadFrame()
Загружает одиночный кадр, не являющийся частью последовательности.
LEDMatrix.loadFrame(buffer[i])
Параметры
buffer[3]— массив из трёх 32-битных целых чисел, где каждый бит представляет светодиод.
renderFrame()
Отрисовывает определённый кадр из последовательности.
LEDMatrix.renderFrame(frameNumber)
Параметры
int— номер кадра для загрузки.
loadSequence()
Загружает последовательность анимации в буфер, но не отображает её.
LEDMatrix.frames[][4]
Параметры
frameNumber— указывает, какой кадр последовательности должен быть отрисован.
play()
Начинает воспроизведение загруженной последовательности.
LEDMatrix.play(state) //true or false
Параметры
loop—trueдля включения зацикливания последовательности,falseдля однократного воспроизведения.
sequenceDone()
Проверяет, завершено ли воспроизведение последовательности или кадр должен быть продвинут на ещё один шаг.
Возвращает
false, если последовательность не завершена,true, если завершена.