#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Encoder.h>
#include <EEPROM.h>
#define ENCODER_A 2
#define ENCODER_B 3
#define BUTTON_PIN 4
#define LED_PIN 5
#define TEMP_SENSOR_PIN A0
#define POWER_BUTTON_PIN 6
Encoder enc(ENCODER_A, ENCODER_B);
LiquidCrystal_I2C lcd(0x27, 16, 2);
const char* menuItems[] = {"A", "B", "C", "D", "F", "Temperatura"};
const char* subMenuItemsA[] = {"acc_secondi", "spm_secondi", "Timer ON MS", "Timer OFF MS", "Salva", "Esci"};
int currentMenuIndex = 0;
int currentSubMenuIndex = 0;
float parameters[5][3];
// Timer parameters
unsigned long timerDurationOn = 5000;
unsigned long timerDurationOff = 5000;
unsigned long secondTimerDuration = 10000;
bool timerRunning = false;
bool ledState = false;
unsigned long previousMillis = 0;
bool inSubMenu = false;
bool buttonIsPressed = false;
bool powerButtonPressed = false;
bool isHeating = false;
bool secondTimerCompleted = false;
unsigned long secondTimerStart = 0;
float targetTemperature = 30.0;
long encoderPosition = 0;
const long encoderThreshold = 8;
float initialTemperature = 24.0;
float betaCoefficient = 3950.0;
void loadParameters();
float readTemperature();
void saveParameters();
void modifyTimerDuration(bool isOn);
void modifyTimerOnDuration();
void modifyTimerOffDuration();
void displayMenu();
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
pinMode(POWER_BUTTON_PIN, INPUT_PULLUP);
Serial.begin(9600);
lcd.begin(16, 2);
lcd.backlight();
loadParameters();
displayMenu();
}
void loop() {
// Gestione del pulsante di accensione
if (digitalRead(POWER_BUTTON_PIN) == LOW && !powerButtonPressed) {
powerButtonPressed = true;
isHeating = true;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Accensione");
lcd.setCursor(0, 1);
lcd.print("in corso");
while (isHeating) {
float temperature = readTemperature();
if (temperature >= targetTemperature) {
isHeating = false;
lcd.clear();
displayMenu();
secondTimerStart = millis();
secondTimerCompleted = false;
}
delay(1000); // Controlla la temperatura ogni secondo
}
} else if (digitalRead(POWER_BUTTON_PIN) == HIGH) {
powerButtonPressed = false;
}
// Gestione del secondo timer
if (!secondTimerCompleted) {
if (millis() - secondTimerStart >= secondTimerDuration) {
secondTimerCompleted = true;
timerRunning = true; // Avvia il primo timer
}
}
// Gestione del primo timer non bloccante
if (timerRunning) {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= (ledState ? timerDurationOn : timerDurationOff)) {
ledState = !ledState;
digitalWrite(LED_PIN, ledState);
previousMillis = currentMillis;
}
}
// Gestione del pulsante
if (digitalRead(BUTTON_PIN) == LOW && !buttonIsPressed) {
buttonIsPressed = true;
if (inSubMenu) {
handleSubMenuAction();
} else {
inSubMenu = true; // Entra nel sottomenu
}
displayMenu();
} else if (digitalRead(BUTTON_PIN) == HIGH) {
buttonIsPressed = false;
}
// Gestione dell'encoder
handleEncoder();
// Mostra la temperatura nel menu "Temperatura"
if (!isHeating && currentMenuIndex == 5) {
float temperature = readTemperature();
lcd.setCursor(0, 1);
lcd.print("Temp: ");
lcd.print(temperature);
lcd.print(" C ");
}
}
void handleSubMenuAction() {
if (currentSubMenuIndex == 4) {
saveParameters();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Parametri");
lcd.setCursor(0, 1);
lcd.print("salvati");
delay(2000);
inSubMenu = false;
currentSubMenuIndex = 0;
} else if (currentSubMenuIndex == 5) {
inSubMenu = false;
currentSubMenuIndex = 0;
} else {
handleSubMenuSelection();
}
}
void handleSubMenuSelection() {
lcd.clear();
if (currentMenuIndex == 0) {
switch (currentSubMenuIndex) {
case 0:
lcd.print("Modifica Acc. Sec.");
delay(2000);
modifyTimerDuration(true);
break;
case 1:
lcd.print("Modifica Spm. Sec.");
delay(2000);
modifyTimerDuration(false);
break;
case 2:
lcd.print("Timer ON MS");
delay(2000);
modifyTimerOnDuration();
break;
case 3:
lcd.print("Timer OFF MS");
delay(2000);
modifyTimerOffDuration();
break;
}
}
}
void handleEncoder() {
long pos = enc.read();
if (pos != encoderPosition) {
if (abs(pos - encoderPosition) >= encoderThreshold) {
if (!inSubMenu) {
currentMenuIndex = (currentMenuIndex + (pos > encoderPosition ? 1 : -1)) % (sizeof(menuItems) / sizeof(menuItems[0]));
if (currentMenuIndex < 0) currentMenuIndex += sizeof(menuItems) / sizeof(menuItems[0]);
} else {
if (currentMenuIndex == 0) {
currentSubMenuIndex = (currentSubMenuIndex + (pos > encoderPosition ? 1 : -1)) % (sizeof(subMenuItemsA) / sizeof(subMenuItemsA[0]));
if (currentSubMenuIndex < 0) currentSubMenuIndex += sizeof(subMenuItemsA) / sizeof(subMenuItemsA[0]);
}
}
encoderPosition = pos;
displayMenu();
}
}
}
void displayMenu() {
lcd.setCursor(0, 0);
lcd.print("Menu: ");
lcd.print(menuItems[currentMenuIndex]);
lcd.setCursor(0, 1);
if (inSubMenu) {
if (currentMenuIndex == 0) {
lcd.print(subMenuItemsA[currentSubMenuIndex]);
}
} else {
lcd.print(" "); // Pulisce la riga se non è in sottomenu
}
}
float readTemperature() {
int sensorValue = analogRead(TEMP_SENSOR_PIN);
float voltage = sensorValue * (5.0 / 1023.0);
const float R0 = 10000;
const float T0 = initialTemperature + 273.15;
float resistance = R0 * (5.0 / voltage - 1);
float temperatureK = 1 / ((log(resistance / R0) / betaCoefficient) + (1 / T0));
return temperatureK - 273.15;
}
void loadParameters() {
// Carica i parametri salvati
}
void saveParameters() {
// Salva i parametri
}
void modifyTimerDuration(bool isOn) {
// Logica per modificare la durata del timer
}
void modifyTimerOnDuration() {
// Logica per modificare la durata del timer acceso
}
void modifyTimerOffDuration() {
// Logica per modificare la durata del timer spento
}