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)


  1. Andy_Big
    19.04.2017 16:57

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

    Под каким катом можно это прочитать?


    1. Dovgaluk
      19.04.2017 17:20

      Чего-то конкретно не хватает?


      1. Dark_Purple
        19.04.2017 20:28

        Не хватает информации по дисплею. Шаг пикселей? В дисплее есть «память» под каждый пиксель?


        1. Dovgaluk
          19.04.2017 21:02

          Размер самого модуля — около 20 см.
          Строго говоря, память в нём есть — сдвиговые регистры в каждом из 16-строчных блоков.
          Т.е. можно выбрать адрес, загрузить 4 строки, соответствующие этому адресу, и они сами будут светиться.


          1. Dark_Purple
            19.04.2017 21:06

            Сходил по сылке, матрица P3 — 3мм шаг.


            1. Dovgaluk
              19.04.2017 21:10

              Да, где-то так и есть. А зачем такая точность с размерами?


              1. Dark_Purple
                19.04.2017 21:15

                Я купил такую матрицу P2. Verilog изучаю. ))


                1. Dovgaluk
                  20.04.2017 08:27

                  Будет интересно увидеть результат.


  1. madf
    19.04.2017 18:24
    +3

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


    1. Dovgaluk
      19.04.2017 18:33

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


      1. nikitosk
        19.04.2017 20:52

        ссылку на дисплей можно?


        1. Dovgaluk
          19.04.2017 20:59

          Я брал вот этот, но потом находил и подешевле.


  1. ukt
    19.04.2017 19:46

    Идея понравилась, заретрогеймить на «современном» железе с закосом под олдскул.

    Астероидс добавите? )


    1. Dovgaluk
      19.04.2017 20:04

      На таком разрешении астероиды, боюсь, будут совсем страшненькие. Но подумать можно.


      1. Sun-ami
        19.04.2017 21:30
        +1

        Можно сделать подобие арканоида


  1. Sun-ami
    19.04.2017 21:24
    +1

    В чём проблема регулировать яркость ШИМ'ом? Для этого предназначен вывод OE. На него можно подать ШИМ частотой несколько сот герц. Для того, чтобы исключить интерференцию этого ШИМ'а с частотой переключения фаз динамической индикации нужно сделать частоту ШИМ'а кратной частоте переключения фаз. При этом ШИМ на OE можно генерировать аппаратно таймером, синхронизировать его с фазами динамической индикации не обязательно.


    1. Dovgaluk
      19.04.2017 21:25
      +1

      Да, интересная идея, надо попробовать. Я пробовал просто делать задержку после вывода каждой строки, но большой частоты так не получить.


  1. sashabeep
    20.04.2017 00:56

    Проще всех с яркостью — накрыть это добро полупрозрачным тонированным зеркалом. Выдумываете вечно проблемы и способы их решения «не с того угла». Да и просто в него можно будет смотреть как в зеркало, когда не светится


    1. nochkin
      20.04.2017 03:34

      В этом случае яркость будет фиксирована и её намного сложнее будет поменять, так как надо менять-добавлять стекло.


      1. sashabeep
        20.04.2017 10:32

        В любом случае, ее надо поменять только 1 раз :)


        1. nochkin
          20.04.2017 23:47

          Почему один раз? Изменилась обстановка или освещение (утро-день-вечер) и уже надо менять для более комфортной игры.


    1. nafikovr
      20.04.2017 09:38

      тогда уж зеркало и ставить.


  1. Tachyon
    20.04.2017 11:26

    Делюсь с Dovgaluk секретом таксистов- они на яркий экран дешевых китайских магнитол, слепящий ночью, наклеивают кусочек тонировочной плёнки, с нужным коэффициентом затемнения. Так и слепить перестаёт и днём видно, и нет размывания изображения как у вас от матового оргстекла. С китая же как и магнитолы тонировочная плёнка будет копейки стоить, тем более её тут не много надо, возможно даже необходимый кусочек в ближайшей автомастерской в обрезках найдёте. Завидую немного тому как всё это реализовано — можно на кикстартер для гиков выводить :). Спасибо за статью.


    1. Dovgaluk
      20.04.2017 11:32

      Спасибо за совет.
      На самом деле с размытием тоже неплохо. Почти как Spectrum, подключённый к старому телевизору.


      1. Tachyon
        20.04.2017 14:59

        Я вот тоже про тонировочную плёнку подумал- она уменьшит яркость, но не сгладит очертания пикселей, матовое стекло размывает острые грани, объединяя отдельные пиксели в цельную фигурку, наверное даже лучше так.


  1. PKav
    20.04.2017 12:33

    Экраны безрамочные, их бы поставить 4 квадратом, и получилось бы уже 128x128.
    Правда, скорее всего, от ардуины пришлось бы избавиться, но результаты бы вышел в разы лучше.


    1. Dovgaluk
      20.04.2017 13:01

      Всё так. Но портативной она бы перестала быть.


  1. KOTYAR
    20.04.2017 14:56

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


    1. Dovgaluk
      20.04.2017 14:57

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


      1. mkc
        20.04.2017 15:01

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


        1. Dovgaluk
          20.04.2017 15:04

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


          1. mkc
            20.04.2017 15:21

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