Аудио спектроанализатор на RGB-ленте WS2812

Имелась в наличии светодиодная лента на базе управляемых RGB светодиодов WS2812 (5м 150 светодиодов), оставшаяся от проекта  Аргентина — Ямайка (5:0) (табло результатов ЧМ 2014 по футболу для пивбара). Пока не используется и решил сделать аудио спектроанализатор на Arduino и MSGEQ7 с визуализацией на этой ленте. MSGEQ7 — 7-ми полосный фильтр для графического эквалайзера. Данный 8-ми выводной чип способен из входного аудиосигнала выделить частотные полосы 63Гц, 160Гц, 400Гц, 1кГц, 2.5кГц, 6.25кГц и 16кГц:

На сайте есть проекты использования микросхемы MSGEQ7, например здесь, где рассмотрена работа MSGEQ7 в связке с Arduino. Так что задача — реализовать красивый вывод данных.

Доска 10×15 

Доска 10x15 LED

В качестве контроллера используем CraftDuino от российского «Robocraft». Это по сути Arduino Duemilanove. 

Схема следующая

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

И плата. Плата вставлена в CraftDuino как шилд,

Печатная плата

Учтены ошибки проекта Аргентина — Ямайка 5:0 , приведшие к сгоранию светодиодов. Перед подключением ленты к источнику тока необходимо добавить конденсатор (1000 μF, 6.3 В или выше). Это предотвратит секции от начального всплеска тока. Кроме того желательно добавить резистор от 300 до 500 Ом резистор между выводом Arduino и вводом данных на первом диоде для предотвращения всплесков напряжения, которые могут повредить первую секцию ленты. 

В качестве блока питания используется блок питания компьютера.

Теперь написание скетча.

Вывод осуществляем на прямоугольник 9×14. Разделяем спектр на 7 полос и выводим на 14 столбцов (2 на полосу) разными цветами. Цвета хранятся в массиве colors[14][3]. Кроме того делаем круговое смещение (движение) цветов по горизонтали. Используется Arduino библиотека Adafruit_NeoPixel.

 #include "Adafruit_NeoPixel.h" #define PIN 6  // Parameter 1 = number of pixels in strip // Parameter 2 = Arduino pin number (most are valid) // Parameter 3 = pixel type flags, add together as needed: //   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs) //   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers) //   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products) //   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2) Adafruit_NeoPixel strip = Adafruit_NeoPixel(150, PIN, NEO_GRB + NEO_KHZ800);  #define MAX_X 10 #define MAX_Y 15  byte maska[135]={    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,    0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,    0,1,1,0,0,0,0,1,0,0,0,0,1,1,1,    0,1,1,0,0,0,1,1,1,0,0,1,1,1,1,    0,1,1,0,1,1,1,1,1,0,0,1,1,1,1,    0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,    0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,    }; int colors[14][3]={{0,150,0},{0,255,0},                    {100,255,0},{255,255,0},                    {150,0,0},{255,0,0},                    {255,0,100},{255,0,255},                    {150,0,255},{0,0,255},                    {0,0,150},{0,150,255},                    {0,255,255},{0,255,100}                    }; int offcolor=0; unsigned long millis1=0; // плохие светодиоды int badleds[]={0,1,15,30};   // #define msg7RESET 11 #define msg7Strobe 12 #define msg7DCout 0  int arr1[7]={0,0,0,0,0,0,0};   void setup() {   Serial.begin(9600);   pinMode(msg7RESET, OUTPUT);   pinMode(msg7Strobe, OUTPUT);   strip.begin();   for(int i=0;i<135;i++)     {     correctstrip(i,0,0,0);     }   strip.show();   Serial.println("oksetup");   }  void loop() {     digitalWrite(msg7RESET, HIGH);   // осуществляем сброс MSGEQ7     delay(5);     digitalWrite(msg7RESET, LOW);       for (int x = 0; x < 7; x++){             // семь частот - семь стробирующих импульсов         digitalWrite(msg7Strobe, LOW);         delayMicroseconds(35);           // ждем установления значения 35 мкс         int spectrumRead = analogRead(A0);      // считываем значение с аналогового входа           int PWMvalue = map(spectrumRead, 0, 1024, 0, 255);  // преобразовываем диапазон 0-1024 к диапазону 0-255 для ШИМ         setVals(x,PWMvalue);         arr1[x]=spectrumRead;          digitalWrite(msg7Strobe, HIGH);     }     for(int i=0;i<7;i++)       {Serial.print(" ");Serial.print(arr1[i]);}     Serial.println();    strip.show();   if(millis()-millis1>1000)     {millis1=millis();offcolor=(offcolor+1)%7;     }   } /////  //удалить испорченные void correctstrip(int place,int color1,int color2,int color3)   {   int offset=0;   for(int i=0;i=j*28)        {        correctstrip((9-j)*15+i*2+1,colors[((i+offcolor)%7)*2][0],colors[((i+offcolor)%7)*2][1],colors[((i+offcolor)%7)*2][2]);        correctstrip((9-j)*15+i*2+2,colors[((i+offcolor)%7)*2+1][0],colors[((i+offcolor)%7)*2+1][1],colors[((i+offcolor)%7)*2+1][2]);         }     else       {       correctstrip((9-j)*15+i*2+1,0,0,0);             correctstrip((9-j)*15+i*2+2,0,0,0);             }       }     }

Список радиоэлементов

Обозначение Тип Номинал Количество Примечание Магазин Мой блокнот
Микросхема MSGEQ7 1
Плата Arduino CraftDuino (Duemomilanove) 1
RGB-лента WS2812 1 10×15
C1, C2, C4 Конденсатор 0.1 мкФ 3
C5 Конденсатор 39 пФ 1
Конденсатор 6.3 В 1000 мкФ 1
R1 Резистор 200 кОм 1
R2, R3 Резистор 22 кОм 2
R4 Резистор 300 Ом 1
Блок питания 400 Вт 1 ATX