Доброго всем дня. Есть код вывода меню настроек написанный под ESP32+LCD1602 с возможностью изменения параметров с помощью энкодера EC11. Но значения по умолчанию выводит. изменить значение получается, но записать измененное значение не получается. При перезагрузки устройства значения загружаются по умолчанию.
C++:
#include <EEPROM.h>
// пример с оптимизированным линейным меню
// оптимизировано очищение дисплея
// названия засунуты в PROGMEM вместо оперативки
// менять значения можно нажатым поворотом, или КЛИКНУТЬ, курсор изменится, и крутить
// значение меняется быстрее при быстром повороте
#include "pgmspace.h"
#define LINES 2 // количество строк дисплея
#define SETTINGS_AMOUNT 6 // количество настроек
#define FAST_STEP 5 // скорость изменения при быстром повороте
// пины энкодера
#define CLK 25
#define DT 32
#define SW 33
#include "GyverEncoder.h"
Encoder enc1(CLK, DT, SW); // для работы c кнопкой
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // адрес 0x27 или 0x3f
int8_t arrowPos = 0;
int8_t screenPos = 0; // номер "экрана"
int vals[SETTINGS_AMOUNT];
bool isFirstRun;
//Массив пунктов меню который выводится на экране
const char *settingsNames[] = {
"MaxT kotla",
"MaxT home",
"Ts1MIN",
"Ts2MIN",
"Ts3MIN",
"ModeA",
};
//Структура хранения данных в EEptrom, рассчитана на 6 пунктов меню 5 из которых имеют тип данных int, 1 пункт тип данных bool
struct MenuItem{
char name[10];
int value;
bool mode;
};
MenuItem param[6];
void setup(){
Serial.begin(115200);
enc1.setType(TYPE2);
EEPROM.begin(100);
// if(EEPROM.read(50)!='w'){
// EEPROM.put(50,'w');
// writeParamStruct(); //При первой компиляции было раскоментировано и данные были записаны в EEPROM
// EEPROM.put(0,param);
// EEPROM.commit();
// }else{
EEPROM.get(0,param);
EEPROM.commit();
// }
lcd.init();
lcd.clear();
lcd.backlight();
//Читаем данные из EEPROM
for(int i=0; i<6;i++){
EEPROM.get(i*sizeof(MenuItem), param[i]);
EEPROM.commit();
}
displayMenu();
}
//Заполнение структры массива данными по умолчанию
void writeParamStruct(){
sprintf(param[0].name, "TempKMax");
param[0].value = 80;
sprintf(param[1].name, "TempHMax");
param[1].value = 25;
sprintf(param[2].name, "TS1MIN");
param[2].value = 10;
sprintf(param[3].name, "TS2MIN");
param[3].value = -5;
sprintf(param[4].name, "TS3MIN");
param[4].value = -15;
sprintf(param[5].name, "AutoMode");
param[5].mode = true;
for (int i = 0; i < 6; i++) {
int address = i * sizeof(struct MenuItem);
EEPROM.put(address, param[i]);
EEPROM.commit();
}
}
//Вывод пунктов меню с данными на дисплей 1602
void displayMenu() {
lcd.clear();
screenPos = arrowPos / LINES;
// Отображение текущего пункта меню и его значение на первой строке дисплея
for (int i = 0; i < LINES; i++) {
lcd.setCursor(0, i);
if (arrowPos == LINES * screenPos + i) lcd.write(126); // рисуем стрелку
else lcd.write(32); // рисуем пробел
// если пункты меню закончились, покидаем цикл for
if (LINES * screenPos + i == SETTINGS_AMOUNT) break;
lcd.print(settingsNames[LINES * screenPos+i]);
lcd.setCursor(12, i);
lcd.print(param[LINES * screenPos+i].value);
}
}
void loop(){
enc1.tick();
Если было двойное нажатие то записываем данные по умолчанию
if(enc1.isDouble()){
writeParamStruct();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Default");
delay(5000);
displayMenu();
}
if (enc1.isTurn()){
//Блок выбора пункта меню
int increment =0;
if(enc1.isRight()) increment =1;
if(enc1.isLeft()) increment =-1;
arrowPos += increment;
arrowPos = constrain(arrowPos,0, SETTINGS_AMOUNT -1);
//Блок изменения значения пункта меню при удержании нажатия и прокручивании энкодера.
increment = 0; // обнуляем инкремент
if (enc1.isRightH()) increment = 1;
if (enc1.isLeftH()) increment = -1;
param[arrowPos].value +=increment;
displayMenu();
}
//Запись данных при удержании нажатия энкодера
if(enc1.isHolded()){
EEPROM.begin(100);
EEPROM.put(0,param);
EEPROM.commit();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Write");
delay(5000);
displayMenu();
}
}