1

Тема: analiz_spectr_atmega8535

#define AUTO_GAIN 1       // автонастройка по громкости (экспериментальная функция)
#define VOL_THR 15        // порог тишины (ниже него отображения на матрице не будет)
#define LOW_PASS 10       // нижний порог чувствительности шумов (нет скачков при отсутствии звука)
#define DEF_GAIN 50       // максимальный порог по умолчанию (при GAIN_CONTROL игнорируется)
#define FHT_N 128         // ширина спектра х2
#define LOG_OUT 1
#define BRIG    5         // ЯРКОСТЬ ИНДИК. 1-10 1=MAX
#define STEP    2000      // ПЛАВНОСТЬ ХОДА ИНД. 1-5000

byte posOffset[12] = {2, 3, 5, 7, 10, 13, 17, 21, 25, 30, 37, 45};
//byte anod[]={16,17,18,19,20,21,22,23,31,30};
byte anod[]={30,31,23,22,21,20,19,18,17,16};
byte katod[]={15,14,13,12,11,10,9,8,7,6,5,4};
int timer_i,kt;

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

#include <FHT.h>     // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=297&download=1

byte gain = DEF_GAIN;   
unsigned long gainTimer,times;
byte maxValue, maxValue_f;
float k = 0.1;
byte ur[12],urr[12];

void setup(){
  delay(100); 
  sbi(ADCSRA, ADPS2);
  cbi(ADCSRA, ADPS1);
  sbi(ADCSRA, ADPS0);
  cli();
  TCCR2=0;
  OCR2 = 20;
  TCCR2 |= (1 << WGM21);
  TCCR2 |= (1 << CS22) | (1 << CS21)| (1 << CS20);
  TIMSK |= (1 << OCIE2);
  sei();
 for(int i=0;i<10;i++){pinMode(anod[i],OUTPUT);}
 for(int i=0;i<12;i++){pinMode(katod[i],OUTPUT);}
  analogReference(INTERNAL);
  pinMode(A0,INPUT); // INPUT AUDIO
  }

void loop(){  
   analyzeAudio(); 
 
for (int pos = 0; pos < 12; pos++) {
 int posLevel = map(fht_log_out[posOffset[pos]], LOW_PASS, gain*0.5, 0, 9);
   posLevel = constrain(posLevel, 0, 9);
     urr[pos] = posLevel;
     if(urr[pos]<ur[pos]){ur[pos]=ur[pos]-1;}
      else{ur[pos] = posLevel;}
      delayMicroseconds(STEP); 
}     
 if (AUTO_GAIN) {
    maxValue_f = maxValue * k + maxValue_f * (1 - k);
    if (millis() - gainTimer > 1500) {      // каждые 1500 мс
      // если максимальное значение больше порога, взять его как максимум для отображения
      if (maxValue_f > VOL_THR) gain = maxValue_f;
      // если нет, то взять порог побольше, чтобы шумы вообще не проходили
      else gain = 100;
      gainTimer = millis();
    }
  } 


  
  } 
ISR(TIMER2_COMP_vect){
  switch(timer_i){
    case 0: cl();kat();an();break;
    case 1: cl();kat();an();break;
    case 2: cl();kat();an();break;
    case 3: cl();kat();an();break;
    case 4: cl();kat();an();break;
    case 5: cl();kat();an();break;
    case 6: cl();kat();an();break;
    case 7: cl();kat();an();break;
    case 8: cl();kat();an();break;
    case 9: cl();kat();an();break;
    case 10: cl();kat();an();break;
    case 11: cl();kat();an();break;
    }
    timer_i++;
 
    if(timer_i>11){timer_i=0;}}  

void an(){
  switch(ur[timer_i]){
    case 0:ch(anod[0],1);ch(anod[1],0);ch(anod[2],0);ch(anod[3],0);ch(anod[4],0);ch(anod[5],0);ch(anod[6],0);ch(anod[7],0);ch(anod[8],0);ch(anod[9],0);break;
    case 1:ch(anod[0],1);ch(anod[1],1);ch(anod[2],0);ch(anod[3],0);ch(anod[4],0);ch(anod[5],0);ch(anod[6],0);ch(anod[7],0);ch(anod[8],0);ch(anod[9],0);break;
    case 2:ch(anod[0],1);ch(anod[1],1);ch(anod[2],1);ch(anod[3],0);ch(anod[4],0);ch(anod[5],0);ch(anod[6],0);ch(anod[7],0);ch(anod[8],0);ch(anod[9],0);break;
    case 3:ch(anod[0],1);ch(anod[1],1);ch(anod[2],1);ch(anod[3],1);ch(anod[4],0);ch(anod[5],0);ch(anod[6],0);ch(anod[7],0);ch(anod[8],0);ch(anod[9],0);break;
    case 4:ch(anod[0],1);ch(anod[1],1);ch(anod[2],1);ch(anod[3],1);ch(anod[4],1);ch(anod[5],0);ch(anod[6],0);ch(anod[7],0);ch(anod[8],0);ch(anod[9],0);break;
    case 5:ch(anod[0],1);ch(anod[1],1);ch(anod[2],1);ch(anod[3],1);ch(anod[4],1);ch(anod[5],1);ch(anod[6],0);ch(anod[7],0);ch(anod[8],0);ch(anod[9],0);break;
    case 6:ch(anod[0],1);ch(anod[1],1);ch(anod[2],1);ch(anod[3],1);ch(anod[4],1);ch(anod[5],1);ch(anod[6],1);ch(anod[7],0);ch(anod[8],0);ch(anod[9],0);break;
    case 7:ch(anod[0],1);ch(anod[1],1);ch(anod[2],1);ch(anod[3],1);ch(anod[4],1);ch(anod[5],1);ch(anod[6],1);ch(anod[7],1);ch(anod[8],0);ch(anod[9],0);break;
    case 8:ch(anod[0],1);ch(anod[1],1);ch(anod[2],1);ch(anod[3],1);ch(anod[4],1);ch(anod[5],1);ch(anod[6],1);ch(anod[7],1);ch(anod[8],1);ch(anod[9],0);break;
    case 9:ch(anod[0],1);ch(anod[1],1);ch(anod[2],1);ch(anod[3],1);ch(anod[4],1);ch(anod[5],1);ch(anod[6],1);ch(anod[7],1);ch(anod[8],1);ch(anod[9],1);break;
    }
  }
void kat(){
  switch(timer_i){                                                             
    case 0:ch(15,1);ch(14,0);ch(13,0);ch(12,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);break;  
    case 1:ch(15,0);ch(14,1);ch(13,0);ch(12,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);break;
    case 2:ch(15,0);ch(14,0);ch(13,1);ch(12,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);break; 
    case 3:ch(15,0);ch(14,0);ch(13,0);ch(12,1);ch(11,0);ch(10,0);ch(9,0);ch(8,0);ch(7,0);ch(6,0);ch(5,0);ch(4,0);break; 
    case 4:ch(15,0);ch(14,0);ch(13,0);ch(12,0);ch(11,1);ch(10,0);ch(9,0);ch(8,0);ch(7,0);ch(6,0);ch(5,0);ch(4,0);break;
    case 5:ch(15,0);ch(14,0);ch(13,0);ch(12,0);ch(11,0);ch(10,1);ch(9,0);ch(8,0);ch(7,0);ch(6,0);ch(5,0);ch(4,0);break;
    case 6:ch(15,0);ch(14,0);ch(13,0);ch(12,0);ch(11,0);ch(10,0);ch(9,1);ch(8,0);ch(7,0);ch(6,0);ch(5,0);ch(4,0);break;
    case 7:ch(15,0);ch(14,0);ch(13,0);ch(12,0);ch(11,0);ch(10,0);ch(9,0);ch(8,1);ch(7,0);ch(6,0);ch(5,0);ch(4,0);break;
    case 8:ch(15,0);ch(14,0);ch(13,0);ch(12,0);ch(11,0);ch(10,0);ch(9,0);ch(8,0);ch(7,1);ch(6,0);ch(5,0);ch(4,0);break;
    case 9:ch(15,0);ch(14,0);ch(13,0);ch(12,0);ch(11,0);ch(10,0);ch(9,0);ch(8,0);ch(7,0);ch(6,1);ch(5,0);ch(4,0);break;
   case 10:ch(15,0);ch(14,0);ch(13,0);ch(12,0);ch(11,0);ch(10,0);ch(9,0);ch(8,0);ch(7,0);ch(6,0);ch(5,1);ch(4,0);break;
   case 11:ch(15,0);ch(14,0);ch(13,0);ch(12,0);ch(11,0);ch(10,0);ch(9,0);ch(8,0);ch(7,0);ch(6,0);ch(5,0);ch(4,1);break;
  }}

void cl(){for(int i=0;i<10;i++){ch(anod[i],0);}for(int i=0;i<12;i++){ch(katod[i],0);}delayMicroseconds(100*BRIG);}  
void ch(int pin, int logic){digitalWrite(pin,logic);}  
void analyzeAudio() {
  for (int iu = 0 ; iu < FHT_N ; iu++) {
    int sample = analogRead(A0)*2;
    fht_input[iu] = sample; // put real data into bins
  }
  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
}