На аудиопроцессоре 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
#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
При подключении микросхемы скетч виснет (перестаёт принимать команды с энкодера и кнопки), сам по себе скетч работает нормально если не считать, что энкодер при вращении по часовой стрелке уменьшает значения. Вы проверяли скетч на реальной микросхеме?
Все скетчи я проверяю на реальных микросхемах, так как приходится еще к ним и библиотеки писать. Проверьте шину i2c может перепутаны контакты. Энкодеры бывают инверсные, просто поменяйте выводы clk dt местами
Тестовый скетч — https://github.com/liman324/TDA7468/blob/master/test.ino
Спасибо за быстрый ответ! Первое, что сделал поменял sda и scl, попробовал подключить к одноименным контактам на Ардуино (у меня китайская псевдоуно) там такие есть. И на аналоговых портах менял. Сама шина рабочая, с часов на 3231 данные получаю. TDA7468 собрал на макетке. На фото. Монтаж несколько раз проверил, подаю ровно 9в. Сразу после загрузки несколько команд с энкодера проходит и скетч останавливается. Как проверить шину на самой микросхеме (может есть тестовый скетч с выводом на ком порт? Может есть стандартные электрические параметры, чтоб тестером прозвонить? В какую сторону копать?
С энкодером Вы правы, перекинул и всё правильно работает.
Проверьте через тестовый скетч, просто загрузите и должен быть звук. Можно даже поменять параметры, громкость, тембр, вход. Если звук есть и все регулируется, то с микросхемой и шиной i2c все в порядке.
Тестовый скетч — https://github.com/liman324/TDA7468/blob/master/test.ino
Массы аудиопроцессора и ардуино объединили? DGND и корпус микросхемы объединить с корпусом ардуино.
Доброго времени суток. А фотографии обратной стороны платки у Вас нет случайно. Ну или чертежика?
Задайте вопрос в комментарии к https://www.youtube.com/watch?v=hVsfGNAJudA
Спасибо
Если коротко, то ошибка была в отсутствии общей земли…
Если длинно, то я даже 2 ардуины пока Ваш комментарий не прочёл, успел поменять (параллельно выяснив, что одна из них «из пакетика» мёртворождённая):-)) Запитать планировал от разных источников, хотя в одном из Ваших проектов видел решение с двумя понижайками от одного источника, а в звуковую часть таким макаром ничего не лезет?
По сути: не смотря на свою древность микруха вполне себе годная, через RMAA конечно не успел прогнать, но на слух, я от такого динозавра, да ещё с однополярным питанием не ожидал более чем адекватного звука… Единственный косячок — при регулировке ВЧ один канал поднимает\опускает ВЧ больше другого, похоже одна из СВВ плёнок в цепи коррекции под замену, по низам такой проблемы нет. Ну и 0.47 на входах маловато, поменяю на 105J.
Относительно скетча: при предварительном изучении не обратил внимания, что нет записи в память значений баланса, в принципе не критично. Не совсем понял зачем нужна delay(300) в блоке cl()? Хочу прикрутить VS1838B (благо в Вашей статье про TDA7439 это дело реализовано). Хочу добавить ещё один экран menu вместо menu=0 на более информативное с часами, номером входа, уровнем громкости, может температуру на радиаторе УНЧ выведу. Хоть я и старый радиолюбитель, но на ардуино это только мой третий проект, поэтому вопрос: на сколько удобно и корректно обращаться к Вам по вопросам модификации Ваших скетчей? Не думаю, что вопросов будет много, (интересно самому разобраться), но на всякий случай…
За оперативную помощь огромное спасибо, если честно — приятно удивлён!
delay(300) в блоке cl() — устранение дребезга кнопок. Баланс в память я пропустил, доделаю. Связаться со мной можно по адресу liman324@yandex.ru
Состояние переменной баланса в EEPROM ДОБАВЛЕНО. Обновите прошивку.
Здравствуйте Уважаемый ГУРУ liman28! У меня такой вопрос: можно ли с TDA7468 взять сигнал постоянной амплитуды для управления анализатором уровня? Что за выходы MIX L и MIX R у аудиопроцесора? Заранее вам благодарен за ответ!
Здравствуйте. MIX L и MIX R — микшерные входы, анализатора уровня в аудиопроцессоре нет.
Вы уверены? Согласно схемам применения в европейских музыкальных центрах, это выходы. Иногда даже указывают, что линейные. Поэтому у вас и интересуюсь. Проверьте пожалуйста.
Да вы правы, это линейный выход, есть другой микшерный вход, он обозначается как MIC-MIX.
Здравствуйте, может сможете помочь, собирал по схеме из даташита и схема завелась, но есть проблема, что микроузел выдаёт очень тихий звук на максимуме, хотя звук и на ее и на микросхеме на максимум, помогите пожалуйста.
Параметр INPUT GAIN установлен на 0 дБ?
Да, пробовал делать максимальный INPUT GAIN, история та же. Просто не понимаю в чем может быть проблема
Регулировка звука работает?
Да, регулировка работает, басы и все остальное, запускал ваш тестовый скетч, может я чего-то не понимаю, сигнал с ПК уходит на вход TDA7468, а далее на усилитель tda7498e. Звук становится слышимым только на максимальных настройках. А в схеме нету предусилителя или чего-то иного. Извините меня за моё невежество.
Коэффициент усиления аудиопроцессора около 1 на уровне 0 дБ, такая проблема мне ранее не встречалась.
Если напрямую сигнал с ПК подать на усилитель, звук громкий?
Да. Вот не знаю. Нашел схему на радиокоте где эту схему подключают к микрухе MAX, она поднимает с 2 до 5 в.
В общем проблема была решена. Может кому поможет. Может я в силу своей неопытности не знал. В общем
Нужно было сделать такую обвязку на IS и MUX. Или просто замкнуть. Если вам не составит сложности, можете объяснить почему так.
Почему так не знаю, но между IS и MUX поставьте лучше конденсатор 1…2,2 мкФ
Хорошо, спасибо.
Подскажите пожалуйста, как боротся с напряжением на выходе, по даташиту 4.5V, измерит и там 4.55V, при этом пытался ставить конденсаторы как полярные так и не полярные, появилась другая проблема в виде хлопков при включении и выключении.
В setup() перед audio() попробуйте поставить строку
tda.setOutput(0);
delay(1000);
tda.setOutput(1);
Это активация режима MUTE при включении, может поможет от хлопка.
Постоянное напряжение должно присутствовать на выходе, конечно необходимо ставить разделительный конденсатор.
В момент одновременного включения как усилителя так и tda это не сильно помогает, после конденсатора разделительного пики при включении доходят до 1В, после выключения соответственно -1В, Пробовал ставить резисторы не очень помогает, у меня усилитель с 100% чувствительностью на входе, и хотелось бы избавится именно от пиков при ключении. Какие есть методы, может вы знаете?
Можно поставить реле которое замыкает сигнальные цепи на землю в течении 2 секунд после подачи питания (при отсутствии питания реле замыкает сигнальные цепи). После 2 сек ардуино дает команду разомкнуть контакты реле.