Регулятор громкости и тембра на LC75421M + 0.96′ I2C 128X64 OLED (Arduino)

Ранее в статье рассматривался пример создания на основе аудиопроцессора LC75421M регулятора громкости и тембра с использованием дисплея LCD1602 + I2C, в этой статье аналогичный пример, но с использованием дисплея 0.96′ I2C 128X64 OLED.

В OLED дисплее отсутствует дополнительный слой подсветки всей поверхности экрана. Каждый пиксел, формирующий изображение, испускает самостоятельное свечение. При этом картинка получается яркой и контрастной.

Управление OLED дисплеем в данном примере осуществляется при помощи шины I2C.

Параметры дисплея SSD1306:

  • Технология дисплея: OLED
  • Разрешение дисплея: 128 на 64 точки
  • Диагональ дисплея: 0,96 дюйма
  • Угол обзора: 160°
  • Напряжение питания: 2.8 В ~ 5.5 В
  • Мощность: 0,08 Вт
  • Габариты: 27.3 мм х 27.8 мм х 3.7 мм

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

Регулятор громкости и тембра на 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-х кнопок, так же будет применен ИК пульт который будет дублировать энкодер и кнопки управления.

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

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

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

Скетч:

// 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)
 
#include <Wire.h> 
#include <OLED_I2C.h>           // http://rcl-radio.ru/wp-content/uploads/2022/01/OLED_I2C.zip
#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
 
 
  DS3231 clock;RTCDateTime DateTime;
  OLED  myOLED(SDA, SCL, 8);
  extern uint8_t SmallFont[],BigNumbers[];
  IRrecv irrecv(12); // указываем вывод модуля IR приемника
  Encoder myEnc(9, 8);// DT, CLK
  decode_results ir; 
 
  unsigned long times,oldPosition  = -999,newPosition;
  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,old_sec,power,ball,chl,chr,i1;
  byte w,w2,gr1,gr2,www;
  byte a[6];
 
 
 
void setup(){
  Wire.begin();Wire.setClock(400000L);
  pinMode(CE,OUTPUT);pinMode(DI,OUTPUT);pinMode(CL,OUTPUT);
  digitalWrite(CL,LOW);digitalWrite(CE,LOW);digitalWrite(DI,LOW);
  irrecv.enableIRIn();clock.begin();
  myOLED.begin();
  myOLED.setBrightness(100);
 
  pinMode(10,INPUT);        // КНОПКА МЕНЮ  SW энкодера
  pinMode(11,INPUT_PULLUP); // КНОПКА INPUT
  pinMode(7,INPUT_PULLUP);  // КНОПКА MUTE 
  pinMode(13,OUTPUT);       // ВЫХОД УПРАВЛЕНИЯ STANDBY
  pinMode(A0,INPUT_PULLUP); // КНОПКА POWER
 
  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);}}// очистка памяти при первом включении  
  myOLED.clrScr();
  myOLED.setFont(SmallFont);
  myOLED.print(F("Sound Processors"), CENTER, 10);
  myOLED.print(F("LC75421"), CENTER, 30);
  myOLED.update();
  delay(2000);
  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 )) {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();delay(200);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;w=1;menu=100;cl();au();myOLED.clrScr();myOLED.setFont(SmallFont);myOLED.print(F("MUTE"), CENTER, 25);myOLED.update();}
    if((digitalRead(7)==LOW||ir.value==IR_7)&&mute_reg==1){mute_reg=0;w=1;menu=0;cl();au();}  
    }// power 
/// POWER ////////////////////////////////////
    if((digitalRead(A0)==LOW||ir.value==IR_8)&&power==0){power=1;menu=100;myOLED.setBrightness(1);cl();myEnc.write(0);mute_reg=1;
    myOLED.clrScr();myOLED.setFont(SmallFont);myOLED.print(F("POWER OFF"), CENTER, 10);myOLED.update();
    au();delay(2000);cl();}
 
    if((digitalRead(A0)==LOW||ir.value==IR_8)&&power==1&&digitalRead(10)==HIGH){power=0;menu=0;myOLED.setBrightness(100);cl();myEnc.write(0);mute_reg=0;w=1;
    myOLED.clrScr();myOLED.setFont(SmallFont);myOLED.print(F("POWER ON"), CENTER, 10);myOLED.update();
    au();delay(2000);cl();}  
    /// standby output 
    if(power==1){digitalWrite(13,LOW);}else{digitalWrite(13,HIGH);} 
 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
//////// VOLUME //////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  if(menu==0){
   if(newPosition != oldPosition){oldPosition = newPosition;vol_reg=vol_reg-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;vol_func();au();}
 
   if(ir.value==IR_4){vol_reg--;gr1=1;gr2=0;cl();times=millis();w=1;w2=1;vol_func();au();}// кнопка > 
   if(ir.value==0xFFFFFFFF and gr1==1){vol_reg--;gr2=0;cl();times=millis();w=1;w2=1;vol_func();au();}// кнопка >>>>>>
   if(ir.value==IR_5){vol_reg++;gr1=0;gr2=1;cl();times=millis();w=1;w2=1;vol_func();au();}// кнопка <
   if(ir.value==0xFFFFFFFF and gr2==1){vol_reg++;gr1=0;cl();times=millis();w=1;w2=1;vol_func();au();}// кнопка <<<<<<
 
  if(w==1){w=0;
  myOLED.clrScr();
  myOLED.setFont(SmallFont);myOLED.print(F("VOLUME"), LEFT, 0);myOLED.setFont(BigNumbers);myOLED.printNumI(80-vol_reg, 75, 0);
  myOLED.setFont(SmallFont);myOLED.print(F("IN"), LEFT, 10);
  myOLED.printNumI(in_reg, 20, 10);myOLED.print(F("GAIN"), LEFT, 20);myOLED.printNumI(gain0, 30, 20);
  myOLED.drawLine(0, 30, 128, 30);
  myOLED.setFont(SmallFont);myOLED.print(F("TREBLE"), LEFT, 35);myOLED.printNumI(treb_reg, 75, 35);
  myOLED.setFont(SmallFont);myOLED.print(F("BASS"), LEFT, 45);myOLED.printNumI(bass_reg, 75, 45);
  myOLED.setFont(SmallFont);myOLED.print(F("S_BASS"), LEFT, 55);myOLED.printNumI(s_bass_reg, 75, 55);
  myOLED.update();
  }}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
 
//////// TREBLE //////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  if(menu==1){
  if (newPosition != oldPosition){oldPosition = newPosition;treb_reg=treb_reg+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;treb_func();au();}
 
   if(ir.value==IR_4){treb_reg++;gr1=1;gr2=0;cl();times=millis();w=1;w2=1;treb_func();au();}// кнопка > 
   if(ir.value==IR_5){treb_reg--;gr1=0;gr2=1;cl();times=millis();w=1;w2=1;treb_func();au();}// кнопка <
 
  if(w==1){w=0;
  myOLED.clrScr();
  myOLED.setFont(SmallFont);myOLED.print(F("TREBLE"), LEFT, 0);;myOLED.setFont(BigNumbers);myOLED.printNumI(treb_reg, 75, 0);
  myOLED.drawLine(0, 30, 128, 30);
  myOLED.setFont(SmallFont);myOLED.print(F("BASS"), LEFT, 35);myOLED.printNumI(bass_reg, 75, 35);
  myOLED.setFont(SmallFont);myOLED.print(F("S_BASS"), LEFT, 45);myOLED.printNumI(s_bass_reg, 75, 45);
  myOLED.setFont(SmallFont);myOLED.print(F("BALANCE"), LEFT, 55);myOLED.printNumI(ball, 75, 55);myOLED.print(F("dB"), RIGHT, 55);
  myOLED.update();
  }}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
 
//////// BASS //////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  if(menu==2){
  if (newPosition != oldPosition){oldPosition = newPosition;bass_reg=bass_reg+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;bass_func();au();}
 
   if(ir.value==IR_4){bass_reg++;gr1=1;gr2=0;cl();times=millis();w=1;w2=1;bass_func();au();}// кнопка > 
   if(ir.value==IR_5){bass_reg--;gr1=0;gr2=1;cl();times=millis();w=1;w2=1;bass_func();au();}// кнопка <
 
  if(w==1){w=0;
  myOLED.clrScr();
  myOLED.setFont(SmallFont);myOLED.print(F("BASS"), LEFT, 0);;myOLED.setFont(BigNumbers);myOLED.printNumI(bass_reg, 75, 0);
  myOLED.drawLine(0, 30, 128, 30);
  myOLED.setFont(SmallFont);myOLED.print(F("S_BASS"), LEFT, 35);myOLED.printNumI(s_bass_reg, 75, 35);
  myOLED.setFont(SmallFont);myOLED.print(F("BALANCE"), LEFT, 45);myOLED.printNumI(ball, 75, 45);myOLED.print(F("dB"), RIGHT, 45);
  myOLED.setFont(SmallFont);myOLED.print(F("VOLUME"), LEFT, 55);myOLED.printNumI(80-vol_reg, 75, 55);
  myOLED.update();
  }}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
 
//////// SUPER_BASS //////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  if(menu==3){
  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();}
 
   if(ir.value==IR_4){s_bass_reg++;gr1=1;gr2=0;cl();times=millis();w=1;w2=1;s_bass_func();au();}// кнопка > 
   if(ir.value==IR_5){s_bass_reg--;gr1=0;gr2=1;cl();times=millis();w=1;w2=1;s_bass_func();au();}// кнопка <
 
  if(w==1){w=0;
  myOLED.clrScr();
  myOLED.setFont(SmallFont);myOLED.print(F("S_BASS"), LEFT, 0);myOLED.setFont(BigNumbers);myOLED.printNumI(s_bass_reg, 75, 0);
  myOLED.drawLine(0, 30, 128, 30);
  myOLED.setFont(SmallFont);myOLED.print(F("BALANCE"), LEFT, 35);myOLED.printNumI(ball, 75, 35);myOLED.print(F("dB"), RIGHT, 35);
  myOLED.setFont(SmallFont);myOLED.print(F("VOLUME"), LEFT, 45);myOLED.printNumI(80-vol_reg, 75, 45);
  myOLED.setFont(SmallFont);myOLED.print(F("TREBLE"), LEFT, 55);myOLED.printNumI(treb_reg, 75, 55);
 
  myOLED.update();
  }}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
 
//////// BALANCE //////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  if(menu==4){
  if (newPosition != oldPosition){oldPosition = newPosition;ball=ball+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;ball_fun();au();}
 
   if(ir.value==IR_4){ball++;gr1=1;gr2=0;cl();times=millis();w=1;w2=1;ball_fun();au();}// кнопка > 
   if(ir.value==IR_5){ball--;gr1=0;gr2=1;cl();times=millis();w=1;w2=1;ball_fun();au();}// кнопка <
 
  if(w==1){w=0;
  myOLED.clrScr();
  myOLED.setFont(SmallFont);myOLED.print(F("BALANCE"), LEFT, 0);;myOLED.setFont(BigNumbers);myOLED.printNumI(abs(ball), 75, 0);
  myOLED.setFont(SmallFont);myOLED.print(F("dB"), RIGHT, 0);
  if(ball<=0){myOLED.print(F("LCH"), 35, 20);}
  if(ball>=0){myOLED.print(F("RCH"), RIGHT, 20);}
  myOLED.drawLine(0, 30, 128, 30);
  myOLED.setFont(SmallFont);myOLED.print(F("VOLUME"), LEFT, 35);myOLED.printNumI(80-vol_reg, 75, 35);
  myOLED.setFont(SmallFont);myOLED.print(F("TREBLE"), LEFT, 45);myOLED.printNumI(treb_reg, 75, 45);
  myOLED.setFont(SmallFont);myOLED.print(F("BASS"), LEFT, 55);myOLED.printNumI(bass_reg, 75, 55); 
  myOLED.update();
  }}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
////////////// 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;cl();times=millis();w=1;w2=1;gain_func();au();}// кнопка > 
   if(ir.value==0xFFFFFFFF and gr1==1){gain0++;gr2=0;cl();times=millis();w=1;w2=1;gain_func();au();}// кнопка >>>>>>
   if(ir.value==IR_5){gain0--;gr1=0;gr2=1;cl();times=millis();w=1;w2=1;gain_func();au();}// кнопка <
   if(ir.value==0xFFFFFFFF and gr2==1){gain0--;gr1=0;cl();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;
     }  
  if(www==1){au();www=0;}
 
  if(w==1){w=0;
  myOLED.clrScr();
  myOLED.setFont(SmallFont);myOLED.print(F("INPUT"), LEFT, 0);myOLED.setFont(BigNumbers);myOLED.printNumI(in_reg, 65, 0);
  myOLED.drawLine(0, 30, 128, 30);
  myOLED.setFont(SmallFont);myOLED.print(F("GAIN"), LEFT, 35);myOLED.setFont(BigNumbers);myOLED.printNumI(gain0, 65, 35);
  myOLED.update();
  }} 
 
/////////////////// ЧАСЫ ///////////////////////////////////////////////////////////////////
if(power==1){
  DateTime = clock.getDateTime();hour = DateTime.hour;minut = DateTime.minute;secon = DateTime.second;   
     a[0]=hour/10;
     a[1]=hour%10;
     a[2]=minut/10;
     a[3]=minut%10;
     a[4]=secon/10;
     a[5]=secon%10;
  if(old_sec!=secon){
  myOLED.clrScr();
  myOLED.setFont(BigNumbers);myOLED.printNumI(a[0], 15, 5);myOLED.printNumI(a[1], 30, 5);
  myOLED.setFont(SmallFont);myOLED.print(F(":"), 45, 15);
  myOLED.setFont(BigNumbers);myOLED.printNumI(a[2], 50, 5);myOLED.printNumI(a[3], 65, 5);
  myOLED.setFont(SmallFont);myOLED.print(F(":"), 80, 15);
  myOLED.setFont(BigNumbers);myOLED.printNumI(a[4], 85, 5);myOLED.printNumI(a[5], 100, 5);
  myOLED.update();
  } 
  old_sec=secon;
//// 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 && w2==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);
     cl();menu=0;w2=0;w=1;}        
} // 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(){myOLED.clrScr();ir.value=0;delay(300);}
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 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)

Для получения кодов кнопок Вашего пульта загрузите скетч:

#include <boarddefs.h> // входит в состав библиотеки IRremote
#include <IRremote.h> // http://rcl-radio.ru/wp-content/uploads/2019/06/IRremote.zip

IRrecv irrecv(12); // указываем вывод модуля IR приемника
decode_results ir;

void setup(){
irrecv.enableIRIn();
Serial.begin(9600);
}

void loop(){
if ( irrecv.decode( &ir )) {Serial.print(«0x»);Serial.println( ir.value,HEX);irrecv.resume();}
}

Далее откройте монитор порта, в котором при нажатии кнопки пульта Вы увидите коды кнопок.

Comments

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

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