Регулятор громкости и тембра на LC75343M (Arduino)

ИМС LC75343M представляет собой аудиопроцессор специально разработанный для регулирования параметров аудиосигнала с минимальными искажениями. Аудиопроцессор включает в себя регулятор громкости, тембра, коммутатор входов и предусилители входов.

Более подробно об аудиопроцессоре можно узнать из статьи —  Аудиопроцессор LC75343M (Arduino)

Регулятор громкости и тембра построен на базе Arduino Nano.

Основные параметры регулятора громкости и тембра на LC75343M:

  • Регулировка громкость от 0 дБ до -78 дБ  (64 шага регулирования)
    • от 0 дБ до -50 дБ (шаг 1 дБ),
    • от -50 дБ до -70 дБ (шаг 2 дБ),
    • от -70 дБ до -78 дБ (шаг 4 дБ)
  • Независимая и групповая регулировка громкости
  • Регулировка тембра ±10 дБ с шагом 2 дБ
  • Трех полосная регулировка тембра
  • 5-и канальный стерео селектор входов
  • Предварительный усилитель входов от 0 дБ до +30 дБ (шаг 2 дБ)
  • Напряжение питания от 4,5 В до 9 В
  • Управление цифровое 3-Wire (максимальная тактовая частота 500 кГц)
  • Входное сопротивление 50 кОм
  • Коэффициент нелинейных искажений 0.007 %

Регулятор громкости содержит два основных блока, первый блок микроконтроллерный (Arduino Nano) с органами управления и индикации, второй блок плата аудиопроцессора.

Основное управление параметрами аудиопроцессора будет осуществляться при помощи энкодера (KY-040) и 3-х кнопок, так же будет применен ИК пульт который будет дублировать энкодер и кнопки управления. Вся информация будет выводится на дисплей LCD1602 + I2C (I2C модуль на базе микросхем PCF8574 позволяют подключить символьный дисплей 1602 к плате Arduino всего по двум проводам SDA и SCL (А4 и А5), что дает возможность не использовать цифровые выходы Arduino при подключении дисплея.)

Регулятор тембра имеет два меню, первое основное (main menu), содержит регуляторы громкости и тембра, второе меню (setting menu), содержит редко изменяемые параметры, такие как регулятор баланса и предусилитель входа.

Схема регулятора громкости и тембра

#define CE 3
#define DI 2
#define CL 4
 
#define IR1 0x33B850AF // main/setting menu
#define IR2 0x33B820DF // button encoder
#define IR3 0x33B8946B // mute
#define IR4 0x33B810EF // >>>
#define IR5 0x33B8E01F // <<<
#define IR6 0x33B844BB // INPUT
 
#include <Wire.h> 
#include <LiquidCrystal_I2C.h> // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
#include <Encoder.h>           // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip       
#include <EEPROM.h>
#include <MsTimer2.h>          // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip 
#include <boarddefs.h>         // входит в состав библиотеки IRremote
#include <IRremote.h>          // http://rcl-radio.ru/wp-content/uploads/2019/06/IRremote.zip
 
LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей
Encoder myEnc(8, 9);// DT, CLK
IRrecv irrecv(12); // указываем вывод модуля IR приемника
decode_results ir; 
 
byte input_m[8]={0b0001,0b1001,0b0101,0b1101,0b0011,0b0111,0b1111};
byte input_gain_m[16]{0b0000,0b1000,0b0100,0b1100,0b0010,0b1010,0b0110,0b1110,0b0001,0b1001,0b0101,0b1101,0b0011,0b1011,0b0111,0b1111};
byte volume_m[64]{0b000000,0b100000,0b010000,0b110000,0b001000,0b101000,0b011000,0b111000,0b000100,0b100100,0b010100,0b110100,0b001100,
0b101100,0b011100,0b111100,0b000010,0b100010,0b010010,0b110010,0b001010,0b101010,0b011010,0b111010,0b000110,0b100110,0b010110,0b110110,
0b001110,0b101110,0b011110,0b111110,0b000001,0b100001,0b010001,0b110001,0b001001,0b101001,0b011001,0b111001,0b000101,0b100101,0b010101,
0b110101,0b001101,0b101101,0b011101,0b111101,0b000011,0b100011,0b010011,0b110011,0b001011,0b101011,0b011011,0b111011,0b000111,0b100111,
0b010111,0b110111,0b001111,0b101111,0b011111,0b111111};
byte ch_sel_m[3]{0b10,0b01,0b11};
byte tembr_m[11]{0b1010,0b0010,0b1100,0b0100,0b1000,0b0000,0b1001,0b0101,0b1101,0b0011,0b1011};
byte v1[8] = {0b00111,0b00111,0b00111,0b00111,0b00111,0b00111,0b00111,0b00111};
byte v2[8] = {0b00111,0b00111,0b00000,0b00000,0b00000,0b00000,0b00000,0b00000};      
byte v3[8] = {0b00000,0b00000,0b00000,0b00000,0b00000,0b00000,0b11111,0b11111};
byte v4[8] = {0b11111,0b11111,0b00000,0b00000,0b00000,0b00000,0b11111,0b11111};
byte v5[8] = {0b11100,0b11100,0b00000,0b00000,0b00000,0b00000,0b11100,0b11100};
byte v6[8] = {0b11100,0b11100,0b11100,0b11100,0b11100,0b11100,0b11100,0b11100};
byte v7[8] = {0b00000,0b00000,0b00000,0b00000,0b00000,0b00000,0b00111,0b00111};
byte v8[8] = {0b11111,0b11111,0b00000,0b00000,0b00000,0b00000,0b00000,0b00000}; 
unsigned long times,oldPosition  = -999,newPosition;
int menu0=100,menu,vol_reg,in_reg,mute_reg,treb_reg,mid_reg,bass_reg,ball,fun,chl,chr,i,gain0,gain1,gain2,gain3,gain4,gain5,vol_old;
byte a[6],d1,d2,d3,d4,d5,d6,e1,e2,e3,w,w2,x,www,gr1,gr2;
 
 
void setup() {
  pinMode(CE,OUTPUT);pinMode(DI,OUTPUT);pinMode(CL,OUTPUT);
  digitalWrite(CL,LOW);digitalWrite(CE,LOW);digitalWrite(DI,LOW);
  irrecv.enableIRIn();lcd.init();lcd.backlight();Wire.begin();
  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);
   pinMode(10,INPUT);// encoder SW
   pinMode(11,INPUT_PULLUP);// input button
   pinMode(A0,INPUT_PULLUP);// menu set/main button
   pinMode(A1,INPUT_PULLUP);// mute button
  MsTimer2::set(1, to_Timer);MsTimer2::start();
  if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении  
  Serial.begin(9600);
  vol_reg = EEPROM.read(0);treb_reg = EEPROM.read(1);mid_reg = EEPROM.read(2);bass_reg = EEPROM.read(3);
   gain1 = EEPROM.read(4);gain2 = EEPROM.read(5);gain3 = EEPROM.read(6);gain4 = EEPROM.read(7);gain5 = EEPROM.read(8);
  in_reg = EEPROM.read(9);ball = EEPROM.read(10)-4;
    switch(in_reg){
     case 0: gain0 = gain1;break;
     case 1: gain0 = gain2;break;
     case 2: gain0 = gain3;break;
     case 3: gain0 = gain4;break;
     case 4: gain0 = gain5;break;}
  delay(100);audio_R();audio_L();
  lcd.setCursor(4,0);lcd.print("LC75343M");delay(1000);lcd.clear();
  }
 
void loop() {
 /// IR ////////////////////////////////////////
   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;}// запрет нажатий не активных кнопок пульта  
 /// BUTTON ///////////////////////////////////
   if((digitalRead(10)==LOW||ir.value==IR2)&&menu0==100){menu++;menu0=100;gr1=0;gr2=0;cl();times=millis();w=1;w2=1;if(menu>3){menu=0;}}
   if((digitalRead(10)==LOW||ir.value==IR2)&&menu==100){menu0++;menu=100;gr1=0;gr2=0;cl();times=millis();w=1;w2=1;if(menu0>1){menu0=0;}}
   if((digitalRead(11)==LOW||ir.value==IR6)){in_reg++;cl();times=millis();w=1;w2=1;if(in_reg>4){in_reg=0;}audio_R();audio_L();lcd.setCursor(4,0);lcd.print("INPUT ");lcd.print(in_reg+1);delay(1000);cl();}
   if((digitalRead(A0)==LOW||ir.value==IR1)&&menu<100){menu=100;menu0=0;gr1=0;gr2=0;cl();times=millis();w=1;w2=1;lcd.setCursor(2,0);lcd.print("SETTING MENU");delay(1000);cl();}
   if((digitalRead(A0)==LOW||ir.value==IR1)&&menu0<100){menu0=100;menu=0;gr1=0;gr2=0;cl();times=millis();w=1;w2=1;lcd.setCursor(3,0);lcd.print("MAIN MENU");delay(1000);cl();}
   if((digitalRead(A1)==LOW||ir.value==IR3)&&mute_reg==0){mute_reg=1;menu0=100;menu=100;cl();vol_old=vol_reg;vol_reg=0;audio_R();audio_L();lcd.setCursor(6,0);lcd.print("MUTE");}
   if((digitalRead(A1)==LOW||ir.value==IR3)&&mute_reg==1){mute_reg=0;menu0=100;menu=0;cl();vol_reg=vol_old;audio_R();audio_L();}
 
 ////////////// MENU MAIN /////////////////////////////////
 ////////////// VOLUME ///////////////////////////////////////////////////////////////////
 if(menu==0){
   if(ir.value==IR4){vol_reg++;gr1=1;gr2=0;cl1();times=millis();w=1;w2=1;vol_func();audio_R();audio_L();}// кнопка > 
   if(ir.value==0xFFFFFFFF and gr1==1){vol_reg++;gr2=0;cl1();times=millis();w=1;w2=1;vol_func();audio_R();audio_L();}// кнопка >>>>>>
   if(ir.value==IR5){vol_reg--;gr1=0;gr2=1;cl1();times=millis();w=1;w2=1;vol_func();audio_R();audio_L();}// кнопка <
   if(ir.value==0xFFFFFFFF and gr2==1){vol_reg--;gr1=0;cl1();times=millis();w=1;w2=1;vol_func();audio_R();audio_L();}// кнопка <<<<<<
 
   if (newPosition != oldPosition){oldPosition = newPosition;vol_reg=vol_reg+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;vol_func();audio_R();audio_L();}
   a[0]= (vol_reg-4)/10;a[1]=(vol_reg-4)%10;
   for(x=0;x<2;x++){switch(x){case 0: e1=10,e2=11,e3=12;break;case 1: e1=13,e2=14,e3=15;break;}digit();}
   if(mute_reg==0){lcd.setCursor(0,0);lcd.print("VOLUME");}else{lcd.setCursor(0,0);lcd.print("MUTE");}
   lcd.setCursor(0,1);lcd.print("INPUT ");lcd.print(in_reg+1);
   }
////////////// TREBLE ///////////////////////////////////////////////////////////////////
 if(menu==1){
   if(ir.value==IR4){treb_reg++;gr1=1;gr2=0;cl1();delay(200);times=millis();w=1;w2=1;treb_func();audio_R();audio_L();}// кнопка > 
   if(ir.value==0xFFFFFFFF and gr1==1){treb_reg++;gr2=0;cl1();delay(200);times=millis();w=1;w2=1;treb_func();audio_R();audio_L();}// кнопка >>>>>>
   if(ir.value==IR5){treb_reg--;gr1=0;gr2=1;cl1();delay(200);times=millis();w=1;w2=1;treb_func();audio_R();audio_L();}// кнопка <
   if(ir.value==0xFFFFFFFF and gr2==1){treb_reg--;gr1=0;cl1();delay(200);times=millis();w=1;w2=1;treb_func();audio_R();audio_L();}// кнопка <<<<<<
 
   if (newPosition != oldPosition){oldPosition = newPosition;treb_reg=treb_reg+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;treb_func();
   audio_R();audio_L();}
   a[0]= treb_reg/10;a[1]=treb_reg%10;
   for(x=0;x<2;x++){switch(x){case 0: e1=10,e2=11,e3=12;break;case 1: e1=13,e2=14,e3=15;break;}digit();}
   lcd.setCursor(0,0);lcd.print("TREBLE");lcd.setCursor(0,1);lcd.print("CONTROL");
   }  
////////////// MIDDLE ///////////////////////////////////////////////////////////////////
 if(menu==2){
   if(ir.value==IR4){mid_reg++;gr1=1;gr2=0;cl1();delay(200);times=millis();w=1;w2=1;mid_func();audio_R();audio_L();}// кнопка > 
   if(ir.value==0xFFFFFFFF and gr1==1){mid_reg++;gr2=0;cl1();delay(200);times=millis();w=1;w2=1;mid_func();audio_R();audio_L();}// кнопка >>>>>>
   if(ir.value==IR5){mid_reg--;gr1=0;gr2=1;cl1();delay(200);times=millis();w=1;w2=1;mid_func();audio_R();audio_L();}// кнопка <
   if(ir.value==0xFFFFFFFF and gr2==1){mid_reg--;gr1=0;cl1();delay(200);times=millis();w=1;w2=1;mid_func();audio_R();audio_L();}// кнопка <<<<<<
 
   if (newPosition != oldPosition){oldPosition = newPosition;mid_reg=mid_reg+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;mid_func();
   audio_R();audio_L();}
   a[0]= mid_reg/10;a[1]=mid_reg%10;
   for(x=0;x<2;x++){switch(x){case 0: e1=10,e2=11,e3=12;break;case 1: e1=13,e2=14,e3=15;break;}digit();}
   lcd.setCursor(0,0);lcd.print("MIDDLE");lcd.setCursor(0,1);lcd.print("CONTROL");
   } 
////////////// BASS ///////////////////////////////////////////////////////////////////
 if(menu==3){
   if(ir.value==IR4){bass_reg++;gr1=1;gr2=0;cl1();delay(200);times=millis();w=1;w2=1;bass_func();audio_R();audio_L();}// кнопка > 
   if(ir.value==0xFFFFFFFF and gr1==1){bass_reg++;gr2=0;cl1();delay(200);times=millis();w=1;w2=1;bass_func();audio_R();audio_L();}// кнопка >>>>>>
   if(ir.value==IR5){bass_reg--;gr1=0;gr2=1;cl1();delay(200);times=millis();w=1;w2=1;bass_func();audio_R();audio_L();}// кнопка <
   if(ir.value==0xFFFFFFFF and gr2==1){bass_reg--;gr1=0;cl1();delay(200);times=millis();w=1;w2=1;bass_func();audio_R();audio_L();}// кнопка <<<<<<
 
   if (newPosition != oldPosition){oldPosition = newPosition;bass_reg=bass_reg+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;bass_func();
   audio_R();audio_L();}
   a[0]= bass_reg/10;a[1]=bass_reg%10;
   for(x=0;x<2;x++){switch(x){case 0: e1=10,e2=11,e3=12;break;case 1: e1=13,e2=14,e3=15;break;}digit();}
   lcd.setCursor(0,0);lcd.print("BASS");lcd.setCursor(0,1);lcd.print("CONTROL");
   }    
//////// BALANCE /////////////////////////////////////////////////////////////// 
 if(menu0==0){ 
   if(ir.value==IR4){ball++;gr1=1;gr2=0;cl1();times=millis();w=1;w2=1;ball_fun();audio_R();audio_L();}// кнопка > 
   if(ir.value==IR5){ball--;gr1=0;gr2=1;cl1();times=millis();w=1;w2=1;ball_fun();audio_R();audio_L();}// кнопка <
 
   if (newPosition != oldPosition){oldPosition = newPosition;
   ball=ball-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;ball_fun();audio_R();audio_L();}
   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(i=0;i<2;i++){
      switch(i){
        case 0: e1=1,e2=2,e3=3;break;
        case 1: e1=13,e2=14,e3=15;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);
 }}}  
////////////// INPUT GAIN ///////////////////////////////////////////////////////////////////
 if(menu0==1){
  switch(in_reg){
     case 0: gain0 = gain1;break;
     case 1: gain0 = gain2;break;
     case 2: gain0 = gain3;break;
     case 3: gain0 = gain4;break;
     case 4: gain0 = gain5;break;}
 
   if(ir.value==IR4){gain0++;gr1=1;gr2=0;cl1();times=millis();w=1;w2=1;gain_func();audio_R();audio_L();}// кнопка > 
   if(ir.value==0xFFFFFFFF and gr1==1){gain0++;gr2=0;cl1();times=millis();w=1;w2=1;gain_func();audio_R();audio_L();}// кнопка >>>>>>
   if(ir.value==IR5){gain0--;gr1=0;gr2=1;cl1();times=millis();w=1;w2=1;gain_func();audio_R();audio_L();}// кнопка <
   if(ir.value==0xFFFFFFFF and gr2==1){gain0--;gr1=0;cl1();times=millis();w=1;w2=1;gain_func();audio_R();audio_L();}// кнопка <<<<<<
 
  if (newPosition != oldPosition){oldPosition = newPosition;gain0=gain0+newPosition;myEnc.write(0);newPosition=0;times=millis();www=1;w=1;w2=1;gain_func();}
  switch(in_reg){
     case 0: gain1 = gain0;break;
     case 1: gain2 = gain0;break;
     case 2: gain3 = gain0;break;
     case 3: gain4 = gain0;break;
     case 4: gain5 = gain0;break;}  
     a[0]= gain0/10;a[1]=gain0%10;
   for(x=0;x<2;x++){switch(x){case 0: e1=10,e2=11,e3=12;break;case 1: e1=13,e2=14,e3=15;break;}digit();}
   if(www==1){audio_R();audio_L();www=0;}
   lcd.setCursor(0,0);lcd.print("IN GAIN");
   lcd.setCursor(0,1);lcd.print("INPUT ");lcd.print(in_reg+1);}     
 
////////////////////////////////////////////////////////////////////////////////////////////
  if(millis()-times>10000 && w==1 && mute_reg==0){
     EEPROM.update(0,vol_reg);EEPROM.update(1,treb_reg);EEPROM.update(2,mid_reg);EEPROM.update(3,bass_reg);
     EEPROM.update(4,gain1);EEPROM.update(5,gain2);EEPROM.update(6,gain3);EEPROM.update(7,gain4);EEPROM.update(8,gain5);
     EEPROM.update(9,in_reg);EEPROM.update(10,ball+4);
     if(menu!=0){lcd.clear();menu=0;menu0=100;w=0;}}   
  }  // loop
 
void audio_R(){Write(in_reg,gain0,63-vol_reg-4+ball,  0 , 10-treb_reg,10-mid_reg,10-bass_reg );}  
void audio_L(){Write(in_reg,gain0,63-vol_reg-4-ball,  1 , 10-treb_reg,10-mid_reg,10-bass_reg );}  
 
void cl(){ir.value=0;delay(300);lcd.clear();}
void cl1(){ir.value=0;delay(300);}
void gain_func(){{if(gain0<0){gain0=0;}if(gain0>15){gain0=15;}}}
void ball_fun(){if(ball>4){ball=4;}if(ball<-4){ball=-4;}}
void treb_func(){if(treb_reg<0){treb_reg=0;}if(treb_reg>10){treb_reg=10;}}
void mid_func(){if(mid_reg<0){mid_reg=0;}if(mid_reg>10){mid_reg=10;}}
void bass_func(){if(bass_reg<0){bass_reg=0;}if(bass_reg>10){bass_reg=10;}}
void vol_func(){if(vol_reg<4){vol_reg=4;}if(vol_reg>63){vol_reg=63;}}
void to_Timer(){newPosition = myEnc.read()/4;}  
void digit(){switch(a[x]){
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);}
 
void Write(byte input,byte input_gain,byte volume,byte ch_sel,byte treb,byte mid,byte bass){
  digitalWrite(CL,LOW);
  digitalWrite(CE,LOW);
  byte addr = 0b01000001;
     for(int i = 7; i >= 0; i--){
        digitalWrite(CL,LOW);
        digitalWrite(DI, (addr >> i) & 0x01);
        digitalWrite(CL,HIGH);
        }  
  digitalWrite(CE,HIGH); 
      for(int i = 3; i >= 0; i--){
        digitalWrite(CL,LOW);
        digitalWrite(DI, (input_m[input] >> i) & 0x01);
        digitalWrite(CL,HIGH);
        }
      for(int i = 3; i >= 0; i--){
        digitalWrite(CL,LOW);
        digitalWrite(DI, (input_gain_m[input_gain] >> i) & 0x01);
        digitalWrite(CL,HIGH);
        }  
      for(int i = 5; i >= 0; i--){
        digitalWrite(CL,LOW);
        digitalWrite(DI, (volume_m[volume] >> i) & 0x01);
        digitalWrite(CL,HIGH);
        }  
      for(int i = 1; i >= 0; i--){
        digitalWrite(CL,LOW);
        digitalWrite(DI, (ch_sel_m[ch_sel] >> i) & 0x01);
        digitalWrite(CL,HIGH);
        }  
      for(int i = 3; i >= 0; i--){
        digitalWrite(CL,LOW);
        digitalWrite(DI, (tembr_m[treb] >> i) & 0x01);
        digitalWrite(CL,HIGH);
        }        
      for(int i = 3; i >= 0; i--){
        digitalWrite(CL,LOW);
        digitalWrite(DI, (tembr_m[mid] >> i) & 0x01);
        digitalWrite(CL,HIGH);
        }    
      for(int i = 3; i >= 0; i--){
        digitalWrite(CL,LOW);
        digitalWrite(DI, (tembr_m[bass] >> i) & 0x01);
        digitalWrite(CL,HIGH);
        }  
      for(int i = 3; i >= 0; i--){
        digitalWrite(CL,LOW);
        digitalWrite(DI, (0b1101 >> i) & 0x01);
        digitalWrite(CL,HIGH);
        }                                      
   digitalWrite(CL,LOW);
   digitalWrite(CE,LOW);             
  }

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

#define IR1 0x33B850AF // main/setting menu
#define IR2 0x33B820DF // button encoder
#define IR3 0x33B8946B // mute
#define IR4 0x33B810EF // >>>
#define IR5 0x33B8E01F // <<<
#define IR6 0x33B844BB // INPUT

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

MAIN MENU

SETTING MENU


Доработка

  • Добавлена функция STANDBY, при нажатии на кнопку POWER активируется функция STANDBY, выход D13 служит для управления работой усилителя (активация режима STANDBY).
  • В режиме STANDBY на экран выводится текущее время, для отсчета времени используются часы реального времени DS3231.

Коррекция времени часов: в режиме STANDBY нажать и удерживать кнопку энкодера, далее нажать кнопки INPUT, SET, MUTE для изменения времени часов, минут и обнуления секунд.

Так же предусмотрено изменение яркости дисплея в режиме STANDBY: выход D6 Arduino подключить к пину управления подсветки:

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

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

Яркость подсветки можно настроить через скетч:

#define BRIG_L 50
#define BRIG_H 250
  • BRIG_L — яркость в режиме STANDBY (0-250)
  • BRIG_H — яркость в рабочем режиме (0-250)

Схема

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


Доработка 2

Вывод в меню регулировки громкости часов

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

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

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