ИМС TDA7439 – регулятор громкости и трехполосный регулятор тембра, разработан для использования в HI-FI аппаратуре и качественных автомобильных аудиосистемах, обладает низким уровнем шумов и искажений.
Основные технические характеристики ИМС TDA7439:
- Громкость 48 уровней от -48 до 0 дБ
- Регулировка тембра НЧ, СЧ, ВЧ ±14 дБ (±7 уровней)
- Коммутация входов — 4 стерео канала
- Усиление от 0 до 30 дБ независимое для каждого канала
- Регулировка баланса ±4 дБ (ограниченно программно)
- Напряжение питания от 6 до 10,2 В (типовое значение 9 В)
- КНИ на частоте 1 кГц не более 0,01%
Плата Arduino Nano аудиопроцессор TDA7439 обмениваются данными на шине I2C по линиям SDA (data — данные) и SCL (clock — синхронизация).
Плата | Пин SDA | Пин SCL |
---|---|---|
Arduino Uno, Nano, Pro и Pro Mini | A4 | A5 |
На странице http://rcl-radio.ru/?p=54921 показан пример использования ИМС TDA7439, в качестве органов управления используются кнопки. На этой странице показан пример управления регулятором тембра при помощи энкодера на базе модуля KY-040 и ИК-модуля VS1838B.
Технические характеристики ИК-модуля VS1838B:
- Потребляемый ток: 0,5 мА
- Рабочая частота: 38 КГц
- Расстояние приема сигнала: 20 м
- Эффективный угол приема сигнала: 90˚
- Рабочее напряжение (приемник): 2,7 — 5,5 В
- Рабочее напряжение (модуль): 2,7 — 5,5 В
На рисунке показано изображения пульта под команды которого написан скетч, но пульт можно применить другой, при этом коды кнопок будут соответственно другие. Даже если Вы будете использовать такой же пульт, то вероятней всего коды кнопок будут отличатся. Но в мониторе порта Вы сможете посмотреть коды кнопок и вписать в скетч свои значения.
Стоит обратить внимание на то, что в рассматриваемом пульте при удержании кнопки длительное время сначала следует код команды кнопки, а далее код 0xFFFFFFFF как код удержания нажатой кнопки, при этом код 0xFFFFFFFF подается при удержании любой кнопки. В других пультах для каждой кнопки код удержания кнопки может быть свой для каждой кнопки.
При помощи кнопки энкодера можно переходить по пунктам меню:
- Громкость
- Тембр НЧ
- Тембр СЧ
- Тембр ВЧ
- Баланс
Регулировка параметров громкости, тембра и баланса осуществляется при помощи ручки энкодера. При нажатии на кнопку «INPUT» можно переключить номер канала и при помощи ручки энкодера изменить усиление для каждого канала.
При помощи пульта управления и ИК-датчика так же можно управлять основными настройками регулятора тембра:
- Кнопка 1 — управление громкостью
- Кнопка 2 — управление тембром НЧ
- Кнопка 3 — управление тембром СЧ
- Кнопка 4 — управление тембром ВЧ
- Кнопка 5 — управление балансом
- При помощи кнопок «вверх» и «вниз» происходит перемещение по пунктам меню.
- Кнопки < и > позволяют регулировать параметры громкости, тембра и баланса
- Кнопка # — MUTE
- Кнопка OK позволяет изменять номер канала (регулировка усиления каналов осуществляется при помощи ручки энкодера)
При неактивности органов управления через 10 секунд происходит переход в пункт меню «Громкость», а при неактивности органов управления в течение 60 секунд происходит запись всех параметров (громкость , тембр, баланс, номер канала и усиление каналов) в энергонезависимую память.
TDA7439.zip — скачайте и установите измененную библиотеку для данного скетча
#include <Wire.h> #include <TDA7439.h> #include <LiquidCrystal.h> #include <EEPROMex.h> #include <Encoder.h> #include <IRremote.h> IRrecv irrecv(10); // указываем вывод модуля IR приемника TDA7439 tda; Encoder myEnc(9, 8);//CLK, DT decode_results ir; 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 vol,vol_ram,vol_d,z,bass,bass_ram,mids,mids_ram,treb,treb_ram,balans,balans_ram,in,in_ram,gain,gain1_ram,gain1,gain2,gain2_ram,gain3,gain3_ram,gain4,gain4_ram; byte menu,w,w1,in_d,gr1,gr2,n1,n2,s1,s2,v1,v2,b1,b2; unsigned long time,time1,time3,time4;long oldPosition = -999; void setup() { Serial.begin(9600); Serial.println("TDA7439"); lcd.begin(16, 2); irrecv.enableIRIn(); // запускаем модуль IR lcd.setCursor(0,0);lcd.print(" TDA7439 ");delay(1000); pinMode(12,INPUT);// меню кнопка энкодера SW pinMode(11,INPUT);// in 1-4 lcd.createChar(0,a1); lcd.createChar(1,a2); vol = EEPROM.read(0);// vol eeprom bass = EEPROM.read(1)-7;// bass eeprom mids = EEPROM.read(2)-7;// mids eeprom treb = EEPROM.read(3)-7;// treb eeprom balans = EEPROM.read(4)-4;// balans eeprom in = EEPROM.read(5);// in eeprom gain1 = EEPROM.read(6);// gain1 eeprom gain2 = EEPROM.read(7);// gain2 eeprom gain3 = EEPROM.read(8);// gain3 eeprom gain4 = EEPROM.read(9);// gain4 eeprom g1();audio();ram(); } void loop() { if(millis()-time3>200){ if ( irrecv.decode( &ir )) {Serial.print("0x");Serial.println( ir.value,HEX);time1=millis();time=millis();w=1;w1=1;irrecv.resume();}// IR приемник if(digitalRead(12)==LOW){menu++;ram();in_d=0;myEnc.write(0);oldPosition = -999;time1=millis();w=1;if(menu>4){menu=0;}}// меню if(digitalRead(11)==HIGH){in++;;ram();in_d=1;g2();myEnc.write(0);oldPosition = -999;menu=5;w=1;time1=millis();if(in>4||in<1){in=1;}}// in if(ir.value==0xFF18E7){in_d=0;menu++;cl();if(menu>4){menu=0;}}// меню кнопка вверх 0xFF18E7 if(ir.value==0xFF4AB5){in_d=0;menu--;cl();if(menu==255){menu=4;}}// меню кнопка вниз 0xFF4AB5 if(ir.value==0xFFA25D){menu=0;cl();gr1=0;gr2=0;in_d=0;}// меню кнопка 1(ГРОМКОСТЬ) 0xFFA25D if(ir.value==0xFF629D){menu=1;cl();n1=0;n2=0;in_d=0;}// меню кнопка 2(НЧ) 0xFF629D if(ir.value==0xFFE21D){menu=2;cl();s1=0;s2=0;in_d=0;}// меню кнопка 3(СЧ) 0xFFE21D if(ir.value==0xFF22DD){menu=3;cl();v1=0;v2=0;in_d=0;}// меню кнопка 4(ВЧ) 0xFF22DD if(ir.value==0xFF02FD){menu=4;cl();b1=0;b2=0;in_d=0;}// меню кнопка 5(БАЛАНС) 0xFF02FD if(ir.value==0xFFB04F){menu=0;vol=0;cl();in_d=0;}// кнопка #(MUTE) 0xFFB04F if(ir.value==0xFF38C7){in++;;ram();in_d=1;g2();myEnc.write(0);oldPosition = -999;menu=5;w=1;time1=millis();if(in>4||in<1){in=1;}ir.value=0;}// кнопка OK(IN) 0xFF38C7 time3=millis();} // индикация громкости + управление ////////////// if(menu==0){ if(millis()-time3>100){ if(ir.value==0xFF5AA5){vol++;gr1=1;gr2=0;cl();}// кнопка > 0xFF5AA5 if(ir.value==0xFFFFFFFF and gr1==1){vol++;gr2=0;cl();}// кнопка >>>>>> if(ir.value==0xFF10EF){vol--;gr1=0;gr2=1;cl();}// кнопка < 0xFF10EF if(ir.value==0xFFFFFFFF and gr2==1){vol--;gr1=0;cl();}// кнопка <<<<<< } long newPosition = myEnc.read()/4+vol_ram; if (newPosition != oldPosition) { oldPosition = newPosition; if(millis()-time4>50){ lcd.clear();vol=newPosition; if(vol>48){vol=48;} if(vol<0){vol=0;}// 48 максимальная громкость, 0 минимум громкости lcd.setCursor(0,0);lcd.print("Volume "); lcd.print(-48+vol);lcd.setCursor(13,0);lcd.print("dB"); vol_d=vol/2; if(vol_d>=0){for(z=0;z<=vol_d;z++){lcd.setCursor(z/2,1);lcd.write((uint8_t)0);}} if(vol_d%2==0){lcd.setCursor(z/2,1);lcd.write((uint8_t)1);} lcd.setCursor(13,1);lcd.print(vol); audio();time=millis();time1=millis();w=1;w1=1; time4=millis();} }} // индикация тембр НЧ + управление кнопками ////////////// if(menu==1){ if(ir.value==0xFF5AA5){bass++;n1=1;n2=0;cl();}// кнопка > 0xFF5AA5 if(ir.value==0xFFFFFFFF and n1==1){bass++;n2=0;cl();}// кнопка >>>>>> if(ir.value==0xFF10EF){bass--;n1=0;n2=1;cl();}// кнопка < 0xFF10EF if(ir.value==0xFFFFFFFF and n2==1){bass--;n1=0;cl();}// кнопка <<<<<< long newPosition = myEnc.read()/4+bass_ram; if (newPosition != oldPosition) { oldPosition = newPosition;lcd.clear();bass=newPosition; if(bass>7){bass=7;}if(bass<-7){bass=-7;} lcd.setCursor(0,0);lcd.print("Bass "); lcd.print(bass*2);lcd.setCursor(13,0);lcd.print("dB"); for(z=-7;z<=bass;z++){lcd.setCursor(z+7,1);lcd.write((uint8_t)0);} audio();time=millis();time1=millis();w=1;w1=1; }} /////////////////////////////////////////////////////////// // индикация тембр CЧ + управление кнопками ////////////// if(menu==2){ if(ir.value==0xFF5AA5){mids++;s1=1;s2=0;cl();}// кнопка > 0xFF5AA5 if(ir.value==0xFFFFFFFF and s1==1){mids++;s2=0;cl();}// кнопка >>>>>> if(ir.value==0xFF10EF){mids--;s1=0;s2=1;cl();}// кнопка < 0xFF10EF if(ir.value==0xFFFFFFFF and s2==1){mids--;s1=0;cl();}// кнопка <<<<<< long newPosition = myEnc.read()/4+mids_ram; if (newPosition != oldPosition) { oldPosition = newPosition;lcd.clear();mids=newPosition; if(mids>7){mids=7;}if(mids<-7){mids=-7;} lcd.setCursor(0,0);lcd.print("Mids "); lcd.print(mids*2);lcd.setCursor(13,0);lcd.print("dB"); for(z=-7;z<=mids;z++){lcd.setCursor(z+7,1);lcd.write((uint8_t)0);} audio();time=millis();time1=millis();w=1;w1=1; }} /////////////////////////////////////////////////////////// // индикация тембр BЧ + управление кнопками ////////////// if(menu==3){ if(ir.value==0xFF5AA5){treb++;v1=1;v2=0;cl();}// кнопка > 0xFF5AA5 if(ir.value==0xFFFFFFFF and v1==1){treb++;v2=0;cl();}// кнопка >>>>>> if(ir.value==0xFF10EF){treb--;v1=0;v2=1;cl();}// кнопка < 0xFF10EF if(ir.value==0xFFFFFFFF and v2==1){treb--;v1=0;cl();}// кнопка <<<<<< long newPosition = myEnc.read()/4+treb_ram; if (newPosition != oldPosition) { oldPosition = newPosition;lcd.clear();treb=newPosition; if(treb>7){treb=7;}if(treb<-7){treb=-7;} lcd.setCursor(0,0);lcd.print("Trebble "); lcd.print(treb*2);lcd.setCursor(13,0);lcd.print("dB"); for(z=-7;z<=treb;z++){lcd.setCursor(z+7,1);lcd.write((uint8_t)0);} audio();time=millis();time1=millis();w=1;w1=1; }} /////////////////////////////////////////////////////////// // индикация баланс + управление кнопками +\- 4 дБ /////// if(menu==4){ if(ir.value==0xFF5AA5){balans++;b1=1;b2=0;cl();}// кнопка > 0xFF5AA5 if(ir.value==0xFFFFFFFF and b1==1){balans++;b2=0;cl();}// кнопка >>>>>> if(ir.value==0xFF10EF){balans--;b1=0;b2=1;cl();}// кнопка < 0xFF10EF if(ir.value==0xFFFFFFFF and b2==1){balans--;b1=0;cl();}// кнопка <<<<<< long newPosition = myEnc.read()/4+balans_ram; if (newPosition != oldPosition) { oldPosition = newPosition;lcd.clear();balans=newPosition; if(balans>4){balans=4;}if(balans<-4){balans=-4;} lcd.setCursor(0,0); if(balans>=0){lcd.print("-");}else{lcd.print("+");} lcd.print(abs(balans));lcd.print(" dB "); lcd.print(" <> "); if(balans>=0){lcd.print("+");}else{lcd.print("-");} lcd.print(abs(balans));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);} audio();time=millis();time1=millis();w=1;w1=1; }} ///////////////////////////////////////////////////////////// /////////// input + gain1 ///////////////////////////////////////// if(in_d==1&&in==1){ long newPosition = myEnc.read()/4+gain1_ram; if (newPosition != oldPosition) { oldPosition = newPosition;lcd.clear();gain1=newPosition; if(gain1>15){gain1=15;}if(gain1<0){gain1=0;} lcd.setCursor(0,0);lcd.print("Input: ");lcd.print(in); lcd.setCursor(0,1);lcd.print("Input Gain: ");lcd.print(gain1); g1();audio();time=millis();time1=millis();w=1;w1=1; g2(); }} //////////////////////////////////////////////////////////// /////////// input + gain2 ///////////////////////////////////////// if(in_d==1&&in==2){ long newPosition = myEnc.read()/4+gain2_ram; if (newPosition != oldPosition) { oldPosition = newPosition;lcd.clear();gain2=newPosition; if(gain2>15){gain2=15;}if(gain2<0){gain2=0;} lcd.setCursor(0,0);lcd.print("Input: ");lcd.print(in); lcd.setCursor(0,1);lcd.print("Input Gain: ");lcd.print(gain2); g1();audio();time=millis();time1=millis();w=1;w1=1; g2(); }} //////////////////////////////////////////////////////////// /////////// input + gain3 ///////////////////////////////////////// if(in_d==1&&in==3){ long newPosition = myEnc.read()/4+gain3_ram; if (newPosition != oldPosition) { oldPosition = newPosition;lcd.clear();gain3=newPosition; if(gain3>15){gain3=15;}if(gain3<0){gain3=0;} lcd.setCursor(0,0);lcd.print("Input: ");lcd.print(in); lcd.setCursor(0,1);lcd.print("Input Gain: ");lcd.print(gain3); g1();audio();time=millis();time1=millis();w=1;w1=1; g2(); }} //////////////////////////////////////////////////////////// /////////// input + gain4 ///////////////////////////////////////// if(in_d==1&&in==4){ long newPosition = myEnc.read()/4+gain4_ram; if (newPosition != oldPosition) { oldPosition = newPosition;lcd.clear();gain4=newPosition; if(gain4>15){gain4=15;}if(gain4<0){gain4=0;} lcd.setCursor(0,0);lcd.print("Input: ");lcd.print(in); lcd.setCursor(0,1);lcd.print("Input Gain: ");lcd.print(gain4); g1();audio();time=millis();time1=millis();w=1;w1=1; }} //////////////////////////////////////////////////////////// if(millis()-time>10000 && w1==1){// возврат в меню громкости через 10 сек неактивности ram();myEnc.write(0);menu=0;w1=0;in_d=0; } if(millis()-time1>60000 && w==1){// запись всех настроек в EEPROM через 60 сек неактивности EEPROM.update(0,vol); EEPROM.update(4,balans+4); EEPROM.update(1,bass+7); EEPROM.update(2,mids+7); EEPROM.update(3,treb+7); EEPROM.update(5,in); EEPROM.update(6,gain1);EEPROM.update(7,gain2);EEPROM.update(8,gain3);EEPROM.update(9,gain4);w=0; } }//void void ram(){vol_ram=vol,bass_ram=bass,mids_ram=mids,treb_ram=treb,balans_ram=balans,in_ram=in,gain1_ram=gain1;gain2_ram=gain2;gain3_ram=gain3;gain4_ram=gain4;} void g1(){if(in==1){gain=gain1;}if(in==2){gain=gain2;}if(in==3){gain=gain3;}if(in==4){gain=gain4;}} void g2(){if(in==1){gain1=gain;}if(in==2){gain2=gain;}if(in==3){gain3=gain;}if(in==4){gain4=gain;}} void cl(){ir.value=0;ram();delay(100);lcd.clear();myEnc.write(0);oldPosition = -999;} void audio(){ tda.setInput(in); // 1 to 4 // номер канала tda.inputGain(gain); // 0 to 15 // усиление tda.setVolume(vol); // 0 to 48 ( 0 is mute) // громкость tda.setSnd(bass, 1); //-7 to +7 , 1 - Bass | 2 - Mids | 3 - Trebble tda.setSnd(mids, 2); tda.setSnd(treb, 3); tda.spkAtt(4-balans, 4+balans); // баланс R L от 0 to 79 (db) }
Следующий скетч аналогичен первому, но в нем в качестве управления используется только энкодер и одна кнопка «INPUT».
TDA7439.zip — скачайте и установите измененную библиотеку для данного скетча
#include <Wire.h> #include <TDA7439.h> #include <LiquidCrystal.h> #include <EEPROMex.h> #include <Encoder.h> TDA7439 tda; Encoder myEnc(9, 8);//CLK, DT 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 vol,vol_ram,vol_d,z,bass,bass_ram,mids,mids_ram,treb,treb_ram,balans,balans_ram,in,in_ram,gain,gain1_ram,gain1,gain2,gain2_ram,gain3,gain3_ram,gain4,gain4_ram; byte menu,w,w1,in_d; unsigned long time,time1;long oldPosition = -999; void setup() { Serial.begin(9600); Serial.print("TDA7439"); lcd.begin(16, 2); lcd.setCursor(0,0);lcd.print(" TDA7439 ");delay(1000); pinMode(12,INPUT);// меню кнопка энкодера SW pinMode(11,INPUT);// in 1-4 lcd.createChar(0,a1); lcd.createChar(1,a2); vol = EEPROM.read(0);// vol eeprom bass = EEPROM.read(1)-7;// bass eeprom mids = EEPROM.read(2)-7;// mids eeprom treb = EEPROM.read(3)-7;// treb eeprom balans = EEPROM.read(4)-4;// balans eeprom in = EEPROM.read(5);// in eeprom gain1 = EEPROM.read(6);// gain1 eeprom gain2 = EEPROM.read(7);// gain2 eeprom gain3 = EEPROM.read(8);// gain3 eeprom gain4 = EEPROM.read(9);// gain4 eeprom g1();audio();ram(); } void loop() { if(digitalRead(12)==LOW){menu++;ram();in_d=0;myEnc.write(0);oldPosition = -999;delay(300);time1=millis();w=1;if(menu>4){menu=0;}}// меню if(digitalRead(11)==HIGH){in++;;ram();in_d=1;g2();myEnc.write(0);oldPosition = -999;menu=5;w=1;delay(300);time1=millis();if(in>4||in<1){in=1;}}// in // индикация громкости + управление ////////////// if(menu==0){ long newPosition = myEnc.read()/4+vol_ram; if (newPosition != oldPosition) { oldPosition = newPosition;lcd.clear();vol=newPosition; if(vol>48){vol=48;} if(vol<0){vol=0;}// 48 максимальная громкость, 0 минимум громкости lcd.setCursor(0,0);lcd.print("Volume "); lcd.print(-48+vol);lcd.setCursor(13,0);lcd.print("dB"); vol_d=vol/2; if(vol_d>=0){for(z=0;z<=vol_d;z++){lcd.setCursor(z/2,1);lcd.write((uint8_t)0);}} if(vol_d%2==0){lcd.setCursor(z/2,1);lcd.write((uint8_t)1);} lcd.setCursor(13,1);lcd.print(vol); audio();time=millis();time1=millis();w=1;w1=1; }} // индикация тембр НЧ + управление кнопками ////////////// if(menu==1){ long newPosition = myEnc.read()/4+bass_ram; if (newPosition != oldPosition) { oldPosition = newPosition;lcd.clear();bass=newPosition; if(bass>7){bass=7;}if(bass<-7){bass=-7;} lcd.setCursor(0,0);lcd.print("Bass "); lcd.print(bass*2);lcd.setCursor(13,0);lcd.print("dB"); for(z=-7;z<=bass;z++){lcd.setCursor(z+7,1);lcd.write((uint8_t)0);} audio();time=millis();time1=millis();w=1;w1=1; }} /////////////////////////////////////////////////////////// // индикация тембр CЧ + управление кнопками ////////////// if(menu==2){ long newPosition = myEnc.read()/4+mids_ram; if (newPosition != oldPosition) { oldPosition = newPosition;lcd.clear();mids=newPosition; if(mids>7){mids=7;}if(mids<-7){mids=-7;} lcd.setCursor(0,0);lcd.print("Mids "); lcd.print(mids*2);lcd.setCursor(13,0);lcd.print("dB"); for(z=-7;z<=mids;z++){lcd.setCursor(z+7,1);lcd.write((uint8_t)0);} audio();time=millis();time1=millis();w=1;w1=1; }} /////////////////////////////////////////////////////////// // индикация тембр BЧ + управление кнопками ////////////// if(menu==3){ long newPosition = myEnc.read()/4+treb_ram; if (newPosition != oldPosition) { oldPosition = newPosition;lcd.clear();treb=newPosition; if(treb>7){treb=7;}if(treb<-7){treb=-7;} lcd.setCursor(0,0);lcd.print("Trebble "); lcd.print(treb*2);lcd.setCursor(13,0);lcd.print("dB"); for(z=-7;z<=treb;z++){lcd.setCursor(z+7,1);lcd.write((uint8_t)0);} audio();time=millis();time1=millis();w=1;w1=1; }} /////////////////////////////////////////////////////////// // индикация баланс + управление кнопками +\- 4 дБ /////// if(menu==4){ long newPosition = myEnc.read()/4+balans_ram; if (newPosition != oldPosition) { oldPosition = newPosition;lcd.clear();balans=newPosition; if(balans>4){balans=4;}if(balans<-4){balans=-4;} lcd.setCursor(0,0); if(balans>=0){lcd.print("-");}else{lcd.print("+");} lcd.print(abs(balans));lcd.print(" dB "); lcd.print(" <> "); if(balans>=0){lcd.print("+");}else{lcd.print("-");} lcd.print(abs(balans));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);} audio();time=millis();time1=millis();w=1;w1=1; }} ///////////////////////////////////////////////////////////// /////////// input + gain1 ///////////////////////////////////////// if(in_d==1&&in==1){ long newPosition = myEnc.read()/4+gain1_ram; if (newPosition != oldPosition) { oldPosition = newPosition;lcd.clear();gain1=newPosition; if(gain1>15){gain1=15;}if(gain1<0){gain1=0;} lcd.setCursor(0,0);lcd.print("Input: ");lcd.print(in); lcd.setCursor(0,1);lcd.print("Input Gain: ");lcd.print(gain1); g1();audio();time=millis();time1=millis();w=1;w1=1; g2(); }} //////////////////////////////////////////////////////////// /////////// input + gain2 ///////////////////////////////////////// if(in_d==1&&in==2){ long newPosition = myEnc.read()/4+gain2_ram; if (newPosition != oldPosition) { oldPosition = newPosition;lcd.clear();gain2=newPosition; if(gain2>15){gain2=15;}if(gain2<0){gain2=0;} lcd.setCursor(0,0);lcd.print("Input: ");lcd.print(in); lcd.setCursor(0,1);lcd.print("Input Gain: ");lcd.print(gain2); g1();audio();time=millis();time1=millis();w=1;w1=1; g2(); }} //////////////////////////////////////////////////////////// /////////// input + gain3 ///////////////////////////////////////// if(in_d==1&&in==3){ long newPosition = myEnc.read()/4+gain3_ram; if (newPosition != oldPosition) { oldPosition = newPosition;lcd.clear();gain3=newPosition; if(gain3>15){gain3=15;}if(gain3<0){gain3=0;} lcd.setCursor(0,0);lcd.print("Input: ");lcd.print(in); lcd.setCursor(0,1);lcd.print("Input Gain: ");lcd.print(gain3); g1();audio();time=millis();time1=millis();w=1;w1=1; g2(); }} //////////////////////////////////////////////////////////// /////////// input + gain4 ///////////////////////////////////////// if(in_d==1&&in==4){ long newPosition = myEnc.read()/4+gain4_ram; if (newPosition != oldPosition) { oldPosition = newPosition;lcd.clear();gain4=newPosition; if(gain4>15){gain4=15;}if(gain4<0){gain4=0;} lcd.setCursor(0,0);lcd.print("Input: ");lcd.print(in); lcd.setCursor(0,1);lcd.print("Input Gain: ");lcd.print(gain4); g1();audio();time=millis();time1=millis();w=1;w1=1; }} //////////////////////////////////////////////////////////// if(millis()-time>10000 && w1==1){// возврат в меню громкости через 10 сек неактивности ram();myEnc.write(0);menu=0;w1=0;in_d=0; } if(millis()-time1>60000 && w==1){// запись всех настроек в EEPROM через 60 сек неактивности EEPROM.update(0,vol_ram); EEPROM.update(4,balans+4); EEPROM.update(1,bass+7); EEPROM.update(2,mids+7); EEPROM.update(3,treb+7); EEPROM.update(5,in); EEPROM.update(6,gain1);EEPROM.update(7,gain2);EEPROM.update(8,gain3);EEPROM.update(9,gain4);w=0; } }//void void ram(){vol_ram=vol,bass_ram=bass,mids_ram=mids,treb_ram=treb,balans_ram=balans,in_ram=in,gain1_ram=gain1;gain2_ram=gain2;gain3_ram=gain3;gain4_ram=gain4;} void g1(){if(in==1){gain=gain1;}if(in==2){gain=gain2;}if(in==3){gain=gain3;}if(in==4){gain=gain4;}} void g2(){if(in==1){gain1=gain;}if(in==2){gain2=gain;}if(in==3){gain3=gain;}if(in==4){gain4=gain;}} void audio(){ tda.setInput(in); // 1 to 4 // номер канала tda.inputGain(gain); // 0 to 15 // усиление tda.setVolume(vol); // 0 to 48 ( 0 is mute) // громкость tda.setSnd(bass, 1); //-7 to +7 , 1 - Bass | 2 - Mids | 3 - Trebble tda.setSnd(mids, 2); tda.setSnd(treb, 3); tda.spkAtt(4-balans, 4+balans); // баланс R L от 0 to 79 (db) }
Форумы:
Обновленный скетч TDA7439_01.zip
Улучшена работа энкодера, изменено графическое исполнение шкал регулировок, добавлен ИК пульт (прокрутка меню и кнопки <>), при нажатии кнопки IN можно регулировать усиление каждого входа, для выхода из режима IN нужно подождать 5 сек.
Скетч протестирован!!!
Для нормальной работы скетча необходимо скачать дополнительные библиотеку:
IRremote.zip — библиотека изменена
Дополнительные файлы:
- 7439.lay6.zip
- Фото (автор: Анатолий Постоленко)
Dear Liman 28,
I am Tarunesh here, i am a new to a arduino programming, I compiled the above given code but it shows so many errors for example g1 is not declared.
The site has auto-translation of text, often the sketch is distorted, in the language menu, select Russian to copy the sketch without distortion.
Yes definitely its working now thank you thank you very much Mr.Liman.
One more favour i need in this Аудиопроцессор R2S15902FP (Arduino), can you please implement it with ir remote.
http://forum.rcl-radio.ru/viewtopic.php?pid=669#p669
Thank u Mr. Liman,
Is there any way to introduce usb MP3,Bluetooth and FM in TDA7439+LCD+SPECTRUM ANALYZER.
I AM USING TDA WITH small mp3 BT module(chines).I am sending you the code and pics for your knowledge. Here the problem is I have to use infrared led to transmit the signals is there any way to remove the IR reciever of module and connect 3 wires directly from Arduino to the module.
#include
#include
#include
#include
#include
#include
//…………………………….custom remote………………………………………..//
#define bassup 0x807F30CF
#define bassdown 0x807FB04F
#define tup 0x807F08F7
#define tdown 0x807F8877
#define midup 0x807F28D7
#define middown 0x807FA857
#define vup 0x807F32CD
#define vdown 0x807F52AD
const long interval = 1000; // eprom update time
const long intervalscreen = 5000; //screen delay
unsigned long previousMillis = 0;
unsigned long previoustime ;
unsigned long currenttime ;
//…………………………………………………………………………………………….//
unsigned long lastCode;
#define CLK 10 //LCD clock pin
#define DIO 9 //LCD data pin
int RECV_PIN = 5; // ir reciver
int statelcd=0;
//…………………………..object ………………………………..//
IRrecv irrecv(RECV_PIN);
decode_results results;
IRsend irsend;
TDA7439 tda;
TM1637Display display(CLK, DIO);
//………………………..lcd char segment varable………………….//
const uint8_t a1[] = {SEG_F | SEG_G | SEG_E | SEG_C | SEG_D }; //base
const uint8_t a2[] = { SEG_F| SEG_E | SEG_D| SEG_G}; //treble
const uint8_t a3[] = { SEG_A | SEG_F | SEG_E | SEG_D};//mid
//…………………….default setting varable …………………………..//
int b=7;
int t=7;
int m=7;
int v=48;
int i=1;
int g=0;
//………………….read varable for eprom………………………..//
int b1;
int t1;
int m1;
int v1;
int i1;
int g1;
//………………….setting address varable eeprom………………….//
int address0= 300;
int address1= 301;
int address2= 302;
int address3 =303;
int address4 =304;
int address5 =305;
//………………………….epron check time…………………………….//
void setup()
{
Wire.begin();
Serial. begin (9600);
defaultscreen();
readsetting();
delay(10);
//tda. setInput (1) ;
defaulttda();
delay(10);
screen (a1, b);
defaulttda();
delay(10);
irrecv.enableIRIn();
}
void loop() {
if (irrecv.decode(&results))
{
// Serial.println(results.value, HEX);
translateIR();
irrecv.resume(); // Receive the next value
}
currenttime =millis();
if(statelcd==1)
{if (currenttime — previoustime >= intervalscreen)
{ statelcd=0;
defaultscreen();
}
}
unsigned long currentMillis = millis();
if (currentMillis — previousMillis >= interval) {
previousMillis = currentMillis;
if(b1!=b ){ EEPROM.write(address0,b); b1=b;}
if(t1!=t ){ EEPROM.write(address1,t); t1=t;}
if(m1!=m ){ EEPROM.write(address2,m); m1=m;}
if(v1!=v ){ EEPROM.write(address3,v); v1=v;}
if(i1!=i ){ EEPROM.write(address4,i); i1=i;}
if(g1!=g ){ EEPROM.write(address5,g); g1=g;}
}
}
//…………………………………………………………………//
void defaultscreen()
{
display.setBrightness(0x0f);
display.clear();
}
//…………………………………………………………………//
void defaulttda()
{//Serial.println(«okk»);
tda. setInput(i) ; // 1 to 4 // channel number
tda. inputGain(g) ; // 0 to 15 // gain
tda. setVolume (v) ; // 0 to 48 (0 is mute) // loudness
tda. setSnd(b-7,3) ; // — 7 to +7, 1 — Bass | 2 — Mids | 3 — Trebble
tda. setSnd(m-7,2) ; //| 2 — Mids |
tda. setSnd (t-7,1) ; //3 — Trebble
tda. spkAtt (0,0) ; // R-L balance from 0 to 79 (db)
}
//…………………………………………………………………//
void screen (uint8_t ra[], int x)
{
display.setSegments(ra,true);
display.showNumberDec(x, true, 2, 2);
statelcd=1;
previoustime = currenttime;
}
//…………………………………………………………………//
void tdachange(){
Serial. println ( «TDA7439» ) ;
tda. setInput (i) ; // 1 to 4 // channel number
tda. inputGain (g) ; // 0 to 15 // gain
tda. setVolume (m) ; // 0 to 48 (0 is mute) // loudness
tda. setSnd (b-7, 1 ) ; // 1 — Bass -7 to +7
tda. setSnd (m-7, 2 ) ; //2 — Mids -7 to +7
tda. setSnd (t-7, 3 ) ; //3 — Trebble -7 to +7
tda. spkAtt ( 0,0 ) ; // R-L balance from 0 to 79 (db)
}
//=============================================================================//
void translateIR() //………………………………………………..// takes action based on IR code received
{
if(results.value == 0xFFFFFFFF){ results.value = lastCode; }
Serial.println(results.value, HEX);
if(results.value == bassup ) { if(b=0) {if (b!=0) b—; screen ( a1, b); tda. setSnd (b-7, 1 ) ; }} //change bass down
if(results.value == tup ) { if(t=0) {if (t!=0) t—; screen ( a2, t); tda. setSnd (t-7, 3 ) ; }} //change terable down
if(results.value == midup ) { if(m=0) {if (m!=0) m—; screen ( a3, m); tda. setSnd (m-7, 2 ) ; }} //change midd down
// if(results.value == vup ) { if(v=0) {if (v!=0) v—; tda. setVolume(v); }} //change vol up
// delay(100);
remote();
irrecv.enableIRIn();
lastCode=results.value;
} //………………………………………………………………………………………………………………..//
void remote()
{
int ch=results.value;
//if(ch==0x807FBA45){irsend.sendNEC(0x1FE48B7, 32); Serial.println(«okk»); }
switch(ch)
{
case 0x807FBA45 : irsend.sendNEC(0x1FE48B7, 32); break; //power on/off
case 0x807F32CD : irsend.sendNEC(0x1FE609F, 32); break; //volume up
case 0x807F52AD : irsend.sendNEC(0x1FEA05F, 32); break; //volume down
case 0x807F7A85 : irsend.sendNEC(0x1FE10EF, 32); break; //repeat
case 0x807F6897 : irsend.sendNEC(0x1FE906F, 32); break; //USB/SD
case 0x807F926D : irsend.sendNEC(0x1FE40BF, 32); break; //previous channel
case 0x807FD22D : irsend.sendNEC(0x1FEC03F, 32); break; //next channel
case 0x807F3AC5 : irsend.sendNEC(0x1FE58A7, 32); break; //mode
case 0x807F9A65 : irsend.sendNEC(0x1FE50AF, 32); break; //1
case 0x807F1AE5 : irsend.sendNEC(0x1FED827, 32); break; //2
case 0x807F5AA5 : irsend.sendNEC(0x1FEF807, 32); break; //3
case 0x807FDA25 : irsend.sendNEC(0x1FE30CF, 32); break; //4
case 0x807FAA55 : irsend.sendNEC(0x1FEB04F, 32); break; //5
case 0x807F2AD5 : irsend.sendNEC(0x1FE708F, 32); break; //6
case 0x807F6A95 : irsend.sendNEC(0x1FE00FF, 32); break; //7
case 0x807FEA15 : irsend.sendNEC(0x1FEF00F, 32); break; //8
case 0x807F8A75 : irsend.sendNEC(0x1FE9867, 32); break; //9
case 0x807F0AF5 : irsend.sendNEC(0x1FEE01F, 32); break; //0
case 0x807FCA35 : irsend.sendNEC(0x1FE20DF, 32); break; //equaliser
case 0x807F12ED : irsend.sendNEC(0x1FE807F, 32); break; //pause/play
case 0x807FFA05 : irsend.sendNEC(0x1FE7887, 32); break; //mute
}
}
void readsetting()
{
b1=EEPROM.read(address0); // read bass setting
t1=EEPROM.read(address1); // read trable setting
m1=EEPROM.read(address2); // read mid setting
v1=EEPROM.read(address3); // read volume setting
i1=EEPROM.read(address4); // read input setting
g1=EEPROM.read(address5); // read gain setting
if(b1>=0 && b1 =0 && t1 =0 && m1 =0 && v1 =0 && i1 =0 && g1 <=15){g=g1;}
}
void displaysitting()
{
Serial. print("base value -7 to +7 is "); Serial. println(b) ;
Serial. print("treble value -7 to +7 is "); Serial. println(t) ;
Serial. print("mid value -7 to +7 is "); Serial. println(m) ;
Serial. print("vol value 0 to 48 is "); Serial. println(v) ;
Serial. print("channal is "); Serial. println(i) ;
Serial. print("gain is "); Serial. println(g) ;
}
#include
#include
#include
#include
#include
#include
In below code.
Mr. Liman can you please mail me on tarunesh1119@gmail.com.
I MEAN TO SAY LIKE THIS
https://diyremotekit.blogspot.com/2017/08/diy-r2s15902fp-based-51-remote-kit.html
IMAGE GIVEN BELOW
sO THAT ARDUINO CANT CONTROL THIS MODULE USING ANY REMOTE
I can’t help You, I don’t know this MP3 module. I only support my projects. Moreover, I don’t know English, I can’t understand even half of what You wrote, machine translation is not accurate.
If i attach mp3 usb BT module, to your project tda7439 ir ,than i have to use 2 remotes, one for your project and one for controlling the USB MP3 BT module, so I have send a program, that
uses a single remote for controlling both the devices, but only the problem is to send the data, arduino uses ir LED. can we use wire instead of ir led which comes from arduino pin and attach directly to IR receiver of the usb mp3 BT module.
connect via a 4.7 kOhm resistor
Than it will convert modulate signals to demodulate signals so that microcontroller can read.
will you please tell me Which is your correct tested sketch having TDA7439+IR+encoder+Spectrum function.
ande what i have to connect with A1 power,standby D12
YES I GOT IT only the problem is if i add chines mp3 usb Bluetooth module than i have to use two separate remotes one foe TDA7439 and one for the mp3 usb Bluetooth module. is there any way to operate both the device with single remote.
Apply a signal from the linear output to input A0 through a 0.1 μF blocking capacitor.
i did not understand this can you elaborate it.
send a signal to input A0 via a 0.1 UF capacitor
means i have to attach the capacitor to A0 and push button D11
ok i got it its audio signal
http://forum.rcl-radio.ru/viewtopic.php?id=60
I AM USING THIS SKETCH the tested one at the last of the web page
«Re: TDA7439 + encoder + IR remote + STANDBY + spectrum analyzer
Added input preamp function
Tested»
in want a small change in it for bass,treble and middle function.
if i press Bass+/- button of remote, it directly dispaly the bass*/- function instead
of entering through menu
same like that with treble,middle only.
by default volume+/- is working directly.
TDA7439 + encoder + IR remote + STANDBY + spectrum analyzer
Added input preamp function
Tested»
http://forum.rcl-radio.ru/viewtopic.php?id=60
can we operate bass treble middle directly from the remote by pressing Bass+,Bass-,treble+,Tereble- button without selecting from menu option
Yes, it can be done. I will try to add these buttons.
I think,changes require only in menu option because volume is working directly when I press vol. Up and down button of remote. Bass treble and middle is not working directly.
http://forum.rcl-radio.ru/viewtopic.php?pid=1898#p1898
specify the code buttons for your IR remote control
#define IR_1 0x2FDD02F // меню кнопка вверх
#define IR_2 0x2FD32CD // меню кнопка вниз
#define IR_3 0x2FD906F // кнопка >
#define IR_4 0x2FDF20D // кнопка < #define IR_5 0x2F00000 // BASS++ #define IR_6 0x2F00001 // BASS-- #define IR_7 0x2F00002 // TREBLE++ #define IR_8 0x2F00003 // TREBLE-- #define IR_9 0x2F00004 // MIDDLE++ #define IR_10 0x2F00005 // MIDDLE--
Thank you Mr.Liman. It is working now but with following errors in all bass treble and middle. and some times remote functions get conflict. means up and down functions work oppositely
like this also
Update the sketch, I made corrections — http://forum.rcl-radio.ru/viewtopic.php?pid=1898#p1898
I didn’t test on the Board, You will have to test, there may be errors in the code.
#define IR_1 0x2FDD02F // меню кнопка вверх
#define IR_2 0x2FD32CD // меню кнопка вниз
replace
#define IR_2 0x2FDD02F // меню кнопка вверх
#define IR_1 0x2FD32CD // меню кнопка вниз
If bass,Treble and middle functions works directly by pressing the buttons bass up/down,treble up/down and middle up/down than there is no use of menu function from remote, that’s why i didn’t assign any IR value of menu option.
#define IR_1 0x2FDD02F // меню кнопка вверх
#define IR_2 0x2FD32CD // меню кнопка вниз
no use of these values.
i think all these functions require a gap of milliseconds.
ok i will try and let you know.
i have made some changes
if(ir.value==IR_3&&menu!=0){vol++;menu=0;gr1=1;gr2=0;cl1();w2=1;if(vol48){vol=48;}audio();}// кнопка >
if(ir.value==IR_4&&menu!=0){vol—;menu=0;gr1=0;gr2=1;cl1();w2=1;if(vol48){vol=48;}audio();}// кнопка 7){bass=7;}if(bass
if(ir.value==IR_6){bass—;gr1=0;gr2=1;cl1();w2=1;if(bass>7){bass=7;}if(bass<-7){bass=-7;}audio();}// кнопка <
\\ remains as it is for treble and middle
now its working and thank you Mr. Liman