Темброблок на TDA8425 (Arduino)

ИМС TDA8425 представляет собой двухканальный (стереофонический) регулятор громкости и тембра с микропроцессорным управлением.

Технические характеристики:

  • Производитель: Philips
  • Напряжение питания минимальное 7 В
  • Напряжение питания максимальное 13,2 В
  • Частотный диапазон 35…20000 Гц
  • Коэффициент гармоник 0,05%
  • Выходное напряжение максимальное 1 В
  • Регулировка громкости 48 уровней от -88 дБ до +6 дБ с шагом 2 дБ
  • Регулировка тембра НЧ  от -12 дБ до +15 дБ с шагом 3 дБ
  • Регулировка тембра ВЧ  от -12 дБ до +12 дБ с шагом 3 дБ
  • Регулировка баланса 8 дБ с шагом 2 дБ

 

Плата Arduino Nano аудиопроцессор TDA8425 обмениваются данными на шине I2C по линиям SDA (data — данные) и SCL (clock — синхронизация).

Темброблок имеет пять кнопок управления:

  • МЕНЮ — перебор параметров (громкость, баланс, тембр НЧ, тембр ВЧ, выбор канала)
  • ПЛЮС — прибавление громкости, тембра и др.
  • МИНУС  — уменьшение громкости, тембра и др.
  • MUTE — включение/выключение режима MUTE
  • — 20 дБ — при нажатии на кнопку громкость уменьшается на 20 дБ

Если кнопки регулировок «ПЛЮС» и «МИНУС» и кнопка «МЕНЮ» не были активны в течении 10 секунд, то происходит запись всех настроек в энергонезависимую память (функция EEPROM.update не перезаписывает ячейку памяти если значение переменной не менялось), так же происходит переход из режима регулировок тембра, баланса, выбора входа в режим регулировки громкости.

Если в режиме MUTE нет необходимости, то выход D9 необходимо подключить к GND.

  #include <Wire.h>
  #include <TDA8425.h>
  #include <LiquidCrystal.h>
  #include <EEPROM.h>//#include <EEPROMex.h>
  TDA8425 tda;
  LiquidCrystal lcd(7, 6, 2, 3, 4, 5);// RS,E,D4,D5,D6,D7
  byte a1[8]={0b00000,0b11011,0b11011,0b11011,0b11011,0b11011,0b11011,0b00000};
  byte a2[8]={0b00000,0b11000,0b11000,0b11000,0b11000,0b11000,0b11000,0b00000};
  int menu,vol_d,z,w,w1,bass_d,treb,treb_d,balans,db;
  byte vol,bass,in,mute=0;
  unsigned long time;
 
void setup(){
  Serial.begin(9600);
  lcd.begin(16, 2);
  pinMode(12,INPUT);// меню
  pinMode(11,INPUT);// плюс
  pinMode(10,INPUT);// минус
  pinMode(9,INPUT);// mute
  pinMode(8,INPUT);// -20дБ
  lcd.createChar(0,a1); lcd.createChar(1,a2); 
  vol = EEPROM.read(0);// vol eeprom
  bass = EEPROM.read(1);// bass eeprom
  treb = EEPROM.read(2);// treb eeprom
  in = EEPROM.read(3);// in eeprom
  balans = EEPROM.read(4)-4;// balans eeprom
   audio();
  lcd.setCursor(4,0);lcd.print("TDA8425");delay(500);
 }
 
void loop(){
   if(digitalRead(12)==HIGH){menu++;mute=0;audio();cl();time=millis();w1=1;if(menu>4){menu=0;}}// меню
 
 // индикация громкости + управление кнопками //////////////
   if(menu==0){
   if(digitalRead(11)==HIGH){vol++;w=1;if(vol>63){vol=63;}}// 63 максимальная громкость = +6 дБ 
   if(digitalRead(10)==HIGH){vol--;w=1;if(vol<=16){vol=16;}}// 16 минимум громкости = -88 дБ
  lcd.setCursor(0,0);lcd.print("Volume    ");
  vol_d=vol*2-120;
   if(vol_d>=0){lcd.print("+");}else{lcd.print("-");}
   if(vol_d>-10){{lcd.print(" ");}}
  lcd.print(abs(vol_d));lcd.print(" dB   ");
 // ползунок громкости начинает работать с -56 дБ
   if(vol-32>0){for(z=0;z<=vol-33;z++){lcd.setCursor(z/2,1);lcd.write((uint8_t)0);}}
   if((vol-32)%2==0&&vol-32>=0){lcd.setCursor(z/2,1);lcd.write((uint8_t)1);}
   if(w==1){audio();cl();time=millis();w1=1;w=0;}
 }
 ///////////////////////////////////////////////////////////
 
 // индикация баланс + управление кнопками +\- 8 дБ ///////
   if(menu==1){
   if(digitalRead(11)==HIGH){balans++;w=1;if(balans>4){balans=4;}}
   if(digitalRead(10)==HIGH){balans--;w=1;if(balans<-4){balans=-4;}}
  lcd.setCursor(0,0);
   if(balans*2>=0){lcd.print("-");}else{lcd.print("+");}
  lcd.print(abs(balans*2));lcd.print(" dB ");
  lcd.print(" <>  ");
   if(balans*2>=0){lcd.print("+");}else{lcd.print("-");}
  lcd.print(abs(balans*2));lcd.print(" dB ");
  lcd.setCursor(0,1);lcd.print("R");
  lcd.setCursor(15,1);lcd.print("L");
   if(balans<0){lcd.setCursor(balans+7,1);lcd.write((uint8_t)0);}
   if(balans>0){lcd.setCursor(balans+8,1);lcd.write((uint8_t)0);}
   if(balans==0){lcd.setCursor(7,1);lcd.write((uint8_t)0);lcd.setCursor(8,1);lcd.write((uint8_t)0);}
   if(w==1){audio();cl();time=millis();w1=1;w=0;}
 }
 /////////////////////////////////////////////////////////////
 
 // индикация тембр НЧ + управление кнопками //////////////
   if(menu==2){
   if(digitalRead(11)==HIGH){bass++;w=1;if(bass>11){bass=11;}}// 11 максимум тембр = +15 дБ 
   if(digitalRead(10)==HIGH){bass--;w=1;if(bass<2||bass==255){bass=2;}}// 2 минимум тембр = -12 дБ
  lcd.setCursor(0,0);lcd.print("Bass      ");
  bass_d=bass*3-18;
   if(bass_d>=0){lcd.print("+");}else{lcd.print("-");}
   if(bass_d>-10&&bass_d<=0||bass_d<10&&bass_d>0){{lcd.print(" ");}}
  lcd.print(abs(bass_d));lcd.print(" dB   ");
   if(bass>1){for(z=3;z<=bass+1;z++){lcd.setCursor(z,1);lcd.write((uint8_t)0);}}
   if(w==1){audio();cl();time=millis();w1=1;w=0;}
 }
 ///////////////////////////////////////////////////////////
 
 // индикация тембр ВЧ + управление кнопками //////////////
   if(menu==3){
   if(digitalRead(11)==HIGH){treb++;w=1;if(treb>10){treb=10;}}// 10 максимум тембр = +12 дБ 
   if(digitalRead(10)==HIGH){treb--;w=1;if(treb<2||treb==255){treb=2;}}// 2 минимум тембр = -12 дБ
  lcd.setCursor(0,0);lcd.print("Treble    ");
  treb_d=treb*3-18;
   if(treb_d>=0){lcd.print("+");}else{lcd.print("-");}
   if(treb_d>-10&&treb_d<=0||treb_d<10&&treb_d>0){{lcd.print(" ");}}
  lcd.print(abs(treb_d));lcd.print(" dB   ");
   if(treb>1){for(z=3;z<=treb+1;z++){lcd.setCursor(z,1);lcd.write((uint8_t)0);}}
   if(w==1){audio();cl();time=millis();w1=1;w=0;}
 }
 ///////////////////////////////////////////////////////////
 
 /////////// input /////////////////////////////////////////
   if(menu==4){
   if(digitalRead(11)==HIGH){in++;w=1;if(in>1&&in<255){in=0;}}
   if(digitalRead(10)==HIGH){in--;w=1;if(in>2){in=1;}}
  lcd.setCursor(0,0);lcd.print("Source selector");
  lcd.setCursor(0,1);lcd.print("Input: ");lcd.print(in);
   if(w==1){audio();cl();time=millis();w1=1;w=0;}
 }
////////////////////////////////////////////////////////////
 
////////////////// mute //////////////////////////////////
   if(digitalRead(9)==HIGH){mute++;if(mute>1){mute=0;}
   if(mute==1){menu=-1;}else{menu=0;}
  audio();cl();
  lcd.setCursor(6,0);lcd.print("MUTE");
 }
///////////////////////////////////////////////////////////
 
///////////////////  -20 dB ///////////////////////////////
   if(digitalRead(8)==HIGH&&db==0){vol=vol-10;db=1;delay(500);audio();cl();}
   if(digitalRead(8)==HIGH&&db==1){vol=vol+10;db=0;delay(500);audio();cl();}
//////////////////////////////////////////////////////////
 
// запись всех настроек в EEPROM если кнопки + и - не нажимались в течении 10 сек
// если настройки тембра, баланса и номер входа не менялись в течении 10 сек, переход в рег. Громкости
   if(millis()-time>10000 && w1==1){
     EEPROM.update(0,vol);
     EEPROM.update(4,balans+4);
     EEPROM.update(1,bass);
     EEPROM.update(2,treb);
     EEPROM.update(3,in);
  menu=0;w1=0;cl();
 }
}
 
void cl(){
  delay(200);
  lcd.clear();
 }
 
void audio(){
  tda.setVolumeL(vol+balans);
  tda.setVolumeR(vol-balans);
  tda.setBass(bass);
  tda.setTreble(treb);
  tda.setMute(mute);
  tda.setSource(in);
 }

Библиотеки

TDA8425.ZIP 

MsTimer2.ZIP

Encoder.zip


Следующий вариант темброблока аналогичен первому, только вместо кнопок управления «ПЛЮС» и «МИНУС» и  «МЕНЮ» применен энкодер.

В данном варианте регулятора тембра и громкости, меню разделено на две части, первое меню это настройка громкости и тембра, второе меню это настройка баланса и выбор источника сигнала. При нажатии на кнопку энкодера происходит перебор основных параметров (громкость и тембр), для того чтобы попасть во второе меню необходимо нажать и удерживать кнопку энкодера, при быстром пролистывании основных параметров появится меню настройки баланса, при повторном нажатии кнопки энкодера меню выбора источника сигнала.

Если энкодер не активен в течении 10 секунд происходит переход на регулировку громкости и запись всех настроек в энергонезависимую память.

  #include <Wire.h>
  #include <TDA8425.h>
  #include <Encoder.h>
  #include <LiquidCrystal.h>
  #include <EEPROM.h>//
 // #include <EEPROMex.h>
  #include <MsTimer2.h>
   Encoder myEnc(11, 10);//CLK, DT
   TDA8425 tda;
   LiquidCrystal lcd(7, 6, 2, 3, 4, 5);// RS,E,D4,D5,D6,D7
   byte a1[8]={0b00000,0b11011,0b11011,0b11011,0b11011,0b11011,0b11011,0b00000};
   byte a2[8]={0b00000,0b11000,0b11000,0b11000,0b11000,0b11000,0b11000,0b00000};
   int z,vol,vol_d,balans,bass,bass_d,treb,treb_d,in,mute,sss,db;
   byte menu,w1;
   long oldPosition  = -999,newPosition;
   unsigned long time;
 
   void to_Timer(){ //функция таймера
 newPosition = myEnc.read()/4;}
 
void setup() {
  Serial.begin(9600);
   lcd.begin(16, 2);
   pinMode(12,INPUT);// меню кнопка энкодера SW
   lcd.createChar(0,a1); lcd.createChar(1,a2); 
   vol = EEPROM.read(0);// vol eeprom
   bass = EEPROM.read(1);// bass eeprom
   treb = EEPROM.read(2);// treb eeprom
   in = EEPROM.read(3);// in eeprom
   balans = EEPROM.read(4)-4;// balans eeprom
   audio();
   lcd.setCursor(4,0);lcd.print("TDA8425");delay(500);
   MsTimer2::set(1, to_Timer);MsTimer2::start();
}
 
void loop() {
   if(digitalRead(12)==LOW&&menu<3){sss++;menu++;myEnc.write(0);oldPosition  = -999;delay(300);time=millis();w1=1;if(menu>2){menu=0;}if(sss>2){menu=3;delay(300);}}// меню
   if(digitalRead(12)==HIGH){sss=0;}
   if(menu==3&&digitalRead(12)==LOW&&sss==0){menu=4;oldPosition  = -999;delay(300);time=millis();w1=1;lcd.clear();}
   if(menu==4&&digitalRead(12)==LOW){menu=0;delay(300);lcd.clear();}
   ///////////////////////// громкость /////////////////////////////
   if(menu==0){
   if (newPosition != oldPosition) {
    oldPosition = newPosition;
    vol=vol+newPosition;myEnc.write(0);newPosition=0;lcd.clear();time=millis();w1=1;if(vol>63){vol=63;}if(vol<16){vol=16;}audio();}
 
  lcd.setCursor(0,0);lcd.print("Volume    ");
  vol_d=vol*2-120;
   if(vol_d>=0){lcd.print("+");}else{lcd.print("-");}
   if(vol_d>-10){{lcd.print(" ");}}
  lcd.print(abs(vol_d));lcd.print(" dB   ");
 // ползунок громкости начинает работать с -56 дБ
   if(vol-32>0){for(z=0;z<=vol-33;z++){lcd.setCursor(z/2,1);lcd.write((uint8_t)0);}}
   if((vol-32)%2==0&&vol-32>=0){lcd.setCursor(z/2,1);lcd.write((uint8_t)1);}
  }
   ///////////////////////// баланс /////////////////////////////
  if(menu==3){
  if (newPosition != oldPosition) {
    oldPosition = newPosition;
    balans=balans+newPosition;myEnc.write(0);newPosition=0;lcd.clear();time=millis();w1=1;if(balans>4){balans=4;}if(balans<-4){balans=-4;}audio();}
 
  lcd.setCursor(0,0);
   if(balans*2>=0){lcd.print("-");}else{lcd.print("+");}
  lcd.print(abs(balans*2));lcd.print(" dB ");
  lcd.print(" <>  ");
   if(balans*2>=0){lcd.print("+");}else{lcd.print("-");}
  lcd.print(abs(balans*2));lcd.print(" dB ");
  lcd.setCursor(0,1);lcd.print("L");
  lcd.setCursor(15,1);lcd.print("R");
   if(balans<0){lcd.setCursor(balans+7,1);lcd.write((uint8_t)0);}
   if(balans>0){lcd.setCursor(balans+8,1);lcd.write((uint8_t)0);}
   if(balans==0){lcd.setCursor(7,1);lcd.write((uint8_t)0);lcd.setCursor(8,1);lcd.write((uint8_t)0);}
}
  ///////////////////////// тембр нч /////////////////////////////
  if(menu==1){
   if (newPosition != oldPosition) {
    oldPosition = newPosition;
    bass=bass+newPosition;myEnc.write(0);newPosition=0;lcd.clear();time=millis();w1=1;if(bass>11){bass=11;}if(bass<2){bass=2;}audio();}
 
  lcd.setCursor(0,0);lcd.print("Bass      ");
  bass_d=bass*3-18;
   if(bass_d>=0){lcd.print("+");}else{lcd.print("-");}
   if(bass_d>-10&&bass_d<=0||bass_d<10&&bass_d>0){{lcd.print(" ");}}
  lcd.print(abs(bass_d));lcd.print(" dB   ");
   if(bass>1){for(z=3;z<=bass+1;z++){lcd.setCursor(z,1);lcd.write((uint8_t)0);}}
 }
   ///////////////////////// тембр вч /////////////////////////////
  if(menu==2){
   if (newPosition != oldPosition) {
    oldPosition = newPosition;
    treb=treb+newPosition;myEnc.write(0);newPosition=0;lcd.clear();time=millis();w1=1;if(treb>11){treb=11;}if(treb<2){treb=2;}audio();}
 
   if(treb>10){treb=10;}if(treb<2||treb==255){treb=2;}
  lcd.setCursor(0,0);lcd.print("Treble    ");
  treb_d=treb*3-18;
   if(treb_d>=0){lcd.print("+");}else{lcd.print("-");}
   if(treb_d>-10&&treb_d<=0||treb_d<10&&treb_d>0){{lcd.print(" ");}}
  lcd.print(abs(treb_d));lcd.print(" dB   ");
   if(treb>1){for(z=3;z<=treb+1;z++){lcd.setCursor(z,1);lcd.write((uint8_t)0);}}
 }
  ///////////////////////// input /////////////////////////////
  if(menu==4){
if (newPosition != oldPosition) {
    oldPosition = newPosition;
    in=in+newPosition;myEnc.write(0);newPosition=0;lcd.clear();time=millis();w1=1;if(in>1){in=0;}if(in<0){in=1;}audio();}
 
  lcd.setCursor(0,0);lcd.print("Source selector");
  lcd.setCursor(0,1);lcd.print("Input: ");lcd.print(in);
 }
////////////////// mute //////////////////////////////////
   if(digitalRead(9)==HIGH){mute++;if(mute>1){mute=0;}
   if(mute==1){menu=-1;}else{oldPosition  = -999;menu=0;}
  audio(); delay(300);lcd.clear();
  lcd.setCursor(6,0);lcd.print("MUTE");
 }
///////////////////////////////////////////////////////////
 
///////////////////  -20 dB ///////////////////////////////
    if(digitalRead(8)==HIGH&&db==0){vol=vol-10;db=1;delay(500);audio();myEnc.write(0);menu=0;lcd.clear();}
    if(digitalRead(8)==HIGH&&db==1){vol=vol+10;db=0;delay(500);audio();myEnc.write(0);menu=0;lcd.clear();}
//////////////////////////////////////////////////////////
 
 
   if(millis()-time>10000 && w1==1){// сохранение всех настроек в eeprom через 60 сек неактивности
     myEnc.write(0);
     EEPROM.update(0,vol);
     EEPROM.update(4,balans+4);
     EEPROM.update(1,bass);
     EEPROM.update(2,treb);
     EEPROM.update(3,in);
     w1=0;menu=0;lcd.clear(); }
 
 }// loop
 
void audio(){
  tda.setVolumeL(vol+balans);
  tda.setVolumeR(vol-balans);
  tda.setBass(bass);
  tda.setTreble(treb);
  tda.setMute(mute);
  tda.setSource(in);
 }

Видео


Следующий скетч позволяет добавить анализатор спектра, при этом линейный входной сигнал необходимо  подать на вход А0. При неактивности кнопок управления и энкодера через 10 секунд происходит запись всех измененных параметров в энергонезависимую память и активация анализатора спектра, если нажать кнопку энкодера или покрутить его ручку анализатор спектра прекращает работать, и осуществляется переход в основное меню (громкость).

Дополнительно во второе меню (нажать и удерживать кнопку энкодера) добавлены настройки анализатора спектра:

  • AUTO_GAIN — автонастройка по громкости (0…1)
  • VOL_THR — порог тишины, ниже него отображения на экране не будет, это значение всегда должно быть быть меньше DEF_GAIN (10…100) (25-30 оптимально), параметр активен когда AUTO_GAIN = 1
  • LOW_PASS — нижний порог чувствительности шумов, нет скачков при отсутствии звука, это значение должно быть меньше DEF_GAIN (10..100) (35-40 оптимально)
  • DEF_GAIN — максимальный порог по умолчанию, это значение всегда должно быть выше VOL_THR и LOW_PASS (30…200)(80-120 оптимально), параметр активен когда AUTO_GAIN = 0
  • GRAPH_ATT — аттенюатор чувствительности (0,5…1,5), параметр активен когда AUTO_GAIN = 1
  • GRAPHICS — изменение вида графических полос (0…4)
  • Conv. speed — скорость преобразования для аналогового входа (чем больше значение тем более узкий частотный диапазон):
    • 0 — CLK/4
    • 1 — CLK/8 (оптимально)
    • 2  — CLK/16
    • 3  — CLK/32
    • 4  — CLK/64
    • 5  — CLK/128

Для перехода по параметрам настроек анализатора спектра необходимо нажимать кнопку MUTE.

Скетч не тестировался, возможно требуется правка кода.

Дополнительная библиотека FHT.ZIP

  #define FHT_N 256          // ширина спектра х2
  #define LOG_OUT 1
  #include <FHT.h>          
  #include <LiquidCrystal.h>
  #include <Wire.h>
  #include <TDA8425.h>
  #include <Encoder.h>
  #include <EEPROM.h>
 // #include <EEPROMex.h>
  #include <MsTimer2.h>
   LiquidCrystal lcd(7, 6, 2, 3, 4, 5);// RS,E,D4,D5,D6,D7
   Encoder myEnc(11, 10);//CLK, DT
   TDA8425 tda;
  // вручную забитый массив тонов, сначала плавно, потом круче
   byte posOffset[16] = {2, 3, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
   int AUTO_GAIN;    // автонастройка по громкости (экспериментальная функция)
   int VOL_THR;       // порог тишины (ниже него отображения на экране не будет)
   int LOW_PASS;        // нижний порог чувствительности шумов (нет скачков при отсутствии звука)
   int DEF_GAIN;     // максимальный порог по умолчанию (при GAIN_CONTROL игнорируется)
   unsigned long gainTimer,time;
   byte maxValue, maxValue_f,www,www1,spek,menu,w1,w2,y;
   float k = 0.1,k_usil;
   int z,vol,vol_d,balans,bass,bass_d,treb,treb_d,in,mute,sss,i,sp,graf,k_us,gain,i2,sped,db;
   long oldPosition  = -999,newPosition;
 
    void to_Timer(){ //функция таймера
    newPosition = myEnc.read()/4;}
 
void setup() { Serial.begin(9600);
  lcd.begin(16, 2);// LCD 16X2
  ADMUX  = 0b11100000; 
  //ADCSRA = 0b11110011;
   if(EEPROM.read(0)>100){ // используется только один раз при первом запуске, если ячейка памяти для громкости вне диапазона регулирования
     EEPROM.update(0,40);  // установка всех настроек по умолчанию
     EEPROM.update(4,0);
     EEPROM.update(1,0);
     EEPROM.update(2,0);
     EEPROM.update(3,0);
     EEPROM.update(5,1);
     EEPROM.update(6,30);
     EEPROM.update(7,35);
     EEPROM.update(8,80);
     EEPROM.update(9,0);
     EEPROM.update(10,10);
     EEPROM.update(11,0);
   }
   pinMode(12,INPUT);// меню кнопка энкодера SW
   vol = EEPROM.read(0);// vol eeprom
   bass = EEPROM.read(1);// bass eeprom
   treb = EEPROM.read(2);// treb eeprom
   in = EEPROM.read(3);// in eeprom
   balans = EEPROM.read(4)-4;// balans eeprom
   AUTO_GAIN = EEPROM.read(5);
   VOL_THR = EEPROM.read(6);
   LOW_PASS = EEPROM.read(7);
   DEF_GAIN = EEPROM.read(8);
   graf = EEPROM.read(9);
   k_us = EEPROM.read(10);
   sped = EEPROM.read(11);
   audio();
   lcd.setCursor(4,0);lcd.print("TDA8425");delay(500);
   MsTimer2::set(1, to_Timer);MsTimer2::start();
}
 
void loop() {
  if(spek==1){
 
  if(www==1){
             if(graf==0){
             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(graf==1){
             byte v1[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b01110};
             byte v2[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b01110, 0b01110};
             byte v3[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b01110, 0b01110, 0b01110};
             byte v4[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b01110, 0b01110, 0b01110, 0b01110};
             byte v5[8] = {0b00000, 0b00000, 0b00000, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110};
             byte v6[8] = {0b00000, 0b00000, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110};
             byte v7[8] = {0b00000, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110};
             byte v8[8] = {0b01110, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110};
             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(graf==2){
             byte v1[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b01010};
             byte v2[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b01010, 0b01010};
             byte v3[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b01010, 0b01010, 0b01010};
             byte v4[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b01010, 0b01010, 0b01010, 0b01010};
             byte v5[8] = {0b00000, 0b00000, 0b00000, 0b01010, 0b01010, 0b01010, 0b01010, 0b01010};
             byte v6[8] = {0b00000, 0b00000, 0b01010, 0b01010, 0b01010, 0b01010, 0b01010, 0b01010};
             byte v7[8] = {0b00000, 0b01010, 0b01010, 0b01010, 0b01010, 0b01010, 0b01010, 0b01010};
             byte v8[8] = {0b01010, 0b01010, 0b01010, 0b01010, 0b01010, 0b01010, 0b01010, 0b01010};
             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(graf==3){
             byte v1[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b10101};
             byte v2[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b10101, 0b10101};
             byte v3[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b10101, 0b10101, 0b10101};
             byte v4[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b10101, 0b10101, 0b10101, 0b10101};
             byte v5[8] = {0b00000, 0b00000, 0b00000, 0b10101, 0b10101, 0b10101, 0b10101, 0b10101};
             byte v6[8] = {0b00000, 0b00000, 0b10101, 0b10101, 0b10101, 0b10101, 0b10101, 0b10101};
             byte v7[8] = {0b00000, 0b10101, 0b10101, 0b10101, 0b10101, 0b10101, 0b10101, 0b10101};
             byte v8[8] = {0b10101, 0b10101, 0b10101, 0b10101, 0b10101, 0b10101, 0b10101, 0b10101};
             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(graf==4){
             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);}
  www=0;
  }
  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);
  while(y<3){y++;
    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);        // залить полосками
    }} y=0;
}
 
 
   k_usil=k_us;k_usil=k_usil*0.1;
  if (AUTO_GAIN==1) {
    maxValue_f = maxValue*k_usil * k + maxValue_f * (1 - k);
   if (millis() - gainTimer > 1500) {      // каждые 1500 мс
      // если максимальное значение больше порога, взять его как максимум для отображения
      if (maxValue_f > VOL_THR) gain = maxValue_f;
      // если нет, то взять порог побольше, чтобы шумы вообще не проходили
      else gain = 100;
      gainTimer = millis();
    }}else{gain=DEF_GAIN;
  }// spektr
  } 
 
   if(digitalRead(12)==LOW&&menu<3){sss++;if(spek==1){menu==0;}else{menu++;}www1=0;spek=0;myEnc.write(0);oldPosition  = -999;delay(300);time=millis();w1=1;if(menu>2){menu=0;}if(sss>2){menu=3;delay(300);}}// меню
   if(digitalRead(12)==HIGH){sss=0;}
   if(menu==3&&digitalRead(12)==LOW&&sss==0){menu=4;oldPosition  = -999;delay(300);time=millis();w1=1;lcd.clear();}
   if(menu==4&&digitalRead(12)==LOW&&sss==0){menu=5;oldPosition  = -999;delay(300);time=millis();w1=1;lcd.clear();}
   if(menu==5&&digitalRead(12)==LOW){menu=0;time=millis();w1=1;delay(300);lcd.clear();}
   if (newPosition != oldPosition&&spek==1) {oldPosition = newPosition;menu=0,www1=0;spek=0;w1=1;time=millis();lcd.clear();}
 
    if(spek==0){
      if(www1==0){byte a1[8]={0b00000,0b11011,0b11011,0b11011,0b11011,0b11011,0b11011,0b00000};
                  byte a2[8]={0b00000,0b11000,0b11000,0b11000,0b11000,0b11000,0b11000,0b00000};
                  lcd.createChar(0,a1); lcd.createChar(1,a2); www1=1; }
 
   ///////////////////////// громкость /////////////////////////////
   if(menu==0){
   if (newPosition != oldPosition) {
    oldPosition = newPosition;
    vol=vol+newPosition;myEnc.write(0);newPosition=0;lcd.clear();time=millis();w1=1;if(vol>63){vol=63;}if(vol<16){vol=16;}audio();}
 
  lcd.setCursor(0,0);lcd.print("Volume    ");
  vol_d=vol*2-120;
   if(vol_d>=0){lcd.print("+");}else{lcd.print("-");}
   if(vol_d>-10){{lcd.print(" ");}}
  lcd.print(abs(vol_d));lcd.print(" dB   ");
 // ползунок громкости начинает работать с -56 дБ
   if(vol-32>0){for(z=0;z<=vol-33;z++){lcd.setCursor(z/2,1);lcd.write((uint8_t)0);}}
   if((vol-32)%2==0&&vol-32>=0){lcd.setCursor(z/2,1);lcd.write((uint8_t)1);}
  }
   ///////////////////////// баланс /////////////////////////////
  if(menu==3){
  if (newPosition != oldPosition) {
    oldPosition = newPosition;
    balans=balans+newPosition;myEnc.write(0);newPosition=0;lcd.clear();time=millis();w1=1;if(balans>4){balans=4;}if(balans<-4){balans=-4;}audio();}
 
  lcd.setCursor(0,0);
   if(balans*2>=0){lcd.print("-");}else{lcd.print("+");}
  lcd.print(abs(balans*2));lcd.print(" dB ");
  lcd.print(" <>  ");
   if(balans*2>=0){lcd.print("+");}else{lcd.print("-");}
  lcd.print(abs(balans*2));lcd.print(" dB ");
  lcd.setCursor(0,1);lcd.print("L");
  lcd.setCursor(15,1);lcd.print("R");
   if(balans<0){lcd.setCursor(balans+7,1);lcd.write((uint8_t)0);}
   if(balans>0){lcd.setCursor(balans+8,1);lcd.write((uint8_t)0);}
   if(balans==0){lcd.setCursor(7,1);lcd.write((uint8_t)0);lcd.setCursor(8,1);lcd.write((uint8_t)0);}
}
  ///////////////////////// тембр нч /////////////////////////////
  if(menu==1){
   if (newPosition != oldPosition) {
    oldPosition = newPosition;
    bass=bass+newPosition;myEnc.write(0);newPosition=0;lcd.clear();time=millis();w1=1;if(bass>11){bass=11;}if(bass<2){bass=2;}audio();}
 
  lcd.setCursor(0,0);lcd.print("Bass      ");
  bass_d=bass*3-18;
   if(bass_d>=0){lcd.print("+");}else{lcd.print("-");}
   if(bass_d>-10&&bass_d<=0||bass_d<10&&bass_d>0){{lcd.print(" ");}}
  lcd.print(abs(bass_d));lcd.print(" dB   ");
   if(bass>1){for(z=3;z<=bass+1;z++){lcd.setCursor(z,1);lcd.write((uint8_t)0);}}
 }
   ///////////////////////// тембр вч /////////////////////////////
  if(menu==2){
   if (newPosition != oldPosition) {
    oldPosition = newPosition;
    treb=treb+newPosition;myEnc.write(0);newPosition=0;lcd.clear();time=millis();w1=1;if(treb>11){treb=11;}if(treb<2){treb=2;}audio();}
 
   if(treb>10){treb=10;}if(treb<2||treb==255){treb=2;}
  lcd.setCursor(0,0);lcd.print("Treble    ");
  treb_d=treb*3-18;
   if(treb_d>=0){lcd.print("+");}else{lcd.print("-");}
   if(treb_d>-10&&treb_d<=0||treb_d<10&&treb_d>0){{lcd.print(" ");}}
  lcd.print(abs(treb_d));lcd.print(" dB   ");
   if(treb>1){for(z=3;z<=treb+1;z++){lcd.setCursor(z,1);lcd.write((uint8_t)0);}}
 }
  ///////////////////////// input /////////////////////////////
  if(menu==4){
if (newPosition != oldPosition) {
    oldPosition = newPosition;
    in=in+newPosition;myEnc.write(0);newPosition=0;lcd.clear();time=millis();w1=1;if(in>1){in=0;}if(in<0){in=1;}audio();}
 
  lcd.setCursor(0,0);lcd.print("Source selector");
  lcd.setCursor(0,1);lcd.print("Input: ");lcd.print(in);
 }
///////////////////////////////////////////////////////////
 
  ///////////////////////// spectrum analyzer /////////////////////////////
  if(menu==5){  
    if(digitalRead(9)==HIGH){sp++;myEnc.write(0);oldPosition  = -999;delay(300);time=millis();if(sp>6){sp=0;}}
     lcd.setCursor(0,0);lcd.print("Spectrum analyzer");
if (newPosition != oldPosition) {
    oldPosition = newPosition;
    switch(sp){ w1=0;
    case 0: AUTO_GAIN=AUTO_GAIN+newPosition;myEnc.write(0);newPosition=0;audio();lcd.clear();time=millis();w1=1;if(AUTO_GAIN>1){AUTO_GAIN=0;}if(AUTO_GAIN<0){AUTO_GAIN=1;};
    lcd.setCursor(0,1);lcd.print("AUTO_GAIN ");lcd.print(AUTO_GAIN);break;
    case 1: VOL_THR=VOL_THR+newPosition;myEnc.write(0);newPosition=0;audio();lcd.clear();time=millis();w1=1;if(VOL_THR>100){VOL_THR=100;}if(VOL_THR<10){VOL_THR=10;};
    lcd.setCursor(0,1);lcd.print("VOL_THR ");lcd.print(VOL_THR);break;
    case 2: LOW_PASS=LOW_PASS+newPosition;myEnc.write(0);newPosition=0;audio();lcd.clear();time=millis();w1=1;if(LOW_PASS>100){LOW_PASS=100;}if(LOW_PASS<10){LOW_PASS=10;};
    lcd.setCursor(0,1);lcd.print("LOW_PASS ");lcd.print(LOW_PASS);break;
    case 3: DEF_GAIN=DEF_GAIN+newPosition;myEnc.write(0);newPosition=0;audio();lcd.clear();time=millis();w1=1;if(DEF_GAIN>200){DEF_GAIN=200;}if(DEF_GAIN<30){DEF_GAIN=30;};
    lcd.setCursor(0,1);lcd.print("DEF_GAIN ");lcd.print(DEF_GAIN);break;
    case 4: k_us=k_us+newPosition;myEnc.write(0);newPosition=0;audio();lcd.clear();time=millis();w1=1;if(k_us>15){k_us=15;}if(k_us<5){k_us=5;}; k_usil=k_us;k_usil=k_usil*0.1;
    lcd.setCursor(0,1);lcd.print("GRAPH_ATT ");lcd.print(k_usil,1);break;
    case 5: graf=graf+newPosition;myEnc.write(0);newPosition=0;audio();lcd.clear();time=millis();w1=1;if(graf>4){graf=4;}if(graf<0){graf=0;};
    lcd.setCursor(0,1);lcd.print("GRAPHICS ");lcd.print(graf);break;
    case 6: sped=sped+newPosition;w2=0;myEnc.write(0);newPosition=0;audio();lcd.clear();time=millis();w1=1;if(sped>5){sped=5;}if(sped<0){sped=0;};
    lcd.setCursor(0,1);lcd.print("Conv. speed ");lcd.print(sped);break;
 
  }}}
 /////////////////////////////////////////////////////////////////////////
    }// spek = 0
  if(w2==0){
    switch(sped){
      case 0: ADCSRA = 0b11110010;break;
      case 1: ADCSRA = 0b11110011;break;
      case 2: ADCSRA = 0b11110100;break;
      case 3: ADCSRA = 0b11110101;break;
      case 4: ADCSRA = 0b11110110;break;
      case 5: ADCSRA = 0b11110111;break;
    }w2=1;}
 
////////////////// mute //////////////////////////////////
   if(digitalRead(9)==HIGH&&menu!=5){mute++;if(mute>1){mute=0;}
   if(mute==1){menu=-1;w1=0;spek=0;www1=0;}else{oldPosition  = -999;menu=0;}
  audio();delay(300);lcd.clear();
  lcd.setCursor(6,0);lcd.print("MUTE");
 }
///////////////////////////////////////////////////////////
 
///////////////////  -20 dB ///////////////////////////////
 if(digitalRead(8)==HIGH&&db==0){vol=vol-10;db=1;delay(500);audio();myEnc.write(0);menu=0;lcd.clear();}
 if(digitalRead(8)==HIGH&&db==1){vol=vol+10;db=0;delay(500);audio();myEnc.write(0);menu=0;lcd.clear();}
//////////////////////////////////////////////////////////
 
 
   if(millis()-time>10000 && w1==1){// сохранение всех настроек в eeprom через 60 сек неактивности
     //myEnc.write(0);
     EEPROM.update(0,vol);
     EEPROM.update(4,balans+4);
     EEPROM.update(1,bass);
     EEPROM.update(2,treb);
     EEPROM.update(3,in);
     EEPROM.update(5,AUTO_GAIN);
     EEPROM.update(6,VOL_THR);
     EEPROM.update(7,LOW_PASS);
     EEPROM.update(8,DEF_GAIN);
     EEPROM.update(9,graf);
     EEPROM.update(10,k_us);
     EEPROM.update(11,sped);
     w1=0;menu=0;lcd.clear();spek=1;www=1; sp=0;}
 
 }// loop
 
void audio(){
  tda.setVolumeL(vol+balans);
  tda.setVolumeR(vol-balans);
  tda.setBass(bass);
  tda.setTreble(treb);
  tda.setMute(mute);
  tda.setSource(in);  }
 
void analyzeAudio() {  
   cli(); 
 while( i < FHT_N ) {  i++; 
    do{ADCSRA |= (1 << ADSC);} 
    while((ADCSRA & (1 << ADIF)) == 0);
    fht_input[i] = (ADCL|ADCH << 8); 
    }i=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();
}

  • tda8425_01.zip — основное меню: громкость, тембр, баланс, выбор входа, в дополнительном меню настройки только анализатора спектра.


TDA8425 + энкодер + пульт + STANDBY — http://forum.rcl-radio.ru/viewtopic.php?id=57


TDA8425 + энкодер + пульт + STANDBY + часы(DS3231) — http://forum.rcl-radio.ru/viewtopic.php?id=59


Дополнительные материалы:

Comments

      1. а как кнопку инвертировать? потому что я попытался сделать макетную плату с 3 кнопками с кнопками муте и -20 дб, и после соединения 3 кнопки в таком же исполнении происходило тоже самое, режимы с бешеной скоростью переключаются…

        1. Не совсем понял Ваше подключение, энкодер будет участвовать в управлении или нет? Если вы хотите продублировать кнопку энкодера простой кнопкой используя один и тот же цифровой выход, то просто коммутируйте кнопку от земли, а плюс питания через резистор. Можно использовать кнопку подключенную к другому цифровому выходу.
          Инвертирование кнопки:
          if(digitalRead(11)==HIGH) или if(digitalRead(11)==LOW) в зависимости к массе или +5 В притянут цифровой выход для кнопки

        2. Попробуйте поменять местами +- на энкодере, в нем нет электроники, только контакты. Кнопка инвертируется. slk dt так же можно поменять местами для изменения направления вращения энкодера.

  1. Доброго дня. Заметил особенность в энкодерах. Покупал два у разных поставщиков. При подключении один вёл себя «как надо», второй сходил с ума. При изучении обоих обнаружил, что у одного энкодера резисторы подтяжки на минус питания. (этот работал безупречно), а у второго энкодера резисторы подтяжки к плюсу питания, а кнопка энкодера была вообще без резистора, хотя место на плате было предусмотрено. Перепаял резисторы и добавил на кнопку резистор 10 КОм. После доработки и этот энкодер стал работать как нужно.

  2. Вопрос автору. Как доработать скетч, чтобы при переключении входов аудиоконтроллера, на любых свободных пинах Ардуино появлялся и фиксировался высокий уровень? Это нужно, чтобы используя реле запускать доп. устройства.

    1. За состояние выхода отвечает переменная in, поэтому в конце скетча перед }//loop можно добавить следующий код:

      if(in==0){digitalWrite(13, HIGH);}
      else{
      digitalWrite(13, LOW);
      }

      В setup() добавить:
      pinMode(13,OUTPUT);

      1. Спасибо. Возникло желание оснастить этот процессор МП3 плеером. Коммутируя вход «0» будет одновременно запитываться и блок плеера.

      1. Спасибо. Подскажите, пожалуйста, ещё пару моментов.
        1. На схеме есть входные 0ЛК 0ПК 1ЛК 1ПК, при этом на входе есть миниджек 3 проводами (земля, правый канал, левый канал), собственно как это подключить ко входам микросхемы? Коротить между собой 0ЛК с 1ЛК и 0ПК с 1ЛК и подключать к миниджеку?
        2. Хочу собрать вместе со спектром. Вопрос: на А0 подавать выходной сигнал с микросхемы или с усилителя?

        1. 1. ПК и ЛК + общий (земля), неиспользуемые входы не надо ни с чем замыкать, если вход не предполагается использовать, то даже разделительные конденсаторы ставить не нужно.
          2. Подавать нужно сигнал с линейного выхода через разделительный конденсатор 1 мкФ (этот же сигнал подается на вход tda8425).

          1. Хорошо, спасибо. Но разве не с микросхемы на А0? Так как если сигнал подать с линейного выхода то анализ будет производится не обработанного сигнала (без коррекции НЧ/ВЧ)

            1. Можно и так, но с линейного выхода сигнал без обработки, в этом вся суть. Тем более сигнал с выхода микросхемы имеет непостоянную амплитуду из-за регулировки громкости. В анализаторе спектра много настроек, например такие как автоусиление, порог тишины, порог шума — как эти параметры будут влиять на отображение эквалайзера при изменении громкости я не знаю (практически эти параметры работать не будут).

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

                byte maxValue, maxValue_f,www,www1,spek,menu,w1,w2,y;
                float k = 0.1,k_usil;
                int z,vol,vol_d,balans,bass,bass_d,treb,treb_d,in,mute,sss,i,sp,graf,k_us,gain,i2,sped;

                конкретно maxValue_f, www, www1, in, spek, sss, i, sp, graf, k_us, gain, i2, sped
                Спасибо.

  3. Я не смогу объяснить, это надо пересматривать весь код, я уже все не вспомню. Но по коду все понятно если его разобрать по частям:
    например in номер входа, www www1 — это заглушки, gain — предусиление и так далее, а i2 — вообще не нужна, просто забыл стереть. sss — ключ нажатия кнопки энкодера.

      1. Все эти переменные Вам не нужны, необходимо просто пролистывать меню (menu), управлять громкостью, тембром и балансом (vol, bass, treb,balans) и коммутатором входов (in)

        Например перелистывание меню:
        if(ir.value==0xFF18E7){menu++;cl();if(menu>4){menu=0;}}// меню кнопка вверх 0xFF18E7
        if(ir.value==0xFF4AB5){menu--;cl();if(menu==255){menu=4;}}// меню кнопка вниз 0xFF4AB5

        (в основном цикле)

        громкость:
        if(ir.value==0xFF5AA5){vol++;g1=1;g2=0;cl();}// кнопка > 0xFF5AA5
        if(ir.value==0xFFFFFFFF and g1==1){vol++;g2=0;cl();}// кнопка >>>>>>
        if(ir.value==0xFF10EF){vol--;g1=0;g2=1;cl();}// кнопка < 0xFF10EF if(ir.value==0xFFFFFFFF and g2==1){vol--;g1=0;cl();}// кнопка <<<<<<

        (в секции menu=0, добавить новые переменные int g1, g2;)
        и аналогично для тембра баланса в своих секциях

        в самом начале цикла строка опроса ИК:
        if ( irrecv.decode( &ir )) {delay(200);Serial.print("0x");Serial.println( ir.value,HEX);time1=millis();time=millis();w=1;w1=1;irrecv.resume();}// IR приемник

        в setup:
        irrecv.enableIRIn(); // запускаем модуль IR

        в начало скетча под библиотекой:
        IRrecv irrecv(12); // указываем вывод модуля IR приемника

        ну и сама библиотека:
        #include "IRremote.h"

  4. при зажатой кнопке энкодера открывается выбор входа, а потом если нажать кнопку то открываются настройки анализатора, собственно, вопрос: что нужно изменить в коде для того чтобы при зажатой кнопке открывались только настройки спектра? 2. что нужно изменить чтобы при запуске автоматически активировался спектр?

    1. Для запуска анализатора спектра сразу после включения необходимо создать новую переменную:
      byte qwerty =1;
      Далее измените код:
      if(millis()-time>10000 && w1==1||qwerty==1){// сохранение всех настроек в eeprom через 60 сек неактивности
      //myEnc.write(0);
      EEPROM.update(0,vol);
      EEPROM.update(4,balans+4);
      EEPROM.update(1,bass);
      EEPROM.update(2,treb);
      EEPROM.update(3,in);
      EEPROM.update(5,AUTO_GAIN);
      EEPROM.update(6,VOL_THR);
      EEPROM.update(7,LOW_PASS);
      EEPROM.update(8,DEF_GAIN);
      EEPROM.update(9,graf);
      EEPROM.update(10,k_us);
      EEPROM.update(11,sped);
      w1=0;menu=0;lcd.clear();spek=1;www=1; sp=0;qwerty=0;}

      Во втором меню активация которого включается удержанием кнопки, помимо настроек анализатора имеются настройки баланса и выбор входа, их надо перенести в основное меню:

      Измените код:
      if(digitalRead(12)==LOW&&menu4){menu=0;}if(sss>2){menu=5;lcd.clear();lcd.setCursor(0,0);lcd.print(" MENU2 "); delay(1000);}}// меню
      if(digitalRead(12)==HIGH){sss=0;}
      //if(menu==3&&digitalRead(12)==LOW&&sss==0){menu=4;oldPosition = -999;delay(300);time=millis();w1=1;lcd.clear();}
      // if(menu==4&&digitalRead(12)==LOW&&sss==0){menu=5;oldPosition = -999;delay(300);time=millis();w1=1;lcd.clear();}
      if(menu==5&&digitalRead(12)==LOW){menu=0;time=millis();w1=1;delay(300);lcd.clear();}
      if (newPosition != oldPosition&&spek==1) {oldPosition = newPosition;menu=0,www1=0;spek=0;w1=1;time=millis();lcd.clear();}

          1. понял, спасибо. такая проблема нарисовалась — играет только один канал из двух (сам усилок рабочий, проверялось), собирал по вашей схеме, собственно проблема в самой 8425 или ещё в чём-то?

            1. Проверить работоспособность TDA8425 очень просто:
              tda.setVolumeL(vol+balans);
              tda.setVolumeR(vol-balans);
              эти функции отвечают за громкость в каждом канале, установить максимальную громкость:
              tda.setVolumeL(63);
              tda.setVolumeR(63);
              К выходу подключите наушники, если звука в одном из каналов нет, значит TDA неисправна

  5. Сделал два варианта плат. Один под установку пленочных кондеев на входе и выходе. Другую — под электролиты. Разницы в звуке не заметил. Усилитель простой — Technics SU-VZ320. Колонки — -полочники QUADRAL Allsonic SM 90 II.

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

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