diff --git a/control-panel-for-for-dac/control-panel-for-for-dac.ino b/control-panel-for-for-dac/control-panel-for-for-dac.ino index 1c5d116..5b47668 100644 --- a/control-panel-for-for-dac/control-panel-for-for-dac.ino +++ b/control-panel-for-for-dac/control-panel-for-for-dac.ino @@ -4,6 +4,10 @@ // https://www.hackster.io/mircemk/diy-arduino-vfd-display-20x2-vu-volume-unit-meter-37898f // https://github.com/AlexGyver/FHTSpectrumAnalyzer/blob/master/Firmware/spertrum1602/spertrum1602.ino +#include +#include + + #define GAIN 5 // усиление 0...50 #define STEP 20 // плавность полос 0...20 #define RL 1 // RL - горизонт, вертикаль 0...1 @@ -55,7 +59,9 @@ double prevVolts = 100.0; #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) -#include + +// Адрес PT2257 (0x44 в 7-битном формате, или 0x88 в 8-битном) +#define PT2257_ADDRESS 0x44 // LiquidCrystal lcdVuMeter(2, 3, 4, 5, 6, 7);// RS,E,D4,D5,D6,D7 LiquidCrystal_I2C lcdVuMeter(0x27, 16, 2); @@ -64,6 +70,9 @@ LiquidCrystal_I2C lcdService(0x26, 16, 2); bool usb, bluetooth, mp3; int menu = 1; bool menuShow = false; +int att_coax = 0; +int att_spdif = 0; +int att_bt = 0; // ------------------------------------- ПОЛОСОЧКИ ------------------------------------- byte v1[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111}; @@ -81,6 +90,13 @@ byte maxValue, maxValue_f; float k = 0.1; void setup() { + Wire.begin(); + // Инициализация PT2257 - сброс и включение + writePT2257(0xFF); // Сброс + delay(100); + writePT2257(0xCE); // Включение (0xCF для выключения) + setVolume(79); + lcdVuMeter.init(); lcdVuMeter.backlight(); lcdVuMeter.clear(); @@ -114,20 +130,28 @@ void setup() { pinMode(A0,INPUT);// A0 - аналоговый вход R pinMode(A1,INPUT);// A1 - аналоговый вход L - // первый запуск и установка занчений переменных в память + // первый запуск и установка значений переменных в память if (EEPROM.read(INIT_ADDR) != INIT_KEY) { - EEPROM.write(INIT_ADDR, INIT_KEY); - usb = true; - bluetooth = false; - mp3 = false; - - EEPROM.put(10, usb); - EEPROM.put(12, bluetooth); - EEPROM.put(14, mp3); - } else { + EEPROM.write(INIT_ADDR, INIT_KEY); + usb = true; + bluetooth = false; + mp3 = false; + att_coax = 0; // Минимальная громкость + att_spdif = 0; // Минимальная громкость + att_bt = 0; // Минимальная громкость + + EEPROM.put(10, usb); + EEPROM.put(12, bluetooth); + EEPROM.put(16, att_coax); + EEPROM.put(18, att_spdif); + EEPROM.put(20, att_bt); + } else { usb = EEPROM.read(10); bluetooth = EEPROM.read(12); -// mp3 = EEPROM.read(14); +// mp3 = EEPROM.read(14); + att_coax = EEPROM.read(16); + att_spdif = EEPROM.read(18); + att_bt = EEPROM.read(20); } // поднимаем частоту опроса аналогового порта до 38.4 кГц, по теореме @@ -143,28 +167,23 @@ void setup() { analogReference(EXTERNAL); - if (usb) { - digitalWrite(RELAY_POWER_BT,HIGH); -// digitalWrite(RELAY_POWER_MP3,HIGH); - digitalWrite(RELAY_POWER_USB,HIGH); - delay(500); - digitalWrite(RELAY_OUT_USB,HIGH); - digitalWrite(RELAY_OUT_BT,LOW); -// digitalWrite(RELAY_OUT_MP3_LEFT,HIGH); -// digitalWrite(RELAY_OUT_MP3_RIGHT,HIGH); - } +if (usb) { + digitalWrite(RELAY_POWER_BT,HIGH); + digitalWrite(RELAY_POWER_USB,HIGH); + delay(500); + digitalWrite(RELAY_OUT_USB,HIGH); + digitalWrite(RELAY_OUT_BT,LOW); + applyCurrentVolume(); // Применить громкость после инициализации +} - if (bluetooth) { - digitalWrite(RELAY_POWER_USB,HIGH); -// digitalWrite(RELAY_POWER_MP3,HIGH); - delay(500); -// digitalWrite(RELAY_OUT_MP3_LEFT,HIGH); -// digitalWrite(RELAY_OUT_MP3_RIGHT,HIGH); - delay(1000); - digitalWrite(RELAY_OUT_USB,LOW); - digitalWrite(RELAY_OUT_BT,HIGH); - digitalWrite(RELAY_POWER_BT,LOW); - } +if (bluetooth) { + digitalWrite(RELAY_POWER_USB,HIGH); + delay(500); + digitalWrite(RELAY_OUT_USB,LOW); + digitalWrite(RELAY_OUT_BT,HIGH); + digitalWrite(RELAY_POWER_BT,LOW); + applyCurrentVolume(); // Применить громкость после инициализации +} if (mp3) { } lcdChars(); // подхватить коды полосочек @@ -210,9 +229,10 @@ void updateMenu() { case 1: lcdService.clear(); lcdService.print("> USB DAC"); - lcdService.setCursor(2, 1); + lcdService.setCursor(0, 1); if(usb){ - lcdService.print("On"); + lcdService.print("On Vol: "); + lcdService.print(getVolumeLabel(usb ? (att_spdif) : 0)); }else{ lcdService.print("Off"); } @@ -220,24 +240,36 @@ void updateMenu() { case 2: lcdService.clear(); lcdService.print("> Bluetooth"); - lcdService.setCursor(2, 1); + lcdService.setCursor(0, 1); if(bluetooth){ - lcdService.print("On"); + lcdService.print("On Vol: "); + lcdService.print(getVolumeLabel(bluetooth ? att_bt : 0)); }else{ lcdService.print("Off"); } break; -// case 3: -// lcdService.clear(); -// lcdService.print(">MP3 module"); -// lcdService.setCursor(2, 1); -// if(mp3){ -// lcdService.print("On"); -// }else{ -// lcdService.print("Off"); -// } -// break; - case 3: + case 4: + lcdService.clear(); + lcdService.print("> Att S/PDIF"); + lcdService.setCursor(0, 1); + lcdService.print("Level: "); + lcdService.print(getVolumeLabel(att_spdif)); + break; + case 5: + lcdService.clear(); + lcdService.print("> Att Coax"); + lcdService.setCursor(0, 1); + lcdService.print("Level: "); + lcdService.print(getVolumeLabel(att_coax)); + break; + case 6: + lcdService.clear(); + lcdService.print("> Att BlueTooth"); + lcdService.setCursor(0, 1); + lcdService.print("Level: "); + lcdService.print(getVolumeLabel(att_bt)); + break; + case 7: menu = 0; menuShow = false; lcdService.clear(); @@ -245,23 +277,78 @@ void updateMenu() { } } +String getVolumeLabel(int level) { + switch(level) { + case 0: return "Max"; + case 1: return "Med"; + case 2: return "Min"; + default: return "Err"; + } +} +int attenuationVolume(int i) { + // Циклическое переключение между 0,1,2 + return (i + 1) % 3; +} +int convertAttToVolume(int att) { + // PT2257: 0 = максимум громкости, 79 = минимум громкости + // Нам нужно: 0 = максимум, 1 = среднее, 2 = минимум + switch(att) { + case 0: return 0; // Максимальная громкость (0 dB) + case 1: return 1; // Средняя громкость (40 dB) + case 2: return 2; // Минимальная громкость (79 dB) + default: return 0; + } +} void executeMenuAction() { switch (menu) { case 1: actionUSB(); + // При переключении на USB установите соответствующую громкость + applyCurrentVolume(); break; case 2: actionBT(); + // При переключении на Bluetooth установите соответствующую громкость + applyCurrentVolume(); + break; + case 4: + att_spdif = attenuationVolume(att_spdif); + EEPROM.put(18, att_spdif); + if (usb && !digitalRead(OPTOCOUPLE_USB)) { + setVolume(convertAttToVolume(att_spdif)); + } + break; + case 5: + att_coax = attenuationVolume(att_coax); + EEPROM.put(16, att_coax); + if (usb && !digitalRead(OPTOCOUPLE_COAX)) { + setVolume(convertAttToVolume(att_coax)); + } + break; + case 6: + att_bt = attenuationVolume(att_bt); + EEPROM.put(20, att_bt); + if (bluetooth) { + setVolume(convertAttToVolume(att_bt)); + } break; -// case 3: -// actionMP3(); -// break; } EEPROM.put(10, usb); EEPROM.put(12, bluetooth); -// EEPROM.put(14, mp3); + updateMenu(); // Обновляем отображение меню } +void applyCurrentVolume() { + if (usb) { + if (!digitalRead(OPTOCOUPLE_USB)) { + setVolume(convertAttToVolume(att_spdif)); + } else if (!digitalRead(OPTOCOUPLE_COAX)) { + setVolume(convertAttToVolume(att_coax)); + } + } else if (bluetooth) { + setVolume(convertAttToVolume(att_bt)); + } +} void actionUSB() { // lcdService.clear(); lcdService.setCursor(2,1); @@ -301,25 +388,55 @@ void actionBT() { // delay(1500); } -//void actionMP3() { -//// lcdService.clear(); -// lcdService.setCursor(2,1); -// lcdService.print("On "); -// digitalWrite(RELAY_POWER_USB,HIGH); -// digitalWrite(RELAY_POWER_BT,HIGH); -// delay(500); -// digitalWrite(RELAY_OUT_USB,HIGH); -// digitalWrite(RELAY_OUT_BT,HIGH); -// delay(1000); -// digitalWrite(RELAY_OUT_MP3_LEFT,LOW); -// digitalWrite(RELAY_OUT_MP3_RIGHT,LOW); -// digitalWrite(RELAY_POWER_MP3,LOW); -// usb = false; -// bluetooth = false; -// mp3 = true; -// delay(1500); -//} +///================== Аттенюатор =========================== + +void writePT2257(byte command) { + Wire.beginTransmission(PT2257_ADDRESS); + Wire.write(command); + Wire.endTransmission(); +} + +void setVolume(int volume) { + // PT2257 принимает ослабление от 0 до 79 dB + volume = constrain(volume, 0, 79); + + // Разделяем на десятки и единицы + int tens = volume / 10; + int units = volume % 10; + + // Устанавливаем громкость для левого канала + writePT2257(0xD0 + tens); // Десятки для левого канала + writePT2257(0xE0 + units); // Единицы для левого канала + + // Устанавливаем громкость для правого канала + writePT2257(0x50 + tens); // Десятки для правого канала + writePT2257(0x60 + units); // Единицы для правого канала +} + +void setVolumeLeft(int volume) { + volume = constrain(volume, 0, 79); + int tens = volume / 10; + int units = volume % 10; + + writePT2257(0xD0 + tens); + writePT2257(0xE0 + units); +} + +void setVolumeRight(int volume) { + volume = constrain(volume, 0, 79); + int tens = volume / 10; + int units = volume % 10; + + writePT2257(0x50 + tens); + writePT2257(0x60 + units); +} + +void mute(bool muteOn) { + writePT2257(muteOn ? 0x7D : 0x7E); // Mute/unmute +} + +///============================================================= uint32_t btnTimer = 0; @@ -398,6 +515,7 @@ void loop() { gainTimer = millis(); } } +// setVolume(2); } void analyzeAudio() { for (int i = 0 ; i < FHT_N ; i++) {