Аудиопроцессор TDA7468D на Arduino

На аудиопроцессоре TDA7468 совместно с Arduino можно собрать высоко качественный регулятор тембра и громкости. Аудипроцессор имеет 4 стерео входа и один стерео выход.

Аудиопроцессор имеет следующие характеристики:

  • Напряжение питания 5…10 В (9 В рекомендуемое)
  • КНИ не более 0.01%
  • Отношение сигнал.шум 100 дБ
  • Разделение каналов 90 дБ
  • Ток потребления  9 мА
  • Регулировка громкости от -62 до 0 дБ с шагом 1 дБ (ограничено программно)
  • Регулировка тембра -14…+14 дБ с шагом 2 дБ
  • Раздельный предусилитель для каждого входа 0…14 дБ с шагом 2 дБ
  • Регулировка баланса ±4 дБ

Регулировка основных параметров осуществляется при помощи энкодера KY-040, переключение входов осуществляется отдельной кнопкой подключенной к цифровому входу Arduino D12. Информация о соcтоянии основных параметров выводится на LCD дисплея LCD1602 на базе контроллера HD44780.

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

Плата Пин SDA Пин SCL
Arduino Uno, Nano, Pro и Pro Mini A4 A5

Все параметры заносятся в энергонезависимую память.

Библиотека TDA7468.zip или https://github.com/liman324/TDA7468.git

Дополнительные библиотеки Encoder MsTimer2

#include <Wire.h>
#include <TDA7468.h>
#include <MsTimer2.h>
#include <LiquidCrystal.h>
#include <Encoder.h>
#include <EEPROM.h>
  TDA7468 tda;
  Encoder myEnc(9, 8);//CLK, DT подключение энкодера
  LiquidCrystal lcd(7, 6, 2, 3, 4, 5);// RS,E,D4,D5,D6,D7 подключение LCD
   byte a1[8]={0b00000,0b11011,0b11011,0b11011,0b11011,0b11011,0b11011,0b00000};
  byte a2[8]={0b00000,0b11000,0b11000,0b11000,0b11000,0b11000,0b11000,0b00000};
   unsigned long newPosition,time,oldPosition  = -999;
   int vol,vol_d,menu,w1,z,mute=1,treb,treble_d,bass,bass_d,in,gain,gain1,gain2,gain3,gain4,balans;
 
void setup(){ 
  Serial.begin(9600);Wire.begin();
   lcd.begin(16, 2);lcd.createChar(0,a1); lcd.createChar(1,a2);
   pinMode(A0,INPUT);// КНОПКА ЭНКОДЕРA
   pinMode(12,INPUT);// IN 
     MsTimer2::set(1, to_Timer);MsTimer2::start();
     vol = EEPROM.read(0);treb = EEPROM.read(1)-7;bass = EEPROM.read(2)-7;in = EEPROM.read(3);
     gain1 = EEPROM.read(4);gain2 = EEPROM.read(5);gain3 = EEPROM.read(6);gain4 = EEPROM.read(7);
     balans = EEPROM.read(8)-4;
   audio();
}
 
void to_Timer(){ //функция таймера
 newPosition = myEnc.read()/4;}
 
 
void loop(){
   if((analogRead(A0)<900)){menu++;cl();myEnc.write(0);time=millis();w1=1;if(menu>4){menu=0;}}// меню
   if(digitalRead(12)==HIGH){in++;if(in>3){in=0;}audio();lcd.clear();lcd.print("IN ");lcd.print(in+1);delay(1000);}
  //////////////////////////////////////// Volume -62 ... 0 дБ //////////////////////////////////////
 if(menu==0){
    if (newPosition != oldPosition) {
    oldPosition = newPosition;
    vol=vol+newPosition;myEnc.write(0);newPosition=0;audio();lcd.clear();time=millis();w1=1;if(vol>62){vol=62;}if(vol<1){vol=1;}}
 
  lcd.setCursor(0,0);if(mute==1){lcd.print("Volume   ");}else{lcd.print("MUTE     ");}
  lcd.print(-62+vol);lcd.setCursor(13,0);lcd.print("dB");vol_d=vol/3;
   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);}
//////////////////////////////////////////////////////////////////////////////////////////////////////
  /////////////////////// индикация тембр ВЧ -14...14 дБ ///////////////////
   if(menu==1){
     if (newPosition != oldPosition) {
    oldPosition = newPosition;
    treb=treb+newPosition;myEnc.write(0);newPosition=0;audio();lcd.clear();time=millis();w1=1;if(treb>7){treb=7;}if(treb<-7){treb=-7;}} 
 
  lcd.setCursor(0,0);lcd.print("Treble   ");
  lcd.print(treb*2);lcd.setCursor(13,0);lcd.print("dB");treble_d=treb+7;
   if(treble_d>=0){for(z=0;z<=treble_d;z++){lcd.setCursor(z,1);lcd.write((uint8_t)0);}}
 }
/////////////////////////////////////////////////////////////////////////////////////
 
  /////////////////////// индикация тембр НЧ -14...14 дБ ///////////////////
   if(menu==2){
     if (newPosition != oldPosition) {
    oldPosition = newPosition;
    bass=bass+newPosition;myEnc.write(0);newPosition=0;audio();lcd.clear();time=millis();w1=1;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");bass_d=bass+7;
   if(bass_d>=0){for(z=0;z<=bass_d;z++){lcd.setCursor(z,1);lcd.write((uint8_t)0);}}
 }
/////////////////////////////////////////////////////////////////////////////////////
  // индикация баланс + управление кнопками +\- 4 дБ ///////
   if(menu==3){
     if (newPosition != oldPosition) {
    oldPosition = newPosition;
    balans=balans+newPosition;myEnc.write(0);newPosition=0;audio();lcd.clear();time=millis();w1=1;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("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);}
 }
 /////////////////////////////////////////////////////////////
  /////////////////////// gain  ///////////////////
   if(menu==4){
      if(in==0){gain=gain1;}
      if(in==1){gain=gain2;}
      if(in==2){gain=gain3;}
      if(in==3){gain=gain4;}
    if (newPosition != oldPosition) {
    oldPosition = newPosition;
    gain=gain+newPosition;myEnc.write(0);newPosition=0;audio();lcd.clear();time=millis();w1=1;if(gain>7){gain=7;}if(gain<0){gain=0;}
} 
      if(in==0){gain1=gain;}
      if(in==1){gain2=gain;}
      if(in==2){gain3=gain;}
      if(in==3){gain4=gain;}
  lcd.setCursor(0,0);lcd.print("IN ");lcd.print(in+1);lcd.print(" Gain ");lcd.print(gain*2);lcd.print(" dB");
 }
/////////////////////////////////////////////////////////////////////////////////////
 
 if(millis()-time>10000 && w1==1){
     EEPROM.update(0,vol);
     EEPROM.update(2,bass+7);
     EEPROM.update(1,treb+7);
     EEPROM.update(3,in);
     EEPROM.update(4,gain1);EEPROM.update(5,gain2);EEPROM.update(6,gain3);EEPROM.update(7,gain4);
     EEPROM.update(8,balans+4);
  menu=0;w1=0;cl();
 }
}//loop
 void cl(){delay(300);lcd.clear();}
void audio(){
  tda.setInput(in); 
  tda.setGain(gain);
  tda.setSurround(1,0,3,1);// не менять
  tda.setVol_R(vol+balans+4);
  tda.setVol_L(vol-balans+4);  
  tda.setTreb_Bass(treb,bass); 
  tda.setOutput(1); // mute не менять  
  tda.setAlc(0,0,0,0,0,0); // не менять 
}


Тестирование TDA7468 + энкодер + ИК пульт + анализатор спектра — http://forum.rcl-radio.ru/viewtopic.php?id=42

TDA7468 — обновленная библиотека (полный функционал) — http://forum.rcl-radio.ru/viewtopic.php?id=238

Comments

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

  2. Спасибо за быстрый ответ! Первое, что сделал поменял sda и scl, попробовал подключить к одноименным контактам на Ардуино (у меня китайская псевдоуно) там такие есть. И на аналоговых портах менял. Сама шина рабочая, с часов на 3231 данные получаю. TDA7468 собрал на макетке. На фото. Монтаж несколько раз проверил, подаю ровно 9в. Сразу после загрузки несколько команд с энкодера проходит и скетч останавливается. Как проверить шину на самой микросхеме (может есть тестовый скетч с выводом на ком порт? Может есть стандартные электрические параметры, чтоб тестером прозвонить? В какую сторону копать?
    С энкодером Вы правы, перекинул и всё правильно работает.

  3. Если коротко, то ошибка была в отсутствии общей земли…
    Если длинно, то я даже 2 ардуины пока Ваш комментарий не прочёл, успел поменять (параллельно выяснив, что одна из них «из пакетика» мёртворождённая):-)) Запитать планировал от разных источников, хотя в одном из Ваших проектов видел решение с двумя понижайками от одного источника, а в звуковую часть таким макаром ничего не лезет?
    По сути: не смотря на свою древность микруха вполне себе годная, через RMAA конечно не успел прогнать, но на слух, я от такого динозавра, да ещё с однополярным питанием не ожидал более чем адекватного звука… Единственный косячок — при регулировке ВЧ один канал поднимает\опускает ВЧ больше другого, похоже одна из СВВ плёнок в цепи коррекции под замену, по низам такой проблемы нет. Ну и 0.47 на входах маловато, поменяю на 105J.
    Относительно скетча: при предварительном изучении не обратил внимания, что нет записи в память значений баланса, в принципе не критично. Не совсем понял зачем нужна delay(300) в блоке cl()? Хочу прикрутить VS1838B (благо в Вашей статье про TDA7439 это дело реализовано). Хочу добавить ещё один экран menu вместо menu=0 на более информативное с часами, номером входа, уровнем громкости, может температуру на радиаторе УНЧ выведу. Хоть я и старый радиолюбитель, но на ардуино это только мой третий проект, поэтому вопрос: на сколько удобно и корректно обращаться к Вам по вопросам модификации Ваших скетчей? Не думаю, что вопросов будет много, (интересно самому разобраться), но на всякий случай…
    За оперативную помощь огромное спасибо, если честно — приятно удивлён!

  4. Здравствуйте Уважаемый ГУРУ liman28! У меня такой вопрос: можно ли с TDA7468 взять сигнал постоянной амплитуды для управления анализатором уровня? Что за выходы MIX L и MIX R у аудиопроцесора? Заранее вам благодарен за ответ!

  5. Вы уверены? Согласно схемам применения в европейских музыкальных центрах, это выходы. Иногда даже указывают, что линейные. Поэтому у вас и интересуюсь. Проверьте пожалуйста.

  6. Здравствуйте, может сможете помочь, собирал по схеме из даташита и схема завелась, но есть проблема, что микроузел выдаёт очень тихий звук на максимуме, хотя звук и на ее и на микросхеме на максимум, помогите пожалуйста.

          1. Да, регулировка работает, басы и все остальное, запускал ваш тестовый скетч, может я чего-то не понимаю, сигнал с ПК уходит на вход TDA7468, а далее на усилитель tda7498e. Звук становится слышимым только на максимальных настройках. А в схеме нету предусилителя или чего-то иного. Извините меня за моё невежество.

            1. Коэффициент усиления аудиопроцессора около 1 на уровне 0 дБ, такая проблема мне ранее не встречалась.
              Если напрямую сигнал с ПК подать на усилитель, звук громкий?

  7. Подскажите пожалуйста, как боротся с напряжением на выходе, по даташиту 4.5V, измерит и там 4.55V, при этом пытался ставить конденсаторы как полярные так и не полярные, появилась другая проблема в виде хлопков при включении и выключении.

    1. В setup() перед audio() попробуйте поставить строку
      tda.setOutput(0);
      delay(1000);
      tda.setOutput(1);

      Это активация режима MUTE при включении, может поможет от хлопка.

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

      1. В момент одновременного включения как усилителя так и tda это не сильно помогает, после конденсатора разделительного пики при включении доходят до 1В, после выключения соответственно -1В, Пробовал ставить резисторы не очень помогает, у меня усилитель с 100% чувствительностью на входе, и хотелось бы избавится именно от пиков при ключении. Какие есть методы, может вы знаете?

        1. Можно поставить реле которое замыкает сигнальные цепи на землю в течении 2 секунд после подачи питания (при отсутствии питания реле замыкает сигнальные цепи). После 2 сек ардуино дает команду разомкнуть контакты реле.

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