#include <U8g2lib.h>
#include <Wire.h>
#include <avr/pgmspace.h>
#define BUTTON_UP_PIN 12
#define BUTTON_SELECT_PIN 13
#define SIMULATE_SENSOR_PIN 14
#define FLOW_SENSOR_PIN 2 // Zmiana na pin cyfrowy, ponieważ A0 nie obsługuje przerwań zewnętrznych
int currentMenuIndex = 0;
int currentDrinkIndex = 0;
int currentAlcoholIndex = 0;
int currentNonAlcoholIndex = 0;
int currentCupIndex = 0;
volatile unsigned int pulseCount = 0;
enum MenuOption { MAIN_MENU, SELECT_DRINK, SELECT_CUP_FOR_DRINK, SELECT_ALCOHOL_AMOUNT, SELECT_ALCOHOL, SELECT_CUP_FOR_ALCOHOL, SELECT_NON_ALCOHOL, SELECT_CUP_FOR_NON_ALCOHOL, PREPARE_DRINK, ADD_ALCOHOL, ADD_NON_ALCOHOL };
MenuOption currentMenuOption = MAIN_MENU;
enum CupSize { CUP_25, CUP_50, CUP_100, CUP_250, CUP_500 };
CupSize selectedCupSize = CUP_250;
bool simulateSensor = false; // Flaga do symulacji czujnika
// Konfiguracja wyświetlacza OLED
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ SCL, /* data=*/ SDA);
struct Ingredient {
const char* name;
float amount; // Ilość w litrach
};
struct Drink {
const char* name;
Ingredient ingredients[5]; // Zmniejszono maksymalną liczbę składników do 5
int numIngredients; // Liczba składników w drinku
};
// Dynamiczna tablica drinków
Drink drinks[5]; // Zmniejszono maksymalną liczbę drinków do 5
int selectedDrink = 0; // Wybrany drink do edycji
float selectedAlcoholAmount = 0.01; // Jednorazowe zwiększenie ilości alkoholu w litrach
void setup() {
// Inicjalizacja wyświetlacza OLED
u8g2.begin();
// Inicjalizacja przycisków
pinMode(BUTTON_UP_PIN, INPUT_PULLUP);
pinMode(BUTTON_SELECT_PIN, INPUT_PULLUP);
pinMode(SIMULATE_SENSOR_PIN, INPUT_PULLUP); // Przycisk do symulacji czujnika
pinMode(FLOW_SENSOR_PIN, INPUT_PULLUP);
// Inicjalizacja przykładowych drinków
initializeDrinks();
// Inicjalizacja monitora szeregowego
Serial.begin(9600);
// Wyświetlenie komunikatu na OLED
displayMenu();
// Ustawienie przerwania na pinie FLOW_SENSOR_PIN
attachInterrupt(digitalPinToInterrupt(FLOW_SENSOR_PIN), pulseCounter, FALLING);
}
void loop() {
handleButtons();
if (digitalRead(SIMULATE_SENSOR_PIN) == LOW) {
simulateSensor = !simulateSensor;
delay(200); // Debouncing
}
if (simulateSensor) {
simulateFlowSensor();
}
}
unsigned long lastButtonPressTime = 0;
const unsigned long debounceDelay = 200;
void handleButtons() {
if (millis() - lastButtonPressTime > debounceDelay) {
if (digitalRead(BUTTON_UP_PIN) == LOW) {
navigateMenu();
lastButtonPressTime = millis();
}
if (digitalRead(BUTTON_SELECT_PIN) == LOW) {
selectOption();
lastButtonPressTime = millis();
}
}
}
void navigateMenu() {
switch (currentMenuOption) {
case MAIN_MENU:
currentMenuIndex = (currentMenuIndex + 1) % 3; // Trzy opcje w menu głównym
break;
case SELECT_DRINK:
currentDrinkIndex = (currentDrinkIndex + 1) % 5; // Zakładamy 5 drinków
break;
case SELECT_CUP_FOR_DRINK:
currentCupIndex = (currentCupIndex + 1) % 5; // Pięć opcji kubków: 25 ml, 50 ml, 100 ml, 250 ml, 500 ml
break;
case SELECT_ALCOHOL_AMOUNT:
currentAlcoholIndex = (currentAlcoholIndex + 1) % 3; // Trzy poziomy alkoholu: 10 ml, 25 ml, 50 ml
break;
case SELECT_ALCOHOL:
currentAlcoholIndex = (currentAlcoholIndex + 1) % 3; // Trzy rodzaje alkoholu: vodka, tequila, rum
break;
case SELECT_CUP_FOR_ALCOHOL:
currentCupIndex = (currentCupIndex + 1) % 5; // Pięć opcji kubków: 25 ml, 50 ml, 100 ml, 250 ml, 500 ml
break;
case SELECT_NON_ALCOHOL:
currentNonAlcoholIndex = (currentNonAlcoholIndex + 1) % 5; // Pięć napojów bezalkoholowych: sok pomarańczowy, sok ananasowy, sok z limonki, cola, sprite
break;
case SELECT_CUP_FOR_NON_ALCOHOL:
currentCupIndex = (currentCupIndex + 1) % 5; // Pięć opcji kubków: 25 ml, 50 ml, 100 ml, 250 ml, 500 ml
break;
}
displayMenu();
}
void selectOption() {
switch (currentMenuOption) {
case MAIN_MENU:
if (currentMenuIndex == 0) {
currentMenuOption = SELECT_DRINK;
} else if (currentMenuIndex == 1) {
currentMenuOption = SELECT_ALCOHOL;
} else if (currentMenuIndex == 2) {
currentMenuOption = SELECT_NON_ALCOHOL;
}
break;
case SELECT_DRINK:
currentMenuOption = SELECT_CUP_FOR_DRINK;
break;
case SELECT_CUP_FOR_DRINK:
currentMenuOption = SELECT_ALCOHOL_AMOUNT;
break;
case SELECT_ALCOHOL_AMOUNT:
selectedAlcoholAmount = getAlcoholAdjustment(currentAlcoholIndex);
prepareDrink();
currentMenuOption = MAIN_MENU;
break;
case SELECT_ALCOHOL:
currentMenuOption = SELECT_CUP_FOR_ALCOHOL;
break;
case SELECT_CUP_FOR_ALCOHOL:
pourAlcohol(currentAlcoholIndex);
currentMenuOption = MAIN_MENU;
break;
case SELECT_NON_ALCOHOL:
currentMenuOption = SELECT_CUP_FOR_NON_ALCOHOL;
break;
case SELECT_CUP_FOR_NON_ALCOHOL:
pourNonAlcohol(currentNonAlcoholIndex);
currentMenuOption = MAIN_MENU;
break;
}
displayMenu();
}
void displayMenu() {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
switch (currentMenuOption) {
case MAIN_MENU:
u8g2.drawStr(0,10,"Main Menu");
if (currentMenuIndex == 0) {
u8g2.drawStr(0,20,"> Drink");
} else {
u8g2.drawStr(0,20," Drink");
}
if (currentMenuIndex == 1) {
u8g2.drawStr(0,30,"> Sam Alkohol");
} else {
u8g2.drawStr(0,30," Sam Alkohol");
}
if (currentMenuIndex == 2) {
u8g2.drawStr(0,40,"> Sam Sok");
} else {
u8g2.drawStr(0,40," Sam Sok");
}
break;
case SELECT_DRINK:
u8g2.drawStr(0,10,"Wybierz Drink");
u8g2.drawStr(0,30,drinks[currentDrinkIndex].name);
break;
case SELECT_CUP_FOR_DRINK:
u8g2.drawStr(0,10,"Wybierz Naczynie");
if (currentCupIndex == 0) {
u8g2.drawStr(0,30,"> 25 ml");
} else if (currentCupIndex == 1) {
u8g2.drawStr(0,30,"> 50 ml");
} else if (currentCupIndex == 2) {
u8g2.drawStr(0,30,"> 100 ml");
} else if (currentCupIndex == 3) {
u8g2.drawStr(0,30,"> 250 ml");
} else if (currentCupIndex == 4) {
u8g2.drawStr(0,30,"> 500 ml");
}
break;
case SELECT_ALCOHOL_AMOUNT:
u8g2.drawStr(0,10,"Wybierz Alkohol");
if (currentAlcoholIndex == 0) {
u8g2.drawStr(0,30,"> 10 ml");
} else if (currentAlcoholIndex == 1) {
u8g2.drawStr(0,30,"> 25 ml");
} else if (currentAlcoholIndex == 2) {
u8g2.drawStr(0,30,"> 50 ml");
}
break;
case SELECT_ALCOHOL:
u8g2.drawStr(0,10,"Wybierz Alkohol");
if (currentAlcoholIndex == 0) {
u8g2.drawStr(0,30,"> Vodka");
} else if (currentAlcoholIndex == 1) {
u8g2.drawStr(0,30,"> Tequila");
} else if (currentAlcoholIndex == 2) {
u8g2.drawStr(0,30,"> Rum");
}
break;
case SELECT_CUP_FOR_ALCOHOL:
u8g2.drawStr(0,10,"Wybierz Naczynie");
if (currentCupIndex == 0) {
u8g2.drawStr(0,30,"> 25 ml");
} else if (currentCupIndex == 1) {
u8g2.drawStr(0,30,"> 50 ml");
} else if (currentCupIndex == 2) {
u8g2.drawStr(0,30,"> 100 ml");
} else if (currentCupIndex == 3) {
u8g2.drawStr(0,30,"> 250 ml");
} else if (currentCupIndex == 4) {
u8g2.drawStr(0,30,"> 500 ml");
}
break;
case SELECT_NON_ALCOHOL:
u8g2.drawStr(0,10,"Wybierz Napój");
if (currentNonAlcoholIndex == 0) {
u8g2.drawStr(0,30,"> Sok pomarańczowy");
} else if (currentNonAlcoholIndex == 1) {
u8g2.drawStr(0,30,"> Sok ananasowy");
} else if (currentNonAlcoholIndex == 2) {
u8g2.drawStr(0,30,"> Sok z limonki");
} else if (currentNonAlcoholIndex == 3) {
u8g2.drawStr(0,30,"> Cola");
} else if (currentNonAlcoholIndex == 4) {
u8g2.drawStr(0,30,"> Sprite");
}
break;
case SELECT_CUP_FOR_NON_ALCOHOL:
u8g2.drawStr(0,10,"Wybierz Naczynie");
if (currentCupIndex == 0) {
u8g2.drawStr(0,30,"> 25 ml");
} else if (currentCupIndex == 1) {
u8g2.drawStr(0,30,"> 50 ml");
} else if (currentCupIndex == 2) {
u8g2.drawStr(0,30,"> 100 ml");
} else if (currentCupIndex == 3) {
u8g2.drawStr(0,30,"> 250 ml");
} else if (currentCupIndex == 4) {
u8g2.drawStr(0,30,"> 500 ml");
}
break;
}
u8g2.sendBuffer();
}
void initializeDrinks() {
drinks[0] = {"Vodka Martini", {{"Vodka", 0.05}, {"Blue Curacao", 0.01}, {"Lime Juice", 0.01}}, 3};
drinks[1] = {"Tequila Sunrise", {{"Tequila", 0.05}, {"Orange Juice", 0.10}, {"Grenadine", 0.01}}, 3};
drinks[2] = {"Cuba Libre", {{"Rum", 0.05}, {"Cola", 0.10}, {"Lime Juice", 0.01}}, 3};
drinks[3] = {"Blue Lagoon", {{"Vodka", 0.05}, {"Blue Curacao", 0.01}, {"Sprite", 0.10}}, 3};
drinks[4] = {"Margarita", {{"Tequila", 0.05}, {"Lime Juice", 0.10}, {"Orange Juice", 0.05}}, 3};
}
void prepareDrink() {
float cupAmount = getSelectedCupAmount(selectedCupSize);
float totalDrinkAmount = 0.0;
// Oblicz całkowitą oryginalną ilość drinka
for (int i = 0; i < drinks[currentDrinkIndex].numIngredients; i++) {
totalDrinkAmount += drinks[currentDrinkIndex].ingredients[i].amount;
}
// Wyświetl informację o przygotowywaniu drinka
Serial.print("Przygotowywanie drinka: ");
Serial.println(drinks[currentDrinkIndex].name);
// Przelicz ilości składników drinka na wybraną pojemność kubka
for (int i = 0; i < drinks[currentDrinkIndex].numIngredients; i++) {
float originalAmount = drinks[currentDrinkIndex].ingredients[i].amount;
float adjustedAmount = (originalAmount / totalDrinkAmount) * cupAmount; // Przelicz ilość składnika
Serial.print("Dodawanie ");
Serial.print(drinks[currentDrinkIndex].ingredients[i].name);
Serial.print(": ");
Serial.print(adjustedAmount * 1000); // W ml
Serial.println(" ml");
}
}
float getAlcoholAdjustment(int index) {
switch (index) {
case 0:
return 0.01; // 10 ml
case 1:
return 0.025; // 25 ml
case 2:
return 0.05; // 50 ml
default:
return 0.01; // Domyślnie 10 ml
}
}
void pourAlcohol(int alcoholIndex) {
float amount = getSelectedCupAmount(selectedCupSize);
String alcoholType = getAlcoholType(alcoholIndex);
Serial.print("Nalewanie ");
Serial.print(amount * 1000);
Serial.print(" ml ");
Serial.println(alcoholType);
}
void pourNonAlcohol(int nonAlcoholIndex) {
float amount = getSelectedCupAmount(selectedCupSize);
String nonAlcoholType = getNonAlcoholType(nonAlcoholIndex);
Serial.print("Nalewanie ");
Serial.print(amount * 1000);
Serial.print(" ml ");
Serial.println(nonAlcoholType);
}
float getSelectedCupAmount(CupSize cupSize) {
switch (cupSize) {
case CUP_25: return 0.025;
case CUP_50: return 0.05;
case CUP_100: return 0.1;
case CUP_250: return 0.25;
case CUP_500: return 0.5;
default: return 0.25; // Domyślnie 250 ml
}
}
String getAlcoholType(int index) {
switch (index) {
case 0: return "Vodka";
case 1: return "Tequila";
case 2: return "Rum";
default: return "Vodka";
}
}
String getNonAlcoholType(int index) {
switch (index) {
case 0: return "Sok pomarańczowy";
case 1: return "Sok ananasowy";
case 2: return "Sok z limonki";
case 3: return "Cola";
case 4: return "Sprite";
default: return "Sok pomarańczowy";
}
}
void pulseCounter() {
pulseCount++;
Serial.print("Impuls: ");
Serial.println(pulseCount);
}
void simulateFlowSensor() {
// Symulacja 10 impulsów na sekundę
for (int i = 0; i < 10; i++) {
pulseCounter();
delay(100); // Opóźnienie między impulsami (10 razy na sekundę)
}
}