NTP8212 — цифровой усилитель 2х20 Вт (Arduino)

S/PDIF (Sony/Philips Digital Interface) – распространенный и стандартизированный интерфейс, предназначенный для передачи цифрового звука между доступными компонентами, звуковыми картами, ресиверами и аудиоаппаратурой.

I2S — стандарт интерфейса электрической последовательной шины, использующийся для соединения цифровых аудиоустройств. Применяется для передачи PCM-аудиоданных между интегральными схемами в электронном устройстве. Шина I2S передает по разным линиям сигналы синхронизации и сигналы данных, что приводит к снижению фазового дрожания, типичного для систем связи, восстанавливающих сигналы синхронизации из целого потока.

NTP8212 — полнофункциональный цифровой аудио усилитель (класса D), включающий силовой каскад для
системы стерео усилителей. В NTP8212G интегрирована система цифровой обработки аудиосигнала (ЦАП), высокоточный цифровой ШИМ-модулятор и два мощных полномостовых каскада питания МОП-транзисторов.

NTP8212G поддерживает формат передачи цифровых данных I2S (I²S — стандарт интерфейса электрической последовательной шины, использующийся для соединения цифровых аудиоустройств) с частотой дискретизации от 8 кГц до 192 кГц, с разрешением до 24 бит.

Усилитель выдает 2 x 20 Вт (при питании 24 В на нагрузке 8 Ом), оснащен цифровым регулятором громкости, баланса, имеет 5-и полосный эквалайзер, так же доступны функции MUTE и STANDBY.

Структурная схема усилителя

Основные параметры усилителя NTP8212:

  • Напряжение питания цифровое от 3,0 до 3,6 В (3,3 В рекомендуемое)
  • Аналоговое питание от 4,5 до 28 В
  • Отношение сигнал/шум 95 дБ
  • Коэффициент гармоник (THD+N 1W, 1kHz) не более 0,1 %
  • КПД усилителя 90 %
  • Частота PWM 384 кГц
  • Управление цифровое I2C
  • Ток потребления в режиме STANDBY не более 0.2 мкА
  • 5-и полосный эквалайзер 100 Гц, 300 Гц, 1 кГц, 3 кГц, 10 кГц с диапазоном регулировки от -12 до +12 дБ

Для правильной работы цифрового усилителя NTP8212, необходимо использовать ресивер, который преобразует сигнал S/PDIF в формат I2S. В данном примере использован ресивер CS8416.

Параметры ресивера CS8416:

  • Напряжение питания:
    • +3.3 V Analog Supply (VA)
    • +3.3 V Digital Supply (VD)
    • +3.3 V or +5.0 V Digital Interface Supply (VL)
  • Входной формат данных: S/PDIF
  • Выходной формат данных:
    • Left-Justified
    • Right-Justified
    • I2S (аппаратно настроен)
  • Разрядность 16 — 24 бит (аппаратно настроен на 24 бит)
  • Частота дискредитации 32 — 192 кГц (аппаратно настроен на 192 кГц)
  • Фильтр De-emphasis:
    • No De-emphasis (аппаратно настроен)
    • 32 kHz
    • 48 kHz
    • 44.1 kHz
  • Кол-во входов: 8 (аппаратно поддерживает 4)

Ресивер CS8416 имеет цифровой интерфейс управления, но может быть сконфигурирован аппаратно. В данном примере ресивер сконфигурирован аппаратно и имеет выходной формат I2S 24 бит с частотой дискредитации 192 кГц. При аппаратной настройке в ресивере доступно 4 входа S/PDIF (8 входов при программном управлении).

Коммутация входами осуществляется при помощи пинов RSEL1 и RSEL0 микросхемы ресивера , при этом лог. 1 подается с питания VL (+5 В), а логический ноль с DGND.

INPUT RSEL0 RSEL1
RXP0 0 0
RXP1 1 0
RXP2 0 1
RXP3 1 1

Ресивер работает независимо от Arduino, в схеме присутствует индикатор режима работы светодиод D1, при подключении коаксиального кабеля с источником цифрового сигнала светодиод гаснет, при отключении кабеля загорается.

Для управления работой усилителя и ресивера используется плата Arduino Nano, три кнопки и энкодер (модуль KY-040), так же управление полностью продублировано ИК пультом, информация о текущих настройка отображается на дисплее LCD1602 с платой I2C.

Схема ресивера

Схема усилителя

Схема управления

Схема источника питания

На дисплей выводится три меню, переключение меню осуществляется при помощи кнопки энкодера.

  • Меню индикаторов громкости (от 0 до 99) и коммутатора входов

Регулировка громкости осуществляется при помощи энкодера.

  • Меню эквалайзера, регулировка уровня усиления или ослабления выбранной полосы осуществляется при помощи энкодера, выбор полосы происходит при нажатии на кнопку INPUT/EQ_F. Меню эквалайзера содержит графический индикатор регулировки полос.

  • Меню регулировки баланса

  • Режим MUTE

  • Режим STANDBY

Так как предусмотрена управляемая яркость подсветки дисплея, то можно установить яркость подсветки в основном  режиме и в режиме STANDBY (как правило с пониженной яркостью подсветки), регулировка яркости подсветки осуществляется через скетч:

#define BRIG_H 200 // Яркость 0…255 POWER ON
#define BRIG_L 50 // Яркость 0…255 POWER OFF

Подсветка — убрать перемычку с модуля I2C PCF8574 и подключить вывод модуля к цифровому выходу Arduino D6. Перед подключением замерить ток подсветки который не должен превышать 20 мА (у моего модуля ток не более 15 мА, замер производить между контактами перемычки).

 

Максимальный выходной ток одного выхода Arduino Nano не должен превышать 40 мА (рекомендуется не более 20 мА).

ИК пульт дублирует работу энкодера и кнопок. Для управления усилителем подойдет практически любой пульт ИК, для поддержки Вашего пульта необходимо прописать коды кнопок в скетч:

#define IR_1 0x2FDD02F // Кнопка вверх
#define IR_2 0x2FD32CD // Кнопка вниз
#define IR_3 0x2FD906F // Кнопка >
#define IR_4 0x2FDF20D // Кнопка <
#define IR_5 0x2FD6A95 // Кнопка IN
#define IR_6 0x2FDEA15 // Кнопка MUTE
#define IR_7 0x2FD00FF // Кнопка STANDBY (POWER)

Для получения кодов кнопок Вашего пульта загрузите скетч и откройте монитор порта, при нажатии кнопки пульта его код будет отображен в мониторе порта.

Усилитель в настройке не нуждается, помимо занесения в скетч кодов кнопок пульта и параметров подсветки дисплея можно подкорректировать в скетче общее усиление усилителя:

#define GAIN 80 // 63 — 126 КОЭФФИЦИЕНТ УСИЛЕНИЯ УСИЛИТЕЛЯ

#define I2C_NTP8212 0x2A // Address chip | MONITOR_0 = GND 
#define GAIN    80  // 63 - 126 КОЭФФИЦИЕНТ УСИЛЕНИЯ УСИЛИТЕЛЯ
 
#define CLK     9   //  ENCODER 
#define DT      8   //  ENCODER 
#define SW     10   //  ENCODER 
 
#define IR_1 0x2FDD02F // Кнопка вверх
#define IR_2 0x2FD32CD // Кнопка вниз
#define IR_3 0x2FD906F // Кнопка >
#define IR_4 0x2FDF20D // Кнопка <
#define IR_5 0x2FD6A95 // Кнопка IN
#define IR_6 0x2FDEA15 // Кнопка MUTE
#define IR_7 0x2FD00FF // Кнопка STANDBY (POWER)
 
#define BRIG_H 200      // Яркость 0...255 POWER ON
#define BRIG_L 50       // Яркость 0...255 POWER OFF
 
#include <Wire.h>
#include <EEPROM.h>
#include <MsTimer2.h>                    // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
#include <Encoder.h>                     // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <LiquidCrystal_I2C.h>           // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1 
#include <boarddefs.h>          // входит в состав библиотеки IRremote
#include <IRremote.h>           // http://rcl-radio.ru/wp-content/uploads/2019/06/IRremote.zip 
 Encoder myEnc(CLK, DT);
 LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей 
 IRrecv irrecv(12); // указываем вывод модуля IR приемника
 decode_results ir; 
 
 unsigned long times,times1,oldPosition  = -999,newPosition;
 byte i,d1,d2,d3,d4,d5,d6,e1,e2,e3;
 int menu,vol,a[3],in,qi,qq;
 byte w,w2,mute,m0=1,m1;
 int q[5],qqq[5],ball,chl,chr,i1;  
 bool gr1,gr2,www,power;
 
 
void setup() {
  delay(500);
  Wire.begin();
  Serial.begin(9600);
  irrecv.enableIRIn();
  MsTimer2::set(1, to_Timer);MsTimer2::start();
  pinMode(2,OUTPUT); // RSEL0 PIN  CS8416
  pinMode(3,OUTPUT); // RSEL1 PIN  CS8416
  pinMode(4,OUTPUT); // RESET PIN  NTP8212
  pinMode(5,OUTPUT); // FAULT PIN  NTP8212
  pinMode(A0,INPUT_PULLUP); // MUTE
  pinMode(A1,INPUT_PULLUP); // INPUT
  pinMode(A2,INPUT_PULLUP); // POWER
  pinMode(6,OUTPUT);  // ВЫХОД УПРАВЛЕНИЯ ПОДСВЕТКОЙ
  analogWrite(6, BRIG_H);// больше 200 не делать
  digitalWrite(5,HIGH);delay(100);
  digitalWrite(4,HIGH);delay(50);
  digitalWrite(4,LOW);delay(50);
  digitalWrite(4,HIGH);delay(50);
 
  if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении 
  vol = EEPROM.read(0);in = EEPROM.read(1);
  q[0] = EEPROM.read(2)-100;q[1] = EEPROM.read(3)-100;q[2] = EEPROM.read(4)-100;q[3] = EEPROM.read(5)-100;q[4] = EEPROM.read(6)-100;
  ball = EEPROM.read(7);
 
  in_sw();
  init_ntp();
  Serial.print("Chip ID: 0x");Serial.println(wireRead(I2C_NTP8212,0x7F),HEX);
  Serial.println(wireRead(I2C_NTP8212,0x54),HEX);
  Serial.println(wireRead(I2C_NTP8212,0x59),HEX);
  Serial.println(wireRead(I2C_NTP8212,0x5E),BIN);
 
  lcd.init();lcd.backlight();
  lcd.setCursor(5,0);lcd.print("CS 8416");
  lcd.setCursor(5,1);lcd.print("NTP8212");
  delay(1000);lcd.clear(); 
}
 
void loop() {
   if ( irrecv.decode( &ir )) {Serial.print("0x");Serial.println( ir.value,HEX);irrecv.resume();times=millis();w=1;w2=1;}// IR приемник - чтение, в мониторе порта отображаются коды кнопок
   if(ir.value==0){gr1=0;gr2=0;}// запрет нажатий не активных кнопок пульта  
 
   if(m0==1){m0=0;
    byte v1[8] = {0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07};
    byte v2[8] = {0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00};      
    byte v3[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F};
    byte v4[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x1F,0x1F};
    byte v5[8] = {0x1C,0x1C,0x00,0x00,0x00,0x00,0x1C,0x1C};
    byte v6[8] = {0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C};
    byte v7[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07};
    byte v8[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00};
    lcd.createChar(1, v1);lcd.createChar(2, v2);lcd.createChar(3, v3);lcd.createChar(4, v4);lcd.createChar(5, v5);lcd.createChar(6, v6);lcd.createChar(7, v7);lcd.createChar(8, v8);}
   if(m1==1){m1=0;
    byte v1[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b01110};
    byte v2[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b01110, 0b01110};
    byte v3[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b01110, 0b01110, 0b01110};
    byte v4[8] = {0b00000, 0b00000, 0b00000, 0b00000, 0b01110, 0b01110, 0b01110, 0b01110};
    byte v5[8] = {0b00000, 0b00000, 0b00000, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110};
    byte v6[8] = {0b00000, 0b00000, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110};
    byte v7[8] = {0b00000, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110};
    byte v8[8] = {0b01110, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110, 0b01110};
    lcd.createChar(0, v1);lcd.createChar(1, v2);lcd.createChar(2, v3);lcd.createChar(3, v4);lcd.createChar(4, v5);lcd.createChar(5, v6);lcd.createChar(6, v7);lcd.createChar(7, v8);}
 
  if(power==0){
  /// MENU //////////////////////////////
  if(digitalRead(SW)==LOW){menu++;if(menu>2){menu=0;};switch(menu){case 0: m0=1;break;case 1: m1=1;break;case 2: m0=1;break;}delay(200);lcd.clear();w=1;w2=1;times=millis();w2=1;}
  if(ir.value==IR_1){menu++;gr1=0;gr2=0;cl1();times=millis();w=1;w2=1;if(menu>2){menu=0;};switch(menu){case 0: m0=1;break;case 1: m1=1;break;case 2: m0=1;break;}delay(200);lcd.clear();w=1;w2=1;times=millis();w2=1;}
  if(ir.value==IR_2){menu--;gr1=0;gr2=0;cl1();times=millis();w=1;w2=1;if(menu<0){menu=2;};switch(menu){case 0: m0=1;break;case 1: m1=1;break;case 2: m0=1;break;}delay(200);lcd.clear();w=1;w2=1;times=millis();w2=1;}
 
  /// INPUT ////////////////////////////
  if((digitalRead(A1)==LOW||ir.value==IR_5)&&menu!=1){in++;gr1=0;gr2=0;if(in>3){in=0;}menu=100;w=1;w2=1;times=millis();cl();lcd.setCursor(4,0);lcd.print("INPUT ");lcd.print(in+1);
  in_sw();
  delay(500);cl();menu=0;}
 
 /// MUTE //////////////////////////////
 if((digitalRead(A0)==LOW||ir.value==IR_6)&&mute==0){mute=1;gr1=0;gr2=0;menu=100;cl();wireWrite(I2C_NTP8212,0x26,0b10000011);lcd.setCursor(6,0);lcd.print("MUTE");}
 if((digitalRead(A0)==LOW||ir.value==IR_6)&&mute==1){mute=0;gr1=0;gr2=0;menu=0;m0=1;cl();wireWrite(I2C_NTP8212,0x26,0b10000000);w2=1;}  
  }
 /// POWER ///////////////////////////// 
  if((ir.value==IR_7||digitalRead(A2)==LOW)&&power==0){power=1;cl();lcd.setCursor(3,0);lcd.print("POWER  OFF");menu=100;m0=1;
    wireWrite(I2C_NTP8212,0x27,0b00000011); // standby [1:0] = 11 ST on
    delay(3000);analogWrite(6,BRIG_L);}// power off
  if((ir.value==IR_7||digitalRead(A2)==LOW)&&power==1){power=0;analogWrite(6, BRIG_H);cl();lcd.setCursor(3,0);lcd.print("POWER   ON ");
    w2=1;w=1;menu=0;m0=1;myEnc.write(0);
    wireWrite(I2C_NTP8212,0x27,0b00000000); // standby [1:0] = 11 ST on
    delay(3000);cl();}// power on
 
 
 /// VOLUME ///////////////////////////////////////////////////
 if(menu==0){
   if(ir.value==IR_3){vol++;gr1=1;gr2=0;cl1();times=millis();www=1;w=1;w2=1;if(vol>127){vol=127;}if(vol<28){vol=28;}}// кнопка > 
   if(ir.value==0xFFFFFFFF and gr1==1){vol++;gr2=0;cl1();times=millis();www=1;w=1;w2=1;if(vol>127){vol=127;}if(vol<28){vol=28;}}// кнопка >>>>>>
   if(ir.value==IR_4){vol--;gr1=0;gr2=1;cl1();times=millis();www=1;w=1;w2=1;if(vol>127){vol=127;}if(vol<28){vol=28;}}// кнопка <
   if(ir.value==0xFFFFFFFF and gr2==1){vol--;gr1=0;cl1();times=millis();www=1;w=1;w2=1;if(vol>127){vol=127;}if(vol<28){vol=28;}}// кнопка <<<<<<  
 
   if (newPosition != oldPosition){oldPosition = newPosition;
     vol=vol+newPosition;myEnc.write(0);newPosition=0;w=1;times=millis();w2=1;
     if(vol>127){vol=127;}if(vol<28){vol=28;}
     www=1;
     }
   if(www==1){www=0;
     wireWrite(I2C_NTP8212,0x2E,vol*2);// общая громкость
     wireWrite(I2C_NTP8212,0x2F,240+ball);// ПК громкость
     wireWrite(I2C_NTP8212,0x30,240-ball);// ЛК громкость
   }  
      lcd.setCursor(0,0);lcd.print("VOLUME ");
      lcd.setCursor(0,1);lcd.print("INPUT ");lcd.print(in+1);
 
  if(w2==1){w2=0;
     a[0]=(vol-28)/10;a[1]=(vol-28)%10;
       for(i=0;i<2;i++){
      switch(i){
        case 0: e1=9,e2=10,e3=11;break;
        case 1: e1=12,e2=13,e3=14;break;
        }
      switch(a[i]){
        case 0: d1=1,d2=8,d3=6,d4=1,d5=3,d6=6;break;
        case 1: d1=32,d2=2,d3=6,d4=32,d5=32,d6=6;break;
        case 2: d1=2,d2=8,d3=6,d4=1,d5=4,d6=5;break;
        case 3: d1=2,d2=4,d3=6,d4=7,d5=3,d6=6;break;
        case 4: d1=1,d2=3,d3=6,d4=32,d5=32,d6=6;break;
        case 5: d1=1,d2=4,d3=5,d4=7,d5=3,d6=6;break;
        case 6: d1=1,d2=4,d3=5,d4=1,d5=3,d6=6;break;
        case 7: d1=1,d2=8,d3=6,d4=32,d5=32,d6=6;break;
        case 8: d1=1,d2=4,d3=6,d4=1,d5=3,d6=6;break;
        case 9: d1=1,d2=4,d3=6,d4=7,d5=3,d6=6;break;
    }
      lcd.setCursor(e1,0);lcd.write((uint8_t)d1);lcd.setCursor(e2,0);lcd.write((uint8_t)d2);lcd.setCursor(e3,0);lcd.write((uint8_t)d3);
      lcd.setCursor(e1,1);lcd.write((uint8_t)d4);lcd.setCursor(e2,1);lcd.write((uint8_t)d5);lcd.setCursor(e3,1);lcd.write((uint8_t)d6);
 }} 
 }
 
// Equalizer /////////////////////////////////////
 if(menu==1){ 
   if(digitalRead(A1)==LOW||ir.value==IR_5){qi++;gr1=0;gr2=0;ir.value=0;if(qi>4){qi=0;}w=1;w2=1;delay(300);}
   switch(qi){
    case 0: qq=q[0];break;
    case 1: qq=q[1];break;
    case 2: qq=q[2];break;
    case 3: qq=q[3];break;
    case 4: qq=q[4];break;
    }
 
   if(ir.value==IR_3){qq++;gr1=1;gr2=0;cl1();times=millis();www=1;w=1;w2=1;if(qq>12){qq=12;}if(qq<-12){qq=-12;}}// кнопка > 
   if(ir.value==0xFFFFFFFF and gr1==1){qq++;gr2=0;cl1();times=millis();www=1;w=1;w2=1;if(qq>12){qq=12;}if(qq<-12){qq=-12;}}// кнопка >>>>>>
   if(ir.value==IR_4){qq--;gr1=0;gr2=1;cl1();times=millis();www=1;w=1;w2=1;if(qq>12){qq=12;}if(qq<-12){qq=-12;}}// кнопка <
   if(ir.value==0xFFFFFFFF and gr2==1){qq--;gr1=0;cl1();times=millis();www=1;w=1;w2=1;if(qq>12){qq=12;}if(qq<-12){qq=-12;}}// кнопка <<<<<<   
 
   if (newPosition != oldPosition){oldPosition = newPosition;
     qq=qq+newPosition;myEnc.write(0);newPosition=0;w=1;times=millis();w2=1;
     if(qq>12){qq=12;}if(qq<-12){qq=-12;}
     www=1;
     }
     if(www==1){www=0;
     q[qi]=qq;
     if(qq>=0){
     wireWrite(I2C_NTP8212,0x10,q[0]); 
     wireWrite(I2C_NTP8212,0x11,q[1]); 
     wireWrite(I2C_NTP8212,0x12,q[2]); 
     wireWrite(I2C_NTP8212,0x13,q[3]); 
     wireWrite(I2C_NTP8212,0x14,q[4]);
     }
     if(qq<0){
     wireWrite(I2C_NTP8212,0x10,q[0]+32); 
     wireWrite(I2C_NTP8212,0x11,q[1]+32); 
     wireWrite(I2C_NTP8212,0x12,q[2]+32); 
     wireWrite(I2C_NTP8212,0x13,q[3]+32); 
     wireWrite(I2C_NTP8212,0x14,q[4]+32);
     }}
 
  for (int pos = 0; pos < 5; pos++) {lcd.setCursor(pos, 0);
    qqq[pos] = map(q[pos],-12,12,0,15);
    if (qqq[pos] > 7){lcd.write((uint8_t)qqq[pos] - 8);lcd.setCursor(pos, 1);lcd.write((uint8_t)7);} 
    else {lcd.print(" ");lcd.setCursor(pos, 1);lcd.write((uint8_t)qqq[pos]);}}
    lcd.setCursor(7,0);lcd.print("F ");
    switch(qi){
      case 0: lcd.print("100 Hz");break;
      case 1: lcd.print("300 Hz");break;
      case 2: lcd.print("1  kHz");break;
      case 3: lcd.print("3  kHz");break;
      case 4: lcd.print("10 kHz");break;
      }
    lcd.setCursor(7,1);lcd.print("G ");lcd.print(q[qi]);lcd.print(" dB  ");
 }
 
 //////// BALANCE /////////////////////////////////////////////////////////////// 
 if(menu==2){ 
   if(ir.value==IR_3){ball++;gr1=1;gr2=0;cl1();times=millis();www=1;w=1;w2=1;ball_fun();}// кнопка > 
   if(ir.value==0xFFFFFFFF and gr1==1){ball++;gr2=0;cl1();times=millis();www=1;w=1;w2=1;ball_fun();}// кнопка >>>>>>
   if(ir.value==IR_4){ball--;gr1=0;gr2=1;cl1();times=millis();www=1;w=1;w2=1;ball_fun();}// кнопка <
   if(ir.value==0xFFFFFFFF and gr2==1){ball--;gr1=0;cl1();times=millis();www=1;w=1;w2=1;ball_fun();}// кнопка <<<<<<  
 
   if (newPosition != oldPosition){oldPosition = newPosition;
   ball=ball-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;ball_fun();www=1;
   }
   if(www==1){www=0;
   wireWrite(I2C_NTP8212,0x2E,vol*2);// общая громкость
   wireWrite(I2C_NTP8212,0x2F,240+ball);// ПК громкость
   wireWrite(I2C_NTP8212,0x30,240-ball);// ЛК громкость
   }
   lcd.setCursor(4,0);lcd.print(F("   <>   "));lcd.setCursor(4,1);lcd.print(F("CHL  CHR"));
   chl=(4+ball)-4;chr=(4-ball)-4;
   if(chl<0){lcd.setCursor(12,0);chl=abs(chl);lcd.write((uint8_t)3);}else{lcd.setCursor(12,0);lcd.print(" ");}
   if(chr<0){lcd.setCursor(0,0);chr=abs(chr);lcd.write((uint8_t)3);}else{lcd.setCursor(0,0);lcd.print(" ");}
   if(w2==1){w2=0;a[0]=chl;a[1]=chr;
   for(i1=0;i1<2;i1++){
      switch(i1){
        case 0: e1=1,e2=2,e3=3;break;
        case 1: e1=13,e2=14,e3=15;break;
        }
      switch(a[i1]){
        case 0: d1=1,d2=8,d3=6,d4=1,d5=3,d6=6;break;
        case 1: d1=32,d2=2,d3=6,d4=32,d5=32,d6=6;break;
        case 2: d1=2,d2=8,d3=6,d4=1,d5=4,d6=5;break;
        case 3: d1=2,d2=4,d3=6,d4=7,d5=3,d6=6;break;
        case 4: d1=1,d2=3,d3=6,d4=32,d5=32,d6=6;break;
        case 5: d1=1,d2=4,d3=5,d4=7,d5=3,d6=6;break;
        case 6: d1=1,d2=4,d3=5,d4=1,d5=3,d6=6;break;
        case 7: d1=1,d2=8,d3=6,d4=32,d5=32,d6=6;break;
        case 8: d1=1,d2=4,d3=6,d4=1,d5=3,d6=6;break;
        case 9: d1=1,d2=4,d3=6,d4=7,d5=3,d6=6;break;
    }
      lcd.setCursor(e1,0);lcd.write((uint8_t)d1);lcd.setCursor(e2,0);lcd.write((uint8_t)d2);lcd.setCursor(e3,0);lcd.write((uint8_t)d3);
      lcd.setCursor(e1,1);lcd.write((uint8_t)d4);lcd.setCursor(e2,1);lcd.write((uint8_t)d5);lcd.setCursor(e3,1);lcd.write((uint8_t)d6);
 }}}     
 
 //// EEPROM ///////////////////////////////////////
 if(millis()-times>10000 && w==1 && power==0){w=0;EEPROM.update(0,vol);EEPROM.update(1,in);
 EEPROM.update(2,q[0]+100);EEPROM.update(3,q[1]+100);EEPROM.update(4,q[2]+100);EEPROM.update(5,q[3]+100);EEPROM.update(6,q[4]+100);
 EEPROM.update(7,ball);
 menu=0;cl();m0=1;w2=1;
 }
 
} // loop end
 
void ball_fun(){if(ball>8){ball=8;}if(ball<-8){ball=-8;}}
void cl(){ir.value=0;delay(300);lcd.clear();}
void cl1(){ir.value=0;delay(200);} 
void in_sw(){
  switch(in){
    case 0: digitalWrite(2,LOW);digitalWrite(3,LOW);break;
    case 1: digitalWrite(2,HIGH);digitalWrite(3,LOW);break;
    case 2: digitalWrite(2,LOW);digitalWrite(3,HIGH);break;
    case 3: digitalWrite(2,HIGH);digitalWrite(3,HIGH);break;
    }
  }
void init_ntp(){
  wireWrite(I2C_NTP8212,0x00,0b00011100);//I2S, slave mode|192kHz
  wireWrite(I2C_NTP8212,0x01,0b00000000);
  wireWrite(I2C_NTP8212,0x02,0b00000011);//User defined frequency. 
  wireWrite(I2C_NTP8212,0x03,GAIN);// mix
  wireWrite(I2C_NTP8212,0x04,GAIN);// mix
  wireWrite(I2C_NTP8212,0x05,GAIN);// mix
  wireWrite(I2C_NTP8212,0x06,GAIN);// mix
  wireWrite(I2C_NTP8212,0x0C,0b00001111);
  wireWrite(I2C_NTP8212,0x0D,40); // 3D Delay Amount 
  wireWrite(I2C_NTP8212,0x0E,0); // 3d
  wireWrite(I2C_NTP8212,0x0F,0b00000001); // 5-band graphic equalizer
  wireWrite(I2C_NTP8212,0x10,q[0]); // 100 Hz
  wireWrite(I2C_NTP8212,0x11,q[1]); // 300 Hz
  wireWrite(I2C_NTP8212,0x12,q[2]); // 1kHz
  wireWrite(I2C_NTP8212,0x13,q[3]); //3 kHz
  wireWrite(I2C_NTP8212,0x14,q[4]); // 10 kHz
  wireWrite(I2C_NTP8212,0x15,0xD0); // Prescaler Value Configuration
  wireWrite(I2C_NTP8212,0x17,0);
  wireWrite(I2C_NTP8212,0x18,0);
  wireWrite(I2C_NTP8212,0x19,0);
  wireWrite(I2C_NTP8212,0x1A,0);
  wireWrite(I2C_NTP8212,0x1C,0b00000000);
  wireWrite(I2C_NTP8212,0x1D,0b00000000);
  wireWrite(I2C_NTP8212,0x1E,0b00000000);
  wireWrite(I2C_NTP8212,0x1F,0b00000000);
  wireWrite(I2C_NTP8212,0x22,0b00000000);
  wireWrite(I2C_NTP8212,0x23,0b00000000);
  wireWrite(I2C_NTP8212,0x24,0b00000000);
  wireWrite(I2C_NTP8212,0x25,0b00000000);
  wireWrite(I2C_NTP8212,0x26,0b10000000); //Softmute [1:0] = 00 mute off
  wireWrite(I2C_NTP8212,0x27,0b00000000); // standby [1:0] = 11 ST on
  wireWrite(I2C_NTP8212,0x28,0b00000000); // otherwise >> PWM MASK output is high.
  wireWrite(I2C_NTP8212,0x29,0b00000000);
  wireWrite(I2C_NTP8212,0x2A,0b00000000);
  wireWrite(I2C_NTP8212,0x2B,0b00001011);
  wireWrite(I2C_NTP8212,0x2C,0b01000011);
  wireWrite(I2C_NTP8212,0x2D,0b00000000);
  wireWrite(I2C_NTP8212,0x2E,vol*2);// общая громкость
  wireWrite(I2C_NTP8212,0x2F,240+ball);// ПК громкость
  wireWrite(I2C_NTP8212,0x30,240-ball);// ЛК громкость
  wireWrite(I2C_NTP8212,0x32,0b00000010);
  wireWrite(I2C_NTP8212,0x33,0b00000000);
  wireWrite(I2C_NTP8212,0x38,0b00000010);// PWM D-BTL MODE (see 0x4E)
  wireWrite(I2C_NTP8212,0x39,0);//  I2C Glitch Filter
  wireWrite(I2C_NTP8212,0x4E,0x08);
  wireWrite(I2C_NTP8212,0x50,0b00000000);
  wireWrite(I2C_NTP8212,0x52,0b10010000);
  wireWrite(I2C_NTP8212,0x53,0b00000000);
  wireWrite(I2C_NTP8212,0x55,0b00000011);
  wireWrite(I2C_NTP8212,0x56,0b00100001);
  wireWrite(I2C_NTP8212,0x5A,0x10);
  wireWrite(I2C_NTP8212,0x5B,0x01);
  wireWrite(I2C_NTP8212,0x5C,0x00);
  wireWrite(I2C_NTP8212,0x5D,0b01000000);
  wireWrite(I2C_NTP8212,0x5F,0b00000000);
  wireWrite(I2C_NTP8212,0x61,0b00000001);
  wireWrite(I2C_NTP8212,0x62,0b00011000);//Power Device: Normal operation
  wireWrite(I2C_NTP8212,0x66,0b00000000);
  wireWrite(I2C_NTP8212,0x7C,0b00000000);
  wireWrite(I2C_NTP8212,0x7D,0b00000000);
  wireWrite(I2C_NTP8212,0x7E,0b00000000);
  }
 
byte wireRead(byte addr, byte reg){ // I2C
  Wire.beginTransmission(addr);
  Wire.write (reg);
  Wire.endTransmission();
  Wire.requestFrom(addr,1);
  while(Wire.available()<1);
  byte value = Wire.read();
  return value;
  }  
 
void wireWrite(byte addr, byte reg, byte data){
  Wire.beginTransmission(addr);
  Wire.write (reg);
  Wire.write (data);
  Wire.endTransmission();
  } 
 
void to_Timer(){newPosition = myEnc.read()/4;}  
 

Доработка №1:

  • Добавлен модуль часов реального времени DS3231
  • Показания часов выводятся в режиме POWER OFF (STANDBY)
  • Коррекция времени часов производится в режиме POWER OFF (STANDBY), для коррекции времени часов нажмите и удерживайте нажатой кнопку энкодера, далее нажать для коррекции кнопку:
    • MUTE — для корректировки часов
    • INPUT — для корректировки минут
    • POWER — для обнуления секунд

Схема модуля управления

Скетч — http://forum.rcl-radio.ru/viewtopic.php?pid=7178#p7178


Доработка №2:

  • Вывод в меню громкости информации о наличии сигнала S/PDIF.
  • При отсутствии сигнала (не подключен кабель, выбран не верный вход, длительная пауза при воспроизведении звука) усилитель переходит в режим STANDBY.

В схему ресивера и блока управления необходимо внести незначительные изменения

Скетч — http://forum.rcl-radio.ru/viewtopic.php?pid=7179#p7179

 

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

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