Аудиопроцессор 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. При подключении микросхемы скетч виснет (перестаёт принимать команды с энкодера и кнопки), сам по себе скетч работает нормально если не считать, что энкодер при вращении по часовой стрелке уменьшает значения. Вы проверяли скетч на реальной микросхеме?

    1. Все скетчи я проверяю на реальных микросхемах, так как приходится еще к ним и библиотеки писать. Проверьте шину i2c может перепутаны контакты. Энкодеры бывают инверсные, просто поменяйте выводы clk dt местами

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

    1. Проверьте через тестовый скетч, просто загрузите и должен быть звук. Можно даже поменять параметры, громкость, тембр, вход. Если звук есть и все регулируется, то с микросхемой и шиной i2c все в порядке.
      Тестовый скетч — https://github.com/liman324/TDA7468/blob/master/test.ino

  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 сек ардуино дает команду разомкнуть контакты реле.

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

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