4095 светодиодов и все-все-все

Как ни удивительно, с выводом изображения на такой дисплей вполне справляется контроллер ATmega328, что лежит в основе Arduino Uno. Из этого всего получилась «карманная» консоль (весом несколько килограмм), в которую прошита игра по мотивам Space Invaders. В планах придумать что-нибудь ещё, ведь свободной памяти осталось полно.

Под катом вы сможете прочитать о том, как такой дисплей устроен и как им можно управлять.

Иногда вместо того, чтобы находить старые компьютеры в коллекцию, я делаю их самостоятельно из подручных материалов.

В этот раз хотелось сделать что-то компактное с разрешением на уровне приставок и компьютеров начала 80х. Правда дисплей в 64x64 пикселя не дотягивает до Atari 2600, но зато на целых 64 пикселя больше, чем дисплей Nokia 3310, где игры тоже были. Так что его должно было с запасом должно хватить как минимум для комфортной игры в тетрис или понг.


Кроме дисплея я раздобыл плату, совместимую с Arduino Uno, и стал думать как бы теперь со всем этим добром взлететь.

Компания Adafruit продаёт подобные дисплеи и на её сайте можно найти примеры их использования. Там же есть ссылка на библиотеку для работы с ними. Библиотека поддерживает Arduino Uno и Arduino Mega.

Эта библиотека организует видеопамять, где и хранит цвета пикселей. Пользовательская программа перекрашивает эти пиксели, а изображение выводится на дисплей в обработчике прерывания таймера. С маленькими дисплеями это работает неплохо, но в моём случае такой способ не годится. Даже если на каждый пиксель выделять по полбайта (по одному биту на R, G, B и один лишний), то для матрицы 64x64 понадобится 2 килобайта памяти. А это всё что есть у ATmega328P. Можно, конечно, взять процессор помощнее, но это не путь джедая.

Ведь кто нас заставляет хранить все строки экрана сразу? Можно вычислять каждую строку заново перед выв��дом на экран. Для примитивной графики из нескольких спрайтов эти вычисления не должны занять слишком много времени, поэтому всё должно сработать.


Дело было в лесу летней компьютерной школе, искать документацию на микросхемы и трассировать плату, чтобы понять что куда подключено, было лень. Поэтому алгоритм работы с дисплеем я выделил из заранее скачанных библиотек:

  • Выставляем на входах дисплея адрес выводимой строки
  • Заполняем массив цветами пикселей спрайтов, которые пересекаются с текущей строкой
  • Задвигаем по очереди все пиксели в сдвиговый регистр, который управляет светодиодами
  • Защёлкиваем полученные данные и подаём их на выходы регистров

В итоге под видеопамять выделен массив размером только в четыре строки экрана. Почему четыре? Всё потому, что одновременно мы задвигаем данные в две строки — ведь у матрицы две группы входов: R1/G1/B1 и R2/G2/B2. Управляют они двумя строками, отстоящими друг от друга на 16 пикселей.

Но тогда почему не две строки, а четыре? Оказывается, что матрица 64x64 состоит из двух независимых матриц 32x64. Можно было бы к каждой подключить отдельные выходы процессора, но у ATmega328 их недостаточно. К счастью, заботливый производитель предусмотрел каскадирование этих матриц — выход сдвигового регистра одной можно подключить ко входу другой. Тогда получится логическая матрица 32x128, которая физически отображается как 64x64. То есть в каждой фазе нам надо задвинуть в регистры две строки по 128 пикселей — а это и есть 4 строки физического экрана.



Прототип консоли мы сделали во время летней компьютерной школы. Первой игрой стало нечто, отдалённо напоминающее Space Invaders.



В реальности светодиоды очень уж выжигали глаза. Отрегулировать их яркость с помощью ШИМ вряд ли получится — быстродействия ATmega не хватает. Надо брать какой-нибудь ARM или ПЛИС.

Финальный вариант я оформил в деревянном корпусе. Экран защищён зашкуренным оргстеклом. За счёт рассеяния света глаза теперь не выжигаются, но на видео работу приставки теперь снять сложнее — всё изображение становится размытым.



Вся программа использует 1101 байт (53%) ОЗУ и 6432 (19%) байт ПЗУ. Остаётся ещё место, чтобы сделать несколько игр и меню для их выбора.

Ссылки

  1. Исходники проекта: github.com/Dovgalyuk/BackspaceInvaders
  2. Описание работы матрицы на сайте adafruit: learn.adafruit.com/32x16-32x32-rgb-led-matrix
  3. Библиотека от adafruit для управления матрицей: github.com/adafruit/RGB-matrix-Panel
  4. Библиотека от adafruit для рисования графических примитивов: github.com/adafruit/Adafruit-GFX-Library
  5. Похожий проект на более мощном процессоре: learn.adafruit.com/ledgames-beaglebone-black-64x64-led-game/overview
  6. Статья про управление дисплеем меньшего размера: geektimes.ru/post/275548