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

Ранее в http://rcl-radio.ru/?p=128799 был показан пример тестового запуска аудиопроцессора LC75421M, на этой странице будет показан пример практического применения аудиопроцессора в качестве регулятора громкости и тембра.

Регулятор громкости и тембра на LC75421M содержит следующие компоненты:

  • Аудиопроцессор LC75421M
  • Плата Arduino Nano (Atmega328)
  • Энкодер KY-040 (модуль)
  • Три тактовые кнопки
  • Модуль часов реального времени DS3231
  • ИК-датчик VS1838B
  • Пульт ДУ (NEC)
  • Дисплей LCD1602 с модулем I2C

Регулятор громкости и тембра на LC75421M обладает следующими характеристиками:

  • Регулировка громкости от -76 до 0 дБ (шаг 1 дБ)
  • Регулировка баланса ±4 дБ
  • Регулировка BASS от 0 до 14 шагов (±11.9 дБ)
  • Регулировка TREBLE от 0 до 14 шагов (±11.9 дБ)
  • Регулировка SUPER BASS от 0 до 10 шагов (0…+20 дБ)
  • 5-и канальный селектор входов с независимой регулировкой предусилителя от 0 до 18,75 дБ
  • Режим MUTE
  • Режим STANDBY
  • Часы с коррекцией времени
  • Напряжение питания от 7,5 до 10 В
  • Изменение яркости подсветки

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

Громкость

BASS

SUPER BASS

TREBLE

Баланс

Часы (работаю в режиме STANDBY)

Коррекция времени часов: в режиме STANDBY нажать и удерживать кнопку энкодера, далее нажать кнопки INPUT,  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)

Схема подключения аудиопроцессора

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

Скетч:

// LC75421
#define CE 3
#define DI 2
#define CL 4
// IR
#define IR_2 0x2FDB24D // Кнопка menu
#define IR_4 0x2FD906F // Кнопка >
#define IR_5 0x2FDF20D // Кнопка <
#define IR_6 0x2FD6A95 // Кнопка IN
#define IR_7 0x2FDF00F // Кнопка MUTE
#define IR_8 0x2FD00FF // Кнопка STANDBY (POWER)
// LED
#define BRIG_L 50       // 0...250 яркость power on
#define BRIG_H 250      // 0...250 яркость power off
 
#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
#include <DS3231.h>             // http://rcl-radio.ru/wp-content/uploads/2022/07/DS3231.zip
 
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}; 
 
  DS3231 clock;RTCDateTime DateTime;
  LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей
  IRrecv irrecv(12); // указываем вывод модуля IR приемника
  Encoder myEnc(9, 8);// DT, CLK
  decode_results ir; 
 
  unsigned long times,oldPosition  = -999,newPosition;
  byte a[6],d1,d2,d3,d4,d5,d6,e1,e2,e3,w,w2,x,gr1,gr2,www;
  int menu,vol_reg,mute_reg,in_reg,bass_reg,s_bass_reg,treb_reg;
  int gain0,gain1,gain2,gain3,gain4,gain5;
  int hour,minut,secon,power,ball,chl,chr,i1;
 
 
 
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();clock.begin();Serial.begin(9600);
  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);        // КНОПКА МЕНЮ  SW энкодера
  pinMode(11,INPUT_PULLUP); // КНОПКА INPUT
  pinMode(7,INPUT_PULLUP);  // КНОПКА MUTE 
  pinMode(13,OUTPUT);       // ВЫХОД УПРАВЛЕНИЯ STANDBY
  pinMode(A0,INPUT_PULLUP); // КНОПКА POWER
  pinMode(6,OUTPUT);        // PWM output LED подсветка
  analogWrite(6, BRIG_H);
  MsTimer2::set(3, to_Timer);MsTimer2::start();
  //  clock.setDateTime(__DATE__, __TIME__); // Устанавливаем время на часах, основываясь на времени компиляции скетча
  if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении  
  delay(200);
  vol_reg = EEPROM.read(0);treb_reg = EEPROM.read(1);bass_reg = EEPROM.read(2);s_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;
     }
  au();
  }
 
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(power==0){
   if(mute_reg==0){   
     if(digitalRead(10)==LOW||ir.value==IR_2){menu++;gr1=0;gr2=0;cl();times=millis();w=1;w2=1;if(menu>4){menu=0;}}
     if(digitalRead(11)==LOW||ir.value==IR_6){in_reg++;menu=5;cl();times=millis();w=1;w2=1;www=1;if(in_reg>5){in_reg=1;}}
     }
     if((digitalRead(7)==LOW||ir.value==IR_7)&&mute_reg==0){mute_reg=1;menu=100;cl();au();lcd.setCursor(6,0);lcd.print("MUTE");}
     if((digitalRead(7)==LOW||ir.value==IR_7)&&mute_reg==1){mute_reg=0;menu=0;cl();au();}   
     }// power 
/// POWER ////////////////////////////////////
 if((digitalRead(A0)==LOW||ir.value==IR_8)&&power==0){power=1;menu=100;analogWrite(6,BRIG_L);cl();myEnc.write(0);mute_reg=1;lcd.setCursor(4,0);lcd.print("POWER OFF");au();delay(2000);cl();}
 if((digitalRead(A0)==LOW||ir.value==IR_8)&&power==1&&digitalRead(10)==HIGH){power=0;menu=0;analogWrite(6,BRIG_H);cl();myEnc.write(0);mute_reg=0;lcd.setCursor(4,0);lcd.print("POWER  ON");au();delay(2000);cl();}    
/// standby output 
 if(power==1){digitalWrite(13,LOW);}else{digitalWrite(13,HIGH);}
 
 
////////////// VOLUME ///////////////////////////////////////////////////////////////////
 if(menu==0){
   if(ir.value==IR_5){vol_reg++;gr1=1;gr2=0;cl1();times=millis();w=1;w2=1;vol_func();au();}// кнопка > 
   if(ir.value==0xFFFFFFFF and gr1==1){vol_reg++;gr2=0;cl1();times=millis();w=1;w2=1;vol_func();au();}// кнопка >>>>>>
   if(ir.value==IR_4){vol_reg--;gr1=0;gr2=1;cl1();times=millis();w=1;w2=1;vol_func();au();}// кнопка <
   if(ir.value==0xFFFFFFFF and gr2==1){vol_reg--;gr1=0;cl1();times=millis();w=1;w2=1;vol_func();au();}// кнопка <<<<<<
 
   if (newPosition != oldPosition){oldPosition = newPosition;vol_reg=vol_reg-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;vol_func();au();}
   a[0]= (80-vol_reg)/10;a[1]=(80-vol_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();}
   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);
  }
 
////////////// TREBLE ///////////////////////////////////////////////////////////////////
 if(menu==1){
   if(ir.value==IR_4){treb_reg++;gr1=1;gr2=0;cl1();delay(200);times=millis();w=1;w2=1;treb_func();au();}// кнопка > 
   if(ir.value==0xFFFFFFFF and gr1==1){treb_reg++;gr2=0;cl1();delay(200);times=millis();w=1;w2=1;treb_func();au();}// кнопка >>>>>>
   if(ir.value==IR_5){treb_reg--;gr1=0;gr2=1;cl1();delay(200);times=millis();w=1;w2=1;treb_func();au();}// кнопка <
   if(ir.value==0xFFFFFFFF and gr2==1){treb_reg--;gr1=0;cl1();delay(200);times=millis();w=1;w2=1;treb_func();au();}// кнопка <<<<<<
 
   if (newPosition != oldPosition){oldPosition = newPosition;treb_reg=treb_reg+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;treb_func();au();}
   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");
   }  
////////////// BASS ///////////////////////////////////////////////////////////////////
 if(menu==2){
   if(ir.value==IR_4){bass_reg++;gr1=1;gr2=0;cl1();delay(200);times=millis();w=1;w2=1;bass_func();au();}// кнопка > 
   if(ir.value==0xFFFFFFFF and gr1==1){bass_reg++;gr2=0;cl1();delay(200);times=millis();w=1;w2=1;bass_func();au();}// кнопка >>>>>>
   if(ir.value==IR_5){bass_reg--;gr1=0;gr2=1;cl1();delay(200);times=millis();w=1;w2=1;bass_func();au();}// кнопка <
   if(ir.value==0xFFFFFFFF and gr2==1){bass_reg--;gr1=0;cl1();delay(200);times=millis();w=1;w2=1;bass_func();au();}// кнопка <<<<<<
 
   if (newPosition != oldPosition){oldPosition = newPosition;bass_reg=bass_reg+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;bass_func();au();}
   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");
   }  
////////////// SUPER_BASS ///////////////////////////////////////////////////////////////////
 if(menu==3){
   if(ir.value==IR_4){s_bass_reg++;gr1=1;gr2=0;cl1();delay(200);times=millis();w=1;w2=1;s_bass_func();au();}// кнопка > 
   if(ir.value==0xFFFFFFFF and gr1==1){s_bass_reg++;gr2=0;cl1();delay(200);times=millis();w=1;w2=1;s_bass_func();au();}// кнопка >>>>>>
   if(ir.value==IR_5){s_bass_reg--;gr1=0;gr2=1;cl1();delay(200);times=millis();w=1;w2=1;s_bass_func();au();}// кнопка <
   if(ir.value==0xFFFFFFFF and gr2==1){s_bass_reg--;gr1=0;cl1();delay(200);times=millis();w=1;w2=1;s_bass_func();au();}// кнопка <<<<<<
 
   if (newPosition != oldPosition){oldPosition = newPosition;s_bass_reg=s_bass_reg+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;s_bass_func();au();}
   a[0]= s_bass_reg/10;a[1]=s_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("S_BASS");lcd.setCursor(0,1);lcd.print("CONTROL");
   } 
//////// BALANCE /////////////////////////////////////////////////////////////// 
 if(menu==4){ 
   if(ir.value==IR_4){ball++;gr1=1;gr2=0;cl1();times=millis();w=1;w2=1;ball_fun();au();}// кнопка > 
   if(ir.value==IR_5){ball--;gr1=0;gr2=1;cl1();times=millis();w=1;w2=1;ball_fun();au();}// кнопка <
 
   if (newPosition != oldPosition){oldPosition = newPosition;
   ball=ball-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;ball_fun();au();}
   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);
 }}}     
////////////// INPUT GAIN ///////////////////////////////////////////////////////////////////
 if(menu==5){
  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==IR_4){gain0++;gr1=1;gr2=0;cl1();times=millis();w=1;w2=1;gain_func();au();}// кнопка > 
   if(ir.value==0xFFFFFFFF and gr1==1){gain0++;gr2=0;cl1();times=millis();w=1;w2=1;gain_func();au();}// кнопка >>>>>>
   if(ir.value==IR_5){gain0--;gr1=0;gr2=1;cl1();times=millis();w=1;w2=1;gain_func();au();}// кнопка <
   if(ir.value==0xFFFFFFFF and gr2==1){gain0--;gr1=0;cl1();times=millis();w=1;w2=1;gain_func();au();}// кнопка <<<<<<
 
  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){au();www=0;}
   lcd.setCursor(0,0);lcd.print("IN GAIN");lcd.setCursor(0,1);lcd.print("INPUT ");lcd.print(in_reg);}      
 
/////////////////// ЧАСЫ ///////////////////////////////////////////////////////////////////
DateTime = clock.getDateTime();hour = DateTime.hour;minut = DateTime.minute;secon = DateTime.second;   
if(power==1){
     a[0]=DateTime.hour/10;
     a[1]=DateTime.hour%10;
     a[2]=DateTime.minute/10;
     a[3]=DateTime.minute%10;
     a[4]=DateTime.second/10;
     a[5]=DateTime.second%10;
   for(x=0;x<4;x++){
    switch(x){
        case 0: e1=0,e2=1,e3=2;break;
        case 1: e1=3,e2=4,e3=5;break;
        case 2: e1=7,e2=8,e3=9;break;
        case 3: e1=10,e2=11,e3=12;break;
   }digit();}
 
   lcd.setCursor(6,0);lcd.print(".");lcd.setCursor(6,1);lcd.print(".");
   lcd.setCursor(14,1);lcd.print(a[4]);lcd.setCursor(15,1);lcd.print(a[5]);   
//// set time ////
  if(digitalRead(10)==LOW&&digitalRead(11)==LOW){hour++;if(hour>23){hour=0;} clock.setDateTime(2022, 7, 15, hour, minut, secon);delay(100);}// input button HH++
  if(digitalRead(10)==LOW&&digitalRead(7)==LOW){minut++;if(minut>59){minut=0;} clock.setDateTime(2022, 7, 15, hour, minut, secon);delay(100);}// mute MM++
}                 
 
 
////////////////// EEPROM //////////////////////////////////////////////////////////////
 if(millis()-times>5000 && w==1 && mute_reg==0){
     EEPROM.update(0,vol_reg);EEPROM.update(1,treb_reg);EEPROM.update(2,bass_reg);EEPROM.update(3,s_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;}w=0;}        
} // loop end
 
void ball_fun(){if(ball>4){ball=4;}if(ball<-4){ball=-4;}}
void gain_func(){if(gain0<0){gain0=0;}if(gain0>15){gain0=15;}}
void vol_func(){if(vol_reg<4){vol_reg=4;}if(vol_reg>80){vol_reg=80;}}
void treb_func(){if(treb_reg<0){treb_reg=0;}if(treb_reg>14){treb_reg=14;}}
void bass_func(){if(bass_reg<0){bass_reg=0;}if(bass_reg>14){bass_reg=14;}} 
void s_bass_func(){if(s_bass_reg<0){s_bass_reg=0;}if(s_bass_reg>10){s_bass_reg=10;}}  
void to_Timer(){newPosition = myEnc.read()/4;} 
void cl(){ir.value=0;delay(300);lcd.clear();}
void cl1(){ir.value=0;delay(200);}  
void au(){
       //fader s _bass     bass      treb      vol            in_g   in      rf  out_g ch mute
  audio(15,    s_bass_reg, bass_reg, treb_reg, vol_reg-ball,  gain0, in_reg, 1,  0,    1, mute_reg );// Lch (ch=1) | front(rf=1,fader=15)
  audio(15,    s_bass_reg, bass_reg, treb_reg, vol_reg+ball,  gain0, in_reg, 0,  0,    2, mute_reg );// Rch (ch=2) | rear (rf=0,fader=15)
  }
 
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 audio(int fader, int super_bass, int bass, int treb, int vol, int in_gain, int in, int rf, int out_gain, int ch, int mute){
  byte tembr[15]{0b1111,0b0111,0b1011,0b0011,0b1101,0b0101,0b1001,0b0000,0b1000,0b0100,0b1100,0b0010,0b1010,0b0110,0b1110}; 
  byte volume_m[81]{0b000100101,0b11000101,0b01000101,0b10000101,0b00111001,0b11011001,0b01011001,0b10011001,0b00101001,0b11001001,0b01001001,0b10001001,0b00110001,
0b11010001,0b01010001,0b10010001,0b00100001,0b11000001,0b01000001,0b10000001,0b00111110,0b11011110,0b01011110,0b10011110,0b00101110,0b11001110,0b01001110,0b10001110,
0b00110110,0b11010110,0b01010110,0b10010110,0b00100110,0b11000110,0b01000110,0b10000110,0b00111010,0b11011010,0b01011010,0b10011010,0b00101010,0b11001010,0b01001010,
0b10001010,0b00110010,0b11010010,0b01010010,0b10010010,0b00100010,0b11000010,0b01000010,0b10000010,0b00111100,0b11011100,0b01011100,0b10011100,0b00101100,0b11001100,
0b01001100,0b10001100,0b00110100,0b11010100,0b01010100,0b10010100,0b00100100,0b11000100,0b01000100,0b10000100,0b00111000,0b11011000,0b01011000,0b10011000,0b00101000,
0b11001000,0b01001000,0b10001000,0b00110000,0b11010000,0b01010000,0b10010000,0b00000000};
 
  digitalWrite(CL,LOW);
  digitalWrite(CE,LOW);
    byte addr = 0b10000001;                                         
 for(int i = 7; i >= 0; i--){
   digitalWrite(CL,LOW);
   digitalWrite(DI, (addr >> i) & 0x01);
   digitalWrite(CL,HIGH);
   }
   digitalWrite(CL,LOW);
   delayMicroseconds(1);
   digitalWrite(CE,HIGH);
 
///////////// Fader step control /////////////////////////
/// int 0...15 === - ... 0 dB
// 0...3 bit
for(int i = 0; i <= 3; i++){
   digitalWrite(CL,LOW);
  switch(i){
   case 0: digitalWrite(DI, (fader & 0b0001)>>0);break;
   case 1: digitalWrite(DI, (fader & 0b0010)>>1);break;
   case 2: digitalWrite(DI, (fader & 0b0100)>>2);break;
   case 3: digitalWrite(DI, (fader & 0b1000)>>3);break;
   }
   digitalWrite(CL,HIGH);
   }
/////////////// Super bass control ////////////////////////
/// int 0...10 === flat ... boos max
// 4...7 bit
for(int i = 0; i <= 3; i++){
   digitalWrite(CL,LOW);
  switch(i){
   case 0: digitalWrite(DI, (super_bass & 0b0001)>>0);break;
   case 1: digitalWrite(DI, (super_bass & 0b0010)>>1);break;
   case 2: digitalWrite(DI, (super_bass & 0b0100)>>2);break;
   case 3: digitalWrite(DI, (super_bass & 0b1000)>>3);break;
   }
   digitalWrite(CL,HIGH);
   }
//////////// bass //////////////////////////////////
/// int 0...14 === step1...step15
// 8...11 bit
  for(int i = 3; i >= 0; i--){
        digitalWrite(CL,LOW);
        digitalWrite(DI, (tembr[bass] >> i) & 0x01);
        digitalWrite(CL,HIGH);
        }  
//////////// treb //////////////////////////////////
/// int 0...14 === step1...step15
// 12...15 bit
  for(int i = 3; i >= 0; i--){
        digitalWrite(CL,LOW);
        digitalWrite(DI, (tembr[treb] >> i) & 0x01);
        digitalWrite(CL,HIGH);
        }  
//////////// volume /////////////////////////
// int 0...80 === -79...0 dB
// 16...23 bit
  for(int i = 7; i >= 0; i--){
        digitalWrite(CL,LOW);
        digitalWrite(DI, (volume_m[vol] >> i) & 0x01);
        digitalWrite(CL,HIGH);
        }  
///////////// input gain control /////////////////////////
/// int 0...15 === 0 ... 18.75 dB
// 24...27 bit
for(int i = 0; i <= 3; i++){
   digitalWrite(CL,LOW);
  switch(i){
   case 0: digitalWrite(DI, (in_gain & 0b0001)>>0);break;
   case 1: digitalWrite(DI, (in_gain & 0b0010)>>1);break;
   case 2: digitalWrite(DI, (in_gain & 0b0100)>>2);break;
   case 3: digitalWrite(DI, (in_gain & 0b1000)>>3);break;
   }
   digitalWrite(CL,HIGH);
   } 
/////////// input_1 //////////////////////////////////
/// int 1...5 === in1...in5
// 28...29 bit
    int in1;
  switch(in){
    case 1:  in1 = 0b00;break;                       
    case 2:  in1 = 0b10;break; 
    case 3:  in1 = 0b01;break;                          
    case 4:  in1 = 0b11;break;  
    case 5:  in1 = 0b00;break;                      
    }
  for(int i = 1; i >= 0; i--){
    digitalWrite(CL,LOW);
    digitalWrite(DI, (in1 >> i) & 0x01);
    digitalWrite(CL,HIGH);
    }  
////////// rear/front ///////////
// int 0...1 === rear...front  
// 30 bit      
    digitalWrite(CL,LOW);
    digitalWrite(DI, rf);
    digitalWrite(CL,HIGH);
////////// out gain ///////////
// int 0...3 === 0 0 +6.5 +8.5 
// 31 bit
   int out_gain1;
   switch(out_gain){
    case 0: out_gain1 = 0;break;
    case 1: out_gain1 = 0;break;
    case 2: out_gain1 = 1;break;
    case 3: out_gain1 = 1;break;
    }      
    digitalWrite(CL,LOW);
    digitalWrite(DI, out_gain1);
    digitalWrite(CL,HIGH);    
/////////// input_2 //////////////////////////////////
/// int 1...5 === in1...in5
// 32 bit
    int in2;
  switch(in){
    case 1:  in2 = 1;break;                       
    case 2:  in2 = 1;break; 
    case 3:  in2 = 1;break;                          
    case 4:  in2 = 1;break;  
    case 5:  in2 = 0;break;                      
    }
    digitalWrite(CL,LOW);
    digitalWrite(DI, in2);
    digitalWrite(CL,HIGH);
/////////// Channel selection //////////////////////////////////
/// int 0...3 === Initial setting, Lch, Rch, LR
// 33...34 bit
  switch(ch){
    case 0:  ch = 0b00;break;                       
    case 1:  ch = 0b01;break; 
    case 2:  ch = 0b10;break;                          
    case 3:  ch = 0b11;break;                        
    }
  for(int i = 1; i >= 0; i--){
    digitalWrite(CL,LOW);
    digitalWrite(DI, (ch >> i) & 0x01);
    digitalWrite(CL,HIGH);
    }
////////// mute ///////////
// int 0...1 === off...on 
// 35 bit      
    digitalWrite(CL,LOW);
    digitalWrite(DI, mute);
    digitalWrite(CL,HIGH);  
///// test ////////////
// 36...38 bit
  for(int i = 2; i >= 0; i--){
    digitalWrite(CL,LOW);
    digitalWrite(DI, 0);
    digitalWrite(CL,HIGH);  
    }          
////////// out gain ///////////
// int 0...3 === 0 0 +6.5 +8.5 
// 39 bit
   int out_gain2;
   switch(out_gain){
    case 0: out_gain2 = 0;break;
    case 1: out_gain2 = 1;break;
    case 2: out_gain2 = 0;break;
    case 3: out_gain2 = 1;break;
    }      
    digitalWrite(CL,LOW);
    digitalWrite(DI, out_gain2);
    digitalWrite(CL,HIGH); 
 ///// test ////////////
 // 40 ... 43 bit
  for(int i = 3; i >= 0; i--){
    digitalWrite(CL,LOW);
    digitalWrite(DI, 0);
    digitalWrite(CL,HIGH);     
    }
//// end byte    
    digitalWrite(CL,LOW);
    delayMicroseconds(1);
    digitalWrite(CE,LOW);

  }

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

#define IR_2 0x2FDB24D // Кнопка menu
#define IR_4 0x2FD906F // Кнопка >
#define IR_5 0x2FDF20D // Кнопка <
#define IR_6 0x2FD6A95 // Кнопка IN
#define IR_7 0x2FDF00F // Кнопка MUTE
#define IR_8 0x2FD00FF // Кнопка STANDBY (POWER)

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

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

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