#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
// переключатель режимов: TEST (true) / Готовое изделие (false); чтобы не жечь "EEPROM"
#define TEST_MODE true // false, когда будешь готов к "боевому" железу.
// --- Точные настройки пинов ---
const int FLOW_SENSOR_PIN = 2; // Синяя кнопка / Датчик Холла (D2 -> GND)
const int BUTTON_MODE_PIN = 3; // Черная кнопка MODE (листает меню) (D3 -> GND)
const int BUTTON_RESET_PIN = 4; // КРАСНАЯ КНОПКА СБРОСА/сохранения (D4 -> GND)
const int BUTTON_UP_PIN = 5; // Кнопка ВВЕРХ Up (D5 -> GND)
const int BUTTON_DOWN_PIN = 6; // Кнопка ВНИЗ Down (D6 -> GND)
const int LED_PIN = 13; // Встроенный светодиод паники/потока
// --- Калибровка расхода и ресурс ---
float calibrationFactor = 0.04500; // Теперь это переменная (по умолчанию 450), для теста 0.0450
const float TOTAL_RESOURCE_LITERS = 10000.0; // Ресурс, в железе 8000-10000 л.
// --- Адреса в EEPROM ---
const int EEPROM_ADDR_LITERS = 0; // счетчик ресурса установленного картриджа, литры
const int EEPROM_ADDR_TOTAL = 4; // тотальный счетчик, литры
const int EEPROM_ADDR_INIT = 10;
const int EEPROM_ADDR_CALIB = 14; // Калибровка
const int EEPROM_ADDR_DAYS = 18; // Хранение ресурса по сроку (дней) (int)
const int EEPROM_ADDR_PERIODS = 20; // Хранение 4-часовых окон (int)
const int EEPROM_INIT_KEY = 42;
// --- Переменные для прерываний ---
volatile unsigned long pulseCount = 0;
volatile bool isFlowing = false;
volatile unsigned long lastPulseTime = 0;
volatile unsigned long flowPulsesSec = 0;
unsigned long lastFlowMillis = 0;
float currentFlowRate = 0.0;
// --- Переменные основного цикла ---
float litersPassed = 0.0;
float totalLitersPassed = 0.0;
float currentResource = TOTAL_RESOURCE_LITERS;
unsigned long lastEepromWriteTime = 0;
bool needEepromWrite = false;
// --- ОПТИМИЗИРОВАННЫЙ ТАЙМЕР (4-ЧАСОВЫЕ ОКНА) ---
int daysPassed = 0;
int periodsAccumulated = 0; // От 0 до 5 (6 периодов = 24 часа)
unsigned long lastPeriodMillis = 0;
const unsigned long SAVE_PERIOD = 1000UL; // 14400000UL (4 часа, в симуляторе ставь 1000UL для теста)
// --- Состояния кнопок ---
bool isModePressed = false;
unsigned long lastModeReleaseTime = 0;
const unsigned long DEBOUNCE_TIME = 200;
// --- Стейт-машина 8-секундного протокола Красной кнопки (Reset) ---
enum ResetState { STATE_NORMAL, STATE_COUNTDOWN, STATE_ABORTED };
ResetState currentResetState = STATE_NORMAL;
unsigned long resetStartTime = 0;
int lastSecondsRemaining = -1;
unsigned long lastLedToggleTime = 0;
bool currentLedState = false;
// --- Логика режима сна ---
bool isSleeping = false;
bool screenToldToSleep = false;
unsigned long sleepTransitionTimer = 0;
unsigned long lastActivityTime = 0;
const unsigned long SLEEP_TIMEOUT = 60000; //300000 - это 5 минут
// --- Состояния экрана ---
int displayMode = 0;
unsigned long lastBlinkTime = 0;
bool blinkState = true;
unsigned long lastDisplayUpdateTime = 0;
const unsigned long DISPLAY_UPDATE_INTERVAL = 250;
LiquidCrystal_I2C lcd(0x27, 16, 2);
// --- Кастомные символы ---
byte customChars [8][8] = {
{B11111, B10000, B10000, B10000, B10000, B10000, B10000, B11111}, //0 Левый пустой край [
{B11111, B00001, B00001, B00001, B00001, B00001, B00001, B11111}, //1 Правый пустой край ]
{B11111, B00000, B00000, B00000, B00000, B00000, B00000, B11111}, //2 Пустое тело =
{B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111}, //3 Заполненный блок #
{B00100, B01110, B11111, B00000, B00000, B11111, B01110, B00100}, //4 стрелки up/down
{B00100, B01110, B11111, B00100, B00100, B00100, B00100, B00000}, //5 стрелка вверх
{B00100, B00100, B00100, B00100, B11111, B01110, B00100, B00000}, //6 стрелка вниз
{B00000, B00001, B00011, B10110, B11100, B01000, B00000, B00000} //7 галочка
};
void flowPulseISR() {
pulseCount++;
flowPulsesSec++;
lastPulseTime = millis();
isFlowing = true;
}
void setup() {
Serial.begin(9600);
Serial.println(F("--- AQUA MONITOR 3.8 SYSTEM START ---"));
pinMode(FLOW_SENSOR_PIN, INPUT_PULLUP);
pinMode(BUTTON_MODE_PIN, INPUT_PULLUP);
pinMode(BUTTON_RESET_PIN, INPUT_PULLUP);
pinMode(BUTTON_UP_PIN, INPUT_PULLUP);
pinMode(BUTTON_DOWN_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
lcd.init();
lcd.backlight();
for (int i = 0; i < 8; i++) {
lcd.createChar(i, customChars[i]);
}
lcd.setCursor(0, 0); lcd.print("RD&P Laboratory ");
lcd.setCursor(0, 1); lcd.print(" with Gemini O_o");
delay(1500);
lcd.clear();
lcd.setCursor(0, 0); lcd.print("AQUA MONITOR 3.8");
lcd.setCursor(0, 1);
for (int i = 0; i < 16; i++) {
lcd.write(3);
delay(30);
}
delay(1000);
lcd.clear();
if (EEPROM.read(EEPROM_ADDR_INIT) != EEPROM_INIT_KEY) {
EEPROM.write(EEPROM_ADDR_INIT, EEPROM_INIT_KEY);
if (!TEST_MODE) {
EEPROM.put(EEPROM_ADDR_LITERS, 0.0f);
EEPROM.put(EEPROM_ADDR_TOTAL, 0.0f);
EEPROM.put(EEPROM_ADDR_CALIB, 0.04500f); // Базовая калибровка датчика при первом запуске 450.0f, для теста 0.0450f
EEPROM.put(EEPROM_ADDR_DAYS, 0);
EEPROM.put(EEPROM_ADDR_PERIODS, 0);
}
litersPassed = 0.0;
totalLitersPassed = 0.0;
calibrationFactor = 0.04500; //450.0 - Калибровка датчика по умолчанию, для теста 0.0450
daysPassed = 0;
periodsAccumulated = 0;
} else {
if (!TEST_MODE) {
EEPROM.get(EEPROM_ADDR_LITERS, litersPassed);
EEPROM.get(EEPROM_ADDR_TOTAL, totalLitersPassed);
EEPROM.get(EEPROM_ADDR_CALIB, calibrationFactor);
EEPROM.get(EEPROM_ADDR_DAYS, daysPassed);
EEPROM.get(EEPROM_ADDR_PERIODS, periodsAccumulated);
}
if (isnan(calibrationFactor) || calibrationFactor < 100 || calibrationFactor > 1000) calibrationFactor = 450.0;
if (daysPassed < 0 || daysPassed > 3000) daysPassed = 0;
if (periodsAccumulated < 0 || periodsAccumulated >= 6) periodsAccumulated = 0;
Serial.print(F("Loaded Unit Liters: ")); Serial.println(litersPassed, 3);
Serial.print(F("Loaded Total Liters: ")); Serial.println(totalLitersPassed, 3);
Serial.print(F("Loaded Calib Factor: ")); Serial.println(calibrationFactor);
Serial.print(F("Loaded Days Passed: ")); Serial.println(daysPassed);
}
currentResource = TOTAL_RESOURCE_LITERS - litersPassed;
attachInterrupt(digitalPinToInterrupt(FLOW_SENSOR_PIN), flowPulseISR, FALLING);
unsigned long startupTime = millis();
lastFlowMillis = startupTime;
lastPeriodMillis = startupTime;
lastActivityTime = startupTime;
Serial.println(F("System Ready."));
}
void loop() {
unsigned long currentTime = millis();
if (currentTime - lastPeriodMillis >= SAVE_PERIOD) {
lastPeriodMillis = currentTime;
if (currentResetState == STATE_NORMAL) {
periodsAccumulated++;
if (periodsAccumulated >= 6) {
periodsAccumulated = 0;
daysPassed++;
if (!TEST_MODE) EEPROM.put(EEPROM_ADDR_DAYS, daysPassed);
}
if (!TEST_MODE) EEPROM.put(EEPROM_ADDR_PERIODS, periodsAccumulated);
}
}
if (currentTime - lastFlowMillis >= 1000) {
noInterrupts();
unsigned long pulsesLastSec = flowPulsesSec;
flowPulsesSec = 0;
interrupts();
float targetFlowRate = ((float)pulsesLastSec * 60.0) / calibrationFactor;
currentFlowRate = (currentFlowRate * 0.4) + (targetFlowRate * 0.6);
if (pulsesLastSec == 0 && currentTime - lastPulseTime > 1200) {
currentFlowRate = 0.0;
}
lastFlowMillis = currentTime;
}
if (isFlowing) {
if (currentResetState == STATE_NORMAL) {
noInterrupts();
unsigned long pulses = pulseCount;
pulseCount = 0;
isFlowing = false;
interrupts();
if (pulses > 0) {
float delta = (float)pulses / calibrationFactor;
litersPassed += delta;
totalLitersPassed += delta;
currentResource = TOTAL_RESOURCE_LITERS - litersPassed;
needEepromWrite = true;
lastEepromWriteTime = currentTime;
lastActivityTime = currentTime;
digitalWrite(LED_PIN, HIGH);
}
}
}
if (currentResetState == STATE_NORMAL && currentTime - lastPulseTime > 200) {
digitalWrite(LED_PIN, LOW);
}
// Фоновое сохранение литров, // Запись in EEPROM через 60 секунд после остановки потока
if (needEepromWrite && (currentTime - lastEepromWriteTime > 60000)) {
if (!TEST_MODE) {
EEPROM.put(EEPROM_ADDR_LITERS, litersPassed);
EEPROM.put(EEPROM_ADDR_TOTAL, totalLitersPassed);
}
needEepromWrite = false;
Serial.println(F("[EEPROM] Data saved successfully."));
}
bool modeState = (digitalRead(BUTTON_MODE_PIN) == LOW);
bool upState = (digitalRead(BUTTON_UP_PIN) == LOW);
bool downState = (digitalRead(BUTTON_DOWN_PIN) == LOW);
if (modeState && !isModePressed) {
if (currentTime - lastModeReleaseTime > DEBOUNCE_TIME) {
isModePressed = true;
lastActivityTime = currentTime;
if (isSleeping || screenToldToSleep) {
isSleeping = false;
screenToldToSleep = false;
lcd.backlight();
lcd.clear();
Serial.println(F("[SYSTEM] Woke up from sleep."));
} else {
if (currentResetState == STATE_NORMAL) {
if (displayMode == 6) {
// Если мы в меню 6 и жмем Mode - выходим без сохранения
displayMode = 5;
if (!TEST_MODE) EEPROM.get(EEPROM_ADDR_CALIB, calibrationFactor);
} else {
displayMode++;
if (displayMode > 5) displayMode = 0; // листаем меню от 0 до 5 (6 - калибровка)
}
lcd.clear();
Serial.print(F("[UI] Display mode changed to: ")); Serial.println(displayMode);
}
}
}
} else if (!modeState && isModePressed) {
isModePressed = false;
lastModeReleaseTime = currentTime;
lastActivityTime = currentTime;
}
// ВХОД В НАСТРОЙКИ (UP + DOWN) на экране "5"
if (displayMode == 5 && currentResetState == STATE_NORMAL && !isSleeping) {
if (upState ) { //&& downState) { // тут, для теста, убрал вторую кнопку для входа в "6" !!!
displayMode = 6;
lastActivityTime = currentTime;
lcd.clear();
delay(500);
}
}
if (displayMode == 6 && currentResetState == STATE_NORMAL && !isSleeping) {
if (upState && !downState && calibrationFactor < 600.0) {
calibrationFactor += 5.0;
lastActivityTime = currentTime;
delay(200);
}
if (downState && !upState && calibrationFactor > 300.0) {
calibrationFactor -= 5.0;
lastActivityTime = currentTime;
delay(200);
}
}
bool currentPhysicalResetState = digitalRead(BUTTON_RESET_PIN);
bool resetState = (currentPhysicalResetState == LOW);
if (!isSleeping && !screenToldToSleep) {
if (resetState) lastActivityTime = currentTime;
if (currentResetState == STATE_NORMAL) {
if (resetState && (displayMode == 3 || displayMode == 4 || displayMode == 6)) {
currentResetState = STATE_COUNTDOWN;
resetStartTime = currentTime;
lastSecondsRemaining = -1;
detachInterrupt(digitalPinToInterrupt(FLOW_SENSOR_PIN));
digitalWrite(LED_PIN, LOW);
lcd.clear();
Serial.println(F("[PROTOCOL] Countdown Started! Holding RESET button..."));
}
}
else if (currentResetState == STATE_COUNTDOWN) {
if (!resetState) {
currentResetState = STATE_ABORTED;
resetStartTime = currentTime;
digitalWrite(LED_PIN, LOW);
lcd.clear();
lcd.setCursor(0, 0); lcd.print("Process ABORTED!");
if (displayMode == 6) {
lcd.setCursor(0, 1); lcd.print("Settings Reverted");
if (!TEST_MODE) EEPROM.get(EEPROM_ADDR_CALIB, calibrationFactor);
} else {
lcd.setCursor(0, 1); lcd.print("Data NOT Deleted");
}
Serial.println(F("[PROTOCOL] ABORTED by user! Data is safe."));
}
else {
unsigned long elapsed = currentTime - resetStartTime;
int secondsRemaining = 8 - (elapsed / 1000);
if (secondsRemaining < 0) secondsRemaining = 0;
if (secondsRemaining != lastSecondsRemaining) {
lastSecondsRemaining = secondsRemaining;
lcd.setCursor(0, 0);
if (displayMode == 3) lcd.print("UPDATE the Unit?");
else if (displayMode == 4) lcd.print("ERASE Total Vol?");
else if (displayMode == 6) lcd.print("SAVED NEW Value?");
lcd.setCursor(0, 1); lcd.print(" Passed "); lcd.print(secondsRemaining); lcd.print(" sec. ");
Serial.print(F("[PROTOCOL] Time left: ")); Serial.print(secondsRemaining); Serial.println(F("s..."));
}
unsigned long toggleInterval = (secondsRemaining * 50) + 30;
if (currentTime - lastLedToggleTime > toggleInterval) {
currentLedState = !currentLedState;
digitalWrite(LED_PIN, currentLedState ? HIGH : LOW);
lastLedToggleTime = currentTime;
}
if (elapsed >= 8000) {
Serial.println(F("[PROTOCOL] 8 SECONDS REACHED. EXECUTING..."));
digitalWrite(LED_PIN, HIGH);
lcd.clear();
if (displayMode == 6) lcd.print("SAVING DATA... ");
else lcd.print("ERASING DATA... ");
lcd.setCursor(0, 1);
for (int i = 0; i < 16; i++) {
lcd.write(3);
delay(30);
}
delay(1000);
lcd.clear();
if (displayMode == 3) {
litersPassed = 0.0;
daysPassed = 0;
periodsAccumulated = 0;
currentResource = TOTAL_RESOURCE_LITERS;
if (!TEST_MODE) {
EEPROM.put(EEPROM_ADDR_LITERS, litersPassed);
EEPROM.put(EEPROM_ADDR_DAYS, daysPassed);
EEPROM.put(EEPROM_ADDR_PERIODS, periodsAccumulated);
Serial.println(F("[EEPROM] Unit Data Updated."));
}
}
else if (displayMode == 4) {
litersPassed = 0.0;
totalLitersPassed = 0.0;
daysPassed = 0;
periodsAccumulated = 0;
currentResource = TOTAL_RESOURCE_LITERS;
if (!TEST_MODE) {
EEPROM.put(EEPROM_ADDR_LITERS, litersPassed);
EEPROM.put(EEPROM_ADDR_TOTAL, totalLitersPassed);
EEPROM.put(EEPROM_ADDR_DAYS, daysPassed);
EEPROM.put(EEPROM_ADDR_PERIODS, periodsAccumulated);
Serial.println(F("[EEPROM] Total System FULL ERASE completed."));
}
}
else if (displayMode == 6) {
if (!TEST_MODE) {
EEPROM.put(EEPROM_ADDR_CALIB, calibrationFactor);
Serial.println(F("[EEPROM] Calibration Factor Saved."));
}
}
needEepromWrite = false;
pulseCount = 0;
currentFlowRate = 0.0;
displayMode = 0;
digitalWrite(LED_PIN, LOW);
lcd.clear();
currentResetState = STATE_NORMAL;
attachInterrupt(digitalPinToInterrupt(FLOW_SENSOR_PIN), flowPulseISR, FALLING);
lastActivityTime = currentTime;
Serial.println(F("[SYSTEM] Returned to normal operation."));
}
}
}
else if (currentResetState == STATE_ABORTED) {
lastActivityTime = currentTime;
if (currentTime - resetStartTime > 1500) {
lcd.clear();
currentResetState = STATE_NORMAL;
attachInterrupt(digitalPinToInterrupt(FLOW_SENSOR_PIN), flowPulseISR, FALLING);
lastActivityTime = currentTime;
}
}
}
if (currentResetState == STATE_NORMAL) {
if (!isSleeping && !screenToldToSleep && (currentTime - lastActivityTime >= SLEEP_TIMEOUT)) {
screenToldToSleep = true;
sleepTransitionTimer = currentTime;
lcd.backlight(); lcd.clear();
lcd.setCursor(0, 0); lcd.print("[O_o] (z-z-z) ");
lcd.setCursor(5, 1); lcd.print("sleeping... ");
Serial.println(F("[SYSTEM] Preparing to sleep..."));
}
if (!isSleeping && screenToldToSleep && (currentTime - sleepTransitionTimer >= 2000)) {
isSleeping = true;
screenToldToSleep = false;
lcd.noBacklight(); lcd.clear();
Serial.println(F("[SYSTEM] Device is now sleeping."));
}
}
if (currentTime - lastBlinkTime > 500) {
blinkState = !blinkState;
lastBlinkTime = currentTime;
}
if (currentResetState == STATE_NORMAL && !isSleeping && !screenToldToSleep) {
if (currentTime - lastDisplayUpdateTime >= DISPLAY_UPDATE_INTERVAL) {
drawDisplay();
lastDisplayUpdateTime = currentTime;
}
}
}
void drawDisplay() {
float percent = (currentResource / TOTAL_RESOURCE_LITERS) * 100.0;
bool isExpiredResource = (currentResource <= 0);
if (displayMode == 0) {
lcd.setCursor(0, 0); lcd.print("Flow: ");
if (currentFlowRate <= 0.05) {
lcd.print("[X] CLOSED ");
}
else if (currentFlowRate < 1.800) {
lcd.print("["); lcd.write(5); lcd.print("] Raise! ");
}
else if (currentFlowRate > 2.200) {
lcd.print("["); lcd.write(6); lcd.print("] Lower! ");
}
else {
lcd.print("["); lcd.write(7); lcd.print("] NORMAL ");
}
lcd.setCursor(0, 1);
if (currentFlowRate < 10.0) {
lcd.print("0");
}
lcd.print(currentFlowRate, 3); lcd.print(" L/min ");
}
else if (displayMode == 1) {
// --- ПЕРВАЯ СТРОКА: USAG ###### xxx% (Ровно 16 символов) ---
lcd.setCursor(0, 0);
lcd.print("USAG ");
if (isExpiredResource && !blinkState) {
lcd.print(" ");
}
else {
if (isExpiredResource) {
lcd.write(0); lcd.write(2); lcd.write(2); lcd.write(2); lcd.write(2); lcd.write(1);
}
else {
int activeBlocks = (int)((percent / 100.0) * 6.0 + 0.5);
activeBlocks = constrain(activeBlocks, 1, 6);
for (int i = 0; i < 6; i++) {
if (i < activeBlocks) lcd.write(3);
else {
if (i == 0) lcd.write(0);
else if (i == 5) lcd.write(1);
else lcd.write(2);
}
}
}
}
lcd.print(" ");
int p = (int)percent;
if (p <= 0 && !blinkState) {
lcd.print(" ");
} else {
if (p <= 0) p = 0;
if (p >= 100) {
lcd.print(p); lcd.print("%");
}
else if (p >= 10) {
lcd.print("0"); lcd.print(p); lcd.print("%");
}
else {
lcd.print("00"); lcd.print(p); lcd.print("%");
}
}
// --- ВТОРАЯ СТРОКА: xxxxx L/Days xxx (Ровно 16 символов) ---
lcd.setCursor(0, 1);
float displayLiters = TOTAL_RESOURCE_LITERS - litersPassed;
// Превращаем в целое число без десятичной точки
int litInt = (int)displayLiters;
if (litInt < 0) litInt = 0;
if (litInt > 99999) litInt = 99999; // Защита от переполнения строки
// Мигание литров, если ресурс вышел в ноль
if (displayLiters <= 0.0 && !blinkState) {
lcd.print(" "); // 5 пробелов вместо xxxxx
}
else {
// Добиваем нулями до 5 знаков
if (litInt < 10000) lcd.print("0");
if (litInt < 1000) lcd.print("0");
if (litInt < 100) lcd.print("0");
if (litInt < 10) lcd.print("0");
lcd.print(litInt);
}
lcd.print(" L/Days "); // 8 символов разделителя
int daysLeft = 366 - daysPassed;
// Мигание дней, если срок вышел
if (daysLeft <= 0 && !blinkState) {
lcd.print(" "); // 3 пробела вместо xxx
}
else {
if (daysLeft < 0) daysLeft = 0;
if (daysLeft > 999) daysLeft = 999; // Защита верстки
// Добиваем нулями до 3 знаков
if (daysLeft < 100) lcd.print("0");
if (daysLeft < 10) lcd.print("0");
lcd.print(daysLeft);
}
}
else if (displayMode == 2) {
// --- ПЕРВАЯ СТРОКА: Total: xxxx Days (Ровно 16 символов) ---
lcd.setCursor(0, 0);
lcd.print("Total: ");
int d = daysPassed;
if (d < 0) d = 0;
if (d > 9999) d = 9999; // Максимум 4 символа (адские цифры)
// Добиваем нулями до 4 знаков, строка монолитна
if (d < 1000) lcd.print("0");
if (d < 100) lcd.print("0");
if (d < 10) lcd.print("0");
lcd.print(d);
lcd.print(" Days");
// --- ВТОРАЯ СТРОКА: xxxxxxx.x Litres (Ровно 16 символов) ---
lcd.setCursor(0, 1);
float displayTotal = totalLitersPassed;
if (displayTotal < 0.0) displayTotal = 0.0;
if (displayTotal > 9999999.9) displayTotal = 9999999.9; // Ограничение под 7.1 знаков
// Добиваем нулями до 7 знаков перед точкой
if (displayTotal < 1000000.0) lcd.print("0");
if (displayTotal < 100000.0) lcd.print("0");
if (displayTotal < 10000.0) lcd.print("0");
if (displayTotal < 1000.0) lcd.print("0");
if (displayTotal < 100.0) lcd.print("0");
if (displayTotal < 10.0) lcd.print("0");
lcd.print(displayTotal, 1); // Печать с одной десятой
lcd.print(" Litres");
}
else if (displayMode == 3) {
lcd.setCursor(0, 0); lcd.print("(i) Unit UPDATE: ");
lcd.setCursor(0, 1); lcd.print("HOLD RED Button! ");
}
else if (displayMode == 4) {
lcd.setCursor(0, 0); lcd.print("[!] TOTAL RESET: ");
lcd.setCursor(0, 1); lcd.print("HOLD RED Button! ");
}
else if (displayMode == 5) {
lcd.setCursor(0, 0); lcd.print("<*> SETUP Sensor ");
lcd.setCursor(0, 1); lcd.print("Up+Down > BEGIN! ");
}
else if (displayMode == 6) {
lcd.setCursor(0, 0);
lcd.print("Curr.Value "); lcd.print((int)calibrationFactor);
lcd.print(" "); lcd.write(4); lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("HOLD > Save&Exit");
}
}