Re: TDA7419 + энкодер + ИК пульт + анализатор спектра
раньше я не опускал громкость ниже -45, поэтому баг не проявлялся.
сейчас постоянно,если ниже -48 и до релоуда
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
forum.rcl-radio.ru → Тестирование скетчей → TDA7419 + энкодер + ИК пульт + анализатор спектра
Страницы Назад 1 2 3 4 5 6 7 … 10 Далее
Чтобы отправить ответ, вы должны войти или зарегистрироваться
раньше я не опускал громкость ниже -45, поэтому баг не проявлялся.
сейчас постоянно,если ниже -48 и до релоуда
если я подрезаю строку с индикацией,то дуня не вешается во всем диапазоне регулировки
(т.е. на экране отобрадаются волум -80дб, нижняя пустая)
возвращаю индикацию - вешается
-48дб это случайно не самое начало строки lcd? если да, причина ясна.
именно самое начало
-48 норм, -49 вешалка
попробуйте этот код
обратите внимание на эту команду
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();
}
тэкс , при 32 индикация не доходила до правого края экрана
изменил на 48 - теперь :
-80дб - одна полоска слева
0дб - строка полностью заполнена
дуня не вешается, все норм.
гоняю дальше ...
спасибо!
ну да 16*3=48, а не 32
а есть ли возможность отрихтовать анализатор спектра в плане более достоверного отображения частот?. Ибо подаю синус с генератора частот от 0 до 20к - анализатор выдает интересные вещи... скажем про 5,5кгц вторая строка экрана заполнена полностью, первая на 2/3.
вот бы каждый столбец привязать к частоте,... вот бы лялька получилась))
немного измените параметры
#define VOL_THR 35 // порог тишины (ниже него отображения на матрице не будет)
#define LOW_PASS 30 // нижний порог чувствительности шумов (нет скачков при отсутствии звука)
#define DEF_GAIN 80 // максимальный порог по умолчанию
например
#define VOL_THR 45 // порог тишины (ниже него отображения на матрице не будет)
#define LOW_PASS 40 // нижний порог чувствительности шумов (нет скачков при отсутствии звука)
#define DEF_GAIN 110 // максимальный порог по умолчанию
поигрался с параметрами
1 скрин - 350гц
2скрин - 13700гц
((
выше 2500гц беда практически на любых настройках
Ни чего не получится, мощности ардуино не хватит обрабатывать сигнал правильно, да и библиотека очень упрощенная, так же спектр обрезан примерно до 8 кГц (памяти в ардуино мало).
Это просто заставка примерно анализирующая спектр, так скажем для красоты.
По второму скрину, все просто, частота ушла за пределы чуствительности анализатора, автоусиление подняло сигнал на максимум, Вы видите шум.
По второму скрину, все просто, частота ушла за пределы чуствительности анализатора, автоусиление подняло сигнал на максимум, Вы видите шум.
дык беда то от 2.5кгц...
ну да ладно...
пущяй как заставка скачет)))
По идее, плавно меняя частоту от 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 кГц, на ВЧ появляется много шума, шириной выборки можно немного уменьшить шум.
как вам такое?
// ---------------- НАСТРОЙКИ ----------------
#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 байт.
если срезать скажем весь функционал ик... залезет?
по материалам https://alexgyver.ru/fhtspectrumanalyzer/
Я использовал этот материал.
Запустите этот скетч, посмотрите, в чем разница.
в коде первого поста в строке
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. не вываливалась
а я репу чешу чегоита у меня из канала саба полный спектр наваливает)))))
Исправил.
Я использовал этот материал.
Запустите этот скетч, посмотрите, в чем разница.
значится так...
поигрался с материалами Саши. и заметил,что даже при ширине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();
}
Вам нужно заменить эту функцию, а так же удалить эту строку
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();
Вам нужно заменить эту функцию, а так же удалить эту строку
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 ставить //?
ибо ругается
Я не там их разместил
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();
}
Это на СИ, значить запретить прерывания , а после снова разрешить прерывания
Страницы Назад 1 2 3 4 5 6 7 … 10 Далее
Чтобы отправить ответ, вы должны войти или зарегистрироваться
forum.rcl-radio.ru → Тестирование скетчей → TDA7419 + энкодер + ИК пульт + анализатор спектра
Форум работает на PunBB, при поддержке Informer Technologies, Inc
|