#define IR_1 0x2FDD02F // Кнопка вверх
#define IR_2 0x2FD32CD // Кнопка вниз
#define IR_3 0x2FD906F // Кнопка >
#define IR_4 0x2FDF20D // Кнопка <
#define IR_5 0x2FD708F // Кнопка IN
#define IR_6 0x2FD00FF // Кнопка POWER
#define IR_7 0x2FD2AD5 // Кнопка MUTE
#include <Wire.h>
#include <EEPROM.h>
#include <R2A15908SP.h>
#include <boarddefs.h>
#include <IRremote.h> // http://rcl-radio.ru/wp-content/uploads/2019/06/IRremote.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
R2A15908SP ra;
Encoder myEnc(8, 9);// D8, D9 = CLK, DT
IRrecv irrecv(12); // D12 = IR
decode_results ir;
LiquidCrystal_I2C lcd(0x27,16,2); // SDA, SCL
byte a1[8] = {0b00000,0b10101,0b10101,0b10101,0b10101,0b10101,0b10101,0b00000};
byte a2[8] = {0b00000,0b10100,0b10100,0b10100,0b10100,0b10100,0b10100,0b00000};
byte a3[8] = {0b00000,0b10000,0b10000,0b10000,0b10000,0b10000,0b10000,0b00000};
unsigned long oldPosition = -999,newPosition,times,times1;
byte z,z0,z1,w,w2,power,gr1,gr2,in,in_old,xd,www,mute;
int mode,menu,vol,menu_in,x,gain0,gain1,gain2,gain3,gain4,gain5,bas,treb,ball,stereo;
void setup(){
Serial.begin(9600);
pinMode(7,INPUT); // кнопка энкодера
OCR2A = 200; TCCR1B |= (1 << WGM22)|(1 << CS20)|(1 << CS21); TIMSK2 |= (1 << OCIE2A); // timer2
Wire.begin();lcd.init();lcd.backlight();irrecv.enableIRIn();
lcd.createChar(0,a1);lcd.createChar(1,a2);lcd.createChar(2,a3);
lcd.setCursor(0,0);lcd.print(F(" R2A15908SP "));
delay(2000);lcd.clear();
if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}// очистка памяти при первом включении
vol = EEPROM.read(0);in = EEPROM.read(1);bas = EEPROM.read(2)-7;treb = EEPROM.read(3)-7;ball = EEPROM.read(4)-6;
stereo = EEPROM.read(5);mode = EEPROM.read(6);
gain1 = EEPROM.read(10);gain2 = EEPROM.read(11);gain3 = EEPROM.read(12);gain4 = EEPROM.read(13);gain5 = EEPROM.read(14);
switch(in){
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;}
audio();
}
void loop(){
/////////////////// IR ///////////////////////////////////
if ( irrecv.decode( &ir )) {Serial.print("0x");Serial.println( ir.value,HEX);irrecv.resume();times=millis();w=1;}// IR приемник - чтение, в мониторе порта отображаются коды кнопок
if(ir.value==0){gr1=0;gr2=0;}// запрет нажатий не активных кнопок пульта
if(power==0){
if(ir.value==IR_2 && mute==0){menu++;gr1=0;gr2=0;cl2();times=millis();w=1;w2=1;if(menu>5){menu=0;}}// меню кнопка вверх
if(ir.value==IR_1 && mute==0){menu--;gr1=0;gr2=0;cl2();times=millis();w=1;w2=1;if(menu<0){menu=5;}}// меню кнопка вниз
if(ir.value==IR_5){menu=0;in++;gr1=0;gr2=0;cl2();times=millis();w=1;w2=1;if(in>4){in = 0;}audio();}// IN
if(ir.value==IR_7 && mute==0){mute=1;menu=100;;gr1=0;gr2=0;cl2();times=millis();w=1;w2=1;in_old=in;in=7;audio();lcd.setCursor(0,0);lcd.print(F(" MUTE "));delay(300);}// MUTE
if(ir.value==IR_7 && mute==1){mute=0;menu=0;;gr1=0;gr2=0;cl2();times=millis();w=1;w2=1;in=in_old;audio();delay(300);}// MUTE
}
if(ir.value==IR_6 && power==0){power=1;menu=100;gr1=0;gr2=0;cl2();times=millis();w=1;w2=1;in_old=in;in=7;audio();lcd.setCursor(0,0);lcd.print(F(" POWER OFF "));delay(3000);lcd.noBacklight();}// кнопка POWER OFF
if(ir.value==IR_6 && power==1){power=0;menu=0;gr1=0;gr2=0;cl2();times=millis();w=1;w2=1;in=in_old;audio();lcd.setCursor(0,0);lcd.backlight();lcd.print(F(" POWER ON "));delay(1000);lcd.clear();}// кнопка POWER OFF
//////////////// INPUT MENU //////////////////////////////////////////////////////////
if(power==0){
if(digitalRead(7)==LOW && menu_in==0 && mute==0){x++;xd=1;delay(200);}
if(digitalRead(7)==HIGH && menu_in==0 && x>0 && mute==0){xd=1;x=0;times=millis();times1=millis();w=1;w2=1;}
if(x > 5){menu_in=1;lcd.clear();lcd.setCursor(0,0);lcd.print(F(" INPUT MENU "));delay(1000);lcd.clear(); times1 = millis();}
if(menu_in==1){menu=0;x=0;if(digitalRead(7)==LOW){times=millis();times1=millis();w=1;w2=1;in++;www=1;if(in>4){in = 0;}delay(200); }
//gain
switch(in){
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 (newPosition != oldPosition) {
oldPosition = newPosition;
gain0=gain0+newPosition;myEnc.write(0);newPosition=0;times=millis();times1=millis();w=1;w2=1;www=1;gain_func();audio();}
switch(in){
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){audio();www=0;}
lcd.setCursor(5,1);lcd.print(" ");lcd.print(gain0*2);lcd.print(" ");lcd.setCursor(8,1);lcd.print(F(" dB"));
// end gain
lcd.setCursor(3,0);lcd.print(F("INPUT "));
switch(in){
case 0: lcd.print(F("AUX1"));break;
case 1: lcd.print(F("AUX2"));break;
case 2: lcd.print(F("AUX3"));break;
case 3: lcd.print(F("AUX4"));break;
case 4: lcd.print(F("AUX5"));break;}}
if(digitalRead(7)==HIGH && millis()-times1>3000 && menu_in==1){x=0;menu=-1;menu_in=0;times=millis();times1=millis();w=1;w2=1;lcd.clear();}
if(digitalRead(7)==HIGH && xd == 1 && menu_in==0){menu++;times=millis();w=1;w2=1;xd=0;lcd.clear();if(menu>5){menu=0;}}
}
///////////////// END INPUT MENU ///////////////////////////////////////////////////////
//////////////////// VOLUME /////////////////////////////////
if(menu==0 && menu_in==0 && power==0){
if(ir.value==IR_3){vol++;gr1=1;gr2=0;cl();times=millis();w=1;w2=1;vol_func();audio();}// кнопка >
if(ir.value==0xFFFFFFFF and gr1==1){vol++;gr2=0;cl();times=millis();w=1;w2=1;vol_func();audio();}// кнопка >>>>>>
if(ir.value==IR_4){vol--;gr1=0;gr2=1;cl();times=millis();w=1;w2=1;vol_func();audio();}// кнопка <
if(ir.value==0xFFFFFFFF and gr2==1){vol--;gr1=0;cl();times=millis();w=1;w2=1;vol_func();audio();}// кнопка <<<<<<
if (newPosition != oldPosition){oldPosition = newPosition;
vol=vol+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;vol_func();audio();}
lcd.setCursor(0,0);lcd.print(F("VOLUME "));
if(vol<10){lcd.setCursor(8,0);}else{lcd.setCursor(7,0);}lcd.print(" ");lcd.print(vol-12);lcd.print(" ");
lcd.setCursor(12,0);
switch(in){
case 0: lcd.print(F("AUX1"));break;
case 1: lcd.print(F("AUX2"));break;
case 2: lcd.print(F("AUX3"));break;
case 3: lcd.print(F("AUX4"));break;
case 4: lcd.print(F("AUX5"));break;}
if(w2==1){
for(z=0,z0=0,z1=0;z<=map(vol, 12,87, 0, 48);z++,z1++){if(z1>2){z1=0;z0++;}
if(z1==1){lcd.setCursor(z0,1);lcd.write((uint8_t)0);lcd.setCursor(z0+1,1);lcd.print(F(" "));}}
if(z1==3){lcd.setCursor(z0,1);lcd.write((uint8_t)1);}
if(z1==2){lcd.setCursor(z0,1);lcd.write((uint8_t)2);}w2=0;}}
///////////////////////// BASS +/-14 dB /////////////////////////////////////////////////////////
if(menu==1){
if(ir.value==IR_3){bas++;gr1=1;gr2=0;cl3();times=millis();w=1;w2=1;bass_func();audio();}// кнопка >
if(ir.value==0xFFFFFFFF and gr1==1){bas++;gr2=0;cl3();times=millis();w=1;w2=1;bass_func();audio();}// кнопка >>>>>>
if(ir.value==IR_4){bas--;gr1=0;gr2=1;cl3();times=millis();w=1;w2=1;bass_func();audio();}// кнопка <
if(ir.value==0xFFFFFFFF and gr2==1){bas--;gr1=0;cl3();times=millis();w=1;w2=1;bass_func();audio();}// кнопка <<<<<<
if (newPosition != oldPosition) {
oldPosition = newPosition;
bas=bas+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;bass_func();audio();}
lcd.setCursor(0,0);lcd.print(F("BASS "));
if(bas>=0){lcd.print(F("+"));}lcd.print(bas*2);lcd.print(" ");lcd.setCursor(13,0);lcd.print(F("dB"));
if(w2==1){
for(z=0,z0=0,z1=0;z<=(bas*2+14+1);z++,z1++){if(z1>2){z1=0;z0++;}
if(z1==1){lcd.setCursor(z0+3,1);lcd.write((uint8_t)0);lcd.setCursor(z0+1+3,1);lcd.print(F(" "));}}
if(z1==3){lcd.setCursor(z0+3,1);lcd.write((uint8_t)1);}
if(z1==2){lcd.setCursor(z0+3,1);lcd.write((uint8_t)2);}w2=0;}}
/////////////////////// END BASS //////////////////////////////////
///////////////////////// TREBLE +/-14 dB /////////////////////////////////////////////////////////
if(menu==2){
if(ir.value==IR_3){treb++;gr1=1;gr2=0;cl3();times=millis();w=1;w2=1;treb_func();audio();}// кнопка >
if(ir.value==0xFFFFFFFF and gr1==1){treb++;gr2=0;cl3();times=millis();w=1;w2=1;treb_func();audio();}// кнопка >>>>>>
if(ir.value==IR_4){treb--;gr1=0;gr2=1;cl3();times=millis();w=1;w2=1;treb_func();audio();}// кнопка <
if(ir.value==0xFFFFFFFF and gr2==1){treb--;gr1=0;cl3();times=millis();w=1;w2=1;treb_func();audio();}// кнопка <<<<<<
if (newPosition != oldPosition) {
oldPosition = newPosition;
treb=treb+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;treb_func();audio();}
lcd.setCursor(0,0);lcd.print(F("TREBLE "));
if(treb>=0){lcd.print(F("+"));}lcd.print(treb*2);lcd.print(" ");lcd.setCursor(13,0);lcd.print(F("dB"));
if(w2==1){
for(z=0,z0=0,z1=0;z<=(treb*2+14+1);z++,z1++){if(z1>2){z1=0;z0++;}
if(z1==1){lcd.setCursor(z0+3,1);lcd.write((uint8_t)0);lcd.setCursor(z0+1+3,1);lcd.print(F(" "));}}
if(z1==3){lcd.setCursor(z0+3,1);lcd.write((uint8_t)1);}
if(z1==2){lcd.setCursor(z0+3,1);lcd.write((uint8_t)2);}w2=0;}}
/////////////////////// END TREBLE //////////////////////////////////
////////////////// BALANCE /////////////////////////////////////////////////////////////////
if(menu==3){
if(ir.value==IR_3){ball++;gr1=1;gr2=0;cl3();times=millis();w=1;w2=1;ball_func();audio();}// кнопка >
if(ir.value==0xFFFFFFFF and gr1==1){ball++;gr2=0;cl3();times=millis();w=1;w2=1;ball_func();audio();}// кнопка >>>>>>
if(ir.value==IR_4){ball--;gr1=0;gr2=1;cl3();times=millis();w=1;w2=1;ball_func();audio();}// кнопка <
if(ir.value==0xFFFFFFFF and gr2==1){ball--;gr1=0;cl3();times=millis();w=1;w2=1;ball_func();audio();}// кнопка <<<<<<
if (newPosition != oldPosition) {
oldPosition = newPosition;
ball=ball+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;ball_func();audio();}
lcd.setCursor(0,0);
if(ball>=0){lcd.print("-");}else{lcd.print("+");}
lcd.print(abs(ball));lcd.print(" dB ");
lcd.print(" <> ");
if(ball>=0){lcd.print("+");}else{lcd.print("-");}
lcd.print(abs(ball));lcd.print(" dB ");
if(w2==1){lcd.setCursor(ball+5,1);lcd.print(F(" "));
if(ball==0){lcd.setCursor(ball+7,1);lcd.write((uint8_t)0);lcd.write((uint8_t)0);}
if(ball>0){ lcd.setCursor(ball+8,1);lcd.write((uint8_t)0);}
if(ball<0){ lcd.setCursor(ball+7,1);lcd.write((uint8_t)0);}
lcd.print(F(" "));w2=0;}}
/////////////// Stereo / Mono //////////////////////////
if(menu==4){
if(ir.value==IR_3){stereo++;gr1=1;gr2=0;cl3();times=millis();w=1;w2=1;if(stereo>2){stereo=0;}audio();}// кнопка >
if(ir.value==IR_4){stereo--;gr1=0;gr2=1;cl3();times=millis();w=1;w2=1;if(stereo<0){stereo=2;}audio();}// кнопка <
if (newPosition != oldPosition) {
oldPosition = newPosition;
stereo=stereo+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;if(stereo>2){stereo=0;};if(stereo<0){stereo=2;}audio();}
lcd.setCursor(0,0);lcd.print(" Stereo / Mono ");
lcd.setCursor(0,1);
switch(stereo){
case 0: lcd.print(" STEREO ");break;
case 1: lcd.print(" Lch Mono ");break;
case 2: lcd.print(" Rch Mono ");break;
}}
/////////////// Mode Selector //////////////////////////
if(menu==5){
if(ir.value==IR_3){mode++;gr1=1;gr2=0;cl3();times=millis();w=1;w2=1;if(mode>3){mode=0;}audio();}// кнопка >
if(ir.value==IR_4){mode--;gr1=0;gr2=1;cl3();times=millis();w=1;w2=1;if(mode<0){mode=3;}audio();}// кнопка <
if (newPosition != oldPosition) {
oldPosition = newPosition;
mode=mode+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w2=1;if(mode>3){mode=0;};if(mode<0){mode=3;}audio();}
lcd.setCursor(0,0);lcd.print(" Mode Selector ");
lcd.setCursor(0,1);
switch(mode){
case 0: lcd.print(" BYPASS ");break;
case 1: lcd.print(" TONE ");break;
case 2: lcd.print("Tone&Surround Hi");break;
case 3: lcd.print("Tone&Surround Lo");break;
}}
///////////// EEPROM ////////////////////////////////////////
if(millis()-times>5000 && w==1){
EEPROM.write(0,vol);EEPROM.write(1,in);EEPROM.write(2,bas+7);EEPROM.write(3,treb+7);EEPROM.write(4,ball+6);
EEPROM.write(5,stereo);EEPROM.write(6,mode);
EEPROM.write(10,gain1);EEPROM.write(11,gain2);EEPROM.write(12,gain3);EEPROM.write(13,gain4);EEPROM.write(14,gain5);
menu=0;w=0;w2=1;cl2();}
}// LOOP
void ball_func(){if(ball>6){ball=6;}if(ball<-6){ball=-6;}}
void treb_func(){if(treb>7){treb=7;}if(treb<-7){treb=-7;}}
void bass_func(){if(bas>7){bas=7;}if(bas<-7){bas=-7;}}
void gain_func(){if(gain0>10){gain0=10;}if(gain0<0){gain0=0;}}
void vol_func(){if(vol>87){vol=87;}if(vol<12){vol=12;}}
void cl(){ir.value=0;}
void cl1(){ir.value=0;delay(20);}
void cl2(){ir.value=0;lcd.clear();}
void cl3(){ir.value=0;delay(100);}
void audio(){
ra.setVolume_left(vol-6+ball); // -87...0 dB === int 0...87
ra.setVolume_right(vol-6-ball);// -87...0 dB === int 0...87
ra.setIn_Gain(in,gain0); // IN 1...5 === byte 0...4 /// int 7 === mute
// GAIN 0...20 dB step 2 dB === int 0...10
ra.setStereo(stereo,mode); // 0 = stereo / 1 = Lch / 2 = Rch
// 0 = bypass / 1 = tone / 2 = tone&surround_hi / 3 = tone&surround_low
ra.setTone(bas,treb); // bass and treb -14...14 dB step 2 dB === int -7...7
}
ISR (TIMER2_COMPA_vect){newPosition = myEnc.read()/4;}