AVR-USB-MEGA16: цветомузыка на светодиодной RGB-ленте WS2811 Печать
Добавил(а) microsin   

Давно зрела мысль сделать на светодиодной RGB ленте GE60RGB2811C цветомузыку, и вот наконец выбрал для этого время.

Лента GE60RGB2811C состоит 300 штук RGB-светодиодов. В корпус каждого встроен контроллер WS2811, благодаря чему каждый светодиод может управляться отдельно по одному проводу данных, несмотря на то, что все светодиоды соединены в цепочку [1]. Такое решение обладает большим удобством и гибкостью, так как количество проводов для подключения и управления лентой снижается до минимума, и при этом ленту можно нарезать кусками любой длины. В качестве контроллера для ленты была выбрана макетная плата AVR-USB-MEGA16 [2].

Принцип работы контроллера довольно прост - на вход подается звуковой сигнал, который усиливается и приводится к колебаниям уровня напряжения от 0 до 5 вольт. Это нужно для того, чтобы удобно было подсчитывать количество изменений за единицу времени и регистрировать уровни сигнала. Далее сигнал подается параллельно на вход счетчика и на вход АЦП. По частоте и амплитуде сигнала контроллер принимает решение, какие цвета в каком месте ленты нужно зажечь. Для удобства звуковой сигнал принимается с помощью электретного микрофона. Упрощенная схема контроллера показана на рисунке.

ws2811-disco-lights-controller-block-diagram

Микрофонный усилитель собран по стандартной схеме с применением УНЧ КР538УН3Б в корпусе DIP8. Можно применить любой другой усилитель, даже на транзисторах, это не критично. Главное требование, которое предъявляется к усилителю - обеспечение достаточного уровня сигнала с размахом на выходе от 0.5 до 4.5 вольт, и он должен питаться от напряжения +5V.

K538UN3B-microphone-amp

Выход микрофонного усилителя соединен с контактами P1 (PA0, вход АЦП микроконтроллера) и P9 (PB1, вход T1 аппаратного счетчика микроконтроллера). Цифровые данные поступают на RGB-ленту с контакта P12 (PB4, простой порт GPIO микроконтроллера, настроенный как выход).

ws2811-disco-lights-controller-AVR-USB-MEGA16-connection

Для увеличения быстродействия кварцевый резонатор был заменен на 20 МГц. Схема микрофонного усилителя собрана на макетном поле AVR-USB-MEGA16.

ws2811-disco-lights-controller-top ws2811-disco-lights-controller-bottom

В данной разработке интерфейс USB используется только для обновления программного обеспечения firmware.

[Питание]

Обычно макетная плата AVR-USB-MEGA16 получает питание от USB, но здесь не тот случай - она должна получать питание, как и светодиодная лента, от блока питания. Но для того, чтобы перепрограммировать плату через USB бутлоадер, возможность питания от USB желательно сохранить. Поэтому в схему макетной платы AVR-USB-MEGA16 нужно внести незначительные изменения - подать питание и от USB, и от блока питания ATX через 2 диода Шоттки. На рисунке показана часть схемы макетной платы, которая касается переделки.

WS2811-disco-lights-controller-power-source

Смысл переделки заключается в том, чтобы обеспечить питание контроллера от любого из двух источников питания - и от USB, и от блока питания ATX, и при этом исключить возможность замыкания этих источников друг на друга, если они подключены одновременно.

Лента из 300 светодиодов потребляет 18А от источника стабилизированного постоянного напряжения 5V. Это большой ток, и для его обеспечения лучше всего подойдет обычный импульсный блок питания от компьютера. Ленту и контроллер нужно запитать от разных шлейфов блока питания ATX, потому что лента создает значительные пульсации напряжения 5V при большом токе потребления, и эти пульсации могут повлиять на работу микрофонного усилителя. На фото показан пример подключения контроллера и ленты к разным шлейфам стандартного блока питания ATX Power Man IW-ISP300J2-0 на 235 Вт. По каналу +5V такой блок питания может предоставить ток до 25A, чего более чем достаточно для питания нашей светодиодной ленты.

WS2811-disco-lights-ATX-power-connecting

[Алгоритм работы firmware]

Передача полного массива данных для всей ленты из 300 светодиодов занимает время порядка 7.5 мс, выполнение остальных задач занимает около 0.3 мс. Таким образом, внешний вид ленты может обновляться примерно каждые 8 мс, т. е. с частотой 125 Гц. Это означает, что генерируемые цветовые эффекты получаются очень динамичные, и полностью соответствуют звуковой картине. Вот упрощенный алгоритм работы на псевдокоде:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
      ИНИЦИАЛИЗАЦИЯ_АЦП_И_СЧЕТЧИКАLOOP:
      N=0
      CT1=0CYCLE300:
      ПЕРЕДАТЬ_ДАННЫЕ RGB[N]
      СОХРАНИТЬ_УРОВЕНЬ_СИГНАЛА_В_ЯЧЕЙКУ АЦП[N]
      N++
      ЕСЛИ (N < 300), ТО ПЕРЕХОД НА CYCLE300
      СГЕНЕРИРОВАТЬ_НОВЫЕ_ДАННЫЕ_RGB (ИЗ АЦП[300] и CT1)
      GOTO LOOP 

В течение 300 проходов цикла CYCLE300 аппаратно подсчитываются импульсы на входе T1, и запоминаются в регистрах счетчика CT1. Счетчиком цикла и одновременно индексом для массива является переменная N. Параллельно в каждом проходе CYCLE300 выполняется оцифровка звукового сигнала и запоминание его уровня в массиве АЦП[300]. Как я уже упоминал, прокрутка цикла CYCLE300 (тело цикла строки 5..9) от начала до конца занимает 7.5 мс. После этого в CT1 хранится количество подсчитанных за это время импульсов, т. е. по значению счетчика CT1 можно судить о спектре входного сигнала. Теперь нужно сформировать новые данные (строка 10), учитывая значение счетчика и накопленные оцифрованные данные с АЦП. От значения в массиве АЦП[N] будет зависеть яркость каждого соответствующего светодиода, а от значения CT1 - его цвет.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void FillRGB (u16 idx, u8 R, u8 G, u8 B)
{
   RGB[idx].r = R;
   RGB[idx].g = G;
   RGB[idx].b = B;
}
//Эта функция вызывается в главном цикле main.void generateRGB (u16 CT1) { for (u16 N=0; N < 300; N++) { if (0 == CT1) FillRGB (N, 0, 0, 0); //выключено else if (2 > CT1) FillRGB (N, ADC[N], 0, 0); //красный else if (10 > CT1) FillRGB (N, ADC[N], ADC[N], 0); //желтый else if (15 > CT1) FillRGB (N, ADC[N], 0, ADC[N]); //фиолетовый else if (20 > CT1) FillRGB (N, 0, ADC[N], 0); //зеленый else if (25 > CT1) FillRGB (N, 0, ADC[N], ADC[N]); //бирюзовый else if (30 > CT1) FillRGB (N, 0, 0, ADC[N]); //синий else FillRGB (N, ADC[N], ADC[N], ADC[N]); //белый } }

Подробнее см. исходный код проекта и файл readme.txt в архиве [6].

[Код драйвера WS2811]

Для управления драйвером WS2811 [1] был взят готовый код на языке ассемблера WS2811.h [4]. WS2811.h использует inline-ассемблер, и подробно рассмотрен в статье [5]. Этот код был немного доработан, чтобы одновременно с передачей данных на WS2811 читать данные с АЦП и сохранять их в массив АЦП[300]. Код WS2811.h рассчитан на частоту кварца 16 МГц, но он без переделки работает и на частоте 20 МГц, поскольку длительности формируемых интервалов выходных последовательных данных остаются в пределах нормы. Код доработанного драйвера и весь исходный код проекта можно скачать по ссылке [6].

[Что можно еще улучшить]

1. Схема подачи сигнала на АЦП применена упрощенная - звуковой сигнал просто подается на вход АЦП. На самом же деле нужно выделить огибающую звукового сигнала (применить детектор одной полуволны), и уже эту огибающую подавать на вход АЦП. Ключевые слова для поиска: усредняющий демодулятор на ОУамплитудный детектор на операционном усилителе, активный пиковый детектор.

active-precesion-rectifier active-peak-detector

2. Частотный анализ сигнала также упрощен - предположения о спектре сигнала делается на основании значения счетчика импульсов. Однако поскольку частота прокруток циклов передачи на RGB-ленту достаточно высокая - 125 Гц, то можно между циклами вклинить обработку реального цифрового фильтра [3]. При этом частота обновления может упасть до 25..50 Гц (что не будет заметно для глаза), но качество формирования цветомузыкальных эффектов можно повысить.

[Ссылки]

1. WS2811: микросхема для управления трехцветным RGB-светодиодом.
2. Макетная плата AVR-USB-MEGA16.
3. AVR223: Digital Filters with AVR (цифровые фильтры на AVR).
4. Driving the WS2811 at 800KHz with a 16MHz AVR site:bleaklow.com.
5. AVR-GCC: руководство по встраиванию кода на ассемблере.
6. 160124color-music-DS1307.zip - исходный код проекта color-music для макетной платы AVR-USB-MEGA16 (AVR Studio 4.19, микроконтроллер ATmega32A, кварцевый резонатор 20 МГц) и готовая прошивка.
7. WS2811-AVR-USB-MEGA16-disco-lights-video.mp4 - оригинал видеоролика (необработанное видео).
8. Самодельные часы с эффектом "бесконечного зеркала".