пятница, 14 ноября 2014 г.

Цветомузыка на базе Arduino Pro Mini

HELLO WORLD
Это мой первый проект на базе Arduino а именно Pro Mini.




Раньше я делал цветомузыки на LPT порте, но позже решил сделать более независимую от ПК цветомузыку. Поскольку с платформой Arduino я был уже знаком, выбирать не пришлось.
Поначалу все схемы я рисовал от руки на бумаге и цветомузыку собрал на макетных платах.



Но после сборки все же решил создать схемы в Eagle. Некоторые отличия от сборки есть, но суть осталась. Схему разводки светодиодов не рисовал, по-моему, это творческая часть, но если нужно, нарисую. На плате есть все необходимое:
  • Два аудио разъема для подключения источника сигнала и колонок.
  • Разъем для переключателя левый/правых т.к. цветомузыка работает с одним каналом нужно иметь возможность выбирать из стерео сигнала. 
  • Разъем для усилителя. Усилитель из любых дешевых колонок подойдет. Питание всей цветомузыки подается через кнопку включения на усилителе.
  • Разъем для подключения светодиодов.
  • Три кнопки для переключения режимов. Задумывал три режима – 1 активный (мигание под музыку), 2 пассивный быстрый (с быстрой анимацией, но не под музыку), 3 пассивный медленный (медленная плавная анимация не под музыку) но задумку еще не выполнил.
  • Посадочное место для Arduino Pro Mini.
Все порты платы Arduino защищены резисторами. Что касается транзисторов, я использовал КТ817.

Принципиальная схема

Схема печатной платы
Схема печатной платы

На схемах есть резисторы и конденсаторы с неуказанным номиналом, их нужно рассчитывать в зависимости некоторых параметров – питание, количество светодиодов, характеристики светодиодов и т.д.
Лично я рассчитывал резисторы следующим образом:
Питание я использовал 9В, но предполагал и 12В. Светодиоды разные, к примеру, белые имеют характеристики 3В, 10мА, а красные – 2В, 20мА. На каждом канале у меня по 6 светодиодов одного цвета подключены параллельно, из этого следует – белым светодиодам нужно 3В, 60мА, красным - 2В, 120мА. Далее воспользуемся формулой R = (U – Uz) / I.
Для белых светодиодов:
U = 12В
Uz = 3В
I = 0.06А
R = (12 – 3) / 0.06 = 150 Ом
Для красных светодиодов:
U = 12В
Uz = 2В
I = 0.12А
R = (12 – 2) / 0.12 = 83.3 Ом
В результате я использовал резисторы номиналом 165 Ом (два по 330 Ом параллельно, других небыло в наличии) на все светодиоды. Рассчитывать другие цвета нет смысла, их параметры колеблются между белыми и красными. 
Конденсаторы подбирал на глаз, в результате:


  • Белые и зеленые 220мФ
  • Синие 470мФ
  • Желтые 2200мФ
  • Красные 1500мФ
Что касается программы, она работает, но еще не закончена. Довольно многое стоит еще допилить напильником. В основе всего проекта лежит “Быстрое преобразование Фурье”, а точнее библиотека FFT (Fast Fourier transform).

/*
FFT for LoL Shield v0.9

based on FFT library and code from the Arduino forums and
the Charlieplexing library for the LoL Shield.
*/

#include <fix_fft.h>

#define AUDIOPIN 0  // Аудио вход
#define AButton1 1  // Кнопка 1
#define AButton2 2  // Кнопка 2
#define AButton3 3  // Кнопка 3

char im[128], data[128];
char data_a[14]; // Массив из 14 значений для аналоговых выводов
char data_d[14]; // Массив из 14 значений для цифровых выводов
int i=0, val, vd=0; // Переменные для циклов
int vmin=30000; // Минимальное значение аудиосигнала
int vmax=0; // Максимальное значение аудиосигнала
// Номера аналоговых выводов - Катоды сетодиодов
// const int ALeds[] = {3, 5, 6, 9, 10, 11};
// Номера цифровых выводов - Катоды сетодиодов
const int DLeds[] = {1, 0, 2, 4, 7, 8, 12, 13, 3, 5, 6, 9, 10, 11}; // Номера выводов 6x-digital 6x-PWM
int vBack=0; // общий фоновый
int LastClick = 1; // Номер последней нажатой кнопки

void setup()
{
  for (i=0; i<14; i++)
  {
    pinMode(DLeds[i],OUTPUT);
    digitalWrite(DLeds[i], HIGH);
    // pinMode(ALeds[i],OUTPUT);
  }
}

void Passive()   // Пасивная цветомузыка, мигание без аудио сигнала
{
  for (i=6; i<14; i++)
    {
      digitalWrite(DLeds[i], 1);
      delay(100);
      digitalWrite(DLeds[i], 0);
      delay(100);
    }
}

void Active()   // Активная цветомузыка, обработка аудио сигнала
{
  vmin = 30000;
  vmax = 0;

  for (i=0; i < 128; i++)
  {                                     
    val = analogRead(AUDIOPIN);                                    
    data[i] = val;    // усиливаем входящий сигнал    
    im[i] = 0;                                                     
  }

  fix_fft(data,im,7,0);

  for (i=0; i< 128; i++)
  {                                      
    data[i] = sqrt(data[i] * data[i] + im[i] * im[i]);  
    // получаем абсолютное значение от значения из массива, дальше имеем дело только с положительными числами
  }

  for (i=0; i<8; i++)
  {
    // усредняем соседние значения
    data_a[i] = (data[i*16] + data[i*16 + 1] + data[i*16 + 2] + data[i*16 + 3] + data[i*16 + 4] + data[i*16 + 5] + data[i*16 + 6] + data[i*16 + 7]
    + data[i*16 + 8] + data[i*16 + 9] + data[i*16 + 10] + data[i*16 + 11] + data[i*16 + 12] + data[i*16 + 13] + data[i*16 + 14] + data[i*16 + 15]);
    vmax = max(vmax, data_a[i]); // запоминаем максимальное значение
    vmin = min(vmin, data_a[i]); // запоминаем минимальное значение
  }

  for (i=0; i<8; i++)
  {
    // масштабируем значения под аналоговый вывод
    data_d[i] = map(data_a[i], 0, 63, 0, 1); //цифровые
    // data_avgs[i] = map(data_avgs[i], vmin, vmax, 255, 0); // аналоговые
    // Выводим сигнал
    digitalWrite(DLeds[i], data_d[i]);
    // analogWrite(ALeds[i], data_avgs[i]);
  }

  vBack = map(val, 0, 255, 0, 6);
  for (i=1; i<7; i++)
  {
   if (i <= vBack) // если 
   {
     digitalWrite(DLeds[i+7], 1);
   }
   else // если 
   {
     digitalWrite(DLeds[i+7], 0);
   }
  }
}

void Options() // Третий режим. Назначения пока нет
{
  for (i=6; i<14; i++)
    {
      digitalWrite(DLeds[i], 1);
      delay(100);
    }
  for (i=0; i<14; i++)
    {
      digitalWrite(DLeds[i], 0);
      delay(100);
    }
}

void loop()
{
  
   if (analogRead(AButton1) == 1023) // если 
   {
     LastClick = 1;       // запоминаем, что кнопка 1 была нажата
     Passive();           // вызываем функцию 1й кнопки
   }
   else // если 
   {
     if (analogRead(AButton2) == 1023) // если 
     {
       LastClick = 2;       // запоминаем, что кнопка 1 была нажата
       Active();            // вызываем функцию 1й кнопки
     }
     else // если 
     {
       if (analogRead(AButton3) == 1023) // если 
       {
         LastClick = 3;       // запоминаем, что кнопка 1 была нажата
         Options();           // вызываем функцию 1й кнопки
       }
       else
       {
         switch (LastClick)   // dвспоминаем, какая кнобка была нажата раньше
         {
           case 1:            // выполняется, если последней была нажата кнопка 1
             Passive();       // вызываем функцию 1й кнопки
             break;
           case 2:             // выполняется, если последней была нажата кнопка 2
             Active();         // вызываем функцию 2й кнопки
             break;
           case 3:             // выполняется, если последней была нажата кнопка 3
             Options();        // вызываем функцию 3й кнопки
             break;
         }
       }
     }
   }
}



Имела место глупость слишком рано похвастаться и выложить видео, не имея схем в приемлемом виде. Надеюсь, я не отпугнул заинтересовавшихся людей столь долгой задержкой.






Скачать все материалы одним архивом (Схемы Eagle, Sketch, библиотека FFT, ссылки и фото):

Ссылки на источники:
Arduino Realtime Audio Spectrum Analyzer with Video out!
Индикатор уровня на Arduino и LoL-shield
Arduino: LED цветомузыка
Цветомузыка в люминесцентном светильнике
LPT цветомузыка



7 комментариев:

  1. Файлик не найден, наверное уже ни кто не скачивал. мне бы скейтч пригодился

    ОтветитьУдалить
  2. надо ж было на таком файлообменнике то выложить)))) выложите схему плз на нормальный файлообменник)

    ОтветитьУдалить
  3. Этот комментарий был удален автором.

    ОтветитьУдалить
  4. Что значит комментарий: Усиливаем входящий сигнал?
    Сколько не читал разных источников, так и не вкурил. Это что - трудности перевода?

    ОтветитьУдалить
  5. ссылка на архив не работает

    ОтветитьУдалить
  6. Woori Casino | Free Bonus and Review | Casino Bonuses
    The Woori Casino bonus codes and promotions, bonuses, and promotions all listed above 카지노 are updated ラッキーニッキー frequently for new players, players, 우리카지노

    ОтветитьУдалить
  7. Casino Game For Sale by Hoyle - Filmfile Europe
    › casino-games › casino-games air jordan 18 retro men blue › casino-games where can i find air jordan 18 retro varsity red › casino-games air jordan 18 retro men red cheap Casino Game for sale by Hoyle on Filmfile Europe. Free shipping for most countries, no download required. show air jordan 18 retro racer blue Check the 사설토토 추천 샤오미 deals we have.

    ОтветитьУдалить