7-ми полосный анализатор спектра на светодиодной шкале SHB10R (Arduino)

Светодиодная шкала SHB10R — это, по сути, 10 независимых светодиодов в одном корпусе, выложенных в форме шкалы. У индикатора 20 ножек: анод и катод для каждого светодиода.

SHB10R.pdf

На основе 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
}

 Форум — http://forum.rcl-radio.ru/viewtopic.php?id=119

Comments

Добавить комментарий

Войти с помощью: