ИМС R2S15900SP представляет собой простой двухканальный аудиопроцессор, который содержит 5 коммутируемых стерео входов, регуляторы тембра НЧ и ВЧ, регулятор громкости.
Основные параметры R2S15900SP:
- Напряжение питания от 5 до 10 В (9 В рекомендуемое)
- Ток потребления 15 мА
- Коэффициент гармоник 0.01%
- Максимальное входное напряжение 3.0 Vrms
- Максимальное выходное напряжение 2.5 Vrms
- Усиление выхода 0 … 4,5 дБ (поддерживается библиотекой)
- Разделение каналов -100 дБ
- Диапазон регулировки громкости от -84 до 0 дБ, шаг 1 дБ
- Диапазон регулировки тембра ±15 дБ, шаг 1 дБ
- Режимы — Bypass/ Tone / Tone & Pseudo Stereo or Surround (поддерживается библиотекой)
- Управление I2С
Управление аудиопроцессором осуществляется при помощи платы Arduino Nano, информация об уровне громкости и тембра выводится выводится на LCD дисплея LCD1602 на базе контроллера HD44780 совместно с модулем I2C. I2C модуль на базе микросхемы PCF8574 позволяют подключить символьный дисплей 1602 к плате Arduino всего по двум проводам SDA и SCL (А4 и А5), что дает возможность не использовать цифровые выходы Arduino при подключении дисплея.
Меню регулятора громкости и тембра состоит всего из трех пунктов — регулировка громкости, тембр НЧ, тембр ВЧ. Регулировка параметров осуществляется при помощи энкодер KY-040, дополнительно используются две кнопки IN и MUTE.
#define CLK 9 // ENCODER #define DT 8 // ENCODER #define SW 10 // ENCODER #define MUTE 2 // BUTTON MUTE #define IN 3 // BUTTON INPUT #include <Wire.h> #include <EEPROM.h> #include <MsTimer2.h> // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip #include <R2S15900SP.h> // https://github.com/liman324/R2S15900SP.git #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 Encoder myEnc(CLK, DT); R2S15900SP r2s; LiquidCrystal_I2C lcd(0x27,16,2); // Устанавливаем дисплей byte v1[8] = {0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07}; byte v2[8] = {0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00}; byte v3[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F}; byte v4[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x1F,0x1F}; byte v5[8] = {0x1C,0x1C,0x00,0x00,0x00,0x00,0x1C,0x1C}; byte v6[8] = {0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C}; byte v7[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07}; byte v8[8] = {0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00}; unsigned long times,times1,oldPosition = -999,newPosition; int menu,w,w2,vol,mut=1,a[3],in,bas,treb; byte i,d1,d2,d3,d4,d5,d6,e1,e2,e3; void setup() { Serial.begin(9600);MsTimer2::set(3, to_Timer);MsTimer2::start(); pinMode(SW,INPUT); pinMode(IN,INPUT_PULLUP); pinMode(MUTE,INPUT_PULLUP); lcd.init();lcd.backlight(); 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); 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)-15;treb = EEPROM.read(3)-15; lcd.setCursor(0,0);lcd.print(" R2S15900SP "); delay(1000); audio(); lcd.clear(); } void loop() { if(digitalRead(SW)==LOW){menu++;if(menu>2){menu=0;};delay(200);lcd.clear();w=1;times=millis();w2=1;} if(digitalRead(IN)==LOW){in++;if(in>5){in=1;};delay(200);w=1;times=millis();w2=1;audio();} if(digitalRead(MUTE)==LOW&&mut==1){mut=0;delay(200);w=1;times=millis();w2=1;audio();} if(digitalRead(MUTE)==LOW&&mut==0){mut=1;delay(200);w=1;times=millis();w2=1;audio();} /// VOLUME /////////////////////////////////////////////////// if(menu==0){ if (newPosition != oldPosition){oldPosition = newPosition; vol=vol-newPosition;myEnc.write(0);newPosition=0;w=1;times=millis();w2=1; if(vol>84){vol=84;}if(vol<0){vol=0;} audio();} lcd.setCursor(0,0); if(mut==0){lcd.print("MUTE ");} if(mut==1){lcd.print("VOLUME ");} lcd.setCursor(0,1);lcd.print("IN ");lcd.print(in); if(w2==1){w2=0; a[0]=(84-vol)/10;a[1]=(84-vol)%10; for(i=0;i<2;i++){ switch(i){ case 0: e1=9,e2=10,e3=11;break; case 1: e1=12,e2=13,e3=14;break; } switch(a[i]){ 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); }} } /// bas /////////////////////////////////////////////////// if(menu==1){ if (newPosition != oldPosition){oldPosition = newPosition; bas=bas+newPosition;myEnc.write(0);newPosition=0;w=1;times=millis();w2=1; if(bas>15){bas=15;}if(bas<-15){bas=-15;} audio();} lcd.setCursor(0,0); lcd.print("BASS "); if(bas<0){lcd.setCursor(8,1);lcd.write((uint8_t)0);}else{lcd.setCursor(8,1);lcd.print(" ");} if(w2==1){w2=0; a[0]=abs(bas)/10;a[1]=abs(bas)%10; for(i=0;i<2;i++){ switch(i){ case 0: e1=9,e2=10,e3=11;break; case 1: e1=12,e2=13,e3=14;break; } switch(a[i]){ 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); }} } /// TREB /////////////////////////////////////////////////// if(menu==2){ if (newPosition != oldPosition){oldPosition = newPosition; treb=treb+newPosition;myEnc.write(0);newPosition=0;w=1;times=millis();w2=1; if(treb>15){treb=15;}if(treb<-15){treb=-15;} audio();} lcd.setCursor(0,0); lcd.print("TREBLE "); if(treb<0){lcd.setCursor(8,1);lcd.write((uint8_t)0);}else{lcd.setCursor(8,1);lcd.print(" ");} if(w2==1){w2=0; a[0]=abs(treb)/10;a[1]=abs(treb)%10; for(i=0;i<2;i++){ switch(i){ case 0: e1=9,e2=10,e3=11;break; case 1: e1=12,e2=13,e3=14;break; } switch(a[i]){ 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); }} } //// EEPROM /////////////////////////////////////// if(millis()-times>5000 && w==1){w=0;EEPROM.update(0,vol);EEPROM.update(1,in);EEPROM.update(2,bas+15);EEPROM.update(3,treb+15);menu=0;lcd.clear();w2=1;} delay(10); } void to_Timer(){newPosition = myEnc.read()/4;} void audio(){ r2s.setVol_l(vol); // volume left >> int 84...0 === -84...0 dB r2s.setVol_r(vol); // volume_right >> int 84...0 === -84...0 dB r2s.setIn(1, 0, 1); // input >> int 0 === all off | int 1...5 === input 1...5 // gain >> int 0...1 === 0 dB...+4.5 dB // mute >> int 0...1 === mute on...mute off r2s.set_Bass(1, 1, bas); // surround mode >> int 0...1 === low level...high level // mode selector >> int 0...3 === bypass tone tone&Pseudo_stereo tone&Surround // tone control bas >> int -15...15 === -15dB...+15dB r2s.set_Treb(treb); // tone control treble >> int -15...15 === -15dB...+15dB }