Backspace Invaders или как подключить светодиодный дисплей 64x64 к Arduino

  • Tutorial

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
Метки:
Поделиться публикацией
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама
Комментарии 32
  • 0
    Под катом вы сможете прочитать о том, как такой дисплей устроен

    Под каким катом можно это прочитать?
    • 0
      Чего-то конкретно не хватает?
      • 0
        Не хватает информации по дисплею. Шаг пикселей? В дисплее есть «память» под каждый пиксель?
        • 0
          Размер самого модуля — около 20 см.
          Строго говоря, память в нём есть — сдвиговые регистры в каждом из 16-строчных блоков.
          Т.е. можно выбрать адрес, загрузить 4 строки, соответствующие этому адресу, и они сами будут светиться.
          • 0
            Сходил по сылке, матрица P3 — 3мм шаг.
            • 0
              Да, где-то так и есть. А зачем такая точность с размерами?
              • 0
                Я купил такую матрицу P2. Verilog изучаю. ))
                • 0
                  Будет интересно увидеть результат.
    • +3

      Нет описания конкретного используемого дисплея (адафрут много чего выпускает).
      В игрушке сильно не хватает взрывов захватчиков, просто пропадание — не смотрится.
      Вообще статья так подана, будто старались специально многое скрыть и не рассказать. :)

      • 0
        Дисплей не от adafruit, а с aliexpress. Но принцип работы у них одинаковый.
        Про взрывы согласен, игрушку еще будем дорабатывать.
        А детали я сознательно опускал, чтобы раскрыть основное — логическую организацию дисплея, потому что именно это не очень понятно из того, что удалось найти в интернете. Софт я еще буду перерабатывать и обязательно про это напишу.
    • 0
      Идея понравилась, заретрогеймить на «современном» железе с закосом под олдскул.

      Астероидс добавите? )
      • 0
        На таком разрешении астероиды, боюсь, будут совсем страшненькие. Но подумать можно.
        • +1
          Можно сделать подобие арканоида
      • +1
        В чём проблема регулировать яркость ШИМ'ом? Для этого предназначен вывод OE. На него можно подать ШИМ частотой несколько сот герц. Для того, чтобы исключить интерференцию этого ШИМ'а с частотой переключения фаз динамической индикации нужно сделать частоту ШИМ'а кратной частоте переключения фаз. При этом ШИМ на OE можно генерировать аппаратно таймером, синхронизировать его с фазами динамической индикации не обязательно.
        • +1
          Да, интересная идея, надо попробовать. Я пробовал просто делать задержку после вывода каждой строки, но большой частоты так не получить.
        • 0
          Проще всех с яркостью — накрыть это добро полупрозрачным тонированным зеркалом. Выдумываете вечно проблемы и способы их решения «не с того угла». Да и просто в него можно будет смотреть как в зеркало, когда не светится
          • 0
            В этом случае яркость будет фиксирована и её намного сложнее будет поменять, так как надо менять-добавлять стекло.
            • 0
              В любом случае, ее надо поменять только 1 раз :)
              • 0
                Почему один раз? Изменилась обстановка или освещение (утро-день-вечер) и уже надо менять для более комфортной игры.
            • 0
              тогда уж зеркало и ставить.
            • 0
              Делюсь с Dovgaluk секретом таксистов- они на яркий экран дешевых китайских магнитол, слепящий ночью, наклеивают кусочек тонировочной плёнки, с нужным коэффициентом затемнения. Так и слепить перестаёт и днём видно, и нет размывания изображения как у вас от матового оргстекла. С китая же как и магнитолы тонировочная плёнка будет копейки стоить, тем более её тут не много надо, возможно даже необходимый кусочек в ближайшей автомастерской в обрезках найдёте. Завидую немного тому как всё это реализовано — можно на кикстартер для гиков выводить :). Спасибо за статью.
              • 0
                Спасибо за совет.
                На самом деле с размытием тоже неплохо. Почти как Spectrum, подключённый к старому телевизору.
                • 0
                  Я вот тоже про тонировочную плёнку подумал- она уменьшит яркость, но не сгладит очертания пикселей, матовое стекло размывает острые грани, объединяя отдельные пиксели в цельную фигурку, наверное даже лучше так.
              • 0
                Экраны безрамочные, их бы поставить 4 квадратом, и получилось бы уже 128x128.
                Правда, скорее всего, от ардуины пришлось бы избавиться, но результаты бы вышел в разы лучше.
                • 0
                  Всё так. Но портативной она бы перестала быть.
                • 0

                  А почему она весит так много, из-за аккумулятора для панели?

                  • 0
                    Там сетевой блок питания на 20 ампер.
                    И стенки из ~23мм дуба.
                    • 0

                      А реальное потребление какое?

                      • 0
                        Не знаю, не пробовал измерять.
                        Я ориентировался на советы Adafruit, в которых сказано, что матрица 32x32 может потреблять 4 Ампера.
                        • 0

                          Т.е. До 16-ти ампер, обалдеть...

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.