Создание "Эффекта Матрицы" на ESP32-C3 и WS2812B
В мире программирования и электроники даже простые задачи могут потребовать значительных усилий, особенно если речь идет о создании визуальных эффектов. Одним из таких эффектов является знаменитый "эффект Матрицы" — падающие строки зеленых символов, которые стали визитной карточкой этого фильма. Я решил воссоздать этот эффект на светодиодной матрице 8x8, используя светодиоды WS2812 и микроконтроллер ESP32 C3. Однако, как это часто бывает, задача оказалась сложнее, чем я ожидал. В этой статье я расскажу о своем опыте и о том, как ChatGPT помог мне справиться с этой задачей.
Поиск готового решения
Первым шагом я решил поискать готовое решение в интернете. Я перерыл множество форумов, но, к своему удивлению, не нашел ничего подходящего. Оказалось, что реализация "эффекта Матрицы" на светодиодной матрице WS2812 — не такая уж популярная задача, как я предполагал. Я понял, что придется писать код с нуля.
Применение ChatGPT
Поскольку я не хотел тратить слишком много времени на написание кода с нуля, я решил обратиться за помощью к ChatGPT. Я описал задачу: необходимо было создать анимацию падающих пикселей, имитирующую "эффект Матрицы". ChatGPT предложил использовать библиотеку FastLED для управления светодиодной матрицей и генерации случайных пикселей, которые будут "падать" сверху вниз.
Первые несколько попыток генерации попыток не увенчались успехом. Код либо не работал, либо эффект был далек от того, что я хотел увидеть. То пиксели двигались однообразно, то анимация выглядела неестественно. Каждый раз приходилось вносить правки и корректировать код, чтобы приблизиться к желаемому результату.
Финальный результат
После нескольких десятков генераций кода я наконец выбрал наиболее подходящий вариант кода и отредактировал его под свои потребности. В итоге мне удалось добиться эффекта, который напоминал знаменитые падающие строки из "Матрицы". Пиксели плавно двигаются сверху вниз, создавая иллюзию бесконечного потока данных. Результат можно увидеть на видео, которое я приложил к статье.
Итоговый вариант кода:
#include <FastLED.h>
#define LED_PIN 4 // data pin подключаем к ws2812
#define MATRIX_WIDTH 8 // количество светодиодов по горизонтали
#define MATRIX_HEIGHT 8 // количество светодиодов по вертикали
#define NUM_LEDS MATRIX_WIDTH*MATRIX_HEIGHT //общее количество светодиодов
#define BRIGHTNESS 64 // яркость свечения
#define LED_TYPE WS2812 // тип светодиодов
#define COLOR_ORDER GRB // цветовая последовательность
CRGB leds[NUM_LEDS]; // массив экрана
// Параметры эффекта
#define MAX_TRAILS 4 // количество одновременно выпадающих сверху экрана пикселей
#define TAIL_MIN 2 // мин. длина хвоста падающего пикселя не менее 1
#define TAIL_MAX 6 // макс. длина хвоста падающего пикселя не более 7
#define MIN_SPEED 10 // минимальная скорость пикселя
#define MAX_SPEED 100 // максимальная скорость пикселя
#define MIN_FADING BRIGHTNESS // минимальная яркость хвоста
#define MAX_FADING 200 // максимальная яркость хвоста
#define FRAME 90 // длительность показа кадра
struct PixelTrail // структура падающего пикселя
{
uint8_t x;
uint8_t y;
uint8_t speed;
uint8_t length;
uint8_t delay;
};
PixelTrail trails[MAX_TRAILS];
void setup()
{
// Инициализация светодиодов
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
for (uint8_t i = 0; i < MAX_TRAILS; i++) // Инициализация параметров стартовых пикселей
{
trails[i].x = random(MATRIX_WIDTH); // количество пикселей матрицы по горизонтали
trails[i].y = random(MATRIX_HEIGHT); // количество пикселей матрицы по вертикали
trails[i].speed = random(MIN_SPEED, MAX_SPEED); // Скорость падения
trails[i].length = random(TAIL_MIN,TAIL_MAX); // длина хвоста падающего пикселя
trails[i].delay = millis(); // таймер старта выпадающего пикселя
}
}
void loop()
{
fadeToBlackBy(leds, NUM_LEDS,random(MIN_FADING,MAX_FADING)); // Уменьшить яркость пикселей
for (uint8_t i = 0; i < MAX_TRAILS; i++)
{
if (millis() - trails[i].delay > trails[i].speed)
{
trails[i].y++;
if (trails[i].y >= MATRIX_HEIGHT)
{
trails[i].y = 0;
trails[i].x = random(MATRIX_WIDTH);
trails[i].speed = random(MIN_SPEED, MAX_SPEED);
trails[i].length = random(TAIL_MIN, TAIL_MAX); // длина хвоста тянущегося за пикселем
}
trails[i].delay = millis();
}
for (uint8_t j = 0; j < trails[i].length; j++)
{
uint8_t yPos = trails[i].y - j;
if (yPos >= 0) // формируем затухающий хвост пикселя
{
leds[XY(trails[i].x, yPos)] = CHSV(96, 255, 255 - j * (255 / trails[i].length)); // CHSV(hue, saturation, val) тон. насыщенность, яркость
}
}
}
FastLED.show();
delay(FRAME); // длительность кадра
}
uint8_t XY(uint8_t x, uint8_t y) // расчет координат точек на матрице
{
return (y * MATRIX_WIDTH) + x;
}
Схема подключения
В этом проекте я использовал следующие компоненты:

Выводы
Этот опыт показал мне, что даже с помощью современных инструментов, таких как ChatGPT, создание уникальных визуальных эффектов требует времени и терпения. Хотя ChatGPT предоставил хорошую основу для кода, мне все равно пришлось вносить правки и дорабатывать его, чтобы добиться желаемого результата. Тем не менее, использование ИИ значительно ускорило процесс разработки и помогло мне справиться с задачей, которая изначально казалась сложной.
В заключение хочу сказать, что создание "эффекта Матрицы" на ESP32 и WS2812 - это Ардуино проект который может быть интересен как новичкам, так и опытным разработчикам. И если у вас есть доступ к инструментам, таким как ChatGPT, не бойтесь экспериментировать и пробовать что-то новое.

0 комментариев