Как стать автором
Обновить

Цветомузыка или визуализации музыки

Время на прочтение 6 мин
Количество просмотров 28K
Все началось с одного очень заинтересовавшего меня поста о создании лазерного шоу. Это было как раз под новый год и нужно было что-то придумать для надвигающейся новогодней вечеринке. А лазерное шоу, управляемое музыкой, было тем, что доктор прописал! Китайские указки горели одна за одной, да и яркость их была весьма посредственной. Как раз где-то нашел статью как сделать лазерную указку из DVD-привода. Новый год уже давно прошел, LPT порт сгорел, но зато пришел заказанный мной ATTiny2313 и куча других электронных компонентов. Много времени прошло за паяльником, много переделанных плат, собранных граблей… В конце концов я решил заказать мощный RGB светодиод на 3W. Тогда уже лазерное шоу работало на зеленом лазере 30mW с помощью плагина визуализации Winamp через COM порт. В общем, светодиод произвел на меня огромное впечатление, и я решил добавить к лазерному шоу еще и цветомузыку.

Устройство


Что нам дано: три куллера и лазер для модуля лазерного шоу; два мощных RGB светодиода на 3W. Нужно для этого дела сделать управляющий блок, чтобы у него была возможность общаться с компьютером через COM-порт со специальной программой.

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

image

Для управляющего блока был выбран микроконтроллер ATMega8. Программировать на нем просто, в интернете полно статей. Особенно сильно мне помог сайт EasyElectronics, там я и научился делать простенькие устройства и немного разучил схемотехнику.

Большого выбора светодиодов у меня не было, собственно вариант был только один: ARPL-STAR 3W RGB. ARPL-STAR 3W RG.
У него 6 выводов, так что каждый из трех светодиодов управляется отдельно. В моем случае схема подключения была с общим анодом. Надо сказать, что светодиоды потребляют немаленький ток — каждый по 350мА при максимальной яркости. Всего RGB лампы две и соединены они параллельно к одним и тем же выводам МК, так что ток очень совсем не маленький. Для коммутации была выбрала все та же uln2003 из статьи про лазерное шоу, только использовалось по два вывода на каждый светодиод лампы, т.к. каждый вывод держит только 500мА, так что итого 6 выводов. Скажу сразу, что идея была не самая лучшая. Хоть по параметрам все в порядке, но на деле если лампы горят белым цветом на всю мощность, то uln перегревается и выключается. У меня появилась идея совсем другого дизайна, о котором я напишу ниже.

На схеме стандартная обвеска для МК, для питания встроен разъем Molex, который обеспечивает 12В для куллеров лазерного шоу и 5В для всего остального. Можно подключить к компьютеру, но я пользовался для удобства отдельным блоком питания с выводом типа molex. Для программирования МК использовался стандартный программатор Громова. А вот адаптер RS232<->UART. В дальнейшем планировалось сделать все через USB, но я использовал неправильный разъем USB на плате, так что теперь не могу найти шнур для соединения с компьютером.

Цвет лампы зависит от всех трех светодиодов, которые в нее встроены. Цветовая модель — RGB. Яркость каждого из светодиодов зависит от напряжения. Так что для изменения яркости конкретной компоненты используется ШИМ. Таким образом, для задания цвета контроллеру достаточно передавать три значения от 0 до 255, где 255 означает максимальную яркость. Стоит отметить, что лампы сильно греются, так что нужно сажать их на радиаторы.

Программа МК была написана на Си в AVRStudio и она довольно простая: по приходу байта по UART он заносится в очередь; в главном цикле программа вызывает текущую команду. Комманда — это индекс процедуры в таблице, которую нужно запустить. Используемых команд всего три: простой, очистить цвет и установить цвет. В простое программа смотрит, есть ли данные в очереди, и если есть, то индекс текущей команды меняется на то, что находится в очереди. Команда установки цвета принимает 3 байта данных, так что она висит в главном цикле пока в очереди данных не будет 3 байта.

ШИМ реализован программно. Это сделано потому, что в ATMega8 аппаратных каналов ШИМ всего три, а мне нужно было их шесть: три для куллеров лазерного шоу и три для ламп.

Вот основной код программы:
int main()
{
	#define baudrate 9600L
	#define bauddivider (F_CPU / (16 * baudrate) - 1)
 
	UBRRL = LO(bauddivider);
	UBRRH = HI(bauddivider);
	UCSRA = 0;
	UCSRB = 1<<RXEN|1<<TXEN|1<<RXCIE|0<<TXCIE;
	UCSRC = 1<<URSEL|1<<UPM1|0<<UPM0|1<<UCSZ0|1<<UCSZ1;

	D_SEND('r');

	TCCR0 = (0<<CS02)|(0<<CS01)|(1<<CS00);
	TIMSK = (1<<TOIE0);

	DDRB = DDRD = DDRC = 0xff;
	PORTB = PORTD = PORTC = 0;

	g_currentSetup = 0;
	SetupShowFromPredefines(0);
	g_currentColorSetup = 0;
	SetColorFromPredefines(0);

	UartRcvInit();

	g_command = 0;
	g_shit = 1;
	g_pwmValue = 0;

	sei();

	for(;;)
	{
		//преднастройки. Сделаны по сути для отладки
		//когда запускается МК, лампы начинают менять цвет
		//цвета заданы в таблице
		if (g_shit > 0 && g_counter >= 0xff00)
		{
			g_currentColorSetup++;
			if (g_currentColorSetup == MAX_COLOR_PREDEFINES)
				g_currentColorSetup = 0;
			SetColorFromPredefines(g_currentColorSetup);

			ATOMIC_BLOCK(ATOMIC_FORCEON)
			{
				g_counter = 0;
			}
		}

		PCOMMAND pFunc = (PCOMMAND)pgm_read_word(g_commands + g_command);
		if (pFunc())
		{
			g_command = 0;
		}
	}

	return 0;
}

ISR(USART_RXC_vect)
{
	//прием байта
	UartOnRecieve();
}

ISR(TIMER0_OVF_vect)
{
	g_counter++;
	g_pwmValue++;

	//включение лампы по переполнению значения ШИМ
	if (g_pwmValue == 0)
	{
		LAMP_PORT |= LAMP_MASK;
	}
	
	//как только значение ШИМ достигает определенного значения
	//так определенный порт сразу выключается
	if (g_pwmValue == g_pwm[3]) CBI(LAMP_PORT, LAMP_RED);
	if (g_pwmValue == g_pwm[4]) CBI(LAMP_PORT, LAMP_GREEN);
	if (g_pwmValue == g_pwm[5]) CBI(LAMP_PORT, LAMP_BLUE);
}


Пример команды смены цвета:
//Номер - 4
//Обновление цвета
bool UpdateColor()
{
	ColorData data;

	if (UartRead((byte*)&data, sizeof(ColorData)))
	{
		D_SEND('l');
		g_shit = 0;

		SetColor(&data);

		return true;
	}

	return false;
}

void SetColor(ColorData *pData)
{
	ATOMIC_BLOCK(ATOMIC_FORCEON)
	{
		g_pwm[3] = pData->red;
		g_pwm[4] = pData->green;
		g_pwm[5] = pData->blue;
	}
}


Печатная плата сделана методом ЛУТа.



Программа




Изначально все управлялось с помощью плагина визуализации на Winamp. Но это было не удобно, т.к. часто музыка слушалась вконтакте. Писать было решено на C#, т.к. приложение чисто интерфейсное должно быть. Поискав в интернете информацию о захвате звука, я не нашел ничего дельного, но вспомнил, что в звуковой карте можно настраивать устройство записи на вывод того, что сейчас воспроизводится. Так что я, воспользовавшись библиотекой Bass, быстренько сделал пример. Также оказалось, что в C# есть целый класс для работы с последовательными портами — все оказалось очень просто.

Хотя цветовая модель ламп есть RGB по понятным причинам, она не самая подходящая для визуализации музыки, так что программа использует модель HSV. Каждая цветовая компонента — цвет, насыщенность и яркость — настраиваются независимо. Я решил не ограничиваться только лишь цветомузыкой: для каждой компоненты цвета можно выбирать один из возможных источников: ручной ввод, случайное значение, аудио и копирование другой компоненты. В ручном режиме можно самому настраивать цвет, яркость и насыщенность. С помощью случайного режима можно сделать лампу настроения (есть настройки диапазона, частоты смены и скорости смены). Самый интересный режим — это конечно же аудио.

Все основывается на частотном спектре. Выбирается диапазон частот, который будут влиять на значение компоненты цвета, выбирается уровень сигнала (можно уменьшить, можно увеличить), смещение, сглаживание. Можно также использовать не уровень сигнала, а его изменение. Я обычно ставлю это на яркость ламп и получается такой стробоскопический эффект (стробоскоп, кстати, тоже можно реализовать) — при нарастании уровня сигнала яркость увеличивается, при спаде, соответственно, уменьшается. Тут как раз пригодится сдвиг, с помощью которого можно регулировать начальную яркость.

Что можно сделать


Во-первых, как я писал выше, если включить лампы на полную мощность, то они довольно быстро выключатся из-за uln. К тому же, если лампы нужно расположить на относительно большом расстоянии от головного устройства, то нужно использовать толстенные провода, иначе будут большие потери. Так что у меня появилась идея совсем иного дизайна: сделать каждую лампу как отдельный модуль со своим питанием, своим МК и средствами управления. Эти модули будут подключаться к основному устройству через витую пару, а средства avr позволяют МК общаться между собой. Т.о. можно будет управлять лампами отдельно.

Во-вторых, мигать лампочками можно не только под музыку, но и под видео, можно сделать что-то вроде AmbLight, и текущая архитектура позволяет этого сделать. Есть информация по захвату видео? Сами по себе лампы очень яркие, особенно две, и достаточно освещают комнату в 35 квадратов, поэтому можно вывести просмотр фотографий на новый уровень! Смотрите вы фотографии с моря, а вся комната наливается приятным голубым оттенком — красота!

Заключение


Много сделано, много предстоит сделать, к сожалению не в ближайшее время. Напоследок — видео. К сожалению, фотоаппарат мой не отличается хорошей светочувствительностью, поэтому на видео кажется, что вообще ничего не освещается. На самом деле эффекты очень сильные, а если на сами лампы смотреть, то сильно давит на глаза — самое то для вечеринок.





UPD: В архив добавил исходники программы управления
Теги:
Хабы:
+51
Комментарии 28
Комментарии Комментарии 28

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн