Светодиодная шкала SHB10R — это, по сути, 10 независимых светодиодов в одном корпусе, выложенных в форме шкалы. У индикатора 20 ножек: анод и катод для каждого светодиода.
На основе Arduino используя светодиодную шкалу SHB10R можно сделать простой 7-ми полосный анализатор спектра по 20 диодов (по 2 модуля SHB10R) на одну полосу. В итоге используется 14 светодиодных модулей (140 светодиодов).
Схема анализатора спектра достаточно проста, она содержит всего три основных компонента, это плата Arduino, светодиодная матрица на 14 светодиодных модулях и дешифратор К155ИД3 (SN74154). Для управления анодами светодиодов используются цифровые выходы Arduino D2…D11. Катоды каждого светодиодного модуля замкнуты между собой и подключены к выходам дешифратора К155ИД3 напрямую без транзисторных ключей. Для управления дешифратором используются цифровые выходы Arduino D0, D1 и D12, D13.
Аудио сигнал подается на аналоговый вход Ardiuno A0, через разделительный конденсатор емкостью 0,1 мкФ.
#define AUTO_GAIN 1 // автонастройка по громкости (экспериментальная функция) #define VOL_THR 75 // порог тишины (ниже него отображения на матрице не будет) #define LOW_PASS 70 // нижний порог чувствительности шумов (нет скачков при отсутствии звука) #define DEF_GAIN 110 // максимальный порог по умолчанию #define FHT_N 128 // ширина спектра х2 #define LOG_OUT 1 #include <FlexiTimer2.h> // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=298&download=1 #include <FHT.h> // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=297&download=1 byte ur[8],urr[8];; byte i,dig,seg,i1; byte posOffset[7] = {4, 6, 8, 15, 25, 30, 35}; byte gain_sp = DEF_GAIN; unsigned long gainTimer; byte maxValue, maxValue_f; float k = 0.1; void setup() { FlexiTimer2::set(2, 1.0/2000, flash); FlexiTimer2::start(); ADMUX = 0b01100000; ADCSRA = 0b11010110; for(i=0;i<=13;i++){pinMode(i,OUTPUT);} } void loop(){ analyzeAudio(); // функция FHT, забивает массив fht_log_out[] величинами по спектру for (int pos = 0; pos < 7; pos++) { if (fht_log_out[posOffset[pos]] > maxValue) maxValue = fht_log_out[posOffset[pos]]; int posLevel = map(fht_log_out[posOffset[pos]], LOW_PASS, gain_sp, 1, 20);posLevel = constrain(posLevel, 1, 20); urr[pos] = posLevel; if(urr[pos]<ur[pos]){ur[pos]=ur[pos]-1;} else{ ur[pos] = posLevel;} delay(1); //delayMicroseconds(500); } if (AUTO_GAIN) { maxValue_f = maxValue * k + maxValue_f * (1 - k); if (millis() - gainTimer > 1500) { if (maxValue_f > VOL_THR) gain_sp = maxValue_f; else gain_sp = 150;gainTimer = millis();} else {gain_sp = DEF_GAIN;}} }// loop void flash(){ switch(i){ // 1 ряд case 0: cl();if(ur[0]<=10){dig=1;seg=ur[0];digital();segment();segment1();}else{dig=1;seg=10;digital();segment();seg=0;segment1();}break; case 1: cl();if(ur[0]<=10){dig=2;seg=0;digital();segment();segment1();}else{dig=2;seg=ur[0]-10;digital();segment();segment1();}break; // 2 ряд case 2: cl();if(ur[1]<=10){dig=3;seg=ur[1];digital();segment();segment1();}else{dig=3;seg=10;digital();segment();seg=0;segment1();}break; case 3: cl();if(ur[1]<=10){dig=4;seg=0;digital();segment();segment1();}else{dig=4;seg=ur[1]-10;digital();segment();segment1();}break; // 3 ряд case 4: cl();if(ur[2]<=10){dig=5;seg=ur[2];digital();segment();segment1();}else{dig=5;seg=10;digital();segment();seg=0;segment1();}break; case 5: cl();if(ur[2]<=10){dig=6;seg=0;digital();segment();segment1();}else{dig=6;seg=ur[2]-10;digital();segment();segment1();}break; // 4 ряд case 6: cl();if(ur[3]<=10){dig=7;seg=ur[3];digital();segment();segment1();}else{dig=7;seg=10;digital();segment();seg=0;segment1();}break; case 7: cl();if(ur[3]<=10){dig=8;seg=0;digital();segment();segment1();}else{dig=8;seg=ur[3]-10;digital();segment();segment1();}break; // 5 ряд case 8: cl();if(ur[4]<=10){dig=9;seg=ur[4];digital();segment();segment1();}else{dig=9;seg=10;digital();segment();seg=0;segment1();}break; case 9: cl();if(ur[4]<=10){dig=10;seg=0;digital();segment();segment1();}else{dig=10;seg=ur[4]-10;digital();segment();segment1();}break; // 6 ряд case 10: cl();if(ur[5]<=10){dig=11;seg=ur[5];digital();segment();segment1();}else{dig=11;seg=10;digital();segment();seg=0;segment1();}break; case 11: cl();if(ur[5]<=10){dig=12;seg=0;digital();segment();segment1();}else{dig=12;seg=ur[5]-10;digital();segment();segment1();}break; // 7 ряд case 12: cl();if(ur[6]<=10){dig=13;seg=ur[6];digital();segment();segment1();}else{dig=13;seg=10;digital();segment();seg=0;segment1();}break; case 13: cl();if(ur[6]<=10){dig=14;seg=0;digital();segment();segment1();}else{dig=14;seg=ur[6]-10;digital();segment();segment1();}break; } i++;if(i>13){i=0;}} void segment1(){ switch(seg){ // 1 2 3 4 5 6 7 8 9 10 case 0: ch(11,0);ch(10,0);ch(9,0);ch(8,0);ch(7,0);ch(6,0);ch(5,0);ch(4,0);ch(3,0);ch(2,0);break; case 1: ch(11,1);ch(10,0);ch(9,0);ch(8,0);ch(7,0);ch(6,0);ch(5,0);ch(4,0);ch(3,0);ch(2,0);break; case 2: ch(11,0);ch(10,1);ch(9,0);ch(8,0);ch(7,0);ch(6,0);ch(5,0);ch(4,0);ch(3,0);ch(2,0);break; case 3: ch(11,0);ch(10,0);ch(9,1);ch(8,0);ch(7,0);ch(6,0);ch(5,0);ch(4,0);ch(3,0);ch(2,0);break; case 4: ch(11,0);ch(10,0);ch(9,0);ch(8,1);ch(7,0);ch(6,0);ch(5,0);ch(4,0);ch(3,0);ch(2,0);break; case 5: ch(11,0);ch(10,0);ch(9,0);ch(8,0);ch(7,1);ch(6,0);ch(5,0);ch(4,0);ch(3,0);ch(2,0);break; case 6: ch(11,0);ch(10,0);ch(9,0);ch(8,0);ch(7,0);ch(6,1);ch(5,0);ch(4,0);ch(3,0);ch(2,0);break; case 7: ch(11,0);ch(10,0);ch(9,0);ch(8,0);ch(7,0);ch(6,0);ch(5,1);ch(4,0);ch(3,0);ch(2,0);break; case 8: ch(11,0);ch(10,0);ch(9,0);ch(8,0);ch(7,0);ch(6,0);ch(5,0);ch(4,1);ch(3,0);ch(2,0);break; case 9: ch(11,0);ch(10,0);ch(9,0);ch(8,0);ch(7,0);ch(6,0);ch(5,0);ch(4,0);ch(3,1);ch(2,0);break; case 10: ch(11,0);ch(10,0);ch(9,0);ch(8,0);ch(7,0);ch(6,0);ch(5,0);ch(4,0);ch(3,0);ch(2,1);break;} } void segment(){ switch(seg){ // 1 2 3 4 5 6 7 8 9 10 case 0: ch(11,0);ch(10,0);ch(9,0);ch(8,0);ch(7,0);ch(6,0);ch(5,0);ch(4,0);ch(3,0);ch(2,0);break; case 1: ch(11,1);ch(10,0);ch(9,0);ch(8,0);ch(7,0);ch(6,0);ch(5,0);ch(4,0);ch(3,0);ch(2,0);break; case 2: ch(11,1);ch(10,1);ch(9,0);ch(8,0);ch(7,0);ch(6,0);ch(5,0);ch(4,0);ch(3,0);ch(2,0);break; case 3: ch(11,1);ch(10,1);ch(9,1);ch(8,0);ch(7,0);ch(6,0);ch(5,0);ch(4,0);ch(3,0);ch(2,0);break; case 4: ch(11,1);ch(10,1);ch(9,1);ch(8,1);ch(7,0);ch(6,0);ch(5,0);ch(4,0);ch(3,0);ch(2,0);break; case 5: ch(11,1);ch(10,1);ch(9,1);ch(8,1);ch(7,1);ch(6,0);ch(5,0);ch(4,0);ch(3,0);ch(2,0);break; case 6: ch(11,1);ch(10,1);ch(9,1);ch(8,1);ch(7,1);ch(6,1);ch(5,0);ch(4,0);ch(3,0);ch(2,0);break; case 7: ch(11,1);ch(10,1);ch(9,1);ch(8,1);ch(7,1);ch(6,1);ch(5,1);ch(4,0);ch(3,0);ch(2,0);break; case 8: ch(11,1);ch(10,1);ch(9,1);ch(8,1);ch(7,1);ch(6,1);ch(5,1);ch(4,1);ch(3,0);ch(2,0);break; case 9: ch(11,1);ch(10,1);ch(9,1);ch(8,1);ch(7,1);ch(6,1);ch(5,1);ch(4,1);ch(3,1);ch(2,0);break; case 10: ch(11,1);ch(10,1);ch(9,1);ch(8,1);ch(7,1);ch(6,1);ch(5,1);ch(4,1);ch(3,1);ch(2,1);break;} } void digital(){ switch(dig){ //////// К155ИД3 //////////////////////////////////////// case 1: ch(0,0);ch(1,0);ch(12,0);ch(13,0);break; // 0000 case 2: ch(0,0);ch(1,0);ch(12,0);ch(13,1);break; // 0001 case 3: ch(0,0);ch(1,0);ch(12,1);ch(13,0);break; // 0010 case 4: ch(0,0);ch(1,0);ch(12,1);ch(13,1);break; // 0011 case 5: ch(0,0);ch(1,1);ch(12,0);ch(13,0);break; // 0100 case 6: ch(0,0);ch(1,1);ch(12,0);ch(13,1);break; // 0101 case 7: ch(0,0);ch(1,1);ch(12,1);ch(13,0);break; // 0110 case 8: ch(0,0);ch(1,1);ch(12,1);ch(13,1);break; // 0111 case 9: ch(0,1);ch(1,0);ch(12,0);ch(13,0);break; // 1000 case 10: ch(0,1);ch(1,0);ch(12,0);ch(13,1);break;// 1001 case 11: ch(0,1);ch(1,0);ch(12,1);ch(13,0);break;// 1010 case 12: ch(0,1);ch(1,0);ch(12,1);ch(13,1);break;// 1011 case 13: ch(0,1);ch(1,1);ch(12,0);ch(13,0);break;// 1100 case 14: ch(0,1);ch(1,1);ch(12,0);ch(13,1);break;// 1101 }} void cl(){ dig=1;seg=0;segment();digital(); dig=2;seg=0;segment();digital(); dig=3;seg=0;segment();digital(); dig=4;seg=0;segment();digital(); dig=5;seg=0;segment();digital(); dig=6;seg=0;segment();digital(); dig=7;seg=0;segment();digital(); dig=8;seg=0;segment();digital(); dig=9;seg=0;segment();digital(); dig=10;seg=0;segment();digital(); dig=11;seg=0;segment();digital(); dig=12;seg=0;segment();digital(); dig=13;seg=0;segment();digital(); dig=14;seg=0;segment();digital(); } void ch(int pin, int logic){digitalWrite(pin,logic);} void analyzeAudio() { while(i1 < FHT_N){i1++; do{ADCSRA |= (1 << ADSC);} while((ADCSRA & (1 << ADIF)) == 0);fht_input[i1] = (ADCL|ADCH << 8);}i1=0; fht_window(); // window the data for better frequency response fht_reorder(); // reorder the data before doing the fht fht_run(); // process the data in the fht fht_mag_log(); // take the output of the fht }
Sir
Can I limit the number of led per each band from 20 to 10? That means can I use single led scale per band. How to modify the code? Thank you