#define IR2    0xCB0 // button encoder (pause)
#define IR3    0xC0D // mute
#define IR4    0xCB4 // >>>
#define IR5    0xCB2 // <<<
#define IR6    0x33B844BB // INPUT
#define POWER  0xC3D // STANDBY
#define TUNER  0xC7F
#define DSR    0xDBF
#define CD     0xD3F
#define TAPE   0xCBF
#define DCC    0xDFF
#define PHONO  0xD7F
#include <LC75341.h>           // http://rcl-radio.ru/wp-content/uploads/ … c75341.zip
#include <Wire.h> 
#include <MsTimer2.h>          // http://rcl-radio.ru/wp-content/uploads/ … Timer2.zip 
#include <OLED_I2C.h>          // http://rcl-radio.ru/wp-content/uploads/ … ED_I2C.zip
#include <Encoder.h>           // http://rcl-radio.ru/wp-content/uploads/ … ncoder.zip 
#include <EEPROM.h>
#include <boarddefs.h>         // входит в состав библиотеки IRremote
#include <IRremote.h>          // http://rcl-radio.ru/wp-content/uploads/ … remote.zip
Encoder myEnc(9, 8);// DT, CLK
OLED  myOLED(SDA, SCL, 8);
LC75341 lc(3,4,2);   // CE,DI,CL 
IRrecv irrecv(12); // указываем вывод модуля IR приемника
decode_results ir; 
extern uint8_t SmallFont[],BigNumbers[];
long times,oldPosition  = -999,newPosition;
int vol_reg,menu,mute_reg,power,treb_reg,gain0,gain1,gain2,gain3,gain4,gain5,bass_reg,in_reg,ball,vol_old;
bool w,w2,gr1,gr2,www,standby;
int u;
void setup(){
  Wire.begin();Wire.setClock(400000L);
  irrecv.enableIRIn();
  myOLED.begin();
  myOLED.setBrightness(100);
  Serial.begin(9600);
  MsTimer2::set(1, to_Timer);MsTimer2::start();
  pinMode(10,INPUT);        // encoder SW
  pinMode(7,INPUT_PULLUP);  // mute button
  pinMode(11,INPUT_PULLUP); // input button
//  pinMode(6,INPUT_PULLUP);  // standby button
//  pinMode(5,OUTPUT);        // out standby
  vol_reg = EEPROM.read(0);treb_reg = EEPROM.read(1)-5;bass_reg = EEPROM.read(2);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;
     }
  audio_L();
  audio_R();
}
void loop(){
/// IR ////////////////////////////////////////
   if ( irrecv.decode( &ir )) {Serial.print("0x");Serial.println( ir.value,HEX);u++;irrecv.resume();times=millis();w=1;w2=1;}// IR приемник - чтение, в мониторе порта отображаются коды кнопок
   if(u>1){ir.value=0;u=0;}
   if(ir.value==0){gr1=0;gr2=0;}// запрет нажатий не активных кнопок пульта   
//////// BUTTON /////////////////////////////////////////////////////////////////////////////////////////////////////////////
 if(standby==0){
 if(mute_reg==0){
   if(digitalRead(10)==LOW||ir.value==IR2){menu++;gr1=0;gr2=0;cl();times=millis();w=1;w2=1;if(menu>3){menu=0;}}
   if((digitalRead(11)==LOW||ir.value==IR6)){in_reg++;menu=4;cl();times=millis();w=1;w2=1;www=1;if(in_reg>3){in_reg=0;}}
  }
   if((digitalRead(7)==LOW||ir.value==IR3)&&mute_reg==0){mute_reg=1;menu=100;cl();vol_old=vol_reg;vol_reg=79;audio_R();audio_L();myOLED.clrScr();myOLED.setFont(SmallFont);
       myOLED.print(F("MUTE"), CENTER, 25);myOLED.update();}
   if((digitalRead(7)==LOW||ir.value==IR3)&&mute_reg==1){mute_reg=0;w=1;menu=0;cl();vol_reg=vol_old;audio_R();audio_L();}
 }
   if((digitalRead(6)==LOW||ir.value==POWER)&&standby==0){standby=1;menu=100;cl();;vol_old=vol_reg;vol_reg=79;audio_R();audio_L();myOLED.clrScr();myOLED.setFont(SmallFont);
        myOLED.print(F("POWER OFF"), CENTER, 25);myOLED.update();digitalWrite(5,LOW);delay(2000);myOLED.setBrightness(0);myOLED.clrScr();myOLED.update();}
   if((digitalRead(6)==LOW||ir.value==POWER)&&standby==1){standby=0;w=1;menu=0;cl();vol_reg=vol_old;audio_R();audio_L();myOLED.setBrightness(100);} 
   if((digitalRead(6)==LOW||ir.value==TUNER)&&standby==1){standby=0;w=1;menu=0;cl();vol_reg=vol_old;audio_R();audio_L();myOLED.setBrightness(100);}
   if((digitalRead(6)==LOW||ir.value==DSR)&&standby==1){standby=0;w=1;menu=0;cl();vol_reg=vol_old;audio_R();audio_L();myOLED.setBrightness(100);}
   if((digitalRead(6)==LOW||ir.value==CD)&&standby==1){standby=0;w=1;menu=0;cl();vol_reg=vol_old;audio_R();audio_L();myOLED.setBrightness(100);}
   if((digitalRead(6)==LOW||ir.value==TAPE)&&standby==1){standby=0;w=1;menu=0;cl();vol_reg=vol_old;audio_R();audio_L();myOLED.setBrightness(100);}
   if((digitalRead(6)==LOW||ir.value==DCC)&&standby==1){standby=0;w=1;menu=0;cl();vol_reg=vol_old;audio_R();audio_L();myOLED.setBrightness(100);}
   if((digitalRead(6)==LOW||ir.value==PHONO)&&standby==1){standby=0;w=1;menu=0;cl();vol_reg=vol_old;audio_R();audio_L();myOLED.setBrightness(100);}    
   if(standby==1){digitalWrite(5,LOW);}else{digitalWrite(5,HIGH);}
   
//////// VOLUME //////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  if(menu==0){
  if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;}
  vol_reg=vol_reg+newPosition*4;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;vol_func();audio_R();audio_L();}
   if(ir.value==IR5){vol_reg++/2;gr1=1;gr2=0;cl();times=millis();w=1;w2=1;vol_func();audio_R();audio_L();}// кнопка > 
   if(ir.value==0xFFFFFFFF and gr1==1){vol_reg++;gr2=0;cl();times=millis();w=1;w2=1;vol_func();audio_R();audio_L();}// кнопка >>>>>>
   if(ir.value==IR4){vol_reg--/2;gr1=0;gr2=1;cl();times=millis();w=1;w2=1;vol_func();audio_R();audio_L();}// кнопка <
   if(ir.value==0xFFFFFFFF and gr2==1){vol_reg--;gr1=0;cl();times=millis();w=1;w2=1;vol_func();audio_R();audio_L();}// кнопка <<<<<<
  if(w==1){w=0;
  myOLED.clrScr();
  myOLED.setFont(SmallFont);myOLED.print(F("VOLUME"), LEFT, 0);myOLED.setFont(BigNumbers);myOLED.printNumI(79-vol_reg, 65, 0);
  myOLED.setFont(SmallFont);myOLED.print(F("IN"), LEFT, 10);
  myOLED.printNumI(in_reg+1, 20, 10);myOLED.print(F("GAIN"), LEFT, 20);myOLED.printNumI(gain0*2, 30, 20);
  myOLED.drawLine(0, 30, 128, 30);
  myOLED.setFont(SmallFont);myOLED.print(F("TREBLE"), LEFT, 35);myOLED.printNumI(treb_reg*2, 70, 35);myOLED.print(F("dB"), RIGHT, 35);
  myOLED.setFont(SmallFont);myOLED.print(F("BASS"), LEFT, 45);myOLED.printNumI(bass_reg*2, 70, 45);myOLED.print(F("dB"), RIGHT, 45);
  myOLED.setFont(SmallFont);myOLED.print(F("BALANCE"), LEFT, 55);myOLED.printNumI(ball, 70, 55);myOLED.print(F("dB"), RIGHT, 55);
  myOLED.update();
  }}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
//////// TREBLE //////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  if(menu==1){
  if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;}
  treb_reg=treb_reg-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;treb_func();audio_R();audio_L();}
   if(ir.value==IR4){treb_reg++;gr1=1;gr2=0;cl();times=millis();w=1;w2=1;treb_func();audio_R();audio_L();}// кнопка > 
   if(ir.value==IR5){treb_reg--;gr1=0;gr2=1;cl();times=millis();w=1;w2=1;treb_func();audio_R();audio_L();}// кнопка <
  if(w==1){w=0;
  myOLED.clrScr();
  myOLED.setFont(SmallFont);myOLED.print(F("TREBLE"), LEFT, 0);;myOLED.setFont(BigNumbers);myOLED.printNumI(treb_reg*2, 65, 0);
  myOLED.setFont(SmallFont);myOLED.print(F("dB"), RIGHT, 0);
  myOLED.drawLine(0, 30, 128, 30);
  myOLED.setFont(SmallFont);myOLED.print(F("BASS"), LEFT, 35);myOLED.printNumI(bass_reg*2, 70, 35);myOLED.print(F("dB"), RIGHT, 35);
  myOLED.setFont(SmallFont);myOLED.print(F("BALANCE"), LEFT, 45);myOLED.printNumI(ball, 70, 45);myOLED.print(F("dB"), RIGHT, 45);
  myOLED.setFont(SmallFont);myOLED.print(F("VOLUME"), LEFT, 55);myOLED.printNumI(79-vol_reg, 70, 55);
  myOLED.update();
  }}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
//////// BASS //////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  if(menu==2){
  if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;}
  bass_reg=bass_reg-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;bass_func();audio_R();audio_L();}
   if(ir.value==IR4){bass_reg++;gr1=1;gr2=0;cl();times=millis();w=1;w2=1;bass_func();audio_R();audio_L();}// кнопка > 
   if(ir.value==IR5){bass_reg--;gr1=0;gr2=1;cl();times=millis();w=1;w2=1;bass_func();audio_R();audio_L();}// кнопка <
  if(w==1){w=0;
  myOLED.clrScr();
  myOLED.setFont(SmallFont);myOLED.print(F("BASS"), LEFT, 0);;myOLED.setFont(BigNumbers);myOLED.printNumI(bass_reg*2, 65, 0);
  myOLED.setFont(SmallFont);myOLED.print(F("dB"), RIGHT, 0);
  myOLED.drawLine(0, 30, 128, 30);
  myOLED.setFont(SmallFont);myOLED.print(F("BALANCE"), LEFT, 35);myOLED.printNumI(ball, 70, 35);myOLED.print(F("dB"), RIGHT, 35);
  myOLED.setFont(SmallFont);myOLED.print(F("VOLUME"), LEFT, 45);myOLED.printNumI(79-vol_reg, 70, 45);
  myOLED.setFont(SmallFont);myOLED.print(F("TREBLE"), LEFT, 55);myOLED.printNumI(treb_reg*2, 70, 55);myOLED.print(F("dB"), RIGHT, 55);
  myOLED.update();
  }}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
//////// BALANCE //////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  if(menu==3){
  if(newPosition != oldPosition){oldPosition = newPosition;if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;}
  ball=ball-newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;ball_func();audio_R();audio_L();}
   if(ir.value==IR4){ball++;gr1=1;gr2=0;cl();times=millis();w=1;w2=1;ball_func();audio_R();audio_L();}// кнопка > 
   if(ir.value==IR5){ball--;gr1=0;gr2=1;cl();times=millis();w=1;w2=1;ball_func();audio_R();audio_L();}// кнопка <
  if(w==1){w=0;
  myOLED.clrScr();
  myOLED.setFont(SmallFont);myOLED.print(F("BALANCE"), LEFT, 0);;myOLED.setFont(BigNumbers);myOLED.printNumI(abs(ball), 65, 0);
  myOLED.setFont(SmallFont);myOLED.print(F("dB"), RIGHT, 0);
  if(ball<=0){myOLED.print(F("LCH"), 20, 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(79-vol_reg, 70, 35);
  myOLED.setFont(SmallFont);myOLED.print(F("TREBLE"), LEFT, 45);myOLED.printNumI(treb_reg*2, 70, 45);myOLED.print(F("dB"), RIGHT, 45);
  myOLED.setFont(SmallFont);myOLED.print(F("BASS"), LEFT, 55);myOLED.printNumI(bass_reg*2, 70, 55);myOLED.print(F("dB"), RIGHT, 55);  
  myOLED.update();
  }}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
////////////// INPUT GAIN ///////////////////////////////////////////////////////////////////
 if(menu==4){
  switch(in_reg){
     case 0: gain0 = gain1;break;
     case 1: gain0 = gain2;break;
     case 2: gain0 = gain3;break;
     case 3: gain0 = gain4;break;
     }
  if (newPosition != oldPosition){oldPosition = newPosition;gain0=gain0-newPosition;myEnc.write(0);newPosition=0;times=millis();www=1;w=1;w2=1;gain_func();}
   if(ir.value==IR4){gain0++;gr1=1;gr2=0;cl();times=millis();w=1;w2=1;gain_func();audio_R();audio_L();}// кнопка > 
   if(ir.value==IR5){gain0--;gr1=0;gr2=1;cl();times=millis();w=1;w2=1;gain_func();audio_R();audio_L();}// кнопка <
  switch(in_reg){
     case 0: gain1 = gain0;break;
     case 1: gain2 = gain0;break;
     case 2: gain3 = gain0;break;
     case 3: gain4 = gain0;break;
     }  
  if(www==1){audio_R();audio_L();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+1, 65, 0);
  myOLED.drawLine(0, 30, 128, 30);
  myOLED.setFont(SmallFont);myOLED.print(F("GAIN"), LEFT, 35);myOLED.setFont(BigNumbers);myOLED.printNumI(gain0*2, 65, 35);
  myOLED.setFont(SmallFont);myOLED.print(F("dB"), RIGHT, 35);
  myOLED.update();
  }}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////   
////////////////// EEPROM //////////////////////////////////////////////////////////////
 if(millis()-times>10000 && w2==1 && mute_reg==0 && standby==0){
     EEPROM.update(0,vol_reg);EEPROM.update(1,treb_reg+5);EEPROM.update(2,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){menu=0;}w=1;w2=0;}   
}// end loop
void treb_func(){if(treb_reg<-5){treb_reg=-5;}if(treb_reg>5){treb_reg=5;}}
void gain_func(){{if(gain0<0){gain0=0;}if(gain0>15){gain0=15;}}}
void ball_func(){if(ball>4){ball=4;}if(ball<-4){ball=-4;}}
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>79){vol_reg=79;}}
void to_Timer(){newPosition = myEnc.read()/4;} 
void cl(){myOLED.clrScr();ir.value=0;delay(300);}
void audio_L(){
  lc.addr();
  lc.set_input(in_reg);   // input 1...4 = byte 0...3 (byte 4...7 = All switches off)
  lc.set_gain(gain0);    // gain 0...30 dB step 2 dB = byte 0...15
  lc.set_volume(vol_reg-ball);  // volume 0...-79 dB = byte 0...79
  lc.set_treble(treb_reg);  // treble -10...10 dB step 2 dB = int -5...5 
  lc.set_bass(bass_reg);    // bass 0...20 dB step 2 dB = int 0...10
  lc.set_ch(1);      // Channel Selection RCH = byte 2, LCH = byte 1, Left and right together = byte 3 
  lc.test();
  }
void audio_R(){
  lc.addr();
  lc.set_input(in_reg);   // input 1...4 = byte 0...3 (byte 4...7 = All switches off)
  lc.set_gain(gain0);    // gain 0...30 dB step 2 dB = byte 0...15
  lc.set_volume(vol_reg+ball);  // volume 0...-79 dB = byte 0...79
  lc.set_treble(treb_reg);  // treble -10...10 dB step 2 dB = int -5...5 
  lc.set_bass(bass_reg);    // bass 0...20 dB step 2 dB = int 0...10
  lc.set_ch(2);      // Channel Selection RCH = byte 2, LCH = byte 1, Left and right together = byte 3 
  lc.test();
  }