Авторизация
Регистрация

Напомнить пароль

DIY контроллер LED панели на CPLD

Некоторое время назад участвовал в обсуждении DIY проекта матричных светодиодных часов
И что меня удивило — в качестве устройства отображения использовались древние одноцветные светодиодные матрицы 8х8 с шагом 5 миллиметров. Причём под них разводились сложные печатные платы, делалась софтовая динамическая индикация. И это в то время, когда уже давно доступны по цене в районе 10-20$ готовые полноцветные панели 64х32 с шагом 3 мм. А общий ассортимент подобных панелей очень большой и имеет шаг пикселя от 2 до 10 мм и практически любой размер.

В то же время использовать такие панели в DIY конструкциях достаточно непросто — готовые контроллеры стоят довольно больших денег и не имеют нормального API. Сделать же достаточно быстрое сканирование панели на обычно используемых в DIY микроконтроллерах достаточно сложно. Причём временные интервалы должны выдерживаться с высокой точностью — иначе начинается заметная неравномерность яркости.
Есть неплохие решения на Adafruit, но они все достаточно дорогие и сложные.
После некоторого раздумья возникла мысль — а почему бы не сделать предельно недорогую плату, которая будет мостом между обычной копеечной платой типа ардуино и LED панелью? После какой-то пары месяцев возни родилось что-то работающее :)

Задача и проблемы

Хотелось бы иметь возможность управлять сборной панелью общим размером хотя бы 64х64, имея при этом возможность работы хотя бы в Highcolor (RGB565) с сохранением приемлемой частоты обновления экрана (не менее 50Гц).
Основная сложность заключается в том, что на LED панелях градации цвета формируются только через PWM, причём последовательный. Таким образом для того, чтобы сформировать 64 уровня яркости — за время индикации одного кадра надо 64 раза выдать картинку. То есть 64х50=3200 Гц частота выдачи полной «однобитной» картинки. Следовательно — для выдачи экрана 64х64 надо выдавать данные пикселей со скоростью 3200х64х64=13 Мпикселей/секунду.

Реализация

Все файлы на GITHUB
Совершенно очевидным было то, что без CPLD или FPGA здесь не обойтись — выдавать 26 МБ/сек на недорогих микроконтроллерах физически невозможно.
В качестве памяти мне на форуме IXBT порекомендовали очень интересную FIFO память Averlogic AL422B, которая имеет примерно 400кбайт памяти и может работать на частотах до 50МГц.
Учитывая, что моим основным требованием была максимальная дешевизна компонентов, чтобы готовая платка была доступна самодельщикам — была выбрана Altera EPM3064 — CPLD c 64мя макроячейками. В то же время столь малое количество макроячеек не позволяет сделать динамически конфигурируемую плату — конфигурацию необходимо компилировать непосредственно в CPLD.
Получившаяся схема лежит здесь
Детали:
CPLD EPM3064ATC44-10 — цена на Ali примерно 13-15$ за десяток
FIFO RAM AL422B — цена на Ali примерно 15$ за десяток
Кварцевый генератор на 50МГц. На плате предусмотрена установка в корпусах DIP14/DIP8/7050. Цена на Ali примерно 6-7$ за десяток
Стабилизатор на 3.3В в корпусе SOT223 — chipdip — 40р за штуку
Разъем IDC-10MS — chipdip — 3 р/штуку
Разъем IDC-16MS — chipdip — 8 р/штуку
Разъём IDC-14MS — chipdip — 7 р/штуку
Конденсаторы 1мкФ 0805 — 8 штук примерно по 1 р/штуку
Конденсатор 0,1мкФ 0805 — примерно по 1 р/штуку
Резистор 10к 0805 — копейки :)
Итого по деталям получается 1,5+1,5+0,7=3,7$ и 40+3+8+7+8*1+1=67 р. Всё вместе в пределах 5$ — копейки.
Исходный рисунок платы лежит здесь
Подготовленные gerber файлы для заказа
При пайке платы не забыть запаять перемычки на питание на обратной стороне платы.



Расчёт частоты обновления и ограничения по размерам

Прежде всего необходимо понимать ограничения по размерам сборной панели. Общий размер ограничен частотой кадров (мерцания панели).
Для RGB888 частота регенерации = 50МГц/3/256/кол-во пикселей, то есть, например, для панели 32х32 — 64Гц.
Для RGB565 частота регенерации = 50МГц/2/64/кол-во пикселей, то есть для панели 32х32 — 381Гц.
Глаз более-менее терпит частоту от 50Гц, поэтому для RGB888 максимальный размер сборки примерно 32х32 или 64х16. Для RGB565 — 128х64 или 256х32 (частота регенерации 48Гц).

Коммутация LED панелей

Все панели соединяются последовательно. Схема соединения: сперва справа-налево, потом снизу-вверх. То есть сперва соединяем горизонтали последовательно, потом выход нижнего ряда ко входу второго снизу ряда и т.д. до верхнего ряда.
Контроллер цепляется к правой нижней панели.
Бывают панели, которые имеют по два входных и два выходных разъёма. Такие панели по сути являются просто механической сборкой двух панелей по вертикали. Коммутируются как две независимые панели.
После сборки надо посчитать общую длину цепочки в пикселях — для этого смотрим — сколько всего панелей получилось в цепочке и умножаем это число на ширину панели в пикселях. Это число потом надо будет вбить в значение PIXEL_COUNT при конфигурации FPGA.

Прошивка FPGA

Все необходимые файлы лежат на github. Скачивать нужно прямо папкой.
С сайта Altera после регистрации необходимо скачать и установить Quartus II 13.0sp1. Качать надо ИМЕННО ЭТУ версию — более новые версии уже не поддерживают серию MAX3000. Ломать её не надо — достаточно Web edition (free) версии. При скачивании не забудьте поставить галочки на поддержке MAX3000 и Programmer.
Еще понадобится Altera USB Blaster — обычная цена на ali порядка 3$
Открываем проект al422b_2rgb_8s.qpf
Слева открываем закладку файл и открываем файл led_al422_main.v — это основной файл проекта. В нём надо настроить параметры:

Используемое цветовое пространство. TRUECOLOR — 3 байта на пиксель, формат RGB888. HIGHCOLOR — 2 байта на пиксель, формат RGB565.
Должна быть раскомментирована только одна нужная строка:
//`define TRUECOLOR	1
`define HIGHCOLOR	1

Сколько RGB входов на панели — на панелях со входом HUB75 может быть 1 или 2 входа RGB. Выяснить — сколько именно входов можно таким способом — берём количество пикселей на панели по вертикали. Делим её на число линий сканирования (указано в обозначении панели как 8S, например). Делим на количество входных разъёмов (1 или 2). Например — у меня панель 32х32, сканирование 8S и два входных разъёма — 32/8/2=2 — значит два входа RGB.
Должна быть раскомментирована только одна нужная строка:
//`define RGB_out1	1
`define RGB_out2	1

Сколько линий сканирования на панели — так как поддерживается стандарт HUB75E, то может быть до 32х. Количество линий сканирования обычно есть в названии панели в виде 8S/16S/32S соответственно.
Должна быть раскомментирована только одна нужная строка:
`define SCAN_x8 	1
//`define SCAN_x16 	1
//`define SCAN_x32	1

Общее число пикселей по горизонтали в цепочке. Считаются пиксели во всей цепочке панелей — см. раздел выше «Коммутация LED панелей»
`define PIXEL_COUNT 	64

Фазы выходных сигналов. Наиболее типичная конфигурация такая — OE активен по низкому уровню (коммент снят), CLK работает по фронту (коммент стоит), LAT активен по высокому уровню (коммент стоит). Возможно всякие странные варианты. Выяснять какой именно у вас только экспериментальным способом или снятием схемы и поиском даташитов на используемые микросхемы).
`define LED_OE_ACTIVE_LOW	1
//`define LED_CLK_ON_FALL		1
//`define LED_LAT_ACTIVE_LOW	1

Пред и пост задержки сигнала OE относительно LAT. Предназначены для подавления расплывания пикселей по вертикали в момент коммутации рядов (коммутаторы обычно сильно тормозные). Обычные значения 2/2 — меньше лучше не делать. Увеличение значений приводят к уменьшению общей яркости, поэтому можно использовать для снижения максимальной яркости. Ограничение — в сумме должны быть меньше, чем PIXEL_COUNT.
`define OE_PREDELAY	2
`define OE_POSTDELAY	2

Всё, нажимаем ctrl-L — проект компилируется. Если нигде не напортачили — будет несколько warnings, но не должно быть никаких ошибок. Дальше цепляем спаянную плату к USB Blaster, подаём питание на плату. В Quartus идём в tools — programmer. Выбираем в Hardware setup USB-blaster, нажимаем Start. Всё, CPLD запрограммирована.

Микроконтроллерная часть

Выдача данных на контроллер, в общем-то, предельно проста — сбрасываем адрес записи и потом последовательно выдаём байты данных, стробируя их сигналом WCLK. И вроде бы даже банальной ардуинки хватит для работы. Но есть две проблемы:
а) Надо много памяти. Даже небольшая панель 32х32 в режиме RGB565 требует 2кБайта памяти под экранный буфер. Обычные ардуино на базе Atmega328 содержат всего 2кбайта оперативки. Можно, конечно, использовать плату Mega на базе Atmega2560, которая содержит аж 8 кБайт оперативки, но даже этого мало для панелей нормального размера — панель 128х64 в режиме RGB565 требует 16кБайт памяти.
б) В процессе работы с AL422B вылез не документированный нигде глюк — при записи данных со скоростью меньше 2МБ/сек счётчик адресов работает некорректно и пишет данные «не туда». Возможно это глюк имеющейся у меня партии. Возможно нет. Но этот глюк приходится обходить. Учитывая, что AVR8 работает на 16МГц, то получить с неё данные на нужных скоростях почти нереально.
Предлагаемое решение — уйти на дешёвые платки на базе 32-х битного контроллера STM32F103C8T6. Такая платка стоит на Ali примерно 2.5$ поштучно или около 1.7$ при покупке десятком, то есть дешевле даже Arduino Nano. При этом мы получаем полноценный 32-х битный микроконтроллер, работающий на 72 МГЦ и имеющий 20 кБ оперативной памяти и 64 кБ флеша (сравните с 2кБ/8кБ Atmega328, которая стоит на Nano).
При этом такие платы вполне успешно программируются в среде Arduino. Про это есть неплохая статья на гиктаймс, поэтому я не буду её дублировать. В общем — делайте всё, как описано в статье.
В среде ардуино выбирайте плату Generic STM32F103C, variant STM32F103C8. Рекомендую выбирать режим оптимизации Fastest (-O3). Впрочем, сейчас данные всё равно идут через DMA, поэтому можно использовать любой вариант.

Коммутация происходит по следующей схеме:
Жёстко прибиты в библиотеке:
A0..A7 -> DI0..DI7 AL422B
B0 -> WCLK AL422B
B1 -> WRST AL422B
Назначается в скетче на контроллер:
B10 -> WE AL422B
Общий провод:
G -> GND

Ну и не забудьте подать питание 5В/GND от панели на соответствующие пины контроллера.

Распиновку разъема на контроллере брать со схемы



Программная часть

Так как ставилась задача сделать всё максимально просто и доступно, то весь софт сделан под среду Arduino и оформлен в виде библиотеки LED_PANEL
Библиотека LED-PANEL активно использует библиотеку Adafruit GFX, поэтому она должна быть инсталлирована.
Я настоятельно рекомендую не ставить библиотеку LED_PANEL в каталог libraries, а оставить её в папке со скетчем. Дело в том, что там много железно привязанных параметров и если вы захотите перенести работу на более «жирный» микроконтроллер, то придётся много чего менять в самом коде.

Инициализация идёт примерно в таком виде:

#include "LED_PANEL.h"
 
#define width 32
#define height 32
#define bpp 2
 
#define scan_lines  8
#define RGB_inputs  2
 
#define we_out_pin PB10
 
LED_PANEL led_panel = LED_PANEL(width, height, bpp, scan_lines, RGB_inputs, we_out_pin);

то есть создаём экземпляр класса LED_PANEL, для которого указываем параметры:
width — общая ширина панели в пикселях (всего)
height — общая высота панели в пикселях (всего)
bpp — байт на пиксель, соответственно 2 для RGB565 или 3 для RGB888. Должно соответствовать режиму, прошитому в контроллер.
scan_lines — количество линий сканирования — 8/16/32. Должно соответствовать режиму, прошитому в контроллер.
RGB_inputs — количество RGB входов в разъеме HUB75 — 1/2. Должно соответствовать режиму, прошитому в контроллер.
we_out_pin — пин, к которому подцеплен вывод WE

Обращаю внимание, что при инициализации задаётся только пин WE. Все остальные пины прописаны жёстко в коде, так как они привязаны к используемым каналам таймера и DMA и их изменение повлечёт существенные изменения в коде.

Запуск и очистка экрана в разделе setup:

  led_panel.begin();
  led_panel.clear();

begin инициализирует нужные пины на выход, подключает таймер и DMA
clear очищает буфер

Для рисования можно использовать все стандартные процедуры библиотеки Adafruit GFX — от простейшего drawPixel до вывода текста.
Для выдачи нарисованного в буфер используется процедуры:
led_panel.show();
В таком виде show инициирует передачу данных на контроллер по DMA и немедленно возвращает управление. Узнать — закончилась ли передача можно с помощью функции led_panel.OutIsFree() — если она говорит true, то значит передача закончилась. Есть особенность — если вызвать show, когда передача еще не завершилась — она будет просто проигнорирована.

led_panel.show(false);
аналог show(), но если вызвать show(false), а передача еще не завершилась, то процедура подождёт завершения передачи, потом начнёт новую передачу и вернёт управление

led_panel.show(true);
аналог show(false), но если вызвать show(true), то после начала новой передачи процедура не вернёт управления до завершения передачи

В общем-то — всё.


Некоторые замечания по софту:
а) гамма-коррекция вводится только при использовании режима панели RGB888 при пересчёте цвета из RGB565 (который использует библиотека) функцией ExpandColor. Во всех прочих случаях используется линейная трансфер-функция, то есть яркость прямо пропорциональна значению.
б) софт позволяет подключать несколько LED-контроллеров к одной микроконтроллерной плате. Для этого надо отдать на контроллеры параллельно шину данных, линии RST и CLK. Нужный контроллер выбирается через линию WE. В софте нужно создать отдельный экземпляр класса LED_PANEL для каждого контроллера, при этом у каждого экземпляра при инициализации должны быть указаны разные линии WE (последний параметр).

Ну и теперь —

TO DO

— разобраться с «наводкой» цветов на соседние ряды. Похоже на плохую разводку самой панели (ключи мусорят), но надо проверить.
— сделать класс META_LED_PANEL, который позволит объединять несколько LED_PANEL в один виртуальный экран — это даст возможность создавать большие экраны
— в перспективе уйти на более мощную серию CPLD, например MAXII. Это бы существенно расширило возможности при сохранении невысокой стоимости (EPM1270, который в 20 раз мощнее, стоит 4-5$ штука). Но этим я буду заниматься когда-нибудь потом. Если захочу :) Так как подобные разработки отнимают уж слишком много времени.
Планирую купить +18 Добавить в избранное
+73 +111
свернутьразвернуть
Комментарии (105)
RSS
+
avatar
+3
«ключи мусорят» — так подтягивающие резисторы скорее всего спасут ситуацию, но паять дофига придется.
+
avatar
0
Спасут, причем чем ниже сопротивление — тем лучше спасут. Но надо считать нагрузку на пин и нагрузку на порт чтобы не превысить. И еще если она и в тепле шумит — на холоде от -20 совсем с ума сходить будет.
+
avatar
+1
  • Andy4440
  • 28 декабря 2017, 15:50
Итого по деталям получается 1,5+1,5+0,7=3,7$ и 40+3+8+7+8*1+1=67 р.
А как же цена самой лед панели? Где ее брали и по чем? Цена вопроса вся видимо в ней?
+
avatar
0
  • drv
  • 28 декабря 2017, 15:52
Например, такая панель.
+
avatar
+1
Конкретно та панель, на которой тестирую сейчас, валялась у меня на полке уже года два, поэтому на неё ссылку дать затруднительно. Панель P3 64х32 сейчас можно купить примерно за 20$, если одну штуку. Если больше, то дешевле.
+
avatar
0
  • drv
  • 28 декабря 2017, 15:50
Интересное решение.
В свое время запускал подобную панель 64х32 на Orange Pi Zero.
RGB565 завелось нормально. Правда не без танцев с бубном.
Использовался SPI и буферные элементы для для согласования уровней, так как панелька была 5-ти вольтовая.
+
avatar
+1
Эти панели все 5-ти вольтовые. Но прекрасно едят и выход 3.3В
+
avatar
0
  • drv
  • 28 декабря 2017, 16:05
Это если вам повезло, и у вас на панели установили что то подобное LVC245, а не HC245, как у меня :) Которые ни в какую не работали от 3.3 логики.
+
avatar
+1
Именно HC245 у меня и стоят :)
+
avatar
0
  • drv
  • 28 декабря 2017, 16:48
Вам повезло с 245 от NXP, у них пошире пороги, а что делать тем у кого Fairchild распаян :)
Но всё равно на грани работаете, особенно на таких скоростях. Возможно и проблемы с засветами отдельных пикселей уйдут, если уровни согласовать.
+
avatar
+1
Ну, честно говоря — да, слегка лажанулся :) Сперва развёл и заказал платы, а потом уже подумал, что неплохо бы и преобразователи уровней на выход поставить. В следующую версию добавлю.
+
avatar
0
У 5-вольтовой логики уровень лог.1 находится около 1.8-2.1В что прекрасно попадает в диапазон выходного напряжения 3.3В логики.
+
avatar
+1
а не поделитесь ссылками на информацию как на зерошке завести подобную панель?
+
avatar
0
Присоединяюсь к вопросу!
+
avatar
+1
Вроде на adafruit есть мануал
Там, правда, предполагается использование их переходника, но, вроде, это не обязательно.
+
avatar
0
  • Sidula
  • 28 декабря 2017, 16:21
Для поделок вроде часов или табло можно и 8-ю цветами ограничиться. Тогда, наверное, даже ардуиной можно обойтись.
У адафрута есть библиотеки для ардуины для таких панелей, правда к UNO больше чем 32*32 не подключить и места почти не остаётся.
+
avatar
+3
  • AndyBig
  • 28 декабря 2017, 16:35
Жирный плюс за CPLD и Verilog :)
+
avatar
+1
  • maxspb69
  • 29 декабря 2017, 09:10
Присоединяюсь! Жаль нельзя три сразу поставить! :)
+
avatar
+4
  • mooni73
  • 28 декабря 2017, 16:54
Во как! Статьи уровня хабра выходят не там, а тут! Интересно почему.
+
avatar
+3
Да как-то я там особо не тусуюсь…
+
avatar
0
Согласен. Молодец автор. Жирно плюсую.
+
avatar
0
  • Kasatich
  • 29 декабря 2017, 09:41
На хабре бы скорее всего сказали фи — ну собрал человек несколько стоковых деталей и собрал))
+
avatar
+1
  • AndyBig
  • 29 декабря 2017, 14:57
На гиктаймсе оценили бы, я думаю :)
+
avatar
+2
Ну, теоретически можно там разместить — вроде эккаунт у меня там есть. Не помню — там или здесь не запрещено размещение одного и того же (кросспостинг)?
+
avatar
0
  • AndyBig
  • 29 декабря 2017, 15:40
Там, по-моему, неодобрительно относятся к копипасте, но там Вы можете сделать акцент, к примеру, на «верилог для маленьких на примере полезной приблуды» :)
+
avatar
0
Ну вот, разместил новую версию на geektimes.
Не буду комментировать тамошних комментаторов.
Кстати, сделал новую демку с воспроизведением видео с SD карточки :)
Кто узнает — из какого традиционного для испытания LED панелей ролика кадрик? :)
+
avatar
0
  • AndyBig
  • 19 января 2018, 18:15
Ага, читал сегодня днем Вашу статью там :)
Комментаторы — они везде комментаторы, но в целом Вашу статью вытащили из песочницы -это уже отлично, и приняли благосклонно, судя по плюсам и по Вашему рейтингу :)
Кадрик узнаваем даже в таком виде :))
+
avatar
0
  • pet80
  • 28 декабря 2017, 18:09
Для порядка надо было бы намекнуть сколько весит (надо скачать) сей пакет и какие требования к компьютеру.
+
avatar
+4
  • Taiger
  • 28 декабря 2017, 18:25
Такое чуство что прочитал обзор и ни слова не понял. )
+
avatar
0
  • skif31
  • 28 декабря 2017, 20:19
и вы тоже?
+
avatar
0
  • ssurneed
  • 28 декабря 2017, 18:59
Всё таки я не понимаю почему stm32f103 не может это сделать без cpld. В нём же есть dma
+
avatar
+2
Проблема в том, что для формирования PWM на каждый пиксель надо сделать 3 сравнения с текущим значением PWM. Причём для 6-ти битного цвета это надо сделать 128 раз. Там есть обходной вариант с переменным временем PWM, который позволяет вместо сравнения просто выбирать нужный бит (так сделано в библиотеке от Adafruit).
Поэтому DMA там не сильно помогает, так как для использования DMA надо сделать bitbanding данных в памяти, причём очень неэффективным способом.
В данном же случае микроконтроллер отдаёт «сырые» данные и всю дальнейшую обработку делает CPLD. Никакой микроконтроллер это не успеет. Попробуйте найти хоть один проект, в котором «голый» микроконтроллер поддерживает вывод на панель в честном RGB888.
+
avatar
0
  • ssurneed
  • 28 декабря 2017, 19:27
Ок верю. Я тут не в теме. Ни когда не занимался панелями.
+
avatar
+1
  • AndyBig
  • 28 декабря 2017, 20:46
А в каком виде данные идут в панель? Я думал, что там SPI с данными PWM для каждого цвета каждого пикселя, а на самой панели уже стоят контроллеры LED. Ну, что-то типа многоканальных WS2812 :)
+
avatar
+2
Там всё достаточно просто. На входе интерфейс HUB75

На каждом входе цвета стоит цепочка регистров типа HC595 (но специальные 16-ти канальные версии для светодиодов). Регистров столько, чтобы хватало на ширину панели. Входы клока, параллельной загрузки и разрешения выхода общие для всех регистров. Входы ABCDE — это выбор ряда — идут на обычный дешифратор.
Принцип работы:
— выставляем данные на RGB входы, щелкаем клоком. Повторяем, пока не загрузим всю строку.
— выключаем выходы (чтобы помех не было)
— выдаём на дешифратор номер загруженного ряда
— щелкаем параллельной загрузкой — данные строки переносятся в выходные регистры
— включаем выходы
— повторяем для следующего ряда
То есть классическая динамическая индикация. Понятно, что при таком методе за один такой цикл мы можем каждый конкретный светодиод только включить/выключить.
Для того, чтобы получить градации яркости, такой цикл приходится повторять N-1 раз, где N — число градаций яркости. А учитывая, что при этом это всё еще и мерцает — всё это надо делать очень-очень быстро.
Есть обходной вариант, про который написал Petrovich39 — BAM. При этом время свечения в каждом цикле варьируется в зависимости от веса отображаемого бита. Скажу честно — когда я начинал работу я про этот метод ничего не нашёл. Вполне может быть, что он окажется даже эффективнее, чем я думаю. Надо пробовать.
А отличие от WS2812 именно в том, что панель надо «теребить» всё время и очень быстро. Разработанная мной платой как раз и превращает LED-панель в некий эквивалент WS2812 — выбросил данные и забыл про неё до следующего обновления.
+
avatar
0
  • AndyBig
  • 29 декабря 2017, 15:06
Про загрузку в панель все понял, спасибо за объяснение :)
Что делает Ваша плата — я понял из обзора, просто не совсем понимал зачем это нужно, считал, что такие панели умнее, чем (оказывается) есть на самом деле :)
+
avatar
0
  • AndyBig
  • 29 декабря 2017, 15:37
Почитал про BAM. Идея любопытная, но для большой матрицы все равно придется гнать данные на высокой частоте, AVR не справится :)
А применять этот метод в ПЛИС смысла, наверное, нет, т.к. она и с нормальным ШИМ справляется легко :)
+
avatar
0
Про AVR8 речь вообще не идёт — не та производительность и память. Тут скорее мысль об использовании чего-то подобного с STM32.
А с ПЛИС… С обычным ШИМ не совсем легко — для RGB888 максимальный размер всего 32x32, причём без гамма-коррекции.
К сожалению, без легкой переделки мою платку не заставить формировать BAM — там надо RE управлять, а она сейчас жёстко на земле висит — надо проводок на свободный пин бросать.
В общем — надо сильно подумать, потом поэкспериментировать на STM, потом попробовать сделать V2 с БД и Ш (базой данных и шимом, а не то, что вы подумали) :)
+
avatar
0
  • AndyBig
  • 29 декабря 2017, 17:25
С обычным ШИМ не совсем легко — для RGB888 максимальный размер всего 32x32, причём без гамма-коррекции.
Взять ПЛИС посерьезнее :)
+
avatar
0
Не спасёт. Надо еще и память быструю и жирную. Даже если уйти на 16битную 10нс SRAM, то это даст увеличение максимального размера всего в 4 раза (до 64х64). Нет смысла. Решение проблемы экстенсивным методом не всегда наилучшее :)
+
avatar
0
  • AndyBig
  • 29 декабря 2017, 19:59
Можно поставить два чипа памяти и работать с ними в «черезсточном» режиме :)
Или взять Циклон, у него своей памяти хватит на матрицу 128х128 :)
+
avatar
0
Можно. Учитывая цены тогда проще поставить по платке на каждую панель и лить на них данные с контроллера последовательно — мой софт это предусматривает.
В том то всё и дело, что потенциально BAM режим эти ограничения обходит с лёгкостью вообще. То есть там вычислительная сложность алгоритма в разы меньше.
+
avatar
0
  • AndyBig
  • 29 декабря 2017, 20:13
Ну, скорее не вычислительная, а аппаратно-затратная, но в целом я с этим и не спорю :)
А почему я в самом начале упомянул AVR — потому что 99.9% всех поделок создаются на AVR-ардуинах :)
+
avatar
0
BAM здесь не поможет. Требования по скорости останутся те же, просто увеличится количество участков когда ничего не надо будет делать(это актуально для контроллера, когда в промежутках можно сделать какую-то нужную работу, но для ПЛИС это не актуально). Ну и в большей части случаев эквивалентная частота «обновления» будет выше чем для аналогичной ШИМ, что хорошо для глаз но… если попробуете на изображение сформированное BAM направить камеру, будет каша…
+
avatar
0
Почему же не поможет? Я уже прикинул — получается очень неплохо. Проще всего манипулировать через OE. То есть:
— загрузили биты строки в панель
— выдали OE на время, пропорциональное весу бита
— тем временем грузим следующую строку
— если время OE больше, чем время загрузки следующей строки, то ждём завершения OE
ну и по циклу
В таком случае — если для классического PWM для получения 256 градаций нам на кадр нужно 256 раз считать из памяти значение каждого пикселя, то для BAM это нужно сделать всего 8 раз (!!!). Причём в отличии от PWM ресурсоёмкость растёт пропорционально разрядности бита, а не степенная функция. То есть легко можно обеспечить и 16-ти битный пропорциональный цвет, например.
Тут, правда, вылезает компромисс. Если пытаемся получить предельно высокую частоту обновления, то надо время младшей «1» делать как можно короче (в пределе 1 такт). Но при этом мы заметно теряем в яркости. В то же время для бытовых целей 100% светимость панели вообще не нужна — она сияет как лампочка. В общем — тут надо будет подбирать значение такое, чтобы получить нормальную частоту обновления с приемлемой потерей яркости
+
avatar
0
Не здесь узкое место, оно в загрузке данных в регистр. Мы его при всём желании ускорить не можем, и в идеале составляет 1 такт на пиксель(если использовать DMA которого не везде есть). В итоге, загрузка регистра — является узким горлышком что для ШИМ, что для ВАМ — надо обеспечить загрузку быстрее чем вес младшего бита. Просто в первом варианте на старших битах у нас в промежутках времени не будет а во втором будет масса свободного времени, но ограничение на критический участок кода останется. Если контроллер не обременен особо другими задачами то выигрыша никакого — что он будет молотить ШИМ-ом, что простаивать при ВАМ-е но частота обновления будет определяться временем загрузки в регистр.
Но у ВАМ-а другие проблемы есть. Если надо активно менять яркость светодиодов то возникают пренеприятные артефакты. Может даже «снег» пойти если много светодиодов.
+
avatar
0
Воот. Но для bam надо 8 считываний на цикл, а для pwm — 256. А обеспечивать загрузку быстрее веса первого бита вообще не надо — можно же просто укоротить OE до нужного времени и всё. Да, получится не 100% эффективность по яркости, да и черт с ним.
Артефакты меня мало волнуют на данном этапе.
+
avatar
0
считывания — это какая-то очень тяжелая операция? По времни это будет занимать те же 256 минимальных временных интервалов, только простоя будет больше. И требования к быстродействию алгоритма сравнения останутся те же.
+
avatar
0
Эээээ. Считывание данных из памяти и загрузка регистра — это одна и та же операция. Читаем данные из RAM, вычисляем результат, задвигаем результат в регистр.
> По времни это будет занимать те же 256 минимальных временных интервалов
С чего вдруг? Для BAM нужно заполнить регистр каждой строки всего 8 раз, для PWM — 256 раз. Есть разница?
> И требования к быстродействию алгоритма сравнения останутся те же.
Вы вообще читаете — что вам отвечаю? BAM значительно проще — там вообще не надо делать 8-ми битное сравнение — надо просто выбрать 1 бит данных.
+
avatar
0
А как вы думаете сколько времени будет между загрузкой регистра младшими битами и загрузко йследующего 8-го бита? Ровно столько же сколько и для программного ШИМ между загрузками, тоесть требования к скорости алгоритма остаются прежние. Для контроллера играться с битами может оказаться по времени едва ли не дольше чем сравнивать 8-битное число. Единственное чем BAM лучше — это наличие свободного времени после загрузки каждого старшего бита. остальное точно такое же как и для программного ШИМ.
+
avatar
0
Нет. Дело в том, что мы не обязаны «светить» светодиодом всё время загрузки — мы можем просто включать OE на нужное время. При этом на малых весах битов время цикла будет определяться временем загрузки, а на больших — временем включения OE.
На самом деле я это всё уже реализовал и выигрыш по скорости огромный — сейчас при реализации на BAM я легко делаю на панели 32x32 в режиме RGB888 частоту кадров более 500 к/с. Для классического PWM получалось около 60 к/с. Есть разница?
Статья на гитхабе пока висит в премодерации, но весь код уже здесь:
https://github.com/Anprivate/al422-bam
+
avatar
0
И еще одна прелесть — для PWM требуется сравнивать все биты, а 8-ми битное сравнение, например, в EPM3064 за один такт выполниться не успевает, из-за этого приходится организовывать конвейер. А в BAM мы тупо переносим один бит из RAM и всё — считать не надо вообще ничего.
+
avatar
0
Почитайте про Binary Angle Modulation… Я уже подробностей не помню, но вроде бы позволяет делать это всё на дохлых МК))
+
avatar
0
Вот именно его я и имел в виду под «обходной вариант с переменным временем» :)
Да, есть такой вариант. Может попробую после нового года реализовать — посмотрю — что получится.
+
avatar
0
  • 7profy
  • 17 октября 2022, 03:21
чтобы сформировать 64 уровня яркости — за время индикации одного кадра надо 64 раза выдать картинку
На самом деле — нет. Достаточно 5 раз выдавать «картинку» (т.е. каждую скан-строку). Регулировка яркости производится длительностью сигнала OE после защелки.
И про «засвечивание» — это скорее всего проблема недостаточных задержек при переключении строк/latch/oe.
И микроконтроллер с DMA и портом для внешней памяти (EXMC у stm и клонов) вполне справляется с такой задачей.
+
avatar
0
  • ebook
  • 29 декабря 2017, 06:15
автор — молодец
+
avatar
+1
  • Kila
  • 29 декабря 2017, 08:30
В то же время столь малое количество макроячеек не позволяет сделать динамически конфигурируемую плату — конфигурацию необходимо компилировать непосредственно в CPLD.
Не совсем понятна фраза
+
avatar
0
  • maxspb69
  • 29 декабря 2017, 09:12
Примененный CPLD не позволяет загружать свою конфигурацию извне (с той же ардуины) при каждом включении питания, а «прошивается» через бластер и конфигурацию свою помнит. Для изменения ее — снова перепрошивать.
+
avatar
0
Дополню еще, что при наличии бОльшего количества макроячеек можно было бы иметь все четыре базовых модуля (там отдельные модули для каждой комбинации цветового пространства и количества RGB выходов) одновременно и используемый выбирать мультиплексором. Тогда можно было бы прошивать CPLD один раз, а нужную конфигурацию панели загружать из МК по SPI или I2C.
+
avatar
0
Verilog и программируемая логика — это круто. За обзор заслуженный плюс, но не очень понятна область применения сабжа.
Часы? Для них давно используются сдвиговые регистры и монохромные матрицы.
Мелкие цветные рекламные панно? Матрица из WS2812b, ардуинка и бесконечное количество графики на SD-карте.
+
avatar
0
Собственно да.
Например — часы. Одна панелька P3 64х32 имеет габариты 192х96, что практически идеально для часов. Или можно взять P2.5 — там вообще 160х80. При этом возможности отображения практически не ограничены — можно делать плавное изменение яркости и цвета любой части часов от времени суток например. Максимальная яркость очень большая (панель 32х32 в максимуме ест почти 25 ватт и сияет как лампочка), поэтому можно использовать как временную подсветку ночью, например. То есть простор для фантазии огромный.
Рекламные табло? Пожалуй нет — проще брать готовые контроллеры. Хотя если альтернатива WS2812B, то, пожалуй — да. WS2812 обходятся дорого и имеют огромный шаг (меньше 10 мм сделать малореально). А готовые панели стоят в разы дешевле, чем стоят WS2812.
А в основном — делал для себя :) Дело в том, что мне время от времени приходится делать всевозможные таймеры и индикаторы на подобных панелях (стоят в студиях для отображения текущего времени и обратного отсчёта до рекламы, например). Делать это на STM32 мне надоело — возможностей мало, да и есть некоторые проблемы. Вот и решил сделать отдельный контроллер.
+
avatar
0
  • ssurneed
  • 29 декабря 2017, 12:37
Мне, честно говоря, не нравятся часы на подобных панелях. Для себя я сделал просто на светодиодах 0603
geektimes.ru/post/289389/

Кстати есть ещё APA102-2020 ;)
+
avatar
0
Как чистые ЧАСЫ — да, бессмысленно. Большие семисегментники смотрятся лучше.
А вот в таких проектах — led панели просто напрашиваются.

APA102 стоят порядка 100$ за 1000шт россыпью. На ленте еще дороже. Готовая панель из них размером 16х16 с шагом 10 (!!!) стоит 70$
А нормальная LED панель P3 64x32, то есть с 2048 светодиодами стоит 20$. Цены различаются на порядок. Ну и визуально панель с наклеенными ленточками выглядит колхозом. Готовая LED панель выглядит на порядок лучше.
+
avatar
0
  • ssurneed
  • 29 декабря 2017, 14:04
Я имел ввиду apa102-2020 то есть 2ммx2мм. Они ещё дороже;)
Ни как не придумаю что бы на них сделать;) Мне ленты не нужны обычно.
Зато шаг можно сделать 2.1мм;)
+
avatar
0
Да, что-то не то посмотрел — 2020 стоят 200$ за 1000 штук :)
+
avatar
0
Спасибо за пост! Мы в школах даем Ардуино детям. Но есть дети шибко прошаненные, и хочется им давать что-то посерьезнее, или вообще показать какую-то перспективу, после того как на Ардуино они уже наигрались. Сам в свое время много кодил на VHDL под FPGA Stratix III вот думаю — ПЛИС выглядит логичным шагом после освоения Ардуино. Но для ПЛИС никак не могу найти задач интересных для детей, которые нельзя было бы на Ардуино сделать. Вот Ваш пост в этом плане хорошее дополнение. Буду рад за еще предложенные идеи))
+
avatar
0
  • ssurneed
  • 29 декабря 2017, 15:17
После Ардуино можно нормальные среды показать;) С отладкой, с нормальным текстовым редактором… плис уж совсем хардкор
+
avatar
+1
Да ладно, плисы дешевеют на глазах, зато позволяют опуститься сразу на оооч приличный уровень в плане разработки. Только вот задач нет для этого уровня)))
+
avatar
+1
  • ssurneed
  • 29 декабря 2017, 15:30
Вот только где потом кодить на профессиональном уровне? Изучали предложения на headhanter?
+
avatar
0
ХэдХантер не изучал, но я уже давно не пишу под ПЛИС, а мне все еще периодически пишут с предложениями. В научном плане, всякого рода прототипы самое оно делать на ПЛИС. В плане образования очень полезная штука, а на микроконтроллеры опуститься всегда возможно.
+
avatar
0
  • AndyBig
  • 29 декабря 2017, 15:49
Моего знакомого сейчас зовут в кострукторскую группу, созданную под крылом очень известной военно-технической корпорации. Условия — просто сказка: зарплата большая по местным меркам (половина ставки — больше 40 тысяч на руки), рабочий график свободный (хоть дома работай, только иногда приходи на работу), официальное трудоустройство в этой корпорации. Зовут именно кодить FPGA, не смотря на то, что опыта в этом у него не слишком много, потому что хороших спецов в этой области днем с огнем не сыщешь. Кругом одни ардуинщики :)
+
avatar
+1
  • ssurneed
  • 29 декабря 2017, 15:52
Видимо у нас разные понятия о хорошей заработной плате;)
+
avatar
0
  • AndyBig
  • 29 декабря 2017, 15:59
Для Краснодара и с такими условиями — это очень хорошая зарплата :)
+
avatar
0
  • ssurneed
  • 29 декабря 2017, 16:01
Я тоже не из Москвы;)
Просто я думаю что у хорошего инженера (в России) должна быть ЗП не меньше 200 т.р.
А у дизайнера fpga ещё больше.
+
avatar
0
  • AndyBig
  • 29 декабря 2017, 17:26
Думать можно что угодно, но реальность диктует свои условия :)
+
avatar
0
  • ssurneed
  • 29 декабря 2017, 17:30
Ну я близко к реальности думаю. У меня вот приблизительно так.

И на самом деле это не много если сравнивать с депутатами…
+
avatar
0
  • AndyBig
  • 29 декабря 2017, 17:51
Ну а у нас на одном из предприятий, входящих в ВПК, зарплата ведущего разработчика меньше 50 тысяч, при этом строгий рабочий режим и куча головняка с бумажками :)
Должно быть много чего. Например, я не вижу причин почему зарплата врача должна быть меньше зарплаты инженера или депутата, и что меняет это мое мнение? :)
+
avatar
0
  • ssurneed
  • 29 декабря 2017, 17:59
Я много знаю про зарплаты ВПК в моем городе. Да что там говорить, я и сам работал лет 15 на ВПК. Ведущие получают > 80т.р. у меня выборка по 4м предприятиям. Очень немного по моему.

Зная свой уровень и уровень зарплат(не только в твоём городе) можно договориться с работодателем. Ну обычно.

Насчёт врачей инфы не имею.
+
avatar
0
Мы на третьем курсе вместо стандартной курсовой по разрисовке схемы IBM 360 реализовали вычислительное ядро PIC18 на VHDL под Xilinx. Дык сразу после этой курсовой позвали реализовывать Тетру на ПЛИС ) Мы естественно облажались без опыта, но сам факт меня поразил)
+
avatar
0
  • AndyBig
  • 29 декабря 2017, 23:52
Тетра — имеется в виду стандарт связи? :)
Мне пришлось изучать FPGA по работе, когда появилась нужда в оцифровке и очень узкополосной фильтрации сигнала. По DSP у нас спеца уже не было, уволился, да и по нашим прикидкам даже он не справился бы (подразумевали какой-то из Шарков), решили делать на FPGA и поручили это мне :) Пришлось осваивать начиная от схемотехники и самодельного прошивальщика до тонкостей оптимизации размещения результатов синтеза в кристалле :) Но от конечных результатов я сам был в легком ах… ах, какие результаты получили :) По завершению всех работ результаты превзошли по параметрам изначально планировавшиеся раз в пять :)
+
avatar
0
Да =)
+
avatar
0
  • AndyBig
  • 30 декабря 2017, 00:17
Ну там явно посложнее ядра Пика :)
+
avatar
0
  • ssurneed
  • 30 декабря 2017, 05:07
Мы использовали virtex 6 + tms320c6778. Очень не плохие молотилки цифр. Между fpga и dsp pcie с полезным потоком 3.5 гбита/сек.
+
avatar
0
  • AndyBig
  • 30 декабря 2017, 15:33
Мы с Альтерой работали, с третьими Циклонами :)
В ПЛИСке молотили два канала цифрового фильтра, каждый из трех ступеней, которые получали с АЦП выборки на частоте 625 кГц и накапливали в выходных буферах до 2048 результирующих значений. Во всех трех ступенях каждого фильтра участвовало до 5000 коэффициентов :) Количество коэффициентов и их значения могли меняться в зависимости от требовавшейся полосы фильтра — они загружались в ПЛИСку микроконтроллером перед измерением.
Ну и кучка второстепенных управляющих и регулирующих функций :)
+
avatar
0
Это не в Зеленограде случаем?
+
avatar
0
Тетру не, во Владимире. А в Зеленгораде мы делали ядро PIC18 в самосинхронном варианте на БМК если память не изменяет
+
avatar
0
Угу… и как бонус — оформление доступа к секретке и прилагающиеся к ней 5 лет невыезда за границу. Это счастье обычно не упоминают до последнего момента… дескать «это же само собой разумеется».
+
avatar
0
  • AndyBig
  • 30 декабря 2017, 20:05
Угу, и так бывает :)
+
avatar
0
Вы так говорите «военно-технической корпорации», как будто это что-то хорошее… Ну Амбрелла или Скайнет куда ни шло, а сказка и 40 тыщ, это НИИ ЧаВо…
+
avatar
+1
А их вообще почти нет (задач). Крайне мало сфер, где быстродействия современных МК не хватает. Для примера — у меня это второй рабочий проект на FPGA. Предыдущий был примерно 8 (!) лет назад.
+
avatar
0
  • ssurneed
  • 29 декабря 2017, 15:46
Воот. Хотя у меня проектов было много на xilinx (в основном радиолокация). Но редко кому надо. Очень низкая потребность.
+
avatar
0
Мы архитектуру процессора нетрадиционную пилили на ПЛИС. Рекуррентный процессор. Это было довольно интересно, но это академическая скорее задача.
+
avatar
+2
  • AndyBig
  • 29 декабря 2017, 15:58
Есть задачи, но не на любительском уровне разработок, конечно :) В той же обработке сигналов очень часто востребованы возможности FPGA.
Да даже на бытовом уровне некоторые проекты выиграли бы от применения FPGA. Банально — платы для 3D-принтеров или хоббийных ЧПУ-станков, где FPGA могла бы полностью взять на себя проблемы формирования траекторий и шагов для двигателей, что очень сильно может повысить скорость и точность :)
+
avatar
0
Да ладно — на хрена на управление механикой FPGA? Сейчас там сплошняком AVR8 трудятся. Переход на STM32F4 даст скачок производительности на два порядка, чего более чем достаточно, а они сейчас стоят копейки и программировать их на порядок проще.
+
avatar
+2
  • AndyBig
  • 29 декабря 2017, 17:46
на хрена на управление механикой FPGA?
Например, для высокой стабильности выдаваемых 4-6 двигателям сигналов, потому что джиттер на этих сигналах приводит к заметному снижению достижимых ускорений и скоростей и, как побочный эффект, к увеличению шума моторов :)
Микроконтроллеру и без того работы выше крыши. Даже на STM32 многие из стандартных команд и опций G-кода остаются недоступными из-за нехватки его ресурсов и на обработку G-кода и на формирование в реальном времени сигналов STEP/DIR для нескольких моторов. Вот FPGA как раз и могла бы взять на себя всю рутину генерации сигналов с учетом заданных скоростей/ускорений, оставив микроконтроллеру только математику и вопросы стратегии и интерфейса.
А еще на станки часто ставят оптические линейки для контроля движения оси с разрешением эдак 1-5 микрон и управление моторами согласуют с обратной связью от этих линеек.
+
avatar
0
Мне кажется тут ключевой момент в том, что плисины дешевеют со страшной силой, по крайней мере плисы начального уровня
+
avatar
0
  • AndyBig
  • 30 декабря 2017, 00:00
Угу, четвертый циклон уже стоит каких-то 10 баксов :)
+
avatar
0
  • ssurneed
  • 30 декабря 2017, 05:18
Дешевеют. Например spartan 6 xc6slx16 можно уже за 10$ у китайцев купить. А он уже может и ddr3 и выдать поток данных 2ггц 14бит для ЦАП ad9739. Я даже хотел такой девайс собрать. Но потом забил.

Но только все равно в быту применений мало.
+
avatar
0
зато позволяют опуститься сразу на оооч приличный уровень
Наверное, все таки, подняться, а не опуститься.
+
avatar
0
Ну это уровни абстракции. Низкий уровень требует высокой квалификации, поэтому я и сказал опуститься)
+
avatar
0
  • Alexluts
  • 07 сентября 2018, 12:10
Очень понравился ваш обзор. Хочу тоже попробовать панели, мне желательно получить 128х128 или 256х64. Нашел вашу новую версию РСВ на Хабре и github, с выходными буферами. Но не нашел ваши результаты проверки… Прежде чем заказывать и паять платы хотелось бы знать, все ли в новой версии в порядке
+
avatar
0
Пардон, не видел сообщения. Всё в порядке, работает точно так же, как и без буферов :)
+
avatar
0
  • Alexluts
  • 05 декабря 2018, 14:39
Спасибо за внимание.
Платы я заказал, уже получил, правда пока к сожалению, нет времени спаять и заняться контроллером. Но займусь обязательно.
Немного промазал с панелями, купил 64х32, Р2.5 scan 16, 8 штук, чтобы набрать 128х128. Панели купил по ссылке из обзора на kirich.blog, заоодно, не зная, получится ли самому сделать контроллер, купил заодно и контроллер HD-D30. Панели 64х64 или 64х128 получаются чуть ли не вдвое дешевле, правда скан у них 32.
Задача у меня немного специфичная, надо при необходимости, выводить на панель цифры, тексты, может еще простенькую графику, а в промежутках крутить рекламу, подвижную и нет, а заодно и то что может китайский контроллер — температуру, влажность, часы. Посмотрел на HD-D30 — самому сделать что-то с теми же возможностями при цене около 50USD (4 GB памяти и свой настроечный софт) просто не реально. API на него не достать, но у него есть вход для IK порта, можно выбрать любую из сотен загруженных в него программ. А для подключения своего контроллера использовать доп. коммутатор на HUB75E, и выводить китайца по мере необходимости…
Вот такая немного странная идея…
Если понадобится, могу ли попросить о помощи? С FPGA никогда не возился, только очень давно с советскими ПЛМ (были и такие :)), и пытаться еще и их освоить- слишком сложно для меня
+
avatar
0
При прошивке в CPLD 64х32 все работает прекрасно, без всяких проблем, совсем как у вас на картинке, но после прошивки 128х32 — на экране каша и что туда послал не совмсем понятно. Могли бы Вы помочь мне решить эту проблему?
В личку тоже писал, но почему-то не отвечаете, :(
+
avatar
0
Правда не понял где проблема- в CPLD или в STM32
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.