#include <Keypad.h>
#include <LiquidCrystal.h>
#include <EEPROM.h>
// Impostazioni del display LCD
LiquidCrystal lcd(19, 18, 17, 16, 15, 14);
// Impostazioni tastiera 4x4
const byte ROWS = 4; // 4 righe
const byte COLS = 4; // 4 colonne
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {23, 25, 27, 29}; // Collegare alle righe del Keypad
byte colPins[COLS] = {31, 33, 35, 37}; // Collegare alle colonne del Keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Pin LED
int ledPins[] = {2, 3, 4, 5}; // 4 LED
// Variabili generali
int cocktailCount = 0; // Numero di cocktail eseguiti
bool initialized = false; // Stato di inizializzazione
int cocktailTimes[9][4]; // Tempi di accensione dei LED per i 9 cocktail
// Funzione per caricare i cocktail dalla EEPROM
void loadCocktailsFromEEPROM() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 4; j++) {
cocktailTimes[i][j] = EEPROM.read(i * 4 + j);
}
}
}
// Funzione per salvare i cocktail nella EEPROM
void saveCocktailToEEPROM(int cocktailNumber) {
for (int i = 0; i < 4; i++) {
EEPROM.write(cocktailNumber * 4 + i, cocktailTimes[cocktailNumber][i]);
}
}
// Funzione per gestire la barra di caricamento con durata precisa
void loadingBar(int duration) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Loading...");
// Durata totale del caricamento
int totalSteps = 16; // 16 caratteri sul display
int delayPerStep = duration / totalSteps; // Divisione equa del tempo
for (int i = 0; i < totalSteps; i++) {
lcd.setCursor(i, 1); // Muove il cursore lungo la seconda riga del display
lcd.print("|"); // Stampa la barra di caricamento
delay(delayPerStep); // Attendi il tempo calcolato per ogni passo
}
}
// Funzione per gestire l'accensione dei LED per test
void testLEDs() {
for (int i = 0; i < 4; i++) {
digitalWrite(ledPins[i], HIGH);
delay(500);
digitalWrite(ledPins[i], LOW);
}
}
// Funzione per inizializzare il sistema
void initializeSystem() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Initializing...");
for (int i = 0; i < 4; i++) {
digitalWrite(ledPins[i], HIGH);
}
delay(1000);
for (int i = 0; i < 4; i++) {
digitalWrite(ledPins[i], LOW);
}
}
// Funzione per verificare la password
bool checkPassword() {
String enteredPassword = "";
char key;
lcd.clear();
lcd.print("Enter password:");
while (enteredPassword.length() < 4) {
key = keypad.getKey();
if (key != NO_KEY) {
enteredPassword += key;
lcd.setCursor(enteredPassword.length(), 1);
lcd.print("*");
}
}
return (enteredPassword == "1234");
}
// Funzione per il menu impostazioni
void settingsMenu() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("1: New 2: Delete");
lcd.setCursor(0, 1);
lcd.print("3: Test 4: Count");
char key = NO_KEY;
while (key == NO_KEY) {
key = keypad.getKey();
}
if (key == '1') {
// Aggiungi un nuovo cocktail
addNewCocktail();
} else if (key == '2') {
// Elimina un cocktail
deleteCocktail();
} else if (key == '3') {
// Test dei LED
testLEDs();
} else if (key == '4') {
// Mostra il contatore dei cocktail
showCocktailCount();
}
// Torna alla schermata principale dopo l'operazione
lcd.clear();
lcd.print("A: Start B: Settings");
}
// Funzione per aggiungere un nuovo cocktail
void addNewCocktail() {
lcd.clear();
lcd.print("Add new cocktail:");
delay(1000);
lcd.clear();
lcd.print("Cocktail num (1-9)?");
char key = NO_KEY;
while (key == NO_KEY) {
key = keypad.getKey();
}
int cocktailNumber = key - '1'; // Converti il carattere in indice (0-8)
if (cocktailNumber >= 0 && cocktailNumber < 9) {
lcd.clear();
lcd.print("Set times (ms):");
for (int i = 0; i < 4; i++) {
lcd.clear();
lcd.print("LED ");
lcd.print(i + 1);
lcd.print(":");
String timeInput = "";
while (true) {
char key = keypad.getKey();
if (key != NO_KEY && key >= '0' && key <= '9') {
timeInput += key;
lcd.setCursor(timeInput.length(), 1);
lcd.print(key);
}
if (timeInput.length() == 4) {
cocktailTimes[cocktailNumber][i] = timeInput.toInt(); // Memorizza il tempo
break;
}
}
}
saveCocktailToEEPROM(cocktailNumber); // Salva il cocktail in EEPROM
lcd.clear();
lcd.print("Saved!");
delay(1000);
} else {
lcd.clear();
lcd.print("Invalid input");
delay(1000);
}
}
// Funzione per eliminare un cocktail
void deleteCocktail() {
lcd.clear();
lcd.print("Delete cocktail:");
delay(1000);
lcd.clear();
lcd.print("Cocktail num (1-9)?");
char key = NO_KEY;
while (key == NO_KEY) {
key = keypad.getKey();
}
int cocktailNumber = key - '1'; // Converti il carattere in indice (0-8)
if (cocktailNumber >= 0 && cocktailNumber < 9) {
for (int i = 0; i < 4; i++) {
cocktailTimes[cocktailNumber][i] = 0; // Resetta i tempi
}
saveCocktailToEEPROM(cocktailNumber); // Aggiorna EEPROM
lcd.clear();
lcd.print("Deleted!");
delay(1000);
} else {
lcd.clear();
lcd.print("Invalid input");
delay(1000);
}
}
// Funzione per mostrare il contatore di cocktail
void showCocktailCount() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Cocktails made:");
lcd.setCursor(0, 1);
lcd.print(cocktailCount);
delay(2000);
}
// Funzione per eseguire la sequenza del cocktail
void runCocktail(int cocktailNumber) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Running cocktail");
lcd.setCursor(0, 1);
lcd.print(cocktailNumber);
// Barra di caricamento mentre il cocktail viene preparato
for (int i = 0; i < 16; i++) {
lcd.setCursor(i, 1);
lcd.print("|");
delay(100);
}
// Esegui la sequenza di accensione dei LED in base al cocktail selezionato
for (int i = 0; i < 4; i++) {
if (cocktailTimes[cocktailNumber - 1][i] > 0) {
digitalWrite(ledPins[i], HIGH);
delay(cocktailTimes[cocktailNumber - 1][i]); // Usa il tempo specificato per il LED
digitalWrite(ledPins[i], LOW);
}
}
// Incrementa il contatore dei cocktail eseguiti
cocktailCount++;
// Dopo la sequenza, mostra "Fine" e torna al menu principale
lcd.clear();
lcd.print("Fine");
delay(2000);
}
void setup() {
// Configura i pin dei LED come output
for (int i = 0; i < 4; i++) {
pinMode(ledPins[i], OUTPUT);
}
// Inizializza il display LCD
lcd.begin(16, 2);
// Carica i dati dei cocktail dalla EEPROM
loadCocktailsFromEEPROM();
// Mostra la schermata iniziale
lcd.setCursor(0, 0);
lcd.print("Welcome!");
delay(1000);
lcd.clear();
}
// Funzione principale per gestire l'input dell'utente
void loop() {
if (!initialized) {
loadingBar(2000); // Barra di caricamento che dura esattamente 2 secondi
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("A: Start B: Settings");
initialized = true; // Imposta initialized a true dopo il caricamento
}
char key = keypad.getKey();
if (initialized) { // Assicuriamoci che il menu venga mostrato solo dopo l'inizializzazione
if (key == 'A') {
// Avvia sequenza di inizializzazione
initializeSystem(); // Inizializza solo una volta
lcd.clear();
lcd.print("Choose cocktail:");
char cocktailKey = keypad.waitForKey();
if (cocktailKey >= '1' && cocktailKey <= '9') {
// Esegui sequenza del cocktail
runCocktail(cocktailKey - '0');
}
// Torna alla schermata principale dopo aver eseguito il cocktail
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("A: Start B: Settings");
} else if (key == 'B') {
// Menu impostazioni
if (checkPassword()) {
settingsMenu();
} else {
lcd.clear();
lcd.print("Wrong password");
delay(1000);
}
}
}
}