101

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

раньше я не опускал громкость ниже -45, поэтому баг не проявлялся.
сейчас постоянно,если ниже -48 и до релоуда

102 (2020-05-29 12:47:19 отредактировано roline)

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

если я подрезаю строку с индикацией,то дуня не вешается во всем диапазоне регулировки
(т.е. на экране отобрадаются волум -80дб, нижняя пустая)
возвращаю индикацию - вешается

103

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

-48дб это случайно не самое начало строки lcd? если да, причина ясна.

104 (2020-05-29 12:52:35 отредактировано roline)

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

именно самое начало
-48 норм, -49 вешалка

105

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

попробуйте этот код

обратите внимание на эту команду

vol_d=map(vol,0,80,0,32);

если строка при 0дб будет переползать за область экрана, то уменьшите число 32

#define AUTO_GAIN 1       // автонастройка по громкости
#define VOL_THR 35        // порог тишины (ниже него отображения на матрице не будет)
#define LOW_PASS 30       // нижний порог чувствительности шумов (нет скачков при отсутствии звука)
#define DEF_GAIN 80       // максимальный порог по умолчанию 
#define FHT_N 128         // ширина спектра х2
#define LOG_OUT 1
#include <FHT.h> 
#include <Wire.h> 
#include <TDA7419.h>
#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <Encoder.h>
#include <MsTimer2.h>
#include <boarddefs.h>
#include <IRremote.h>
  TDA7419 tda;
  IRrecv irrecv(12); // указываем вывод модуля IR приемника
  Encoder myEnc(8, 9);//CLK, DT
  decode_results ir;
  LiquidCrystal lcd(7, 6, 2, 3, 4, 5);// RS,E,D4,D5,D6,D7
  byte posOffset[16] = {2, 3, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; // вч выше
  boolean  w,w2,www,mute=1,gr1,gr2;
  byte z,z0,z1,gain1,gain2,gain3,gain_d,rf,lf,rt,lt,sab, in_d,lon_f,lon_d,vol_d, bass_d,treb_d,middle_d;
  int menu,vol,bass,treb,middle,in,gain0;
  int lon,out,vol_out,treb_c,mid_c,bas_c,sab_f;
  unsigned long time,oldPosition  = -999,newPosition;
  unsigned long gainTimer;
  byte maxValue, maxValue_f,spek;
  float k = 0.1;
  byte gain_sp = DEF_GAIN;  
  byte i1,yyy;
  
  
void setup(){ Serial.begin(9600);Wire.begin(); lcd.begin(16, 2);irrecv.enableIRIn(); // запускаем модуль IR
     lcd.setCursor(0,0);lcd.print("    TDA7419    ");delay(1000);// ЗАСТАВКА
     pinMode(10,INPUT);// МЕНЮ КНОПКА SW энкодера
     pinMode(11,INPUT);// ВЫБОР ВХОДА КНОПКА IN
     pinMode(13,INPUT);// КНОПКА SET
     ADMUX  = 0b01100000; ADCSRA = 0b11010100; // http://rcl-radio.ru/?p=57478
     MsTimer2::set(1, to_Timer);MsTimer2::start(); // АКТИВИРУЕМ ПРЕРЫВАНИЯ ДЛЯ ЭНКОДЕРА
  /// считываем все настройки с памяти при включении
   vol = EEPROM.read(0);treb = EEPROM.read(1)-15;middle = EEPROM.read(3)-15;bass = EEPROM.read(3)-15;
   in = EEPROM.read(4);gain1 = EEPROM.read(5);gain2 = EEPROM.read(6);gain3 = EEPROM.read(7);
   lon = EEPROM.read(8);lon_f = EEPROM.read(9);rf = EEPROM.read(10);lf = EEPROM.read(11);
   rt = EEPROM.read(12);lt = EEPROM.read(13);sab = EEPROM.read(14);treb_c = EEPROM.read(15);
   mid_c = EEPROM.read(16);bas_c = EEPROM.read(17);sab_f = EEPROM.read(18);
   switch(in){
     case 1: gain0 = gain1;break;
     case 2: gain0 = gain2;break;
     case 3: gain0 = gain3;break;
     }
   audio();
}

void loop(){
   if (newPosition != oldPosition) {if(spek==1){cl();menu=0;}}
  if(spek==0){
      byte a1[8] = {0b00000,0b10101,0b10101,0b10101,0b10101,0b10101,0b10101,0b00000};
      byte a2[8] = {0b00000,0b10100,0b10100,0b10100,0b10100,0b10100,0b10100,0b00000};
      byte a3[8] = {0b00000,0b10000,0b10000,0b10000,0b10000,0b10000,0b10000,0b00000};
      lcd.createChar(0,a1);lcd.createChar(1,a2);lcd.createChar(2,a3);
    }else{
      byte v1[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11011};
      byte v2[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11011, 0b11011};
      byte v3[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11011, 0b11011, 0b11011};
      byte v4[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b11011, 0b11011, 0b11011, 0b11011};
      byte v5[8] = {0b00000, 0b00000, 0b00000, 0b11011, 0b11011, 0b11011, 0b11011, 0b11011};
      byte v6[8] = {0b00000, 0b00000, 0b11011, 0b11011, 0b11011, 0b11011, 0b11011, 0b11011};
      byte v7[8] = {0b00000, 0b11011, 0b11011, 0b11011, 0b11011, 0b11011, 0b11011, 0b11011};
      byte v8[8] = {0b11011, 0b11011, 0b11011, 0b11011, 0b11011, 0b11011, 0b11011, 0b11011};
      lcd.createChar(0, v1);lcd.createChar(1, v2);lcd.createChar(2, v3);lcd.createChar(3, v4);lcd.createChar(4, v5);lcd.createChar(5, v6);lcd.createChar(6, v7);lcd.createChar(7, v8);
      }

  if(digitalRead(10)==LOW){menu++;cl();time=millis();w=1;w2=1;www=1;if(menu>4){menu=0;}}// меню
  if(digitalRead(11)==HIGH&&menu<5){in++;;cl();time=millis()-7000;w=1;w2=1;www=1;menu=4;if(in>3){in=1;};audio();}// КНОПКА ВЫБОРА ВХОДА IN
  if(digitalRead(13)==HIGH&&menu<5){menu=5;cl();time=millis();w=1;w2=1;}// меню 2 включение меню 2
  if(digitalRead(13)==HIGH&&menu>=5){menu++;cl();time=millis();w=1;w2=1;if(menu>10){menu=0;}}// перебор меню 2 и выход в меню громкости

   ////////////////// ИК приемник - обработка кодов кнопок ///////////////////////////////////////
  if ( irrecv.decode( &ir )) {Serial.print("0x");Serial.println( ir.value,HEX);irrecv.resume();time=millis();w=1;if(spek==1){menu=0;cl();}}// IR приемник - чтение, в мониторе порта отображаются коды кнопок

  if(ir.value==0x2FDD02F){menu++;gr1=0;gr2=0;cl();time=millis();w=1;w2=1;if(menu>4){menu=0;}}// меню кнопка вверх
  if(ir.value==0x2FD32CD){menu--;gr1=0;gr2=0;cl();time=millis();w=1;w2=1;if(menu<0){menu=4;}}// меню кнопка вниз
  if(ir.value==0x2FD708F&&menu<5){in++;cl();time=millis()-7000;w=1;w2=1;www=1;menu=4;if(in>3){in=1;};gr1=0;gr2=0;audio();}// IN
/////////////////////////////// VOLUME -80 ... 0 дБ ////////////////////////////////////////////////
 if(menu==0){
     if(ir.value==0x2FD906F){vol++;gr1=1;gr2=0;cl();w2=1;vol_func();audio();}// кнопка > 
     if(ir.value==0xFFFFFFFF and gr1==1){vol++;gr2=0;cl();w2=1;vol_func();audio();}// кнопка >>>>>>
     if(ir.value==0x2FDF20D){vol--;gr1=0;gr2=1;cl();w2=1;vol_func();audio();}// кнопка <
     if(ir.value==0xFFFFFFFF and gr2==1){vol--;gr1=0;cl();w2=1;vol_func();audio();}// кнопка <<<<<<
   
   if (newPosition != oldPosition){oldPosition = newPosition;
     vol=vol+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;vol_func();audio();} 
     lcd.setCursor(0,0);lcd.print("Volume  ");
     lcd.print(" ");lcd.print(-80+vol);lcd.print(" ");lcd.setCursor(13,0);lcd.print("dB");vol_d=map(vol,0,80,0,32);
   if(w2==1){
   for(z=0,z0=0,z1=0;z<=vol_d;z++,z1++){if(z1>2){z1=0;z0++;}
   if(z1==1){lcd.setCursor(z0,1);lcd.write((uint8_t)0);lcd.setCursor(z0+1,1);lcd.print("   ");}}
   if(z1==3){lcd.setCursor(z0,1);lcd.write((uint8_t)1);}
   if(z1==2){lcd.setCursor(z0,1);lcd.write((uint8_t)2);}w2=0;}}
 
 ///////////////////////// TREBLE +/-15 dB /////////////////////////////////////////////////////////
   if(menu==1){
     if(ir.value==0x2FD906F){treb++;gr1=1;gr2=0;cl();w2=1;treb_func();audio();}// кнопка > 
     if(ir.value==0xFFFFFFFF and gr1==1){treb++;gr2=0;cl();w2=1;treb_func();audio();}// кнопка >>>>>>
     if(ir.value==0x2FDF20D){treb--;gr1=0;gr2=1;cl();w2=1;treb_func();audio();}// кнопка < 
     if(ir.value==0xFFFFFFFF and gr2==1){treb--;gr1=0;cl();w2=1;treb_func();audio();}// кнопка <<<<<<
    
     if (newPosition != oldPosition) {
    oldPosition = newPosition;
    treb=treb+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;treb_func();audio();} 
   lcd.setCursor(0,0);lcd.print("Treble  ");
   lcd.print(" ");lcd.print(treb);lcd.print(" ");lcd.setCursor(13,0);lcd.print("dB");treb_d=treb+15;
   if(w2==1){
   for(z=0,z0=0,z1=0;z<=treb_d;z++,z1++){if(z1>2){z1=0;z0++;}
   if(z1==1){lcd.setCursor(z0+3,1);lcd.write((uint8_t)0);lcd.setCursor(z0+1+3,1);lcd.print("   ");}}
   if(z1==3){lcd.setCursor(z0+3,1);lcd.write((uint8_t)1);}
   if(z1==2){lcd.setCursor(z0+3,1);lcd.write((uint8_t)2);}w2=0;}}

/////////////////////////// MIDDLE +/-15 dB ////////////////////////////////////////////////////////
   if(menu==2){
     if(ir.value==0x2FD906F){middle++;gr1=1;gr2=0;cl();w2=1;middle_func();audio();}// кнопка > 
     if(ir.value==0xFFFFFFFF and gr1==1){middle++;gr2=0;cl();w2=1;middle_func();audio();}// кнопка >>>>>>
     if(ir.value==0x2FDF20D){middle--;gr1=0;gr2=1;cl();w2=1;middle_func();audio();}// кнопка < 
     if(ir.value==0xFFFFFFFF and gr2==1){middle--;gr1=0;cl();w2=1;middle_func();audio();}// кнопка <<<<<<
    
     if (newPosition != oldPosition) {
    oldPosition = newPosition;
    middle=middle+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;middle_func();audio();} 
   lcd.setCursor(0,0);lcd.print("Middle  ");
   lcd.print(" ");lcd.print(middle);lcd.print(" ");lcd.setCursor(13,0);lcd.print("dB");middle_d=middle+15;
   if(w2==1){
   for(z=0,z0=0,z1=0;z<=middle_d;z++,z1++){if(z1>2){z1=0;z0++;}
   if(z1==1){lcd.setCursor(z0+3,1);lcd.write((uint8_t)0);lcd.setCursor(z0+1+3,1);lcd.print("   ");}}
   if(z1==3){lcd.setCursor(z0+3,1);lcd.write((uint8_t)1);}
   if(z1==2){lcd.setCursor(z0+3,1);lcd.write((uint8_t)2);}w2=0;}}

 /////////////////////// BASS +/-15 dB ///////////////////////////////////////////////////////////
   if(menu==3){
     if(ir.value==0x2FD906F){bass++;gr1=1;gr2=0;cl();w2=1;bass_func();audio();}// кнопка > 
     if(ir.value==0xFFFFFFFF and gr1==1){bass++;gr2=0;cl();w2=1;bass_func();audio();}// кнопка >>>>>>
     if(ir.value==0x2FDF20D){bass--;gr1=0;gr2=1;cl();w2=1;bass_func();audio();}// кнопка < 
     if(ir.value==0xFFFFFFFF and gr2==1){bass--;gr1=0;cl();w2=1;bass_func();audio();}// кнопка <<<<<<  
    
    if (newPosition != oldPosition) {
    oldPosition = newPosition;
    bass=bass+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;bass_func();audio();} 
   lcd.setCursor(0,0);lcd.print("Bass    ");
   lcd.print(" ");lcd.print(bass);lcd.print(" ");lcd.setCursor(13,0);lcd.print("dB");bass_d=bass+15;
   if(w2==1){
   for(z=0,z0=0,z1=0;z<=bass_d;z++,z1++){if(z1>2){z1=0;z0++;}
   if(z1==1){lcd.setCursor(z0+3,1);lcd.write((uint8_t)0);lcd.setCursor(z0+1+3,1);lcd.print("   ");}}
   if(z1==3){lcd.setCursor(z0+3,1);lcd.write((uint8_t)1);}
   if(z1==2){lcd.setCursor(z0+3,1);lcd.write((uint8_t)2);}w2=0;}}
   
//////////////// IN + GAIN /////////////////////////////////////////////////////////////
   if(menu==4){ 
       switch(in){
     case 1: gain0 = gain1;break;
     case 2: gain0 = gain2;break;
     case 3: gain0 = gain3;break;
     }
     if(ir.value==0x2FD906F){gain0++;gr1=1;gr2=0;cl();w2=1;gain_func();audio();}// кнопка > 
     if(ir.value==0xFFFFFFFF and gr1==1){gain0++;gr2=0;cl();w2=1;gain_func();audio();}// кнопка >>>>>>
     if(ir.value==0x2FDF20D){gain0--;gr1=0;gr2=1;cl();w2=1;gain_func();audio();}// кнопка < 
     if(ir.value==0xFFFFFFFF and gr2==1){gain0--;gr1=0;cl();w2=1;gain_func();audio();}// кнопка <<<<<<

    if (newPosition != oldPosition) {
    oldPosition = newPosition;
    gain0=gain0+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;gain_func();audio();} 
   switch(in){
     case 1: gain1 = gain0;break;
     case 2: gain2 = gain0;break;
     case 3: gain3 = gain0;break;
     } 
    if(www==1){audio();www=0;}
  lcd.setCursor(0,0);lcd.print("Gain IN ");lcd.print(in);
      lcd.setCursor(10,0);lcd.print(" ");lcd.print(gain0);lcd.print(" ");lcd.setCursor(14,0);lcd.print("dB");gain_d=gain0*2;
   if(w2==1){
   for(z=0,z0=0,z1=0;z<=gain_d;z++,z1++){if(z1>2){z1=0;z0++;}
   if(z1==1){lcd.setCursor(z0+3,1);lcd.write((uint8_t)0);lcd.setCursor(z0+1+3,1);lcd.print("   ");}}
   if(z1==3){lcd.setCursor(z0+3,1);lcd.write((uint8_t)1);}
   if(z1==2){lcd.setCursor(z0+3,1);lcd.write((uint8_t)2);}}w2=0;}

////////////////////////////// loudness ////////////////////////////////////////////////////
 if(menu==5){  
    if (newPosition != oldPosition) {
    oldPosition = newPosition;
    lon_f=lon_f+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;if(lon_f>3){lon_f=0;}if(lon_f<0){lon_f=3;}audio();} 

    lcd.setCursor(0,0);lcd.print("Loudness: ");
      switch(lon_f){
         case 0: lcd.print("FLAT  ");break;
         case 1: lcd.print("400Hz ");break;
         case 2: lcd.print("800Hz ");break;
         case 3: lcd.print("2400Hz");break;}}

 //////////////////////////// loudness Att ////////////////////////////////////////////////
 if(menu==6){
      if (newPosition != oldPosition) {
      oldPosition = newPosition;
      lon=lon+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;if(lon>15){lon=15;}if(lon<0){lon=0;}audio();} 

   lcd.setCursor(0,0);lcd.print("Loud att");
   lcd.print(" ");lcd.print(-lon);lcd.print(" ");lcd.setCursor(13,0);lcd.print("dB");lon_d=lon*2;
   if(w2==1){
   for(z=0,z0=0,z1=0;z<=lon_d;z++,z1++){if(z1>2){z1=0;z0++;}
   if(z1==1){lcd.setCursor(z0+3,1);lcd.write((uint8_t)0);lcd.setCursor(z0+1+3,1);lcd.print("   ");}}
   if(z1==3){lcd.setCursor(z0+3,1);lcd.write((uint8_t)1);}
   if(z1==2){lcd.setCursor(z0+3,1);lcd.write((uint8_t)2);}w2=0;}}
 
////////////////////////////////////////// out /////////////////////////////////////////////////
 if(menu==7){  
   if(digitalRead(11)==HIGH){out++;cl();www=1;w=1;if(out>4){out=0;}audio();} // перебор выходов кнопкой IN
       switch(out){
          case 0:vol_out=rf;break;
          case 1:vol_out=lf;break;
          case 2:vol_out=rt;break;
          case 3:vol_out=lt;break;
          case 4:vol_out=sab;break;
          }
      if (newPosition != oldPosition) {
      oldPosition = newPosition;
      vol_out=vol_out+newPosition;myEnc.write(0);newPosition=0;time=millis();www=1;w=1;w2=1;if(vol_out>15){vol_out=15;}if(vol_out<0){vol_out=0;}audio();} 
      
   lcd.setCursor(0,0);lcd.print("Volume OUT");lcd.setCursor(0,1);
      switch(out){
   case 0:rf=vol_out;lcd.print("RF:  +");lcd.print(rf);break;
   case 1:lf=vol_out;lcd.print("LF:  +");lcd.print(lf);break;
   case 2:rt=vol_out;lcd.print("RT:  +");lcd.print(rt);break;
   case 3:lt=vol_out;lcd.print("LT:  +");lcd.print(lt);break;
   case 4:sab=vol_out;lcd.print("SUBW:  +");lcd.print(sab);break;
   }
    if(www==1){audio();www=0;}
  lcd.print(" dB      ");}
  
   /////////////////////////////////treble center//////////////////////////////////////////////////
 if(menu==8){ 
      if (newPosition != oldPosition) {
      oldPosition = newPosition;
      treb_c=treb_c+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;if(treb_c>3){treb_c=0;}if(treb_c<0){treb_c=3;}audio();} 
  
  lcd.setCursor(0,0);lcd.print("Treble Center ");
  lcd.setCursor(1,6);
    switch(treb_c){
      case 0: lcd.print("10.0 kHz");break;
      case 1: lcd.print("12.5 kHz");break;
      case 2: lcd.print("15.0 kHz");break;
      case 3: lcd.print("17.5 kHz");break;}}  
      
   /////////////////////////////////middle center//////////////////////////////////////////////////
 if(menu==9){ 
      if (newPosition != oldPosition) {
      oldPosition = newPosition;
      mid_c=mid_c+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;if(mid_c>3){mid_c=0;}if(mid_c<0){mid_c=3;}audio();}   
    lcd.setCursor(0,0);lcd.print("Middle Center ");
    lcd.setCursor(1,6);
      switch(mid_c){
        case 0: lcd.print("0.5 kHz");break;
        case 1: lcd.print("1.0 kHz");break;
        case 2: lcd.print("1.5 kHz");break;
        case 3: lcd.print("2.5 kHz");break;}}
        
////////////////////////////////////bass center/////////////////////////////////////////// 
 if(menu==10){ 
      if (newPosition != oldPosition) {
      oldPosition = newPosition;
      bas_c=bas_c+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;if(bas_c>3){bas_c=0;}if(bas_c<0){bas_c=3;}audio();}   
    lcd.setCursor(0,0);lcd.print("Bass Center ");
    lcd.setCursor(1,6);
      switch(bas_c){
         case 0: lcd.print("60 Hz ");break;
         case 1: lcd.print("80 Hz ");break;
         case 2: lcd.print("100 Hz");break;
         case 3: lcd.print("200 Hz");break;}}
         
//////////////////////////////////////subw//////////////////////////////////////////////// 
 if(menu==11){ 
      if (newPosition != oldPosition) {
      oldPosition = newPosition;
      sab_f=sab_f+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;if(sab_f>3){sab_f=0;}if(sab_f<0){sab_f=3;}audio();}   
    lcd.setCursor(0,0);lcd.print("Subwoofer Freq.");
    lcd.setCursor(1,6);
      switch(sab_f){
         case 0: lcd.print("FLAT  ");break;
         case 1: lcd.print("80 Hz ");break;
         case 2: lcd.print("120 Hz");break;
         case 3: lcd.print("160 Hz");break;}}
//////////////////////////////////////////////////////////////////////////////////////
 
Serial.println(time);
 
 if(millis()-time>10000 && w==1){
     EEPROM.update(0,vol);EEPROM.update(1,treb+15);EEPROM.update(2,middle+15);EEPROM.update(3,bass+15);
     EEPROM.update(4,in);EEPROM.update(5,gain1);EEPROM.update(6,gain2);EEPROM.update(7,gain3);
     EEPROM.update(8,lon);EEPROM.update(9,lon_f);
     EEPROM.update(10,rf);EEPROM.update(11,lf);EEPROM.update(12,rt);EEPROM.update(13,lt);
     EEPROM.update(14,sab);EEPROM.update(15,treb_c);EEPROM.update(16,mid_c);EEPROM.update(17,bas_c);
     EEPROM.update(18,sab_f);
     menu=100;lcd.clear();w=0;w2=1;cl();spek=1;}

 
   if(spek==1){
  analyzeAudio();   // функция FHT, забивает массив fht_log_out[] величинами по спектру

  for (int pos = 0; pos < 16; pos++) {   // для окошек дисплея с 0 по 15
    // найти максимум из пачки тонов
    if (fht_log_out[posOffset[pos]] > maxValue) maxValue = fht_log_out[posOffset[pos]];

    lcd.setCursor(pos, 0);

    // преобразовать значение величины спектра в диапазон 0..15 с учётом настроек
    int posLevel = map(fht_log_out[posOffset[pos]], LOW_PASS, gain_sp, 0, 15);
    posLevel = constrain(posLevel, 0, 15);
  while(yyy<2){yyy++;
    if (posLevel > 7) {               // если значение больше 7 (значит нижний квадратик будет полный)
      lcd.write((uint8_t)posLevel - 8);    // верхний квадратик залить тем что осталось
      lcd.setCursor(pos, 1);          // перейти на нижний квадратик
      lcd.write((uint8_t)7);        // залить его полностью
  } 
    else {                          // если значение меньше 8
      lcd.print(" ");                 // верхний квадратик пустой
      lcd.setCursor(pos, 1);          // нижний квадратик
      lcd.write((uint8_t)posLevel);        // залить полосками
    }} yyy=0;
  }  

  if (AUTO_GAIN) {
    maxValue_f = maxValue * k + maxValue_f * (1 - k);
    if (millis() - gainTimer > 1500) {      // каждые 1500 мс
      // если максимальное значение больше порога, взять его как максимум для отображения
      if (maxValue_f > VOL_THR) gain_sp = maxValue_f;

      // если нет, то взять порог побольше, чтобы шумы вообще не проходили
      else gain_sp = 100;
      gainTimer = millis();
    }
  }else{gain_sp = DEF_GAIN;}
  }
     
}//loop

 void gain_func(){if(gain0<0){gain0=0;}if(gain0>15){gain0=15;}}
 void bass_func(){if(bass>15){bass=15;}if(bass<-15){bass=-15;}} 
 void middle_func(){if(middle>15){middle=15;}if(middle<-15){middle=-15;}}
 void treb_func(){if(treb>15){treb=15;}if(treb<-15){treb=-15;}}
 void vol_func(){if(vol<0){vol=0;}if(vol>80){vol=80;}}
 
 void cl(){ir.value=0;delay(300);spek=0;lcd.clear();}
 
 void to_Timer(){newPosition = myEnc.read()/4;}
 
 void audio(){
tda.setInput(in,gain0,0);    //вх1=1, вх2=2, вх3=3
tda.setInput2(0,0,0);   // не используется
tda.setAtt_loudness(lon,lon_f,0,0);
tda.setSoft(mute,0,0,0,0);//mute off (не менять)
tda.setVolume(vol-79,0);   // общая громкость от 0 до 79 макс
tda.setAtt_LF(64+lf,0);   // гром. лк фронт
tda.setAtt_RF(64+rf,0);   // гром. пк фронт
tda.setAtt_LT(64+lt,0);   // гром. лк тыл
tda.setAtt_RT(64+rt,0);   // гром. пк тыл
tda.setAtt_SUB(64+sab,0);  // гром. савбуфер
tda.setAtt_Mix(79,0);   // не использует
tda.setFilter_Treble(treb,treb_c,0); 
tda.setFilter_Middle(middle,0,0);
tda.setFilter_Bass(bass,0,0);
tda.setSub_M_B(sab_f,mid_c,bas_c,0,0);
tda.setMix_Gain_Eff(1,0,0,0,0); // не используется
tda.setSpektor(0,0,1,0,1,0,0);
}

void analyzeAudio() {  
  //cli(); 
 while( i1 < FHT_N ) {  i1++; 
    do{ADCSRA |= (1 << ADSC);} 
    while((ADCSRA & (1 << ADIF)) == 0);
    fht_input[i1] = (ADCL|ADCH << 8); 
    //fht_input[i1] = ADCH; 
    }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
 // sei();
}

106 (2020-05-29 13:06:13 отредактировано roline)

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

тэкс , при 32 индикация не доходила до правого края экрана
изменил на 48 - теперь :
-80дб -  одна полоска слева
0дб - строка полностью заполнена
дуня не вешается, все норм.
гоняю дальше ...
спасибо!

107

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

ну да 16*3=48, а не 32

108

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

а есть ли возможность отрихтовать анализатор спектра в плане более достоверного отображения частот?. Ибо подаю синус с генератора частот от 0 до 20к  - анализатор выдает интересные вещи... скажем про 5,5кгц вторая строка экрана заполнена полностью, первая на 2/3.

109

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

вот бы каждый столбец привязать к частоте,... вот бы лялька получилась))

110

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

немного измените параметры

#define VOL_THR 35        // порог тишины (ниже него отображения на матрице не будет)
#define LOW_PASS 30       // нижний порог чувствительности шумов (нет скачков при отсутствии звука)
#define DEF_GAIN 80       // максимальный порог по умолчанию

например

#define VOL_THR 45        // порог тишины (ниже него отображения на матрице не будет)
#define LOW_PASS 40       // нижний порог чувствительности шумов (нет скачков при отсутствии звука)
#define DEF_GAIN 110       // максимальный порог по умолчанию

111 (2020-05-29 14:25:37 отредактировано roline)

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

http://forum.rcl-radio.ru/uploads/images/2020/05/e86070b4006a0b20a7d6f84ac02dc282.jpg http://forum.rcl-radio.ru/uploads/images/2020/05/434037406c136d80d38b18f8a19abdbe.jpg
поигрался с параметрами
1 скрин - 350гц
2скрин - 13700гц
((

112

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

выше 2500гц беда практически на любых настройках

113

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

Ни чего не получится, мощности ардуино не хватит обрабатывать сигнал правильно, да и библиотека очень упрощенная, так же спектр обрезан примерно до 8 кГц (памяти в ардуино мало).
Это просто заставка примерно анализирующая спектр, так скажем для красоты.

По второму скрину, все просто, частота ушла за пределы чуствительности анализатора, автоусиление подняло сигнал на максимум, Вы видите шум.

114

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

liman324 пишет:

По второму скрину, все просто, частота ушла за пределы чуствительности анализатора, автоусиление подняло сигнал на максимум, Вы видите шум.

дык беда то от 2.5кгц...
ну да ладно...
пущяй как заставка скачет)))

115

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

По идее, плавно меняя частоту от 0 до 10 К Вы должны наблюдать горбик спектра, он должен при повышении частоты перемещаться в право, как только горбик спектра дошел до края экрана, это и есть конец частотного диапазона.

есть параметры которые можно менять чтобы улучшить спектр

byte posOffset[16] = {2, 3, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};

эта строка содержит 16 переменных для каждого столба индикатора, эти переменные обозначают ширину выборки из массива спектра.

далее

#define VOL_THR 35        // порог тишины (ниже него отображения на матрице не будет)
#define LOW_PASS 30       // нижний порог чувствительности шумов (нет скачков при отсутствии звука)
#define DEF_GAIN 80       // максимальный порог по умолчанию
#define FHT_N 128         // ширина спектра х2

основные настроки

FHT_N 128  должен быть 256, но памяти на 256 не хватит. Спектр примерно 16кГц, для 128 снижается до 8 кГц, на ВЧ появляется много шума, шириной выборки можно немного уменьшить шум.

116

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

как вам такое?

// ---------------- НАСТРОЙКИ ----------------
#define DRIVER_VERSION 0   // 0 - маркировка драйвера кончается на 4АТ, 1 - на 4Т
#define GAIN_CONTROL 0     // ручная настройка потенциометром на громкость (1 - вкл, 0 - выкл)

#define AUTO_GAIN 0       // автонастройка по громкости (экспериментальная функция)
#define VOL_THR 35        // порог тишины (ниже него отображения на матрице не будет)

#define LOW_PASS 30        // нижний порог чувствительности шумов (нет скачков при отсутствии звука)
#define DEF_GAIN 80       // максимальный порог по умолчанию (при GAIN_CONTROL игнорируется)

#define FHT_N 256          // ширина спектра х2
// вручную забитый массив тонов, сначала плавно, потом круче
byte posOffset[16] = {2, 3, 4, 6, 8, 10, 12, 14, 16, 20, 25, 30, 35, 60, 80, 100};
// ---------------- НАСТРОЙКИ ----------------

// ---------------------- ПИНЫ ----------------------
#define AUDIO_IN 0          // пин, куда подключен звук
#define POT_PIN 7          // пин потенциометра настройки
// ---------------------- ПИНЫ ----------------------

// --------------- БИБЛИОТЕКИ ---------------
#define LOG_OUT 1
#include <FHT.h>          // преобразование Хартли
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define printByte(args) write(args);
double prevVolts = 100.0;
// --------------- БИБЛИОТЕКИ ---------------
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

// --------- АВТОВЫБОР ОПРЕДЕЛЕНИЯ ДИСПЛЕЯ -------------
// Если кончается на 4Т - это 0х27. Если на 4АТ - 0х3f
#if (DRIVER_VERSION)
LiquidCrystal_I2C lcd(0x27, 16, 2);
#else
LiquidCrystal_I2C lcd(0x3f, 16, 2);
#endif
// --------- АВТОВЫБОР ОПРЕДЕЛЕНИЯ ДИСПЛЕЯ -------------

// ------------------------------------- ПОЛОСОЧКИ -------------------------------------
byte v1[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111};
byte v2[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111};
byte v3[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111};
byte v4[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111};
byte v5[8] = {0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte v6[8] = {0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte v7[8] = {0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte v8[8] = {0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
// ------------------------------------- ПОЛОСОЧКИ -------------------------------------
byte gain = DEF_GAIN;   // усиление по умолчанию
unsigned long gainTimer;
byte maxValue, maxValue_f;
float k = 0.1;

void setup() {
  // поднимаем частоту опроса аналогового порта до 38.4 кГц, по теореме
  // Котельникова (Найквиста) частота дискретизации будет 19 кГц
  // http://yaab-arduino.blogspot.ru/2015/02/fast-sampling-from-analog-input.html
  sbi(ADCSRA, ADPS2);
  cbi(ADCSRA, ADPS1);
  sbi(ADCSRA, ADPS0);

  // для увеличения точности уменьшаем опорное напряжение,
  // выставив EXTERNAL и подключив Aref к выходу 3.3V на плате через делитель
  // GND ---[2х10 кОм] --- REF --- [10 кОм] --- 3V3
  analogReference(EXTERNAL);

  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("AlexGyver");
  lcd.setCursor(0, 1);
  lcd.print("SpektrumAnalyzer");
  lcdChars();   // подхватить коды полосочек
  delay(2000);
}

void loop() {
  // если разрешена ручная настройка уровня громкости
  if (GAIN_CONTROL) gain = map(analogRead(POT_PIN), 0, 1023, 0, 150);

  analyzeAudio();   // функция FHT, забивает массив fht_log_out[] величинами по спектру

  for (int pos = 0; pos < 16; pos++) {   // для окошек дисплея с 0 по 15
    // найти максимум из пачки тонов
    if (fht_log_out[posOffset[pos]] > maxValue) maxValue = fht_log_out[posOffset[pos]];

    lcd.setCursor(pos, 0);

    // преобразовать значение величины спектра в диапазон 0..15 с учётом настроек
    int posLevel = map(fht_log_out[posOffset[pos]], LOW_PASS, gain, 0, 15);
    posLevel = constrain(posLevel, 0, 15);

    if (posLevel > 7) {               // если значение больше 7 (значит нижний квадратик будет полный)
      lcd.printByte(posLevel - 8);    // верхний квадратик залить тем что осталось
      lcd.setCursor(pos, 1);          // перейти на нижний квадратик
      lcd.printByte(7);               // залить его полностью
    } else {                          // если значение меньше 8
      lcd.print(" ");                 // верхний квадратик пустой
      lcd.setCursor(pos, 1);          // нижний квадратик
      lcd.printByte(posLevel);        // залить полосками
    }
  }

  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();
    }
  }
}

void lcdChars() {
  lcd.createChar(0, v1);
  lcd.createChar(1, v2);
  lcd.createChar(2, v3);
  lcd.createChar(3, v4);
  lcd.createChar(4, v5);
  lcd.createChar(5, v6);
  lcd.createChar(6, v7);
  lcd.createChar(7, v8);
}
void analyzeAudio() {
  for (int i = 0 ; i < FHT_N ; i++) {
    int sample = analogRead(AUDIO_IN);
    fht_input[i] = 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
}

скетч

Скетч использует 7110 байт (23%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 1177 байт (57%) динамической памяти, оставляя 871 байт для локальных переменных. Максимум: 2048 байт.

http://forum.rcl-radio.ru/uploads/images/2020/05/528601ffa32aaf9471a785a583039ef0.jpg

117

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

если срезать скажем весь функционал ик... залезет?

118

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

по материалам https://alexgyver.ru/fhtspectrumanalyzer/

119

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

Я использовал этот материал.
Запустите этот скетч, посмотрите, в чем разница.

120 (2020-06-01 04:45:30 отредактировано roline)

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

в коде первого поста в строке

if(digitalRead(13)==HIGH&&menu>=5){menu++;cl();time=millis();w=1;w2=1;if(menu>10){menu=0;}}// перебор меню 2 и выход в меню громкости

menu>10 нужно заменить на menu>11, а то менюха с Subwoofer Freq. не вываливалась

а я репу чешу чегоита у меня из канала саба полный спектр наваливает)))))

121

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

Исправил.

122

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

liman324 пишет:

Я использовал этот материал.
Запустите этот скетч, посмотрите, в чем разница.

значится так...
поигрался с материалами Саши. и заметил,что даже при ширине128  некоторый горбик прослеживается на 14 с лишним кГц.
перекидал некоторые параметры в тутошний скетч и ... не знаю правильно ли это с точки зрения кода, но анализатор (субьективно) стал более правдоподобным(горбик на средневысоких-высоких ...по генератору в районе 14-15кГц).
гляньте,что скажите? или плацебо?

#define AUTO_GAIN 1       // автонастройка по громкости
#define VOL_THR 5        // порог тишины (ниже него отображения на матрице не будет)
#define LOW_PASS 65      // нижний порог чувствительности шумов (нет скачков при отсутствии звука)
#define DEF_GAIN 120       // максимальный порог по умолчанию 
#define FHT_N 128         // ширина спектра х2
#define LOG_OUT 1
#include <FHT.h> 
#include <Wire.h> 
#include <TDA7419.h>
#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <Encoder.h>
#include <MsTimer2.h>
#include <boarddefs.h>
#include <IRremote.h>
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#define printByte(args) write(args);
double prevVolts = 100.0;
  TDA7419 tda;
  IRrecv irrecv(12); // указываем вывод модуля IR приемника
  Encoder myEnc(8, 9);//CLK, DT
  decode_results ir;
  LiquidCrystal lcd(7, 6, 2, 3, 4, 5);// RS,E,D4,D5,D6,D7
  byte posOffset[16] = {2, 3, 4, 6, 8, 10, 12, 14, 16, 20, 25, 28, 32, 40, 45, 50};
  boolean  w,w2,www,mute=1,gr1,gr2;
  byte z,z0,z1,gain1,gain2,gain3,gain_d,rf,lf,rt,lt,sab, in_d,lon_f,lon_d,vol_d, bass_d,treb_d,middle_d;
  int menu,vol,bass,treb,middle,in,gain0;
  int lon,out,vol_out,treb_c,mid_c,bas_c,sab_f;
  unsigned long time,oldPosition  = -999,newPosition;
  unsigned long gainTimer;
  byte maxValue, maxValue_f,spek;
  float k = 0.1;
  byte gain_sp = DEF_GAIN;  
  byte i1,yyy;
  
  
void setup(){
  sbi(ADCSRA, ADPS2);
  cbi(ADCSRA, ADPS1);
  sbi(ADCSRA, ADPS0);
  analogReference(EXTERNAL);
  Serial.begin(9600);
     Wire.begin();
     lcd.begin(16, 2);
     irrecv.enableIRIn();// запускаем модуль IR
     lcd.setCursor(0,0);lcd.print("    TDA7419    ");delay(1000);// ЗАСТАВКА
     pinMode(10,INPUT);// МЕНЮ КНОПКА SW энкодера
     pinMode(11,INPUT);// ВЫБОР ВХОДА КНОПКА IN
     pinMode(13,INPUT);// КНОПКА SET
     ADMUX  = 0b01100000; ADCSRA = 0b11010100; // http://rcl-radio.ru/?p=57478
     MsTimer2::set(1, to_Timer);MsTimer2::start(); // АКТИВИРУЕМ ПРЕРЫВАНИЯ ДЛЯ ЭНКОДЕРА
  /// считываем все настройки с памяти при включении
   vol = EEPROM.read(0);treb = EEPROM.read(1)-15;middle = EEPROM.read(3)-15;bass = EEPROM.read(3)-15;
   in = EEPROM.read(4);gain1 = EEPROM.read(5);gain2 = EEPROM.read(6);gain3 = EEPROM.read(7);
   lon = EEPROM.read(8);lon_f = EEPROM.read(9);rf = EEPROM.read(10);lf = EEPROM.read(11);
   rt = EEPROM.read(12);lt = EEPROM.read(13);sab = EEPROM.read(14);treb_c = EEPROM.read(15);
   mid_c = EEPROM.read(16);bas_c = EEPROM.read(17);sab_f = EEPROM.read(18);
   switch(in){
     case 1: gain0 = gain1;break;
     case 2: gain0 = gain2;break;
     case 3: gain0 = gain3;break;
     }
   audio();
}

void loop(){
   if (newPosition != oldPosition) {if(spek==1){cl();menu=0;}}
  if(spek==0){
      byte a1[8] = {0b00000,0b10101,0b10101,0b10101,0b10101,0b10101,0b10101,0b00000};
      byte a2[8] = {0b00000,0b10100,0b10100,0b10100,0b10100,0b10100,0b10100,0b00000};
      byte a3[8] = {0b00000,0b10000,0b10000,0b10000,0b10000,0b10000,0b10000,0b00000};
      lcd.createChar(0,a1);lcd.createChar(1,a2);lcd.createChar(2,a3);
    }else{
     byte v1[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111};
     byte v2[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111};
     byte v3[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111};
     byte v4[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111};
     byte v5[8] = {0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
     byte v6[8] = {0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
     byte v7[8] = {0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
     byte v8[8] = {0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
      lcd.createChar(0, v1);lcd.createChar(1, v2);lcd.createChar(2, v3);lcd.createChar(3, v4);lcd.createChar(4, v5);lcd.createChar(5, v6);lcd.createChar(6, v7);lcd.createChar(7, v8);
      }

  if(digitalRead(10)==LOW){menu++;cl();time=millis();w=1;w2=1;www=1;if(menu>4){menu=0;}}// меню
  if(digitalRead(11)==HIGH&&menu<5){in++;;cl();time=millis()-7000;w=1;w2=1;www=1;menu=4;if(in>3){in=1;};audio();}// КНОПКА ВЫБОРА ВХОДА IN
  if(digitalRead(13)==HIGH&&menu<5){menu=5;cl();time=millis();w=1;w2=1;}// меню 2 включение меню 2
  if(digitalRead(13)==HIGH&&menu>=5){menu++;cl();time=millis();w=1;w2=1;if(menu>11){menu=0;}}// перебор меню 2 и выход в меню громкости

   ////////////////// ИК приемник - обработка кодов кнопок ///////////////////////////////////////
  if ( irrecv.decode( &ir )) {Serial.print("0x");Serial.println( ir.value,HEX);irrecv.resume();time=millis();w=1;if(spek==1){menu=0;cl();}}// IR приемник - чтение, в мониторе порта отображаются коды кнопок

  if(ir.value==0x2FDD02F){menu++;gr1=0;gr2=0;cl();time=millis();w=1;w2=1;if(menu>4){menu=0;}}// меню кнопка вверх
  if(ir.value==0x2FD32CD){menu--;gr1=0;gr2=0;cl();time=millis();w=1;w2=1;if(menu<0){menu=4;}}// меню кнопка вниз
  if(ir.value==0x2FD708F&&menu<5){in++;cl();time=millis()-7000;w=1;w2=1;www=1;menu=4;if(in>3){in=1;};gr1=0;gr2=0;audio();}// IN
/////////////////////////////// VOLUME -80 ... 0 дБ ////////////////////////////////////////////////
 if(menu==0){
     if(ir.value==0x2FD906F){vol++;gr1=1;gr2=0;cl();w2=1;vol_func();audio();}// кнопка > 
     if(ir.value==0xFFFFFFFF and gr1==1){vol++;gr2=0;cl();w2=1;vol_func();audio();}// кнопка >>>>>>
     if(ir.value==0x2FDF20D){vol--;gr1=0;gr2=1;cl();w2=1;vol_func();audio();}// кнопка <
     if(ir.value==0xFFFFFFFF and gr2==1){vol--;gr1=0;cl();w2=1;vol_func();audio();}// кнопка <<<<<<
   
   if (newPosition != oldPosition){oldPosition = newPosition;
     vol=vol+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;vol_func();audio();} 
     lcd.setCursor(0,0);lcd.print("Volume  ");
     lcd.print(" ");lcd.print(-80+vol);lcd.print(" ");lcd.setCursor(13,0);lcd.print("dB");vol_d=map(vol,0,80,0,48);
   if(w2==1){
   for(z=0,z0=0,z1=0;z<=vol_d;z++,z1++){if(z1>2){z1=0;z0++;}
   if(z1==1){lcd.setCursor(z0,1);lcd.write((uint8_t)0);lcd.setCursor(z0+1,1);lcd.print("   ");}}
   if(z1==3){lcd.setCursor(z0,1);lcd.write((uint8_t)1);}
   if(z1==2){lcd.setCursor(z0,1);lcd.write((uint8_t)2);}w2=0;}}
 
 ///////////////////////// TREBLE +/-15 dB /////////////////////////////////////////////////////////
   if(menu==1){
     if(ir.value==0x2FD906F){treb++;gr1=1;gr2=0;cl();w2=1;treb_func();audio();}// кнопка > 
     if(ir.value==0xFFFFFFFF and gr1==1){treb++;gr2=0;cl();w2=1;treb_func();audio();}// кнопка >>>>>>
     if(ir.value==0x2FDF20D){treb--;gr1=0;gr2=1;cl();w2=1;treb_func();audio();}// кнопка < 
     if(ir.value==0xFFFFFFFF and gr2==1){treb--;gr1=0;cl();w2=1;treb_func();audio();}// кнопка <<<<<<
    
     if (newPosition != oldPosition) {
    oldPosition = newPosition;
    treb=treb+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;treb_func();audio();} 
   lcd.setCursor(0,0);lcd.print("Treble  ");
   lcd.print(" ");lcd.print(treb);lcd.print(" ");lcd.setCursor(13,0);lcd.print("dB");treb_d=treb+15;
   if(w2==1){
   for(z=0,z0=0,z1=0;z<=treb_d;z++,z1++){if(z1>2){z1=0;z0++;}
   if(z1==1){lcd.setCursor(z0+3,1);lcd.write((uint8_t)0);lcd.setCursor(z0+1+3,1);lcd.print("   ");}}
   if(z1==3){lcd.setCursor(z0+3,1);lcd.write((uint8_t)1);}
   if(z1==2){lcd.setCursor(z0+3,1);lcd.write((uint8_t)2);}w2=0;}}

/////////////////////////// MIDDLE +/-15 dB ////////////////////////////////////////////////////////
   if(menu==2){
     if(ir.value==0x2FD906F){middle++;gr1=1;gr2=0;cl();w2=1;middle_func();audio();}// кнопка > 
     if(ir.value==0xFFFFFFFF and gr1==1){middle++;gr2=0;cl();w2=1;middle_func();audio();}// кнопка >>>>>>
     if(ir.value==0x2FDF20D){middle--;gr1=0;gr2=1;cl();w2=1;middle_func();audio();}// кнопка < 
     if(ir.value==0xFFFFFFFF and gr2==1){middle--;gr1=0;cl();w2=1;middle_func();audio();}// кнопка <<<<<<
    
     if (newPosition != oldPosition) {
    oldPosition = newPosition;
    middle=middle+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;middle_func();audio();} 
   lcd.setCursor(0,0);lcd.print("Middle  ");
   lcd.print(" ");lcd.print(middle);lcd.print(" ");lcd.setCursor(13,0);lcd.print("dB");middle_d=middle+15;
   if(w2==1){
   for(z=0,z0=0,z1=0;z<=middle_d;z++,z1++){if(z1>2){z1=0;z0++;}
   if(z1==1){lcd.setCursor(z0+3,1);lcd.write((uint8_t)0);lcd.setCursor(z0+1+3,1);lcd.print("   ");}}
   if(z1==3){lcd.setCursor(z0+3,1);lcd.write((uint8_t)1);}
   if(z1==2){lcd.setCursor(z0+3,1);lcd.write((uint8_t)2);}w2=0;}}

 /////////////////////// BASS +/-15 dB ///////////////////////////////////////////////////////////
   if(menu==3){
     if(ir.value==0x2FD906F){bass++;gr1=1;gr2=0;cl();w2=1;bass_func();audio();}// кнопка > 
     if(ir.value==0xFFFFFFFF and gr1==1){bass++;gr2=0;cl();w2=1;bass_func();audio();}// кнопка >>>>>>
     if(ir.value==0x2FDF20D){bass--;gr1=0;gr2=1;cl();w2=1;bass_func();audio();}// кнопка < 
     if(ir.value==0xFFFFFFFF and gr2==1){bass--;gr1=0;cl();w2=1;bass_func();audio();}// кнопка <<<<<<  
    
    if (newPosition != oldPosition) {
    oldPosition = newPosition;
    bass=bass+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;bass_func();audio();} 
   lcd.setCursor(0,0);lcd.print("Bass    ");
   lcd.print(" ");lcd.print(bass);lcd.print(" ");lcd.setCursor(13,0);lcd.print("dB");bass_d=bass+15;
   if(w2==1){
   for(z=0,z0=0,z1=0;z<=bass_d;z++,z1++){if(z1>2){z1=0;z0++;}
   if(z1==1){lcd.setCursor(z0+3,1);lcd.write((uint8_t)0);lcd.setCursor(z0+1+3,1);lcd.print("   ");}}
   if(z1==3){lcd.setCursor(z0+3,1);lcd.write((uint8_t)1);}
   if(z1==2){lcd.setCursor(z0+3,1);lcd.write((uint8_t)2);}w2=0;}}
   
//////////////// IN + GAIN /////////////////////////////////////////////////////////////
   if(menu==4){ 
       switch(in){
     case 1: gain0 = gain1;break;
     case 2: gain0 = gain2;break;
     case 3: gain0 = gain3;break;
     }
     if(ir.value==0x2FD906F){gain0++;gr1=1;gr2=0;cl();w2=1;gain_func();audio();}// кнопка > 
     if(ir.value==0xFFFFFFFF and gr1==1){gain0++;gr2=0;cl();w2=1;gain_func();audio();}// кнопка >>>>>>
     if(ir.value==0x2FDF20D){gain0--;gr1=0;gr2=1;cl();w2=1;gain_func();audio();}// кнопка < 
     if(ir.value==0xFFFFFFFF and gr2==1){gain0--;gr1=0;cl();w2=1;gain_func();audio();}// кнопка <<<<<<

    if (newPosition != oldPosition) {
    oldPosition = newPosition;
    gain0=gain0+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;gain_func();audio();} 
   switch(in){
     case 1: gain1 = gain0;break;
     case 2: gain2 = gain0;break;
     case 3: gain3 = gain0;break;
     } 
    if(www==1){audio();www=0;}
  lcd.setCursor(0,0);lcd.print("Gain IN ");lcd.print(in);
      lcd.setCursor(10,0);lcd.print(" ");lcd.print(gain0);lcd.print(" ");lcd.setCursor(14,0);lcd.print("dB");gain_d=gain0*2;
   if(w2==1){
   for(z=0,z0=0,z1=0;z<=gain_d;z++,z1++){if(z1>2){z1=0;z0++;}
   if(z1==1){lcd.setCursor(z0+3,1);lcd.write((uint8_t)0);lcd.setCursor(z0+1+3,1);lcd.print("   ");}}
   if(z1==3){lcd.setCursor(z0+3,1);lcd.write((uint8_t)1);}
   if(z1==2){lcd.setCursor(z0+3,1);lcd.write((uint8_t)2);}}w2=0;}

////////////////////////////// loudness ////////////////////////////////////////////////////
 if(menu==5){  
    if (newPosition != oldPosition) {
    oldPosition = newPosition;
    lon_f=lon_f+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;if(lon_f>3){lon_f=0;}if(lon_f<0){lon_f=3;}audio();} 

    lcd.setCursor(0,0);lcd.print("Loudness: ");
      switch(lon_f){
         case 0: lcd.print("FLAT  ");break;
         case 1: lcd.print("400Hz ");break;
         case 2: lcd.print("800Hz ");break;
         case 3: lcd.print("2400Hz");break;}}

 //////////////////////////// loudness Att ////////////////////////////////////////////////
 if(menu==6){
      if (newPosition != oldPosition) {
      oldPosition = newPosition;
      lon=lon+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;if(lon>15){lon=15;}if(lon<0){lon=0;}audio();} 

   lcd.setCursor(0,0);lcd.print("Loud att");
   lcd.print(" ");lcd.print(-lon);lcd.print(" ");lcd.setCursor(13,0);lcd.print("dB");lon_d=lon*2;
   if(w2==1){
   for(z=0,z0=0,z1=0;z<=lon_d;z++,z1++){if(z1>2){z1=0;z0++;}
   if(z1==1){lcd.setCursor(z0+3,1);lcd.write((uint8_t)0);lcd.setCursor(z0+1+3,1);lcd.print("   ");}}
   if(z1==3){lcd.setCursor(z0+3,1);lcd.write((uint8_t)1);}
   if(z1==2){lcd.setCursor(z0+3,1);lcd.write((uint8_t)2);}w2=0;}}
 
////////////////////////////////////////// out /////////////////////////////////////////////////
 if(menu==7){  
   if(digitalRead(11)==HIGH){out++;cl();www=1;w=1;if(out>4){out=0;}audio();} // перебор выходов кнопкой IN
       switch(out){
          case 0:vol_out=rf;break;
          case 1:vol_out=lf;break;
          case 2:vol_out=rt;break;
          case 3:vol_out=lt;break;
          case 4:vol_out=sab;break;
          }
      if (newPosition != oldPosition) {
      oldPosition = newPosition;
      vol_out=vol_out+newPosition;myEnc.write(0);newPosition=0;time=millis();www=1;w=1;w2=1;if(vol_out>15){vol_out=15;}if(vol_out<0){vol_out=0;}audio();} 
      
   lcd.setCursor(0,0);lcd.print("Volume OUT");lcd.setCursor(0,1);
      switch(out){
   case 0:rf=vol_out;lcd.print("RF:  +");lcd.print(rf);break;
   case 1:lf=vol_out;lcd.print("LF:  +");lcd.print(lf);break;
   case 2:rt=vol_out;lcd.print("RT:  +");lcd.print(rt);break;
   case 3:lt=vol_out;lcd.print("LT:  +");lcd.print(lt);break;
   case 4:sab=vol_out;lcd.print("SUBW:  +");lcd.print(sab);break;
   }
    if(www==1){audio();www=0;}
  lcd.print(" dB      ");}
  
   /////////////////////////////////treble center//////////////////////////////////////////////////
 if(menu==8){ 
      if (newPosition != oldPosition) {
      oldPosition = newPosition;
      treb_c=treb_c+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;if(treb_c>3){treb_c=0;}if(treb_c<0){treb_c=3;}audio();} 
  
  lcd.setCursor(0,0);lcd.print("Treble Center ");
  lcd.setCursor(1,6);
    switch(treb_c){
      case 0: lcd.print("10.0 kHz");break;
      case 1: lcd.print("12.5 kHz");break;
      case 2: lcd.print("15.0 kHz");break;
      case 3: lcd.print("17.5 kHz");break;}}  
      
   /////////////////////////////////middle center//////////////////////////////////////////////////
 if(menu==9){ 
      if (newPosition != oldPosition) {
      oldPosition = newPosition;
      mid_c=mid_c+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;if(mid_c>3){mid_c=0;}if(mid_c<0){mid_c=3;}audio();}   
    lcd.setCursor(0,0);lcd.print("Middle Center ");
    lcd.setCursor(1,6);
      switch(mid_c){
        case 0: lcd.print("0.5 kHz");break;
        case 1: lcd.print("1.0 kHz");break;
        case 2: lcd.print("1.5 kHz");break;
        case 3: lcd.print("2.5 kHz");break;}}
        
////////////////////////////////////bass center/////////////////////////////////////////// 
 if(menu==10){ 
      if (newPosition != oldPosition) {
      oldPosition = newPosition;
      bas_c=bas_c+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;if(bas_c>3){bas_c=0;}if(bas_c<0){bas_c=3;}audio();}   
    lcd.setCursor(0,0);lcd.print("Bass Center ");
    lcd.setCursor(1,6);
      switch(bas_c){
         case 0: lcd.print("60 Hz ");break;
         case 1: lcd.print("80 Hz ");break;
         case 2: lcd.print("100 Hz");break;
         case 3: lcd.print("200 Hz");break;}}
         
//////////////////////////////////////subw//////////////////////////////////////////////// 
 if(menu==11){ 
      if (newPosition != oldPosition) {
      oldPosition = newPosition;
      sab_f=sab_f+newPosition;myEnc.write(0);newPosition=0;time=millis();w=1;w2=1;if(sab_f>3){sab_f=0;}if(sab_f<0){sab_f=3;}audio();}   
    lcd.setCursor(0,0);lcd.print("Subwoofer Freq.");
    lcd.setCursor(1,6);
      switch(sab_f){
         case 0: lcd.print("FLAT  ");break;
         case 1: lcd.print("80 Hz ");break;
         case 2: lcd.print("120 Hz");break;
         case 3: lcd.print("160 Hz");break;}}
//////////////////////////////////////////////////////////////////////////////////////
 
Serial.println(time);
 
 if(millis()-time>10000 && w==1){
     EEPROM.update(0,vol);EEPROM.update(1,treb+15);EEPROM.update(2,middle+15);EEPROM.update(3,bass+15);
     EEPROM.update(4,in);EEPROM.update(5,gain1);EEPROM.update(6,gain2);EEPROM.update(7,gain3);
     EEPROM.update(8,lon);EEPROM.update(9,lon_f);
     EEPROM.update(10,rf);EEPROM.update(11,lf);EEPROM.update(12,rt);EEPROM.update(13,lt);
     EEPROM.update(14,sab);EEPROM.update(15,treb_c);EEPROM.update(16,mid_c);EEPROM.update(17,bas_c);
     EEPROM.update(18,sab_f);
     menu=100;lcd.clear();w=0;w2=1;cl();spek=1;}

 
   if(spek==1){
  analyzeAudio();   // функция FHT, забивает массив fht_log_out[] величинами по спектру

  for (int pos = 0; pos < 16; pos++) {   // для окошек дисплея с 0 по 15
    // найти максимум из пачки тонов
    if (fht_log_out[posOffset[pos]] > maxValue) maxValue = fht_log_out[posOffset[pos]];

    lcd.setCursor(pos, 0);

    // преобразовать значение величины спектра в диапазон 0..15 с учётом настроек
    int posLevel = map(fht_log_out[posOffset[pos]], LOW_PASS, gain_sp, 0, 15);
    posLevel = constrain(posLevel, 0, 15);
  while(yyy<2){yyy++;
    if (posLevel > 7) {               // если значение больше 7 (значит нижний квадратик будет полный)
      lcd.write((uint8_t)posLevel - 8);    // верхний квадратик залить тем что осталось
      lcd.setCursor(pos, 1);          // перейти на нижний квадратик
      lcd.write((uint8_t)7);        // залить его полностью
  } 
    else {                          // если значение меньше 8
      lcd.print(" ");                 // верхний квадратик пустой
      lcd.setCursor(pos, 1);          // нижний квадратик
      lcd.write((uint8_t)posLevel);        // залить полосками
    }} yyy=0;
  }  

  if (AUTO_GAIN) {
    maxValue_f = maxValue * k + maxValue_f * (1 - k);
    if (millis() - gainTimer > 1500) {      // каждые 1500 мс
      // если максимальное значение больше порога, взять его как максимум для отображения
      if (maxValue_f > VOL_THR) gain_sp = maxValue_f;

      // если нет, то взять порог побольше, чтобы шумы вообще не проходили
      else gain_sp = 100;
      gainTimer = millis();
    }
  }else{gain_sp = DEF_GAIN;}
  }
     
}//loop

 void gain_func(){if(gain0<0){gain0=0;}if(gain0>15){gain0=15;}}
 void bass_func(){if(bass>15){bass=15;}if(bass<-15){bass=-15;}} 
 void middle_func(){if(middle>15){middle=15;}if(middle<-15){middle=-15;}}
 void treb_func(){if(treb>15){treb=15;}if(treb<-15){treb=-15;}}
 void vol_func(){if(vol<0){vol=0;}if(vol>80){vol=80;}}
 
 void cl(){ir.value=0;delay(300);spek=0;lcd.clear();}
 
 void to_Timer(){newPosition = myEnc.read()/4;}
 
 void audio(){
tda.setInput(in,gain0,0);    //вх1=1, вх2=2, вх3=3
tda.setInput2(0,0,0);   // не используется
tda.setAtt_loudness(lon,lon_f,0,0);
tda.setSoft(mute,0,0,0,0);//mute off (не менять)
tda.setVolume(vol-79,0);   // общая громкость от 0 до 79 макс
tda.setAtt_LF(64+lf,0);   // гром. лк фронт
tda.setAtt_RF(64+rf,0);   // гром. пк фронт
tda.setAtt_LT(64+lt,0);   // гром. лк тыл
tda.setAtt_RT(64+rt,0);   // гром. пк тыл
tda.setAtt_SUB(64+sab,0);  // гром. савбуфер
tda.setAtt_Mix(79,0);   // не использует
tda.setFilter_Treble(treb,treb_c,0); 
tda.setFilter_Middle(middle,0,0);
tda.setFilter_Bass(bass,0,0);
tda.setSub_M_B(sab_f,mid_c,bas_c,0,0);
tda.setMix_Gain_Eff(1,0,0,0,0); // не используется
tda.setSpektor(0,0,1,0,1,0,0);
}

void analyzeAudio() {  
  //cli(); 
 while( i1 < FHT_N ) {  i1++; 
    do{ADCSRA |= (1 << ADSC);} 
    while((ADCSRA & (1 << ADIF)) == 0);
    fht_input[i1] = (ADCL|ADCH << 8); 
    //fht_input[i1] = ADCH; 
    }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
 // sei();
}

123

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

Вам нужно заменить эту функцию, а так же удалить эту строку

ADMUX  = 0b01100000; ADCSRA = 0b11010100; // http://rcl-radio.ru/?p=57478

cli();
void analyzeAudio() {
  for (int i = 0 ; i < FHT_N ; i++) {
    int sample = analogRead(A0);
    fht_input[i] = 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
}
sei();

124 (2020-06-01 13:39:10 отредактировано roline)

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

liman324 пишет:

Вам нужно заменить эту функцию, а так же удалить эту строку

ADMUX  = 0b01100000; ADCSRA = 0b11010100; // http://rcl-radio.ru/?p=57478

cli();
void analyzeAudio() {
  for (int i = 0 ; i < FHT_N ; i++) {
    int sample = analogRead(A0);
    fht_input[i] = 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
}
sei();

а нужно ли перед cli и sei  ставить //?
ибо ругается

125

Re: TDA7419 + энкодер + ИК пульт + анализатор спектра

Я не там их разместил

void analyzeAudio() {
cli();
  for (int i = 0 ; i < FHT_N ; i++) {
    int sample = analogRead(A0);
    fht_input[i] = 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
sei();
}

Это на СИ, значить запретить прерывания , а после снова разрешить прерывания