Операция "пучеглазка". (RGB LED Matrix Panels Test)

Доброго времени суток.


В данной заметке речь пойдёт о светодиодных панелях, используемых в рекламных вывесках и архитектурных ТВ экранах.
Вот примерно таких:


Самые распространённые варианты 16*32 пикселя 16*64, 32*32, 32*64. Есть ещё куча промежуточных вариантов. Также они отличаются размером диодов яркостью и исполнением корпуса.

Панели 256mm*128mm 64*32pixels с пикселем 4мм на диодах SMD2121 и ярокстью 1200CD/M2 стоят от 700р за панель и примерно 300р доставка до третьих стран(2018г).

Хотя в рекламных вывесках они применяются чаще одноцветные:


Суть проблемы:
Есть неисправные РГБ панели размера P4 32 строки на 64 пикселя в каждой. Для ремонта этих панелей необходимо включать отдельные пиксели. Также необходимо полностью отключать панели от питания. Многие скажут что полное отключение от питания излишне, но я считаю что если лезешь паяльником в установку — то установка должна быть обесточена. Включать и отключать при ремонте надо часто и этот процесс необходимо сделать без участия проводов и разъёмов.

Решение.

Пункт первый — поиск информации о том как эти панели работают.
Имеющийся модуль дисплея состоит из 18 панелей 3 подключены последовательно в ряд и 6 параллельных рядов.
Всё это дело управляется контроллером, имеющем один вход данных, один выход и 6 разъёмов для подключения панелей.
Питается от двух блоков питания дающих суммарно 400Вт при напряжении 5В.


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

Вот что мне удалось найти
Панели имеют 3 разъёма: питание, вход данных и выход данных. Напряжение питания 5В, ток до 4А (все пиксели белые максимальная яркость), управление 5В.
Вход и выход данных используются для наращивания панелей построчно:

На данном фото показан экран из панелей 32Х32 пикселя с управлением от Raspberry Pi 3 с адаптером расширителем портов на 4х регистрах 74HCT245.

Контакты разъёма данных обозначены не у всех производителей, но более менее стандартны.
Вот тот вариант, что достался мне:

Не подписанные выводы это «земля», подключенные к минусу питания.
Правда на панелях у меня вообще ни один вывод не подписан, но разводка совпадает.
В зависимости от того какого размера панель в ней могут отсутствовать контакт D и контакты цветов, если панель двухцветная или одноцветная. Если панель меньше 32 строк то могут отсутствовать контакты R1, G1, B1. Я встречал описание на панель у которой использовались только контакты R0,R1,G0,G1, а сама панель была трёхцветной (красный, зелёный, оранжевый (красный+зелёный).

Логика работы панели.

Логически панель состоит из драйверов светодиодов (сдвиговых регистров), образующих буфер длинной в одну строку. Если последовательно соединено несколько панелей то длинна строки равна суммарной длине строки всех последовательных панелей.
Если в панели 32 строки то таких буферов два.
Первый из них строки с 0 по 16 имеет входы R0, G0, B0. Второй (строки с 16 по 31) входы R1, G1, B1.
Если на вход подать «1»= +5В, то пиксель включит нужный цвет.
Входы CLK, LAT и OE у них объединены.

Адресные входы A,B, C, и если панель больше 16 строк то D производят строчную развёртку. При этом на панелях с 32мя строками развёртка идёт в две строки сразу.

Алгоритм передачи данных в панель

  1. Выставляем +5В (лог 1) на вход OE, что отключает дисплей на время обновления.
  2. На адресных входах выставляем номер строки в двоичном виде:
  3. Выбираем будем обновлять только одну строку или две сразу. И выставляем на входах цветов 1 для включенных цветов в нужных пикселях.
  4. Проталкиваем данные в буфер ставя и снимая 1 с входа CLK.
  5. Повторяем выставление цвета и проталкивание для всех пикселей строки (сколько панелей собрали последовательно столько и пихаем, умножив на размер панели).
  6. По завершении проталкивания даём импульс «1» на вход защёлки LAT
  7. Выставляем 0 на вход OE, что включает дисплей.

Замечание по поводу отключения дисплея через ОЕ. Так рекомендуют делать во избежании возникновения ненужной засветки во время обновления буферов строк. На имеющихся у меня панелях такого эффекта при включенном ОЕ не наблюдалось, но за то я очень получил по глазам (до головной боли) из-за большой яркости панели. Панель не имеет встроенной возможности регулировать яркость. Мне же для работы нужна была минимальная яркость. По этой причине на вывод ОЕ панели я подал сигнал ШИМ и задавил яркость всей панели на минимум. При работе с экраном из нескольких панелей так можно регулировать только общую яркость экрана, но не яркость отдельных пикселей.

Про быстродействие такого алгоритма работы с панелями скажу следующее:
Контроллеры AVR могут вывести примерно 4 панели 32х32.
Raspberry Pi 2 может осилить 3 строки (с описанным выше расширителем портов) по 12 матриц 32х32 в каждой (всего 36 панелей).
Из такого расклада становится очевидным что для создания реального экрана надо задействовать минимум Raspberry Pi, а лучше не парить мозг и подключить через покупной контроллер как HDMI дисплей к той-же Raspberry Pi, что сильно упростить создание и обновление контента.

Создание проверочного стенда

Схемотехническое решение
Используем контроллер AVR MEGA16, потому что так мне удобнее. Я лучше знаком с AVR чем с STM и у него достаточно выводов. Тактирование 8МГц от внутреннего источника, потому что мне не надо включать всю панель сразу.
Для отображения координат выбранного к проверке пикселя и его цвета и состояния прочего используем символьный ЖК дисплей 2*16. У меня их много. И тут ему самое место.
Для управления используем энкодер. Это позволит вращением менять выбранный параметр а нажатием кнопки переключатся на следующий параметр. Что в итоге должно дать возможность вообще переключать режимы не глядя на ЖК экран.
Для отключения контроллера от панели ставим буферы с защитой от статики.
Питание панели отключаем через реле. Для того чтобы лезть туда паяльником при включенном стенде.

Схема


По итогу выяснилось что я забыл поставить конденсаторы по входному питанию и добавил в реальную плату 2 конденсатора 470uFx16V параллельно. Если их нет то при включении панели от моего блока питания марки D-Link вся схема работала нестабильно. Если питание панели подаётся от отдельного мощного источника (Она на максимуме 4А кушает) то такого косяка быть не должно.

Код работы с панелью
Настройка таймера для шим яркости панели

// Настройка таймера 1 на шим управление яркостью всей панели
TCCR1A=(1<<COM1A1)|(1<<WGM10); //На выводе OC1A единица, когда OCR1A==TCNT1, восьмибитный ШИМ
TCCR1B=(1<<CS10);		 //Пред делитель = 1
OCR1A=0xFD;			//Яркость минимальная


Дефайны подключения панели.

// Panel
#define PAN_COLOR_PORT PORTC
#define PAN_COLOR_DDR  DDRC

#define PAN_ISO 6 // Отключение буферов
#define PAN_R0  5
#define PAN_R1  1
#define PAN_G0  4
#define PAN_G1  2
#define PAN_B0  3
#define PAN_B1  0

#define PAN_ADR_PORT  PORTD
#define PAN_ADR_DDR   DDRD 

#define PAN_A   6
#define PAN_B   7
#define PAN_C   1
#define PAN_D   2
#define PAN_OE  5
#define PAN_CLK 3
#define PAN_LAT 4


Инициализация портов. У меня всё вразброс для ускорения разводки платы.

// Panel
PAN_COLOR_DDR |=  (1<<PAN_R0|1<<PAN_R1|1<<PAN_G0|1<<PAN_G1|1<<PAN_B0|1<<PAN_B1|1<<PAN_ISO);
PAN_COLOR_PORT&= ~(1<<PAN_R0|1<<PAN_R1|1<<PAN_G0|1<<PAN_G1|1<<PAN_B0|1<<PAN_B1|0<<PAN_ISO); // На всех 0
PAN_COLOR_PORT |= (1<<PAN_ISO); // отключается еденицей

PAN_ADR_DDR |=  (1<<PAN_A|1<<PAN_B|1<<PAN_C|1<<PAN_D|1<<PAN_OE|1<<PAN_CLK|1<<PAN_LAT); 
PAN_ADR_PORT&= ~(1<<PAN_A|1<<PAN_B|1<<PAN_C|1<<PAN_D|0<<PAN_OE|1<<PAN_CLK|1<<PAN_LAT); 
PAN_ADR_PORT|= (1<<PAN_OE); // отключается еденицей


Переменные состояния панели. Напомню задача включить определённый пиксель и проверить работает он или нет.

uint8_t Panel_power = 0;  // Состояние реле подключающего питание тестируемой панели
uint8_t Led_X     = 0; // Выбраный свотодиод по Х
uint8_t Led_Y     = 0; // Выбраный свотодиод по Y
uint8_t Led_color = 0; // Цвет выбранного диода


Отправка данных в панель

if (Panel_power)
    {
        ClearBit(PAN_COLOR_PORT,PAN_ISO); // Включение буферов
        SetBit(PAN_PWR_PORT,PAN_PWR_PIN); // Включение питания панели.
        
        // Выставили адрес 2х строк
        if(Y & 0x01)   SetBit(PAN_ADR_PORT, PAN_A);
        else            ClearBit(PAN_ADR_PORT, PAN_A);
        if(Y & 0x02)   SetBit(PAN_ADR_PORT, PAN_B);
        else            ClearBit(PAN_ADR_PORT, PAN_B);
        if(Y & 0x04)   SetBit(PAN_ADR_PORT, PAN_C);
        else            ClearBit(PAN_ADR_PORT, PAN_C);
        if(Y & 0x08) SetBit(PAN_ADR_PORT,PAN_D);
        else          ClearBit(PAN_ADR_PORT,PAN_D);
 

        if (TCCR1B!=1) {SetBit(TCCR1B,CS10);} // Проверили что шим у нас точно есть.
        
        // Вывод двух строк на панель
        for (uint8_t i = 0; i<PANEL_X_MAX; i++)
        {      
           if (i!=X)
            {
                PAN_COLOR_PORT &= ~(1<<PAN_R0|1<<PAN_R1|1<<PAN_G0|1<<PAN_G1|1<<PAN_B0|1<<PAN_B1); // Все цвета выключены
            }
            else
            {
                PAN_COLOR_PORT&= ~(1<<PAN_R0|1<<PAN_R1|1<<PAN_G0|1<<PAN_G1|1<<PAN_B0|1<<PAN_B1);
                switch(Led_color)
                {
                    case Led_BLACK: 
                        {PAN_COLOR_PORT &= ~(1<<PAN_R0|1<<PAN_R1|1<<PAN_G0|1<<PAN_G1|1<<PAN_B0|1<<PAN_B1);} break;
                            
                    case Led_RED:   
                        {
                            if (Y<16) 
                                {SetBit(PAN_COLOR_PORT,PAN_R0);}
                            else
                            {SetBit(PAN_COLOR_PORT,PAN_R1);}
                        } break;
                        
                    case Led_GREEN: 
                        {
                            if (Y<16)
                                {SetBit(PAN_COLOR_PORT,PAN_G0);}
                            else
                                {SetBit(PAN_COLOR_PORT,PAN_G1);}
                        } break;
                        
                    case Led_BLUE:
                        {
                            if (Y<16)
                                {SetBit(PAN_COLOR_PORT,PAN_B0);}
                            else
                                {SetBit(PAN_COLOR_PORT,PAN_B1);}
                        } break;
                        
                    case Led_WITE:
                        {
                            if (Y<16)
                                {PAN_COLOR_PORT |= (1<<PAN_R0|1<<PAN_G0|1<<PAN_B0);}
                            else
                                {PAN_COLOR_PORT |= (1<<PAN_R1|1<<PAN_G1|1<<PAN_B1);}
                        } break;
                }
            }
        ClearBit(PAN_ADR_PORT,PAN_CLK); // Сбросили CLK
        SetBit(PAN_ADR_PORT,PAN_CLK);  // Поставили CLK
        }
        ClearBit(PAN_ADR_PORT,PAN_LAT);  // Сбросили latch
        SetBit(PAN_ADR_PORT,PAN_LAT);  // Поставили latch
        ClearBit(PAN_ADR_PORT,PAN_LAT);  // Сбросили latch  
    }
    else 
    {   // Здесь отключаем панель для работы с ней.
        ClearBit(TCCR1B,CS10);
        SetBit(PAN_ADR_PORT,PAN_OE);  // Погасили дисплей OE High (disable output)
        SetBit(PAN_COLOR_PORT,PAN_ISO); // Отключение буферов
        ClearBit(PAN_PWR_PORT,PAN_PWR_PIN);// отключение питания панели.
    }  


Я надеюсь комментариев достаточно.
Данный код не претендует на скорость работы, он просто работает. Скорость меня устраивает.

Результат — готовый контроллер стенда



И подопытная панель включен один пиксель. Белым, на минимальной яркости.


Копирайты
За куски использованного кода благодарю:
Di Halt
Chipenable
Papandopala
Adafruit №1 (Разные виды панелей)
Adafruit №2 (Драйвер LED панели для Raspberry Pi)
Adafruit №3 (Драйвер LED панели для Arduino Mega)

В приложении проект Атмел студии 7.
Скомпилированная прошивка.
Схема и печатка из орла.
  • +6
  • 08 января 2018, 01:18
  • skelet
  • 3
Файлы в топике: LEDBoard_test.zip, LEDBoard_test_HEX.zip, LSD_Test.zip

Комментарии (8)

RSS свернуть / развернуть
Адресные входы A,B, C, и если панель больше 16 строк то D производят строчную развёртку. При этом на панелях с 32мя строками развёртка идёт в две строки сразу.
Вообще-то, с трехбитным адресом можно только 8 строк адресовать. Так что 16-строчная должна либо иметь 4 бита адреса (ABCD), либо две цепочки регистров (RGB0 и RGB1).
Контроллеры AVR могут вывести примерно 4 панели 32х32.
Можно выводить через SPI, тогда теоретически можно прокормить 16 килопиксельных панелей на 60Гц, а если снизить рефрешрейт — то и того больше. Правда, возникнут проблемы с хранением фреймбуфера и с тем, что ядро занято практически исключительно запихиванием очередного байтика в передатчик SPI.
На STM32 больше памяти и есть DMA, там лимитирующим фактором будет только частота SPI, можно попробовать раскачать матрицу разрешением порядка QVGA. А если использовать интерфейс внешней памяти — то, вероятно, и больше.
0
  • avatar
  • Vga
  • 08 января 2018, 08:24
Этих панелей на улицах уже пруд пруди, инфа о них должна была когда-то появиться)) Спасибо что поделились.
0
Ни сколько не приуменьшаю заслуг автора статьи, и не хочу обидеть, просто считаю уместным подкинуть дополнительной информации.
По данным панелям достаточно информации есть на https://mysku.ru/blog/aliexpress/55819.html Там есть несколько статей от пользователя kirich (и не тоглько его), кого панели заинтересовали, советую почитать те статьи. Там ещё были часы на ардуино с такой панелью, на скорую не нашёл.
Контроллеры есть не только HDMI, но и автономные, на STM32, с Ethernet интерфейсом и без. Море их. AliExpress ими завален. Стандартов распиновки разъемов несколько, достаются из описаний автономных контроллеров.
В общем штука классная, но кроме рекламных вывесок применить особо некуда (часы/термометр).
+1
Я не натыкался на эти обзоры но да для покупки рекламы статья самое то.
Мне же их надо именно тестировать, дёргая самому. А этой информации почему-то в описаниях панелей нет.
0
На чем сделаны панели и как их подключать и как управлять есть в тех статьях. Я дал линк на «первую попавшуюся» но довольно исчерпывающую. Но статей там много, как и «вариаций панелей».
В них же есть и почему не выйдет купить замену (ниже упомянутый вами момент).
Даже при том, что статья писалась про покупку рекламных блоков, это совершенно не значит, что она/они предназначены только для рекламщиков. Информацию там может почерпнуть и радиолюбитель: устройство панели, способ управления.
0
Линк полезный. пусть будет :)
0
По реализации предложил бы использовать SPI, соединив RGB последовательно.
Минусы:
— надо 2 разъема подключать (но избавляемся от ногодрыга, увеличив тем самым скорость);
— при неисправности регистра в одном цвете не будут работать все, включенные после него.
Второй минус более критичен для стенда проверки. Но вполне допустим.

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

Новые панели пытались покупать, но они сильно отличаются по яркости от остальных и на большом экране разница бросается в глаза. А менять все панели дорого.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.