Недавно на форуме кто-то писал, что на простейших микроконтроллерах цветомузыку сделать невозможно - или спектр не успевает посчитать или даются ссылки на довольно сложные для освоения "с налёту" готовые библиотеки.
Предлагаю для затравки обсуждения или повторения "схему за час":
Картинку из единственного корпуса в Протеусе нарисовал для демонстрации вместе с простейшей программой.
Итак, вместо прикручивания фильтров и всяких БПФ предлагаю попользовать старинный метод примерного определения составляющих спектра сигнала путём подсчёта числа переходов через 0.
Программа просто измеряет длительность переходов и разбивает на группы с желаемой длительностью.
Далее количество накопленного сравниваем с установленными порогами (по вкусу) и зажигаем соответствующие лампочки.
Программу можно попробовать прямо в Протеусе прикрутив файл с подходящими частотами (прицепил) или музыкой.
Ругательства типа "идея - отстой" приветствуются, но только с предложениями по улучшению без сильного усложнения и с теоретическими выкладками!
Собственно вся программа умещается в десяток строчек:
#pragma interrupt_handler int0_isr:iv_INT0
void int0_isr(void)//пересечение нуля (в обеих направлениях, см. MCUCR бит 2 и 3)
{
cnt=TCNT1;//вычитали счётчик
TCNT1=0;//обнулим его, пусть дальше считает пока мы заняты
//делим длительности по диапазонам - выбираются по вкусу (взял 3 КГц, 1 КГц, 300 Гц разделы)
if(cnt‹160) {p1++;}//f›3k 1m/3000/2=160 - это число отсчётов на полпериода желаемой частоты
else if(cnt‹400) {p2++;}//1k‹f‹3k 1m/1000/2=500
else if(cnt‹1600) {p3++;}//300‹f‹1k 1m/300/2=1666
else {p4++;}//f‹300
zeroes++;//сколько пересечений уже
if(zeroes›50)//общее число перечечений нуля - влияет на скорость обновления состояния лампочек
{
PORTC=0;//сбрасываем выходы порта
//по вкусу расставляем пороги на составляющие спектра
if(p1›15)PORTC|= (1‹‹0);
if(p2›25)PORTC|= (1‹‹1);
if(p3›15)PORTC|= (1‹‹2);
if(p4›5)PORTC|= (1‹‹3);
p1=p2=p3=p4=0;//зануляем счетчики после использования
zeroes=0;
}
}