ИМС TDA8425 представляет собой двухканальный (стереофонический) регулятор громкости и тембра с микропроцессорным управлением.
Технические характеристики аудиопроцессора TDA8425:
- Производитель: Philips
- Напряжение питания минимальное 7 В
- Напряжение питания максимальное 13,2 В
- Частотный диапазон 35…20000 Гц
- Коэффициент гармоник 0,05%
- Выходное напряжение максимальное 1 В
- Регулировка громкости 63 уровней от -80 дБ до +6 дБ с шагом 2 дБ
- Регулировка тембра НЧ от -12 дБ до +15 дБ с шагом 3 дБ
- Регулировка тембра ВЧ от -12 дБ до +12 дБ с шагом 3 дБ
- Регулировка баланса 8 дБ с шагом 2 дБ
- Входов 2 (стерео), коммутация программная
- Управление цифровой I2C
Регулятор громкости и тембра на TDA8425 содержит следующие компоненты:
- Плата Arduino Nano (или аналог)
- Энкодер KY-040
- IR — датчик
- Три кнопки управления
- Дисплей OLED 128×32
Основные параметры компонентов схемы:
0,91″ I2C 128×32 OLED — это компактный дисплей, который использует технологию OLED (Organic Light Emitting Diode) для отображения изображений. Дисплей имеет интерфейс I2C, который обеспечивает простое подключение к микроконтроллерам и другим устройствам.
Основные характеристики дисплея:
-
- Разрешение 128×32 пикселей.
- Размер дисплея 0,91 дюйма (около 2,3 см).
- Яркость до 150 кд/м².
- Контрастность 2000:1.
- Угол обзора 160 градусов.
- Поддержка интерфейса I2C с адресом 0x3C.
Arduino Nano:
- Микроконтроллер: ATmega328P
- Напряжение питания: 5 В
- Тактовая частота: 16 МГц
- Память Flash: 32 КБ
- Оперативная память (RAM): 2 КБ
- Постоянная память (EEPROM): 1 КБ
- Количество цифровых выводов: 14
- Количество аналоговых входов: 8
- Размеры платы: приблизительно 45 x 18 мм
Технические характеристики ИК-модуля VS1838B:
- Потребляемый ток: 0,5 мА
- Рабочая частота: 38 КГц
- Расстояние приема сигнала: 20 м
- Эффективный угол приема сигнала: 90˚
- Рабочее напряжение (приемник): 2,7 — 5,5 В
- Рабочее напряжение (модуль): 2,7 — 5,5 В
Основные параметры KY-040:
-
- Принцип работы: Инкрементальный энкодер с механическим переключателем.
- Интерфейс: Сигнал передается по трем линиям:
- CLK (Clock Line) — импульсный сигнал, определяющий направление вращения.
- DT (Data Line) — второй импульсный сигнал, синхронизируется с CLK.
- SW (Switch) — механический выключатель, срабатывающий при нажатии на вал энкодера.
- Напряжение питания: 3.3–5 В постоянного тока.
- Рабочий ток: Очень маленький (<1 мА).
- Размеры: Миниатюрный модуль, удобен для установки на печатные платы.
- Материал вала: Металлический или пластиковый, чувствителен к касанию пальцами.
- Кол-во импульсов на оборот: Обычно 20–30 шагов на полный оборот, точнее указывается производителем конкретного экземпляра.
- Совместимость: Совместим с большинством микроконтроллеров (Arduino, ESP32, STM32 и т.п.).
Схема блока управления
Основные параметры регулятора громкости и баланса
- Регулировка громкости 55 шагов
- Регулировка тембра НЧ от -12 до +15 дБ, шаг 2 дБ
- Регулировка тембра ВЧ от -12 до +12 дБ, шаг 2 дБ
- Регулировка баланса от -8 до +8 дБ, шаг 2 дБ
- Коммутация входов
- Режим MUTE
- Режим STANDBY
- Дополнительный цифровой выход D12 для управления режимом STANDBY УМЗЧ
- Управление энкодер, ИК пульт и три кнопки (INPUT, MUTE, POWER)
ИК пульт дублирует работу энкодера и кнопок. Для управления регулятором подойдет практически любой пульт ИК, для поддержки Вашего пульта необходимо прописать коды кнопок в скетч:
// коды кнопок ИК пульта #define MENU 0x2FDB24D // button encoder #define UP 0x2FDD02F // >>> #define DW 0x2FD32CD // <<< #define INPUT_IR 0x2FD6A95 // IN #define POWER_IR 0x2FD00FF // POWER #define MUTE_IR 0x2FDB04F // MUTE
Для получения кодов кнопок Вашего пульта загрузите скетч и откройте монитор порта, при нажатии кнопки пульта его код будет отображен в мониторе порта.
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Скетч
// энкодер #define ENC_DT 9 #define ENC_CLK 8 #define ENC_SW 10 // ИК датчик #define IR 12 // кнопки управления #define IN_BUTTON 2 #define POWER_BUTTON 3 #define MUTE_BUTTON 4 // выход управления standby #define STANDBY_OUT 13 // коды кнопок ИК пульта #define MENU 0x2FDB24D // button encoder #define UP 0x2FDD02F // >>> #define DW 0x2FD32CD // <<< #define INPUT_IR 0x2FD6A95 // IN #define POWER_IR 0x2FD00FF // POWER #define MUTE_IR 0x2FDB04F // MUTE #include <Wire.h> #include <U8glib.h> // https://github.com/olikraus/u8glib/ #include <Encoder.h> // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip #include <EEPROM.h> #include <MsTimer2.h> // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip #include <boarddefs.h> // входит в состав библиотеки IRremote #include <IRremote.h> // http://rcl-radio.ru/wp-content/uploads/2019/06/IRremote.zip #include <TDA8425.h> // http://rcl-radio.ru/wp-content/uploads/2018/11/TDA8425.zip U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE); // I2C / TWI IRrecv irrecv(IR); Encoder myEnc(ENC_DT, ENC_CLK); decode_results ir; TDA8425 tda; extern uint8_t SmallFont[],BigNumbers[]; long times,oldPosition = -999,newPosition; int vol,balans,bass,treb,in,menu; bool mute=0,gr1,gr2,w,w1,power=0; void setup(){ Wire.begin(); irrecv.enableIRIn(); Serial.begin(9600); MsTimer2::set(3, to_Timer);MsTimer2::start(); if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении pinMode(IN_BUTTON,INPUT_PULLUP); pinMode(POWER_BUTTON,INPUT_PULLUP); pinMode(MUTE_BUTTON,INPUT_PULLUP); pinMode(STANDBY_OUT,OUTPUT); u8g.firstPage(); do { u8g.setFont(u8g_font_profont29r);u8g.drawStr(5,25,"TDA8425"); }while( u8g.nextPage() ); delay(300); digitalWrite(STANDBY_OUT,LOW); vol = EEPROM.read(0);bass = EEPROM.read(1);treb = EEPROM.read(2);balans = EEPROM.read(3)-4;in = EEPROM.read(4); audio(); } void loop(){ // IR //////////////////////////////////////// if ( irrecv.decode( &ir )) {Serial.print("0x");Serial.println( ir.value,HEX);irrecv.resume();times=millis();w=1;}// IR приемник - чтение, в мониторе порта отображаются коды кнопок if(ir.value==0){gr1=0;gr2=0;}// запрет нажатий не активных кнопок пульта if(power==0){ if(digitalRead(ENC_SW)==LOW || ir.value==MENU){menu++;cl();delay(200);times=millis();w1=1;w=1;if(menu>3){menu=0;}} // меню if((digitalRead(IN_BUTTON)==LOW || ir.value==INPUT_IR) && mute==0){in++;cl();times=millis();w1=1;w=1;if(in>1){in=0;}audio(); u8g.firstPage(); do {u8g.setFont(u8g_font_profont29r);u8g.drawStr(0,25,"INPUT");u8g.setPrintPos(95, 25);u8g.print(in+1);}while( u8g.nextPage() );delay(1000);} // input if((digitalRead(MUTE_BUTTON)==LOW || ir.value==MUTE_IR)&& mute==0){mute=1;cl();times=millis();w1=1;w=1;audio(); u8g.firstPage(); do {u8g.setFont(u8g_font_profont29r);u8g.drawStr(25,25,"MUTE");}while( u8g.nextPage() );delay(300);menu=100;} // mute on if((digitalRead(MUTE_BUTTON)==LOW || ir.value==MUTE_IR)&& mute==1){mute=0;cl();times=millis();w1=1;w=1;audio(); delay(300);menu=0;} // mute off } if((digitalRead(POWER_BUTTON)==LOW || ir.value==POWER_IR)&& power==0){power=1;cl();times=millis();w1=1;w=1;mute=1;audio();digitalWrite(STANDBY_OUT,HIGH); u8g.firstPage(); do {u8g.setFont(u8g_font_profont29r);u8g.drawStr(10,25,"STANDBY");}while( u8g.nextPage() );delay(2000);menu=100; u8g.firstPage(); do {}while( u8g.nextPage() );} // power on if((digitalRead(POWER_BUTTON)==LOW || ir.value==POWER_IR)&& power==1){power=0;cl();times=millis();w1=1;w=1;mute=0;audio();digitalWrite(STANDBY_OUT,LOW);delay(300);menu=0;} // power off //////// VOLUME ////////////////////////////////////////////////////////////////////////////////////////////////////////////// if(menu==0){ if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;} vol=vol+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;vol_func();audio();} if(ir.value==UP){vol++;gr1=1;gr2=0;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка > if(ir.value==0xFFFFFFFF and gr1==1){vol++;gr2=0;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка >>>>>> if(ir.value==DW){vol--;gr1=0;gr2=1;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка < if(ir.value==0xFFFFFFFF and gr2==1){vol--;gr1=0;cl();times=millis();w=1;w1=1;vol_func();audio();}// кнопка <<<<<< if(w==1){w=0; // Serial.println(63-vol+balans); u8g.firstPage(); do { u8g.setFont(u8g_font_profont12r);u8g.drawStr(0,8,"VOLUME"); u8g.setFont(u8g_font_profont29r); u8g.setPrintPos(95, 24);u8g.print(vol-4); for(int v_pos=0; v_pos<(59-3)*1.5;v_pos+=4){u8g.drawBox(v_pos+0,16, 2, 1);} for(int v_pos=0; v_pos<(vol-3)*1.5;v_pos+=4){u8g.drawBox(v_pos+0,18, 2, 9);} for(int v_pos=0; v_pos<(59-3)*1.5;v_pos+=4){u8g.drawBox(v_pos+0,28, 2, 1);} } while( u8g.nextPage() ); }} ///////// BASS ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// if(menu==1){ if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;} bass=bass+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;bass_func();audio();} if(ir.value==UP){bass++;gr1=1;gr2=0;ir.value=0;times=millis();w=1;w1=1;bass_func();audio();}// кнопка > if(ir.value==DW){bass--;gr1=0;gr2=1;ir.value=0;times=millis();w=1;w1=1;bass_func();audio();}// кнопка < if(w==1){w=0; u8g.firstPage(); do { u8g.setFont(u8g_font_profont12r);u8g.drawStr(0,8,"BASS"); u8g.setFont(u8g_font_profont29r); u8g.setPrintPos(95, 24);u8g.print(bass-6); for(int v_pos=0; v_pos<(11-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,16, 2, 1);} for(int v_pos=0; v_pos<(bass-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,18, 2, 9);} for(int v_pos=0; v_pos<(11-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,28, 2, 1);} } while( u8g.nextPage() ); }} ///////// TREB ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// if(menu==2){ if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;} treb=treb+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;treb_func();audio();} if(ir.value==UP){treb++;gr1=1;gr2=0;ir.value=0;times=millis();w=1;w1=1;treb_func();audio();}// кнопка > if(ir.value==DW){treb--;gr1=0;gr2=1;ir.value=0;times=millis();w=1;w1=1;treb_func();audio();}// кнопка < if(w==1){w=0; u8g.firstPage(); do { u8g.setFont(u8g_font_profont12r);u8g.drawStr(0,8,"TREBLE"); u8g.setFont(u8g_font_profont29r); u8g.setPrintPos(95, 24);u8g.print(treb-6); for(int v_pos=0; v_pos<(10-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,16, 2, 1);} for(int v_pos=0; v_pos<(treb-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,18, 2, 9);} for(int v_pos=0; v_pos<(10-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,28, 2, 1);} } while( u8g.nextPage() ); }} ///////// BALL ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// if(menu==3){ if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;} balans=balans+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;ball_func();audio();} if(ir.value==UP){balans++;gr1=1;gr2=0;ir.value=0;times=millis();w=1;w1=1;ball_func();audio();}// кнопка > if(ir.value==DW){balans--;gr1=0;gr2=1;ir.value=0;times=millis();w=1;w1=1;ball_func();audio();}// кнопка < if(w==1){w=0; // Serial.println(63-vol+balans); // Serial.println(63-vol-balans); u8g.firstPage(); do { u8g.setFont(u8g_font_profont12r);u8g.drawStr(0,8,"BALANCE"); u8g.setFont(u8g_font_profont29r); if(balans>=0){u8g.setPrintPos(112, 24);u8g.print(balans);u8g.drawStr(95,24,"+");} else{u8g.setPrintPos(95, 24);u8g.print(balans);} for(int v_pos=0; v_pos<(12-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,16, 2, 1);} const int SCREEN_WIDTH = 84; u8g.drawBox(43,18, 1, 9);// 0 dB if(balans >= 0){for(int v_pos=0; v_pos<(balans*8);v_pos+=4){u8g.drawBox(v_pos+48,18, 2, 9);}} else{for(int v_pos=SCREEN_WIDTH-48; v_pos>(SCREEN_WIDTH-(abs(balans)*8)-48); v_pos-=4){u8g.drawBox(v_pos,18, 2, 9);}} for(int v_pos=0; v_pos<(12-1)*8;v_pos+=4){u8g.drawBox(v_pos+0,28, 2, 1);} } while( u8g.nextPage() ); }} ////////////// EEPROM ///////////////////////////////////////////////////////////////////// if(millis()-times>5000 && w1==1 && power==0 && mute==0){ EEPROM.update(0,vol);EEPROM.update(1,bass);EEPROM.update(2,treb);EEPROM.update(3,balans+4);EEPROM.update(4,in); menu=0;w1=0;w=1;myEnc.write(0);} } void to_Timer(){newPosition = myEnc.read()/4;} void audio(){ tda.setVolumeL(vol+balans); tda.setVolumeR(vol-balans); tda.setBass(bass); tda.setTreble(treb); tda.setMute(mute); tda.setSource(in); } void vol_func(){if(vol>59){vol=59;}if(vol<=4){vol=4;}} // int 0 = min ... int 63 = max + ballans 4 dB void bass_func(){if(bass>11){bass=11;}if(bass<2){bass=2;}} // int 6 = 0 dB | int 2 = -12 dB | int 11 = 15 dB void treb_func(){if(treb>10){treb=10;}if(treb<2){treb=2;}} // int 6 = 0 dB | int 2 = -12 dB | int 10 = 12 dB void ball_func(){if(balans>4){balans=4;}if(balans<=-4){balans=-4;}} void cl(){ir.value=0;delay(200);}
Форум — http://forum.rcl-radio.ru/viewtopic.php?pid=12036#p12036
Даташит — tda8425













Уже собрал. Всё отлично работает.
работает как на arduino так и на LGT8F328