345 lines
11 KiB
C++
345 lines
11 KiB
C++
// по материалам:
|
||
//https://www.instructables.com/Simple-LCD-MENU-Using-Arduino/
|
||
// https://alexgyver.ru/lessons/
|
||
// https://www.hackster.io/mircemk/diy-arduino-vfd-display-20x2-vu-volume-unit-meter-37898f
|
||
|
||
#define GAIN 1 // усиление 0...50
|
||
#define STEP 1 // плавность полос 0...20
|
||
#define RL 1 // RL - горизонт, вертикаль 0...1
|
||
// Выходы для управления реле (вкл.вкл ЦАП/Блютуз)
|
||
#define RELAY_POWER_USB 6
|
||
#define RELAY_POWER_BT 7
|
||
#define RELAY_POWER_MP3 10
|
||
#define RELAY_OUT_USB 8
|
||
#define RELAY_OUT_BT 9
|
||
#define RELAY_OUT_MP3 11
|
||
|
||
// Кнопки
|
||
#define BTN_MENU 2 // Кнопка меню
|
||
#define BTN_EXECUTE 3 // Кнопка подтверждения
|
||
#define INIT_ADDR 1023 // номер резервной ячейки
|
||
#define INIT_KEY 1 // ключ первого запуска
|
||
|
||
//#include <LiquidCrystal.h>
|
||
#include <Wire.h>
|
||
#include <LiquidCrystal_I2C.h>
|
||
#include <EEPROM.h>
|
||
|
||
// LiquidCrystal lcdVuMeter(2, 3, 4, 5, 6, 7);// RS,E,D4,D5,D6,D7
|
||
LiquidCrystal_I2C lcdVuMeter(0x27, 16, 2);
|
||
LiquidCrystal_I2C lcdService(0x26, 16, 2);
|
||
|
||
byte z,z0,z1,w,www=1;
|
||
int ur,ul,urr,ull,urrr,ulll;
|
||
int x,i,u_maxr,u_maxl;
|
||
int u_l0[20],u_r0[20];
|
||
bool usb, bluetooth, mp3;
|
||
int menu = 1;
|
||
bool menuShow = false;
|
||
|
||
void setup() {
|
||
pinMode(8,INPUT_PULLUP);
|
||
byte znak_r[8]={0b00000,0b00000,0b11111,0b00101,0b00101,0b11010,0b00000,0b00000};
|
||
byte znak_l[8]={0b00000,0b00000,0b11111,0b10000,0b10000,0b10000,0b00000,0b00000};
|
||
lcdVuMeter.init();
|
||
lcdVuMeter.backlight();
|
||
lcdVuMeter.clear();
|
||
lcdVuMeter.setCursor(0, 0);
|
||
lcdVuMeter.print("R");
|
||
// lcdVuMeter.createChar(4,znak_r);
|
||
lcdVuMeter.setCursor(0, 1);
|
||
lcdVuMeter.print("L");
|
||
lcdService.init();
|
||
lcdService.backlight();
|
||
lcdService.clear();
|
||
// lcdService.setCursor(0, 0);
|
||
// lcdService.print("Menu");
|
||
|
||
// Кнопка управления (переключения)
|
||
pinMode(BTN_MENU, INPUT_PULLUP);
|
||
pinMode(BTN_EXECUTE, INPUT_PULLUP);
|
||
// Выходы для управления реле (вкл.вкл ЦАП/Блютуз)
|
||
pinMode(RELAY_POWER_USB, OUTPUT);
|
||
pinMode(RELAY_POWER_BT, OUTPUT);
|
||
pinMode(RELAY_POWER_MP3, OUTPUT);
|
||
pinMode(RELAY_OUT_USB, OUTPUT);
|
||
pinMode(RELAY_OUT_BT, OUTPUT);
|
||
pinMode(RELAY_OUT_MP3, OUTPUT);
|
||
|
||
// lcdVuMeter.createChar(5,znak_l);
|
||
// lcdVuMeter.begin(16, 2);// lcdVuMeter 16X2
|
||
// analogReference(INTERNAL); // если очень маленький уровень сигнала
|
||
pinMode(A0,INPUT);// A0 - аналоговый вход R
|
||
pinMode(A1,INPUT);// A1 - аналоговый вход L
|
||
|
||
// первый запуск и установка занчений переменных в память
|
||
if (EEPROM.read(INIT_ADDR) != INIT_KEY) {
|
||
EEPROM.write(INIT_ADDR, INIT_KEY);
|
||
usb = true;
|
||
bluetooth = false;
|
||
mp3 = false;
|
||
|
||
EEPROM.put(10, usb);
|
||
EEPROM.put(12, bluetooth);
|
||
EEPROM.put(14, mp3);
|
||
} else {
|
||
usb = EEPROM.read(10);
|
||
bluetooth = EEPROM.read(12);
|
||
mp3 = EEPROM.read(14);
|
||
}
|
||
|
||
w = EEPROM.read(0);
|
||
|
||
|
||
updateMenu();
|
||
}
|
||
|
||
void vu_metter() {
|
||
|
||
if(digitalRead(8)==LOW){w++;www=1;if(w>4){w=0;}delay(200);EEPROM.update(0,w);}
|
||
|
||
if(w==0&&www==1){www=0;
|
||
byte a1[8] = {0b10101,0b10101,0b10101,0b10101,0b10101,0b10101,0b10101,0b10101};
|
||
byte a2[8] = {0b10100,0b10100,0b10100,0b10100,0b10100,0b10100,0b10100,0b10100};
|
||
byte a3[8] = {0b10000,0b10000,0b10000,0b10000,0b10000,0b10000,0b10000,0b10000};
|
||
byte a4[8] = {0b00011,0b00011,0b00011,0b0011,0b0011,0b0011,0b0011,0b0011};//
|
||
lcdVuMeter.createChar(0,a1);lcdVuMeter.createChar(1,a2);lcdVuMeter.createChar(2,a3);lcdVuMeter.createChar(6,a4);}
|
||
if(w==1&&www==1){www=0;
|
||
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};
|
||
byte a4[8] = {0b00000,0b0011,0b0011,0b0011,0b0011,0b0011,0b0011,0b00000};//
|
||
lcdVuMeter.createChar(0,a1);lcdVuMeter.createChar(1,a2);lcdVuMeter.createChar(2,a3);lcdVuMeter.createChar(6,a4);}
|
||
if(w==2&&www==1){www=0;
|
||
byte a1[8] = {0b10101,0b10101,0b10101,0b00000,0b00000,0b10101,0b10101,0b10101};
|
||
byte a2[8] = {0b10100,0b10100,0b10100,0b00000,0b00000,0b10100,0b10100,0b10100};
|
||
byte a3[8] = {0b10000,0b10000,0b10000,0b00000,0b00000,0b10000,0b10000,0b10000};
|
||
byte a4[8] = {0b0011,0b0011,0b0011,0b0011,0b0011,0b0011,0b0011,0b0011};
|
||
lcdVuMeter.createChar(0,a1);lcdVuMeter.createChar(1,a2);lcdVuMeter.createChar(2,a3);lcdVuMeter.createChar(6,a4);}
|
||
if(w==3&&www==1){www=0;
|
||
byte a1[8] = {0b00000,0b10101,0b10101,0b00000,0b00000,0b10101,0b10101,0b00000};
|
||
byte a2[8] = {0b00000,0b10100,0b10100,0b00000,0b00000,0b10100,0b10100,0b00000};
|
||
byte a3[8] = {0b00000,0b10000,0b10000,0b00000,0b00000,0b10000,0b10000,0b00000};
|
||
byte a4[8] = {0b00000,0b0011,0b0011,0b0011,0b0011,0b0011,0b0011,0b00000};
|
||
lcdVuMeter.createChar(0,a1);lcdVuMeter.createChar(1,a2);lcdVuMeter.createChar(2,a3);lcdVuMeter.createChar(6,a4);}
|
||
if(w==4&&www==1){www=0;
|
||
byte a1[8] = {0b00000,0b00000,0b10101,0b10101,0b10101,0b10101,0b00000,0b00000};
|
||
byte a2[8] = {0b00000,0b00000,0b10100,0b10100,0b10100,0b10100,0b00000,0b00000};
|
||
byte a3[8] = {0b00000,0b00000,0b10000,0b10000,0b10000,0b10000,0b00000,0b00000};
|
||
byte a4[8] = {0b00000,0b00000,0b0011,0b0011,0b0011,0b0011,0b00000,0b00000};
|
||
lcdVuMeter.createChar(0,a1);lcdVuMeter.createChar(1,a2);lcdVuMeter.createChar(2,a3);lcdVuMeter.createChar(6,a4);}
|
||
|
||
urr = log(analogRead(0))*GAIN;if(urr>41){urr=41;}
|
||
ull = log(analogRead(1))*GAIN;if(ull>41){ull=41;}
|
||
|
||
if(RL==0){lcdVuMeter.setCursor(0,0);lcdVuMeter.write((uint8_t)4);lcdVuMeter.setCursor(0,1);lcdVuMeter.write((uint8_t)5);}
|
||
if(RL==1){lcdVuMeter.setCursor(0,1);lcdVuMeter.print("L");lcdVuMeter.setCursor(0,0);lcdVuMeter.print("R");}
|
||
|
||
if(urr<ur){ur=ur-1;delay(STEP);}else{ur = urr;}
|
||
for(z=0,z0=0,z1=0;z<=ur;z++,z1++){if(z1>2){z1=0;z0++;}
|
||
if(z1==1){lcdVuMeter.setCursor(z0+1,1);lcdVuMeter.write((uint8_t)0);lcdVuMeter.setCursor(z0+2,1);if(ur<39){lcdVuMeter.print(" ");}}}
|
||
if(z1==3){lcdVuMeter.setCursor(z0+1,1);lcdVuMeter.write((uint8_t)1);}
|
||
if(z1==2){lcdVuMeter.setCursor(z0+1,1);lcdVuMeter.write((uint8_t)2);}
|
||
|
||
if(ull<ul){ul=ul-1;delay(STEP);}else{ul = ull;}
|
||
for(z=0,z0=0,z1=0;z<=ul;z++,z1++){if(z1>2){z1=0;z0++;}
|
||
if(z1==1){lcdVuMeter.setCursor(z0+1,0);lcdVuMeter.write((uint8_t)0);lcdVuMeter.setCursor(z0+2,0);if(ul<39){lcdVuMeter.print(" ");}}}
|
||
if(z1==3){lcdVuMeter.setCursor(z0+1,0);lcdVuMeter.write((uint8_t)1);}
|
||
if(z1==2){lcdVuMeter.setCursor(z0+1,0);lcdVuMeter.write((uint8_t)2);}
|
||
|
||
//////////////////////////////////////////////////////////
|
||
|
||
i++;if(i<19){u_l0[i]=abs(ull);u_r0[i]=abs(urr);}else{i=1;}
|
||
if(i==18){u_maxr=0;u_maxl=0;
|
||
for(x=1;x<=15;x++){
|
||
u_maxl=max(u_maxl,u_l0[x]);
|
||
u_maxr=max(u_maxr,u_r0[x]);}}
|
||
|
||
if(u_maxl<=ull){u_maxl=ull+1;}
|
||
if(u_maxr<=urr){u_maxr=urr+1;}
|
||
|
||
if(u_maxl<ulll){ulll=ulll-1;delay(STEP);}else{ulll = u_maxl;}
|
||
if(u_maxr<urrr){urrr=urrr-1;delay(STEP);}else{urrr = u_maxr;}
|
||
|
||
|
||
lcdVuMeter.setCursor(ulll/3+1,0);if(ulll/3>2){lcdVuMeter.write((uint8_t)6);}lcdVuMeter.print(" ");
|
||
lcdVuMeter.setCursor(urrr/3+1,1);if(urrr/3>2){lcdVuMeter.write((uint8_t)6);}lcdVuMeter.print(" ");
|
||
delay(3);
|
||
}
|
||
|
||
String setUSBinput() {
|
||
return "USB input";
|
||
}
|
||
|
||
|
||
void updateMenu() {
|
||
switch (menu) {
|
||
case 0:
|
||
menu = 1;
|
||
break;
|
||
case 1:
|
||
lcdService.clear();
|
||
lcdService.print(">USB DAC");
|
||
lcdService.setCursor(2, 1);
|
||
if(usb){
|
||
lcdService.print("On");
|
||
}else{
|
||
lcdService.print("Off");
|
||
}
|
||
break;
|
||
case 2:
|
||
lcdService.clear();
|
||
lcdService.print(">Bluetooth");
|
||
lcdService.setCursor(2, 1);
|
||
if(bluetooth){
|
||
lcdService.print("On");
|
||
}else{
|
||
lcdService.print("Off");
|
||
}
|
||
break;
|
||
case 3:
|
||
lcdService.clear();
|
||
lcdService.print(">MP3 module");
|
||
lcdService.setCursor(2, 1);
|
||
if(mp3){
|
||
lcdService.print("On");
|
||
}else{
|
||
lcdService.print("Off");
|
||
}
|
||
break;
|
||
case 4:
|
||
menu = 0;
|
||
menuShow = false;
|
||
lcdService.clear();
|
||
break;
|
||
}
|
||
}
|
||
|
||
void executeMenuAction() {
|
||
switch (menu) {
|
||
case 1:
|
||
actionUSB();
|
||
break;
|
||
case 2:
|
||
actionBT();
|
||
break;
|
||
case 3:
|
||
actionMP3();
|
||
break;
|
||
}
|
||
EEPROM.put(10, usb);
|
||
EEPROM.put(12, bluetooth);
|
||
EEPROM.put(14, mp3);
|
||
}
|
||
|
||
void actionUSB() {
|
||
// lcdService.clear();
|
||
lcdService.setCursor(2,1);
|
||
lcdService.print("On ");
|
||
digitalWrite(RELAY_POWER_BT,LOW);
|
||
digitalWrite(RELAY_POWER_MP3,LOW);
|
||
|
||
digitalWrite(RELAY_OUT_BT,LOW);
|
||
digitalWrite(RELAY_OUT_MP3,LOW);
|
||
delay(1000);
|
||
digitalWrite(RELAY_OUT_USB,HIGH);
|
||
digitalWrite(RELAY_POWER_USB,HIGH);
|
||
usb = true;
|
||
bluetooth = false;
|
||
mp3 = false;
|
||
|
||
delay(1500);
|
||
}
|
||
|
||
void actionBT() {
|
||
// lcdService.clear();
|
||
lcdService.setCursor(2,1);
|
||
lcdService.print("On ");
|
||
digitalWrite(RELAY_POWER_USB,LOW);
|
||
digitalWrite(RELAY_POWER_MP3,LOW);
|
||
|
||
digitalWrite(RELAY_OUT_USB,LOW);
|
||
digitalWrite(RELAY_OUT_MP3,LOW);
|
||
delay(1000);
|
||
digitalWrite(RELAY_OUT_BT,HIGH);
|
||
digitalWrite(RELAY_POWER_BT,HIGH);
|
||
usb = false;
|
||
bluetooth = true;
|
||
mp3 = false;
|
||
|
||
delay(1500);
|
||
}
|
||
|
||
void actionMP3() {
|
||
// lcdService.clear();
|
||
lcdService.setCursor(2,1);
|
||
lcdService.print("On ");
|
||
digitalWrite(RELAY_POWER_USB,LOW);
|
||
digitalWrite(RELAY_POWER_BT,LOW);
|
||
|
||
digitalWrite(RELAY_OUT_USB,LOW);
|
||
digitalWrite(RELAY_OUT_BT,LOW);
|
||
delay(1000);
|
||
digitalWrite(RELAY_OUT_MP3,HIGH);
|
||
digitalWrite(RELAY_POWER_MP3,HIGH);
|
||
usb = false;
|
||
bluetooth = false;
|
||
mp3 = true;
|
||
delay(1500);
|
||
}
|
||
|
||
uint32_t btnTimer = 0;
|
||
|
||
void loop() {
|
||
lcdService.setCursor(0,0);
|
||
// Выводим на экран информацию какой модуль включен
|
||
|
||
if(!menuShow){
|
||
if(usb){
|
||
lcdService.print("USB DAC");
|
||
lcdService.setCursor(0,1);
|
||
lcdService.print(setUSBinput());
|
||
}
|
||
if(bluetooth){
|
||
lcdService.print("Bluetooth");
|
||
}
|
||
if(mp3){
|
||
lcdService.print("MP3 module");
|
||
}
|
||
}
|
||
// bool btnMenuState = digitalRead(BTN_MENU);
|
||
// bool btnExecuteState = digitalRead(BTN_EXECUTE);
|
||
|
||
if (!digitalRead(BTN_MENU)){
|
||
menuShow = true;
|
||
menu ++;
|
||
updateMenu();
|
||
delay(100);
|
||
while (!digitalRead(BTN_MENU));
|
||
}
|
||
if (!digitalRead(BTN_EXECUTE)){
|
||
executeMenuAction();
|
||
updateMenu();
|
||
delay(100);
|
||
while (!digitalRead(BTN_EXECUTE));
|
||
}
|
||
// Тут будет код обработки данных от USB DAC для индикации режима его работы
|
||
// if (digitalRead(8) && usb) {
|
||
// lcdService.setCursor(0,1);
|
||
// lcdService.print("Coaxial");
|
||
// } else if (digitalRead(9) && usb) {
|
||
// lcdService.setCursor(0,1);
|
||
// lcdService.print("Optical");
|
||
// } else if (digitalRead(10) && usb) {
|
||
// lcdService.setCursor(0,1);
|
||
// lcdService.print("Audio ");
|
||
// } else {
|
||
// lcdService.setCursor(0,1);
|
||
// lcdService.print(" ");
|
||
// }
|
||
// lcdService.setCursor(11,1);
|
||
// lcdService.print(digitalRead(8), digitalRead(9));
|
||
|
||
vu_metter();
|
||
}
|