Добавил работу с аттенюатором

This commit is contained in:
Sergey Kalinin
2025-11-08 17:01:00 +03:00
parent e3a4903a78
commit ad88037470

View File

@@ -4,6 +4,10 @@
// https://www.hackster.io/mircemk/diy-arduino-vfd-display-20x2-vu-volume-unit-meter-37898f // 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 // https://github.com/AlexGyver/FHTSpectrumAnalyzer/blob/master/Firmware/spertrum1602/spertrum1602.ino
#include <EEPROM.h>
#include <Wire.h>
#define GAIN 5 // усиление 0...50 #define GAIN 5 // усиление 0...50
#define STEP 20 // плавность полос 0...20 #define STEP 20 // плавность полос 0...20
#define RL 1 // RL - горизонт, вертикаль 0...1 #define RL 1 // RL - горизонт, вертикаль 0...1
@@ -55,7 +59,9 @@ double prevVolts = 100.0;
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#include <EEPROM.h>
// Адрес PT2257 (0x44 в 7-битном формате, или 0x88 в 8-битном)
#define PT2257_ADDRESS 0x44
// LiquidCrystal lcdVuMeter(2, 3, 4, 5, 6, 7);// RS,E,D4,D5,D6,D7 // LiquidCrystal lcdVuMeter(2, 3, 4, 5, 6, 7);// RS,E,D4,D5,D6,D7
LiquidCrystal_I2C lcdVuMeter(0x27, 16, 2); LiquidCrystal_I2C lcdVuMeter(0x27, 16, 2);
@@ -64,6 +70,9 @@ LiquidCrystal_I2C lcdService(0x26, 16, 2);
bool usb, bluetooth, mp3; bool usb, bluetooth, mp3;
int menu = 1; int menu = 1;
bool menuShow = false; 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}; byte v1[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111};
@@ -81,6 +90,13 @@ byte maxValue, maxValue_f;
float k = 0.1; float k = 0.1;
void setup() { void setup() {
Wire.begin();
// Инициализация PT2257 - сброс и включение
writePT2257(0xFF); // Сброс
delay(100);
writePT2257(0xCE); // Включение (0xCF для выключения)
setVolume(79);
lcdVuMeter.init(); lcdVuMeter.init();
lcdVuMeter.backlight(); lcdVuMeter.backlight();
lcdVuMeter.clear(); lcdVuMeter.clear();
@@ -114,20 +130,28 @@ void setup() {
pinMode(A0,INPUT);// A0 - аналоговый вход R pinMode(A0,INPUT);// A0 - аналоговый вход R
pinMode(A1,INPUT);// A1 - аналоговый вход L pinMode(A1,INPUT);// A1 - аналоговый вход L
// первый запуск и установка занчений переменных в память // первый запуск и установка значений переменных в память
if (EEPROM.read(INIT_ADDR) != INIT_KEY) { if (EEPROM.read(INIT_ADDR) != INIT_KEY) {
EEPROM.write(INIT_ADDR, INIT_KEY); EEPROM.write(INIT_ADDR, INIT_KEY);
usb = true; usb = true;
bluetooth = false; bluetooth = false;
mp3 = false; mp3 = false;
att_coax = 0; // Минимальная громкость
EEPROM.put(10, usb); att_spdif = 0; // Минимальная громкость
EEPROM.put(12, bluetooth); att_bt = 0; // Минимальная громкость
EEPROM.put(14, mp3);
} else { 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); usb = EEPROM.read(10);
bluetooth = EEPROM.read(12); 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 кГц, по теореме // поднимаем частоту опроса аналогового порта до 38.4 кГц, по теореме
@@ -143,28 +167,23 @@ void setup() {
analogReference(EXTERNAL); analogReference(EXTERNAL);
if (usb) { if (usb) {
digitalWrite(RELAY_POWER_BT,HIGH); digitalWrite(RELAY_POWER_BT,HIGH);
// digitalWrite(RELAY_POWER_MP3,HIGH); digitalWrite(RELAY_POWER_USB,HIGH);
digitalWrite(RELAY_POWER_USB,HIGH); delay(500);
delay(500); digitalWrite(RELAY_OUT_USB,HIGH);
digitalWrite(RELAY_OUT_USB,HIGH); digitalWrite(RELAY_OUT_BT,LOW);
digitalWrite(RELAY_OUT_BT,LOW); applyCurrentVolume(); // Применить громкость после инициализации
// digitalWrite(RELAY_OUT_MP3_LEFT,HIGH); }
// digitalWrite(RELAY_OUT_MP3_RIGHT,HIGH);
}
if (bluetooth) { if (bluetooth) {
digitalWrite(RELAY_POWER_USB,HIGH); digitalWrite(RELAY_POWER_USB,HIGH);
// digitalWrite(RELAY_POWER_MP3,HIGH); delay(500);
delay(500); digitalWrite(RELAY_OUT_USB,LOW);
// digitalWrite(RELAY_OUT_MP3_LEFT,HIGH); digitalWrite(RELAY_OUT_BT,HIGH);
// digitalWrite(RELAY_OUT_MP3_RIGHT,HIGH); digitalWrite(RELAY_POWER_BT,LOW);
delay(1000); applyCurrentVolume(); // Применить громкость после инициализации
digitalWrite(RELAY_OUT_USB,LOW); }
digitalWrite(RELAY_OUT_BT,HIGH);
digitalWrite(RELAY_POWER_BT,LOW);
}
if (mp3) { if (mp3) {
} }
lcdChars(); // подхватить коды полосочек lcdChars(); // подхватить коды полосочек
@@ -210,9 +229,10 @@ void updateMenu() {
case 1: case 1:
lcdService.clear(); lcdService.clear();
lcdService.print("> USB DAC"); lcdService.print("> USB DAC");
lcdService.setCursor(2, 1); lcdService.setCursor(0, 1);
if(usb){ if(usb){
lcdService.print("On"); lcdService.print("On Vol: ");
lcdService.print(getVolumeLabel(usb ? (att_spdif) : 0));
}else{ }else{
lcdService.print("Off"); lcdService.print("Off");
} }
@@ -220,24 +240,36 @@ void updateMenu() {
case 2: case 2:
lcdService.clear(); lcdService.clear();
lcdService.print("> Bluetooth"); lcdService.print("> Bluetooth");
lcdService.setCursor(2, 1); lcdService.setCursor(0, 1);
if(bluetooth){ if(bluetooth){
lcdService.print("On"); lcdService.print("On Vol: ");
lcdService.print(getVolumeLabel(bluetooth ? att_bt : 0));
}else{ }else{
lcdService.print("Off"); lcdService.print("Off");
} }
break; break;
// case 3: case 4:
// lcdService.clear(); lcdService.clear();
// lcdService.print(">MP3 module"); lcdService.print("> Att S/PDIF");
// lcdService.setCursor(2, 1); lcdService.setCursor(0, 1);
// if(mp3){ lcdService.print("Level: ");
// lcdService.print("On"); lcdService.print(getVolumeLabel(att_spdif));
// }else{ break;
// lcdService.print("Off"); case 5:
// } lcdService.clear();
// break; lcdService.print("> Att Coax");
case 3: 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; menu = 0;
menuShow = false; menuShow = false;
lcdService.clear(); 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() { void executeMenuAction() {
switch (menu) { switch (menu) {
case 1: case 1:
actionUSB(); actionUSB();
// При переключении на USB установите соответствующую громкость
applyCurrentVolume();
break; break;
case 2: case 2:
actionBT(); 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; break;
// case 3:
// actionMP3();
// break;
} }
EEPROM.put(10, usb); EEPROM.put(10, usb);
EEPROM.put(12, bluetooth); 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() { void actionUSB() {
// lcdService.clear(); // lcdService.clear();
lcdService.setCursor(2,1); lcdService.setCursor(2,1);
@@ -301,25 +388,55 @@ void actionBT() {
// delay(1500); // 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; uint32_t btnTimer = 0;
@@ -398,6 +515,7 @@ void loop() {
gainTimer = millis(); gainTimer = millis();
} }
} }
// setVolume(2);
} }
void analyzeAudio() { void analyzeAudio() {
for (int i = 0 ; i < FHT_N ; i++) { for (int i = 0 ; i < FHT_N ; i++) {