#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
// Инициализация дисплея с I2C адресом 0x27 (возможно 0x3F для некоторых дисплеев)
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Пины для кнопок
const int buttonUpPin = 8;
const int buttonDownPin = 9;
const int buttonSelectPin = 10;
// Состояние кнопок
int lastButtonUpState = LOW;
int lastButtonDownState = LOW;
int lastButtonSelectState = LOW;
int vMenu = 0;
int vType = 0;
int vInterval = 0;
int vTypes[15];
// Индекс текущего пункта меню
int menuIndex = 0;
int currentMenu = 0; // 0 - главное меню, 1 - Type 1, 2 - Interval
// EEPROM адреса для сохранения состояния меню
const int vMenuAddress = 0;
const int vTypeAddress = 1;
const int vIntervalAddress = 2;
const int vTypesAddress = 3;
// Главное меню
const char* mainMenuItems[] = {
"Type",
"Interval",
"Work",
};
// Подменю 1
const char* typeItems[] = {
"All Type",
"Orlan",
"CryptoOrlan",
"FPV",
"FPV+ERLS",
"Zala",
//"?Zala",
"Lancet",
"Zala/Lancet",
"Eleron",
//"?Eleron",
"SuperCam",
"Back"
};
// Подменю 2
const char* intervalItems[] = {
"1 min",
"2 min",
"3 min",
"4 min",
"5 min",
"6 min",
"7 min",
"8 min",
"9 min",
"10 min",
"Back"
};
// Количество пунктов в каждом меню
const int mainMenuItemsCount = sizeof(mainMenuItems) / sizeof(mainMenuItems[0]);
const int typeItemsCount = sizeof(typeItems) / sizeof(typeItems[0]);
const int intervalItemsCount = sizeof(intervalItems) / sizeof(intervalItems[0]);
void setup() {
// Настройка пинов кнопок как входы с подтяжкой к 5V
pinMode(buttonUpPin, INPUT_PULLUP);
pinMode(buttonDownPin, INPUT_PULLUP);
pinMode(buttonSelectPin, INPUT_PULLUP);
// Инициализация дисплея
lcd.begin(16, 2);
lcd.backlight();
lcd.print("Menu:");
// Инициализация последовательного порта для отладки
Serial.begin(9600);
initParams();
menuIndex = vMenu;
displayMenu();
}
void loop() {
if (vMenu != 2) {
selectMenu();
} else listenUSB();
}
void listenUSB() {
int buttonSelectState = digitalRead(buttonSelectPin);
Serial.print(buttonSelectState);
if (lastButtonSelectState != buttonSelectState) {
vMenu = 0;
displayMenu();
delay(500);
}
}
void displayMenu() {
lcd.clear();
if (currentMenu == 0) {
lcd.print("Menu:");
lcd.setCursor(0, 1);
//Serial.print(menuIndex);
lcd.print(mainMenuItems[menuIndex]);
if (menuIndex<2) {
lcd.print(" (");
if (menuIndex==0) {
String typeToStr = getTypesToString();
lcd.print(typeToStr);
}
if (menuIndex==1) lcd.print(intervalItems[vInterval]);
lcd.print(")");
}
} else if (currentMenu == 1) {
lcd.print("Type menu:");
lcd.setCursor(0, 1);
lcd.print(typeItems[menuIndex]);
if (vTypes[menuIndex]==1) lcd.print(" <<<");
} else if (currentMenu == 2) {
lcd.print("Interval menu:");
lcd.setCursor(0, 1);
lcd.print(intervalItems[menuIndex]);
if (vInterval==menuIndex) lcd.print(" <<<");
}
}
void selectMenu() {
int buttonUpState = digitalRead(buttonUpPin);
int buttonDownState = digitalRead(buttonDownPin);
int buttonSelectState = digitalRead(buttonSelectPin);
// Отладочная информация
/*
Serial.print("Up: ");
Serial.print(buttonUpState);
Serial.print(", Down: ");
Serial.print(buttonDownState);
Serial.print(", Select: ");*/
//Serial.println(typeItems[vType]);
//Serial.println(intervalItems[vInterval]);
delay(100);
// Обработка нажатия кнопки вверх
if (buttonUpState == LOW && lastButtonUpState == HIGH) {
menuIndex--;
if (menuIndex < 0) {
if (currentMenu == 0) {
menuIndex = mainMenuItemsCount - 1;
} else if (currentMenu == 1) {
menuIndex = typeItemsCount - 1;
} else if (currentMenu == 2) {
menuIndex = intervalItemsCount - 1;
}
}
displayMenu();
}
lastButtonUpState = buttonUpState;
// Обработка нажатия кнопки вниз
if (buttonDownState == LOW && lastButtonDownState == HIGH) {
menuIndex++;
if (currentMenu == 0 && menuIndex >= mainMenuItemsCount) {
menuIndex = 0;
} else if (currentMenu == 1 && menuIndex >= typeItemsCount) {
menuIndex = 0;
} else if (currentMenu == 2 && menuIndex >= intervalItemsCount) {
menuIndex = 0;
}
displayMenu();
}
lastButtonDownState = buttonDownState;
// Обработка нажатия кнопки выбора
if (buttonSelectState == LOW && lastButtonSelectState == HIGH) {
if (currentMenu == 0) {
vMenu = menuIndex;
EEPROM.write(vMenuAddress, vMenu);
if (menuIndex == 0) { // Type
currentMenu = 1;
menuIndex = 0;
} else if (menuIndex == 1) { // Interval
currentMenu = 2;
menuIndex = vInterval;
} else if (menuIndex == 2) { // Show Work
lcd.clear();
lcd.print("Type - ");
String typeToStr = getTypesToString();
lcd.print(typeToStr);
//lcd.print(typeItems[vType]);
lcd.setCursor(0, 1);
lcd.print("Interval - ");
lcd.print(intervalItems[vInterval]);
//delay(2000); // Задержка для отображения действия
return;
}
} else if (currentMenu == 1) {
if (typeItems[menuIndex] == "Back") { // Back from Type
currentMenu = 0;
menuIndex = 0;
} else {
vType = menuIndex;
if (vTypes[menuIndex] == 1) {
vTypes[menuIndex] = 0;
} else {
vTypes[menuIndex] = 1;
if (menuIndex > 0 && vTypes[0] == 1) {
vTypes[0] = 0; // All Type - 0
}
else if (menuIndex == 0) { // All Type - 1 , все остальные в 0
for (int i = 1; i < typeItemsCount; i++) {
vTypes[i] = 0;
}
}
}
//EEPROM.put(vTypesAddress, vTypes);
saveArrayToEEPROM(vTypesAddress, vTypes, typeItemsCount);
/*
lcd.clear();
lcd.print(typeItems[menuIndex]);
delay(2000); // Задержка для отображения действия
currentMenu = 0;
menuIndex = 0;
*/
}
} else if (currentMenu == 2) {
if (intervalItems[menuIndex] == "Back") { // Back from Interval
currentMenu = 0;
menuIndex = 1;
} else {
vInterval = menuIndex;
EEPROM.write(vIntervalAddress, vInterval);
/*
lcd.clear();
lcd.print(intervalItems[menuIndex]);
menuIndex = intervalItemsCount - 1;
delay(2000); // Задержка для отображения действия
currentMenu = 0;
menuIndex = 1;
*/
}
}
displayMenu(); // Возврат к меню
}
lastButtonSelectState = buttonSelectState;
}
void initParams() {
// Чтение сохраненного состояния меню из EEPROM
vType = EEPROM.read(vTypeAddress);
vInterval = EEPROM.read(vIntervalAddress);
vMenu = EEPROM.read(vMenuAddress);
//EEPROM.get(vTypesAddress, vTypes);
readArrayFromEEPROM(vTypesAddress, vTypes, typeItemsCount);
String typeToStr = getTypesToString();
if (typeToStr=="") vTypes[0] = 1;
// Проверка допустимости значений
//if (vType < 0 || vType >= typeItemsCount) vType = 0;
if (vInterval < 0 || vInterval >= intervalItemsCount) vInterval = 0;
if (vMenu<0 || vMenu >= mainMenuItemsCount) vMenu = 0;
}
String getTypesToString() {
String ret = "";
for (int i = 0; i < typeItemsCount; i++) {
if (vTypes[i]==1) {
if (ret=="") ret = typeItems[i];
else ret = ret + '/' + typeItems[i];
Serial.println(ret);
}
}
return ret;
}
void saveArrayToEEPROM(int startAddress, int* array, int size) {
for (int i = 0; i < size; i++) {
EEPROM.put(startAddress + i * sizeof(int), array[i]);
}
}
// Функция для чтения массива из EEPROM
void readArrayFromEEPROM(int startAddress, int* array, int size) {
for (int i = 0; i < size; i++) {
EEPROM.get(startAddress + i * sizeof(int), array[i]);
}
}