#define CLK_ENC 9
#define DT_ENC 10
#define SW_ENC 8
#define CS_PGA 2
#define SCLK_PGA 3
#define DATA_PGA 4
#define BUTTON_INPUT A0
#define BUTTON_POWER A1
#define BUTTON_MUTE A2
#define OUT_IN_1 5
#define OUT_IN_2 6
#define OUT_IN_3 7
#define OUT_POWER 13
#define OUT_MUTE 12
#include <Wire.h>
#include <EEPROM.h>
#include <U8glib.h> // https://github.com/olikraus/u8glib/
#include <Encoder.h> // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <MsTimer2.h> // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
#include <CS3310.h> // http://rcl-radio.ru/wp-content/uploads/2020/11/CS3310.zip
Encoder myEnc(CLK_ENC, DT_ENC);
CS3310 pga(CS_PGA,SCLK_PGA,DATA_PGA);
// U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_FAST);// OLED_1.3
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST);// OLED_0.96
long times,oldPosition = -999,newPosition;
int vol,menu,in,ball,vol_old;
bool mute=0,w=1,w1,power=0;
void setup(){
Wire.begin();Serial.begin(9600);
MsTimer2::set(1, to_Timer);MsTimer2::start();
if(EEPROM.read(100)!=0){for(int i=0;i<101;i++){EEPROM.update(i,0);}}
pinMode(BUTTON_INPUT,INPUT_PULLUP); // КНОПКА INPUT
pinMode(BUTTON_POWER,INPUT_PULLUP); // КНОПКА POWER
pinMode(BUTTON_MUTE,INPUT_PULLUP); // КНОПКА MUTE
pinMode(OUT_POWER,OUTPUT); digitalWrite(OUT_POWER,LOW);
pinMode(OUT_MUTE,OUTPUT);
u8g.firstPage();
do {
u8g.setFont(u8g_font_profont12r);
u8g.drawStr(20,10,"AUDIO PROCESSOR");
u8g.drawStr(42,35,"PGA2311");
u8g.drawStr(30,55,"rcl-radio.ru");
} while( u8g.nextPage() );
delay(2000);
vol = EEPROM.read(0);
ball = EEPROM.read(1)-10;
in = EEPROM.read(2);
switch(in){
case 0: digitalWrite(OUT_IN_1,HIGH);digitalWrite(OUT_IN_2,LOW);digitalWrite(OUT_IN_3,LOW);break;
case 1: digitalWrite(OUT_IN_1,LOW);digitalWrite(OUT_IN_2,HIGH);digitalWrite(OUT_IN_3,LOW);break;
case 2: digitalWrite(OUT_IN_1,LOW);digitalWrite(OUT_IN_2,LOW);digitalWrite(OUT_IN_3,HIGH);break;
}
audio();
digitalWrite(OUT_POWER,HIGH);
digitalWrite(OUT_MUTE,HIGH);
}
void loop(){
/// MENU ///////////////////////////////////////
if(power==0){
if(digitalRead(SW_ENC)==LOW){menu++;if(menu>1){menu=0;}times=millis();w=1;w1=1;delay(200);}
if(digitalRead(BUTTON_INPUT)==LOW){in++;if(in>2){in=0;}times=millis();w=1;w1=1;delay(200);}
if(digitalRead(BUTTON_MUTE)==LOW&&mute==0){mute=1;menu=100;digitalWrite(OUT_MUTE,LOW);delay(300);
u8g.firstPage();do {u8g.setFont(u8g_font_profont12r);u8g.drawStr(50,30,"MUTE");} while( u8g.nextPage() );}
if(digitalRead(BUTTON_MUTE)==LOW&&mute==1){mute=0;w=1;menu=0;delay(300);digitalWrite(OUT_MUTE,HIGH);}
}
if(digitalRead(BUTTON_POWER)==LOW&&power==0){power=1;menu=100;digitalWrite(OUT_MUTE,LOW);delay(300);
u8g.firstPage();do {u8g.setFont(u8g_font_profont12r);u8g.drawStr(37,30,"POWER OFF");} while( u8g.nextPage() );digitalWrite(OUT_POWER,LOW);delay(3000);
u8g.firstPage();do {} while( u8g.nextPage() );}
if(digitalRead(BUTTON_POWER)==LOW&&power==1){power=0;w=1;menu=0;
u8g.firstPage();do {u8g.setFont(u8g_font_profont12r);u8g.drawStr(37,30,"POWER ON");} while( u8g.nextPage() );delay(2000);digitalWrite(OUT_POWER,HIGH);digitalWrite(OUT_MUTE,HIGH);}
/////////////// VOLUME /////////////////////////////////////////////////////////
if(menu==0&&mute==0&&power==0){
if(newPosition != oldPosition&&mute==0){oldPosition = newPosition;
if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;}
vol=vol+newPosition;myEnc.write(0);newPosition=0;times=millis();w=1;w1=1;vol_func();audio();}
}
if(menu==1&&mute==0&&power==0){
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;w1=1;ball_func();audio();}
}
if(w==1&&power==0){w=0;
u8g.firstPage();
do {
u8g.setFont(u8g_font_profont12r);if(menu==0){u8g.drawStr(0,10,"VOLUME");}else{u8g.drawStr(0,10,"volume");}
for(int v_pos=0; v_pos<vol/1.5+1;v_pos+=4){u8g.drawBox(v_pos+45,2, 2, 8);}
u8g.setFont(u8g_font_profont15r);u8g.setPrintPos(35, 25);u8g.print(vol-100);u8g.drawStr(70,25,"dB");
u8g.drawLine(0, 32, 128, 32);
u8g.setFont(u8g_font_profont12r);if(menu==1){u8g.drawStr(0,45,"BALANCE");}else{u8g.drawStr(0,45,"balance");}
for(int b0_pos=0; b0_pos<58+1;b0_pos+=4){u8g.drawBox(b0_pos+57,40, 2, 2);}
if(ball>=0){ for(int b1_pos=0; b1_pos<ball*3+1;b1_pos+=4){u8g.drawBox(b1_pos+85,37, 2, 8);} }
if(ball<=0){ for(int b2_pos=0; b2_pos>ball*3+1;b2_pos-=4){u8g.drawBox(b2_pos+85,37, 2, 8);} }
u8g.drawLine(0, 50, 128, 50);
u8g.setFont(u8g_font_profont12r);u8g.drawStr(0,64,"INPUT");
switch(in){
case 0: u8g.drawStr(50,64,"AUX_1");digitalWrite(OUT_IN_1,HIGH);digitalWrite(OUT_IN_2,LOW);digitalWrite(OUT_IN_3,LOW);break;
case 1: u8g.drawStr(50,64,"AUX_2");digitalWrite(OUT_IN_1,LOW);digitalWrite(OUT_IN_2,HIGH);digitalWrite(OUT_IN_3,LOW);break;
case 2: u8g.drawStr(50,64,"AUX_3");digitalWrite(OUT_IN_1,LOW);digitalWrite(OUT_IN_2,LOW);digitalWrite(OUT_IN_3,HIGH);break;
}
} while( u8g.nextPage() );}
//////// EEPROM //////////////////////////////////////////////////
if(millis()-times>10000 && w1==1 && mute==0 && power==0){EEPROM.update(0,vol);EEPROM.update(1,ball+10);EEPROM.update(2,in);menu=0;w1=0;w=1;}
}
void audio(){
pga.setVol(vol*2+ball*2,vol*2-ball*2);// byte 1...255 === -95.5...+31.5 dB (step 0.5 dB)
}
void to_Timer(){newPosition = myEnc.read()/4;}
void vol_func(){if(vol<0){vol=0;}if(vol>117){vol=117;}}
void ball_func(){if(ball<-10){ball=-10;}if(ball>10){ball=10;}}