#include <Arduino.h>
#define SD_CS_PIN 4
const int HX711_dout = 16;
const int HX711_sck = 17;
#define ENCODER_DT 2
#define ENCODER_CLK 0
#define ENCODER_SW 15
#define ROTARY_ENCODER_VCC_PIN -1
#define PIN_LED -1
#define PIN_WS2812B 5
#define NUM_PIXELS 24
const uint8_t NumPumps = 10;
const uint8_t PumpPIN[NumPumps] = {13, 12, 14, 27, 26, 25, 33, 32, -1, -1};
//hw_timer_t * Blink_Timer = NULL;
//#include <SD.h>
#include <U8g2lib.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
int SCREEN_WIDTH;
int SCREEN_HEIGHT;
int USABLE_SCREEN_WIDTH;
const uint8_t u8g2_font_tpss_tn[2005] U8G2_FONT_SECTION("u8g2_font_tpss_tn") =
"\263\0\3\2\4\4\2\5\5\13\21\377\374\11\374\11\0\1X\2\257\7\270 \5\0B\12!\7\221\303"
"\211\213\0\42\7#\337\212D\11#\13U\303\233\312\240T\6\245\2$\20\225\303\233\245\242d[\22%"
"J\242T\26\0%\15\225\303\213L\12\263\260\26FZ\0&\21\227\303\234\255\224e[)\213\262(K"
"\222%\1'\6!\337\11\1(\14\225\303;)\13\263\64LS\1)\14\225\303\13\265\230fa\26i"
"\0*\13u\307\253Je\313\226\246\10+\12U\307\253\60\32\244\60\2,\6\42\77\32\5-\6\25\317"
"\213A.\6\21\303\211\0/\14\225\303\313,\314\302Z\230\205\0\60\12\225B\233%\363[\262\0\61\13"
"\225B\253LJ\302\236\6\1\62\13\225B\233%\323\302\254\343 \63\15\225B\233%\13#\65\14\265d"
"\1\64\11\225BKM\33\306\36\65\14\225B\213c\70\210E-Y\0\66\15\225B\233%\23\207$s"
"K\26\0\67\12\225B\213A\314\32\273\1\70\15\225B\233%\323\222%sK\26\0\71\15\225B\233%"
"\263%C\30j\311\2:\6A\303\211(;\7R\77\232T\1<\10\225\303\313\254k\7=\10\65\313"
"\213A\35\4>\11\225\303\213\264[G\0\77\15\225\303\233%\13\263b\16\205\21\0@\25\211\303\235a"
"\212\223HJJISRR\242\34H\206!\1A\13\225B\233%\323\206!\363\26B\15\225B\213!"
"\311\264A\311\334\6\5C\13\225B\233%\23{K\26\0D\13\225B\213!\311\374\66(\0E\13\225"
"B\213c\70$a\343 F\13\225B\213c\70$aG\0G\15\225B\233%\23\223!sK\26\0"
"H\13\225B\213\314\66\14\231\267\0I\6\221B\211\7J\11\225B\313>j\311\2K\16\225B\213\314"
"\224\224\264$\252dZ\0L\11\225B\213\260\37\7\1M\14\227B\214t[*R\244z\15N\13\225"
"B\213lR\22i\363\26O\12\225B\233%\363[\262\0P\14\225B\213!\311\264A\11;\2Q\15"
"\225B\233%\363\222(\211RY\0R\14\225B\213!\311\264A\311\274\5S\14\225B\233%S\327P"
"\323\222\5T\11\225B\213A\12\373\11U\11\225B\213\314\337\222\5V\17\225B\213\314\226\224\222(\211"
"\222,\214\0W\21\227B\214\324\232\64%\245\244\226\204I\230D\0X\15\225B\213LKja\226\324"
"l\1Y\13\225B\213LKjaO\0Z\13\225B\213A\254u\14\7\1[\11\223\303\212!\352\323"
"\0\134\12u\303\213\64L\213i\0]\11\223\303\212\251OC\0^\6#\353\232\6_\6\26C\214\3"
"`\6\42k\32\5a\12eB\233%sK\206\0b\14\225B\213\260\70$\231[\262\0c\12eB"
"\233%\23k\311\2d\13\225B\313\226AsK\206\0e\14eB\233%\33\206\60K\26\0f\13\225"
"B+\251\222ma\67\0g\15\245\62\233%sK\206\60\324\222\5h\12\225B\213\260\305\244\271\5i"
"\7\221B\11e\30j\12\322\262\231Z\322/\12\0k\15\225B\213\260))iIT\311\2l\6\221"
"B\211\7m\16gB\214D\31\22S$ER$\25n\11eB\213\304\244\271\5o\12eB\233%"
"sK\26\0p\13\245\62\233%s\33\224\260\21q\22\246\262\233!\311\222,\311\222,\32\322pL\23"
"\0r\12d\302\212d\210\262\66\0s\12eB\233%]\265d\1t\13\224\302\232\254\64$Y'\0"
"u\11eB\213\314[\262\0v\14eB\213LKJI\26F\0w\16gB\214TM\232\222Z\22"
"&\21\0x\13eB\213,\251\205YR\13y\15\245\62\213\314[\62\204\241\226,\0z\11eB\233"
"A\353\66\10{\14\226CL-L\63\71\215c\1|\6\221\303\211\7}\14\226C\14\271\32ki\230"
"\211\0~\7%j\213E\31\241\7\221B\11e\30\242\15u\303\253l\251(QR\331\42\0\243\14\225"
"\303\213\60\34\222\260M\33\6\244\13U\307\213,\231\222h\311\2\245\17\225\303\213LKja\64H\321"
" E\0\246\6\221\303\211m\247\21\246C\234!\211\207$L\206\70M\305dH\0\250\6\25\317\213,"
"\251\17w\303\234AI\225E\311\224EM\6\5\252\17\206C\234)K\262$K\262h\211\207\1\253\7"
"\65\313\233Hj\254\7%\313\213A\14\255\5\0B\14\256\17w\303\234AI\225E\311\224LM\6\5"
"\257\6\25Z\213A\260\7\63\313\232.\0\261\14u\303\253\60\32\244\60\7\6\1\265\5\0B\14\267\5"
"\0B\14\273\11\65\313\213\250$%\0\300\16\305B\233\64G\226L\33\206\314[\0\301\15\305B\273:"
"\262d\332\60d\336\2\302\16\305B\253,\311\201%\323\206!\363\26\303\16\305B\213E\231\227L\33\206"
"\314[\0\304\15\265B\233:\260d\332\60d\336\2\305\17\325B\253,\311rd\311\264a\310\274\5\306"
"\23\231B\235\341\26f\341\60(Y\230\205Y\230\205\331 \307\14\225:\233%\23\333\222-\223\0\310\16"
"\305B\233\64\7\216\341\220\204\215\203\0\311\15\305B\273:p\14\207$l\34\4\312\16\305B\253,\211"
"\207\61\34\222\260q\20\313\15\265B\233\362\60\206C\22\66\16\2\314\11\302A\211(K\372\3\315\11\302"
"B\31-\351/\0\316\11\303A\231\306\250\277\0\317\12\263A\211$\214\372\13\0\320\15\225B\213!\311"
"\264!\321\334\6\5\321\16\305B\213EY\63\333\244$\322f\13\322\14\305B\233\64G\226\314o\311\2"
"\323\14\305B\273:\262d~K\26\0\324\15\305B\253,\311\201%\363[\262\0\325\14\305B\213E\231"
"\227\314o\311\2\326\14\265B\233:\260d~K\26\0\327\7\63J\213\244\3\330\22\227B\254\245\26E"
"RRJJII\252%\311\4\331\14\305B\233\64\7\62\177K\26\0\332\13\305B\273:\220\371[\262"
"\0\333\14\305B\253,\211\63\177K\26\0\334\12\265B\233r\346o\311\2\335\14\305B\273:\220iI"
"-\354\11\336\15\225B\213\60\34\222lP\302F\0\337\16\265:\213!\311\24%sQ\302F\0\340\14"
"\225B\233\64G\226\314-\31\2\341\13\225B\273:\262dn\311\20\342\15\225B\253,\311\201%sK"
"\206\0\343\14\225B\213E\231\227\314-\31\2\344\13\205B\233:\260dn\311\20\345\15\245B\253,\311"
"rd\311\334\222!\346\16iB\235K\226i\303\26f\225\13\0\347\13\205:\233%\23k\311V\3\350"
"\14eB\233%\33\206\60K\26\0\351\14eB\233%\33\206\60K\26\0\352\14eB\233%\33\206\60"
"K\26\0\353\14eB\233%\33\206\60K\26\0\354\10\242\302\211(Mz\355\10\242\302\31\65\351\5\356"
"\11\243B\232v \352\5\357\12\223B\212$\7\242^\0\360\14\225B\313hL\6\315-\31\2\361\13"
"\225B\213EY\23\223\346\26\362\14\225B\233\64G\226\314-Y\0\363\13\225B\273:\262dn\311\2"
"\364\15\225B\253,\311\201%sK\26\0\365\14\225B\213E\231\227\314-Y\0\366\13\205B\233:\260"
"dn\311\2\367\12UF\253\34\30t \2\370\14eB\233%Z\22%\231\222\5\371\13\225B\233\64"
"\7\62o\311\2\372\13\225B\273:\220yK\26\0\373\13\225B\253,\211\63o\311\2\374\12\205B\233"
"r\346-Y\0\375\16\325\62\273:\220yK\206\60\324\222\5\376\14e\302\212pH\262A\11C\0\377"
"\16\305\62\233r\346-\31\302PK\26\0\0\0\0\4\377\377\0";
#include <HX711_ADC.h>
#if defined(ESP8266)|| defined(ESP32) || defined(AVR)
#include <EEPROM.h>
#endif
HX711_ADC LoadCell(HX711_dout, HX711_sck);
const int calVal_eepromAdress = 100;
unsigned long t = 0;
#include <AiEsp32RotaryEncoder.h>
#define ROTARY_ENCODER_STEPS 4
unsigned long shortPressAfterMiliseconds = 50;
unsigned long longPressAfterMiliseconds = 1000;
unsigned long LastEncoderPosChange = 0;
bool circleValues = false;
uint8_t rotaryEncoderMinValue = 0;
uint16_t rotaryEncoderMaxValue = 5000;
AiEsp32RotaryEncoder rotaryEncoderAi = AiEsp32RotaryEncoder(ENCODER_DT, ENCODER_CLK, ENCODER_SW, ROTARY_ENCODER_VCC_PIN, ROTARY_ENCODER_STEPS);
typedef struct {
bool ButtonPressed = false;
bool ButtonPressedLong = false;
uint32_t LastButtonChange = 0;
} ButtonState_T;
ButtonState_T rotaryButton;
typedef struct {
uint16_t Pos = 1;
uint16_t LastPos = Pos;
uint16_t PosLocked = Pos;
uint8_t MainMenuPos = Pos;
bool locked = false;
} rotaryEncoderPos_T;
rotaryEncoderPos_T rotaryEncoderPos;
String menuItems[99];
uint8_t minPos = 1;
uint16_t maxPos = 10;
uint16_t oldmaxPos = maxPos;
uint8_t menuPos = 0;
uint8_t currMenu = 0;
uint8_t lastMenu = 0;
uint32_t curr_millis;
uint32_t delta_millis;
uint32_t last_LED_millis;
uint16_t loop_delay = 50;
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel ws2812b(NUM_PIXELS, PIN_WS2812B, NEO_GRB + NEO_KHZ800);
bool ledState = false;
const int PWMFreq = 25000; /* 25 KHz */
const int PWMResolution = 8;
const int MAX_DUTY_CYCLE = (int)(pow(2, PWMResolution) - 1);
typedef struct {
uint8_t PumpID;
String IngredientName;
bool alcoholic;
} StructIngredients_T;
StructIngredients_T DefaultIngredient[] = {
// PumpID, IngredientName, alcoholic
/* 1 */ { 1, "Orangensaft", false},
/* 2 */ { 2, "Grenadine", false},
/* 3 */ { 3, "Tequilla", true },
/* 4 */ { 4, "Zutat 4", true },
/* 5 */ { 5, "Zutat 5", true },
/* 6 */ { 6, "Zutat 6", true },
/* 7 */ { 7, "Zutat 7", false },
/* 8 */ { 8, "Zutat 8", false },
/* 9 */ { 9, "Zutat 9", false },
/* 10 */ { 10, "Zutat 10", false }
};
StructIngredients_T Ingredient[99];
const int NumDefaultIngredients = (sizeof(DefaultIngredient) / sizeof(StructIngredients_T));
int NumIngredients;
typedef struct {
String CocktailName;
String IngredientName[NumPumps];
uint8_t IngredientAmount[NumPumps];
bool available;
} StructCocktails_T;
StructCocktails_T DefaultCocktail[] = {
{
"Tequilla Sunrise",
{"Tequilla", "Orangensaft", "Grenadine"},
{ 40, 150, 20}
},
{
"Beispiel 2",
{"Weisser Rum", "Orangensaft", "Grenadine"},
{ 15, 20, 20}
},
{
"Tequilla Sunset",
{"Tequilla", "Orangensaft", "Grenadine"},
{ 40, 150, 20}
}
};
StructCocktails_T Cocktail[99];
const int NumDefaultCocktails = (sizeof(DefaultCocktail) / sizeof(StructCocktails_T));
uint8_t NumCocktails;
uint8_t NumCocktailsAvailable = 0;
uint8_t NumCocktailsMenu = 0;
String tmptxt;
uint16_t DefaultGlassize = 400;
float DefaultGlasWeight = 100.0;
uint16_t glassize = DefaultGlassize;
bool AskForIce = true;
bool SERIAL_CONNECTED = false;
/*
void ARDUINO_ISR_ATTR Blink_Function_ISR() {
uint32_t color;
if ( curr_millis - last_LED_millis > 500 ) {
last_LED_millis = curr_millis;
ledState = !ledState;
if (ledState) {
color = ws2812b.Color(0, 128, 0);
} else {
color = ws2812b.Color(0, 0, 0);
}
//ws2812b.setPixelColor(11, color);
//ws2812b.setPixelColor(12, color);
ws2812b.fill(color, 11, 2);
ws2812b.show();
}
}
*/
void blink_led() {
if ( curr_millis - last_LED_millis > 500 ) {
last_LED_millis = curr_millis;
ledState = !ledState;
digitalWrite(PIN_LED, ledState);
}
}
//void blink_ws2812b() {
void blink() {
uint32_t color;
if ( curr_millis - last_LED_millis > 500 ) {
last_LED_millis = curr_millis;
ledState = !ledState;
if (ledState) {
color = ws2812b.Color(0, 128, 0);
} else {
color = ws2812b.Color(0, 0, 0);
}
//ws2812b.setPixelColor(11, color);
//ws2812b.setPixelColor(12, color);
ws2812b.fill(color, 11, 2);
ws2812b.show();
}
}
void LEDCocktailFinished() {
uint8_t NUM_PIXS = 10;
uint8_t PIX_LOW = 0;
uint8_t PIX_HIGH = NUM_PIXELS-1;
uint32_t color;
if ( curr_millis - last_LED_millis > 500 ) {
last_LED_millis = curr_millis;
ledState = !ledState;
if (ledState) {
color = ws2812b.Color(255, 0, 0);
} else {
color = ws2812b.Color(0, 0, 255);
}
}
for ( uint8_t i = PIX_LOW; i < NUM_PIXS; i++ ) {
ws2812b.setPixelColor(i, color);
}
for ( uint8_t i = PIX_HIGH; i > PIX_HIGH-NUM_PIXS; i-- ) {
ws2812b.setPixelColor(i, color);
}
color = ws2812b.Color(255, 255, 255);
for ( uint8_t i = NUM_PIXS; i < PIX_HIGH-NUM_PIXS+1; i++ ) {
ws2812b.setPixelColor(i, color);
}
ws2812b.show();
}
void LEDsoff() {
uint32_t color = ws2812b.Color(0, 0, 0);
for ( uint8_t i = 0; i < NUM_PIXELS; i++ ) {
ws2812b.setPixelColor(i, color);
}
ws2812b.show();
}
void showStatusAmount( float Amount ) {
uint8_t NUM_PIXS = 10;
uint8_t GLOW_PIXS = round(NUM_PIXS * Amount);
uint8_t PIX_LOW = 0;
uint8_t PIX_HIGH = NUM_PIXELS-1;
if ( SERIAL_CONNECTED ) {
Serial.print("Amount: ");
Serial.println(Amount);
Serial.print("GLOW_PIXS: ");
Serial.println(GLOW_PIXS);
}
uint32_t color = ws2812b.Color(255, 0, 0);
/*for ( uint8_t i = PIX_LOW; i < GLOW_PIXS; i++ ) {
ws2812b.setPixelColor(i, color);
}*/
for ( uint8_t i = PIX_HIGH; i > PIX_HIGH-GLOW_PIXS; i-- ) {
ws2812b.setPixelColor(i, color);
}
ws2812b.show();
}
void showPercStatusAmount( uint8_t percent ) {
uint8_t NUM_PIXS = 10;
//map(value, fromLow, fromHigh, toLow, toHigh)
uint8_t GLOW_PIXS = map(percent, 0, 100, 0, NUM_PIXS);
if (GLOW_PIXS > NUM_PIXS) GLOW_PIXS = NUM_PIXS;
uint8_t PIX_LOW = 0;
uint8_t PIX_HIGH = NUM_PIXELS-1;
if ( SERIAL_CONNECTED ) {
Serial.print("percent: ");
Serial.println(percent);
Serial.print("GLOW_PIXS: ");
Serial.println(GLOW_PIXS);
}
uint32_t color = ws2812b.Color(0, 255, 0);
for ( uint8_t i = PIX_LOW; i < GLOW_PIXS; i++ ) {
ws2812b.setPixelColor(i, color);
}/*
for ( uint8_t i = PIX_HIGH; i > PIX_HIGH-GLOW_PIXS; i-- ) {
ws2812b.setPixelColor(i, color);
}*/
ws2812b.show();
}
int aligncenter_H(String text) {
int newposy = (SCREEN_HEIGHT / 2) + ((u8g2.getAscent() - u8g2.getDescent()) / 2) - 1 ;
return newposy;
}
int aligncenter(int posx, String text) {
int newposx = posx - (u8g2.getUTF8Width(text.c_str()) / 2);
return newposx;
}
int alignright(int posx, String text) {
int newposx = posx - u8g2.getUTF8Width(text.c_str());
return newposx;
}
void drawFramedText(int x, int y, String text) {
int space = 3;
int text_w;
if ( text == "zur\374ck" ) {
text_w = u8g2.getUTF8Width("zuruck");
} else {
text_w = u8g2.getUTF8Width(text.c_str());
}
int text_h = u8g2.getAscent() - u8g2.getDescent();
int frame_x = x - ( space + 1 );
int frame_y = y - u8g2.getAscent() - ( space + 1 ) ;
int frame_width = text_w + ( 2 * space ) + 2;
int frame_height = text_h + ( 2 * space ) + 1;
u8g2.drawFrame(frame_x, frame_y, frame_width, frame_height);
int text_x = x;
int text_y = y;
u8g2.drawStr(text_x, text_y, text.c_str());
}
void drawFramedTextSelected(int x, int y, String text) {
int space = 1;
int text_w;
if ( text == "zur\374ck" ) {
text_w = u8g2.getUTF8Width("zuruck");
} else {
text_w = u8g2.getUTF8Width(text.c_str());
}
int text_h = u8g2.getAscent() - u8g2.getDescent();
int frame_x = x - ( space + 1 );
int frame_y = y - u8g2.getAscent() - ( space + 1 );
int frame_width = text_w + ( 2 * space ) + 2;
int frame_height = text_h + ( 2 * space ) + 1;
u8g2.drawBox(frame_x, frame_y, frame_width, frame_height);
int text_x = x;
int text_y = y;
u8g2.setDrawColor(0);
u8g2.drawStr(text_x, text_y, text.c_str());
u8g2.setDrawColor(1);
}
void drawSelectedTextLine(int y, String text, int space) {
int text_w;
if ( text == "zur\374ck" ) {
text_w = u8g2.getUTF8Width("zuruck");
} else {
text_w = u8g2.getUTF8Width(text.c_str());
}
int text_h = u8g2.getAscent() - u8g2.getDescent();
int radius = 3;
int frame_x = 0;
int frame_y = y - u8g2.getAscent() - ( space + 1 );
int frame_width = USABLE_SCREEN_WIDTH;
int frame_height = text_h + ( 2 * space ) + 1;
u8g2.drawRFrame(frame_x, frame_y, frame_width, frame_height, radius);
int text_x = frame_x + space + 1;
int text_y = y;
u8g2.drawStr(text_x, text_y, text.c_str());
}
void drawScrollbar(int pos, int max_pos) {
int pixel_size = 1;
int bar_width = ( 2 * pixel_size ) + pixel_size;
int bar_height = SCREEN_HEIGHT / max_pos;
for (int i = 1; i < SCREEN_HEIGHT; i++) {
u8g2.drawBox(SCREEN_WIDTH - (2 * pixel_size), i, pixel_size, pixel_size);
i = i + pixel_size + 1;
}
u8g2.drawBox(SCREEN_WIDTH - bar_width, (bar_height * pos) - bar_height, bar_width, bar_height);
USABLE_SCREEN_WIDTH = SCREEN_WIDTH - bar_width - 1;
}
void drawWords(int xloc, int yloc, const char *msg ) {
int dspwidth = u8g2.getDisplayWidth();
int strwidth = 0;
char glyph[2]; glyph[1] = 0;
for (const char *ptr = msg, *lastblank = NULL; *ptr; ++ptr) {
while (xloc == 0 && (*msg == ' ' || *msg == '\n'))
if (ptr == msg++) ++ptr;
glyph[0] = *ptr;
strwidth += u8g2.getStrWidth(glyph);
if (*ptr == ' ') lastblank = ptr;
else ++strwidth;
if (*ptr == '\n' || xloc + strwidth > dspwidth) {
int starting_xloc = xloc;
while (msg < (lastblank ? lastblank : ptr)) {
glyph[0] = *msg++;
xloc += u8g2.drawStr(xloc, yloc, glyph);
}
strwidth -= xloc - starting_xloc;
yloc += u8g2.getMaxCharHeight();
xloc = 0; lastblank = NULL;
}
}
while (*msg) {
glyph[0] = *msg++;
xloc += u8g2.drawStr(xloc, yloc, glyph);
}
}
void updateMenu() {
switch (currMenu) {
case 1:
CocktailMenu();
break;
case 2:
SetupMenu();
break;
case 3:
ZutatenMenu();
break;
default:
mainMenu();
break;
}
}
void mainMenu() {
maxPos = 2;
rotaryEncoderAi.setBoundaries(minPos, maxPos, false);
uint8_t mi = 0;
menuItems[mi] = "Hauptmen\374";
mi++;
if (NumCocktailsAvailable > 0) {
menuItems[mi] = "Cocktails";
mi++;
maxPos = 2;
} else {
maxPos = 1;
}
menuItems[mi] = "Setup";
u8g2.clearBuffer();
drawScrollbar(rotaryEncoderPos.Pos, maxPos);
u8g2.setFont(u8g2_font_tpss_tn);
u8g2.drawStr(aligncenter(USABLE_SCREEN_WIDTH / 2, menuItems[0]), 10, menuItems[0].c_str());
int mid_screen_pos = (SCREEN_HEIGHT / 2) + (u8g2.getAscent() / 2);
int mid_menu_pos = ((SCREEN_HEIGHT - 12) / 2) + (u8g2.getAscent() / 2) + 12;
if ( rotaryEncoderPos.Pos != 1 ) {
u8g2.drawStr(4, mid_menu_pos - 17, menuItems[rotaryEncoderPos.Pos - 1].c_str());
}
drawSelectedTextLine(mid_menu_pos, menuItems[rotaryEncoderPos.Pos], 3);
if ( rotaryEncoderPos.Pos != maxPos ) {
u8g2.drawStr(4, mid_menu_pos + 17, menuItems[rotaryEncoderPos.Pos + 1].c_str());
}
u8g2.sendBuffer();
}
void CocktailMenu() {
maxPos = NumCocktailsAvailable + 1;
rotaryEncoderAi.setBoundaries(minPos, maxPos, circleValues);
menuItems[0] = "Cocktails";
uint8_t i = 1;
while (i < maxPos) {
for (int CocktailID = 0; CocktailID < NumCocktails; CocktailID++) {
if ( Cocktail[CocktailID].available ) {
menuItems[i] = Cocktail[CocktailID].CocktailName;
i++;
}
}
}
menuItems[maxPos] = "zur\374ck";
u8g2.clearBuffer();
drawScrollbar(rotaryEncoderPos.Pos, maxPos);
u8g2.setFont(u8g2_font_tpss_tn);
u8g2.drawStr(aligncenter(USABLE_SCREEN_WIDTH / 2, menuItems[0]), 10, menuItems[0].c_str());
int mid_screen_pos = (SCREEN_HEIGHT / 2) + (u8g2.getAscent() / 2);
int mid_menu_pos = ((SCREEN_HEIGHT - 12) / 2) + (u8g2.getAscent() / 2) + 12;
if ( rotaryEncoderPos.Pos != 1 ) {
u8g2.drawStr(4, mid_menu_pos - 17, menuItems[rotaryEncoderPos.Pos - 1].c_str());
}
drawSelectedTextLine(mid_menu_pos, menuItems[rotaryEncoderPos.Pos], 3);
if ( rotaryEncoderPos.Pos != maxPos ) {
u8g2.drawStr(4, mid_menu_pos + 17, menuItems[rotaryEncoderPos.Pos + 1].c_str());
}
u8g2.sendBuffer();
}
void ZutatenMenu() {
maxPos = NumIngredients + 2;
rotaryEncoderAi.setBoundaries(minPos, maxPos, circleValues);
menuItems[0] = "Zutaten";
uint8_t i = 1;
while (i < maxPos) {
for (uint8_t IngredientID = 0; IngredientID < NumIngredients; IngredientID++) {
menuItems[i] = Ingredient[IngredientID].IngredientName;
i++;
}
}
menuItems[maxPos - 1] = "reset";
menuItems[maxPos] = "zur\374ck";
u8g2.clearBuffer();
drawScrollbar(rotaryEncoderPos.Pos, maxPos);
u8g2.setFont(u8g2_font_tpss_tn);
u8g2.drawStr(aligncenter(USABLE_SCREEN_WIDTH / 2, menuItems[0]), 10, menuItems[0].c_str());
int mid_screen_pos = (SCREEN_HEIGHT / 2) + (u8g2.getAscent() / 2);
int mid_menu_pos = ((SCREEN_HEIGHT - 12) / 2) + (u8g2.getAscent() / 2) + 12;
if ( rotaryEncoderPos.Pos > 2 ) {
u8g2.setFont(u8g2_font_5x8_tf);
u8g2.drawStr(5, mid_menu_pos - 24, menuItems[rotaryEncoderPos.Pos - 2].c_str());
}
if ( rotaryEncoderPos.Pos != 1 ) {
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(4, mid_menu_pos - 15, menuItems[rotaryEncoderPos.Pos - 1].c_str());
}
u8g2.setFont(u8g2_font_7x14_tf);
drawSelectedTextLine(mid_menu_pos, menuItems[rotaryEncoderPos.Pos], 2);
if ( rotaryEncoderPos.Pos != maxPos ) {
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(4, mid_menu_pos + 12, menuItems[rotaryEncoderPos.Pos + 1].c_str());
}
if ( rotaryEncoderPos.Pos < maxPos - 1 ) {
u8g2.setFont(u8g2_font_5x8_tf);
u8g2.drawStr(5, mid_menu_pos + 20, menuItems[rotaryEncoderPos.Pos + 2].c_str());
}
u8g2.sendBuffer();
}
void SetupMenu() {
menuItems[0] = "Setup Men\374";
menuItems[1] = "Zutaten";
menuItems[2] = "Kalibrieren";
menuItems[3] = "Waage";
menuItems[4] = "Tara";
menuItems[5] = "Pumpen reinigen";
menuItems[6] = "Pumpen leeren";
menuItems[7] = "Pumpen f\374llen";
menuItems[8] = "zur\374ck";
maxPos = 8;
rotaryEncoderAi.setBoundaries(minPos, maxPos, circleValues);
u8g2.clearBuffer();
drawScrollbar(rotaryEncoderPos.Pos, maxPos);
u8g2.setFont(u8g2_font_tpss_tn);
u8g2.drawStr(aligncenter(USABLE_SCREEN_WIDTH / 2, menuItems[0]), 10, menuItems[0].c_str());
int mid_screen_pos = (SCREEN_HEIGHT / 2) + (u8g2.getAscent() / 2);
int mid_menu_pos = ((SCREEN_HEIGHT - 12) / 2) + (u8g2.getAscent() / 2) + 12;
if ( rotaryEncoderPos.Pos != 1 ) {
u8g2.drawStr(4, mid_menu_pos - 17, menuItems[rotaryEncoderPos.Pos - 1].c_str());
}
drawSelectedTextLine(mid_menu_pos, menuItems[rotaryEncoderPos.Pos], 3);
if ( rotaryEncoderPos.Pos != maxPos ) {
u8g2.drawStr(4, mid_menu_pos + 17, menuItems[rotaryEncoderPos.Pos + 1].c_str());
}
u8g2.sendBuffer();
}
void CheckForGlas() {
/**********************************************************************
* Check weight
**********************************************************************/
float start_weight = 0.0;
float delay_weight = 10000.0;
float delta_weight = 10000.0;
float glas_weight = 0.0;
start_weight = getChilledLoadCellValue();
if ( SERIAL_CONNECTED ) {
Serial.print("Start Gewicht: ");
Serial.print(start_weight);
Serial.println(" Gramm.");
}
/**********************************************************************
* Waiting for glas
**********************************************************************/
int count = 0;
bool _resume = false;
while (_resume == false) {
curr_millis = millis();
//blink();
count++;
if (count < 500) {
delay_weight = getLoadCellValue_noFeedback();
if ( SERIAL_CONNECTED ) {
Serial.print(count);
Serial.print(" - Delay Gewicht: ");
Serial.print(delay_weight);
Serial.println(" Gramm.");
}
delta_weight = delay_weight - start_weight;
if ( SERIAL_CONNECTED ) {
Serial.print(count);
Serial.print(" - Delta Gewicht: ");
Serial.print(delta_weight);
Serial.println(" Gramm.");
}
if (delta_weight > DefaultGlasWeight) {
_resume=true;
}
} else {
_resume=true;
}
}
delay(1000);
glas_weight = getChilledLoadCellValue() - start_weight;
if ( SERIAL_CONNECTED ) {
Serial.print("Glas Gewicht: ");
Serial.print(glas_weight);
Serial.println(" Gramm.");
}
/**********************************************************************
* Asking if glas is in place
**********************************************************************/
if ( glas_weight < DefaultGlasWeight ) {
while (rotaryButton.ButtonPressed == false) {
curr_millis = millis();
//blink();
UpdateButton();
tmptxt = "OK";
drawFramedText(alignright(SCREEN_WIDTH - 4, tmptxt), SCREEN_HEIGHT - 5, tmptxt );
u8g2.sendBuffer();
}
unpressButton();
}
}
void modifyIngredient(uint8_t IngredientID) {
maxPos = 2;
rotaryEncoderAi.setBoundaries(minPos, maxPos, true);
rotaryEncoderPos.Pos = 2;
rotaryEncoderPos.PosLocked = rotaryEncoderPos.Pos;
rotaryEncoderAi.setEncoderValue(rotaryEncoderPos.Pos);
bool modify = false;
bool _resume = false;
int old_value = Ingredient[IngredientID].PumpID;
while ( !_resume ) {
curr_millis = millis();
//blink();
UpdateButton();
// *******************************************
// Button Actions
// *******************************************
if ( rotaryEncoderPos.PosLocked == 1 && rotaryButton.ButtonPressed && !modify ) {
unpressButton();
modify = true;
rotaryEncoderPos.locked = true;
rotaryEncoderAi.setBoundaries(0, NumPumps, true);
rotaryEncoderPos.Pos = Ingredient[IngredientID].PumpID;
rotaryEncoderAi.setEncoderValue(rotaryEncoderPos.Pos);
} else if ( rotaryEncoderPos.PosLocked == 1 && rotaryButton.ButtonPressed && modify) {
unpressButton();
modify = false;
rotaryEncoderPos.locked = false;
Ingredient[IngredientID].PumpID = rotaryEncoderPos.Pos;
if ( checkIngredient() ) {
//writeIngredients();
rotaryEncoderPos.PosLocked = 2;
old_value = Ingredient[IngredientID].PumpID;
} else {
Ingredient[IngredientID].PumpID = old_value;
rotaryEncoderPos.PosLocked = 1;
}
rotaryEncoderAi.setBoundaries(minPos, maxPos, true);
rotaryEncoderPos.Pos = rotaryEncoderPos.PosLocked;
rotaryEncoderAi.setEncoderValue(rotaryEncoderPos.Pos);
} else if ( rotaryEncoderPos.PosLocked == 2 && rotaryButton.ButtonPressed ) {
rotaryEncoderAi.setBoundaries(minPos, NumIngredients + 2, true);
unpressButton();
_resume = true;
}
// *******************************************
// PRINT DISPLAY
// *******************************************
if ( ((curr_millis - rotaryButton.LastButtonChange) < 60) || ((curr_millis - LastEncoderPosChange) < 60)) {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tpss_tn);
u8g2.drawStr(aligncenter(USABLE_SCREEN_WIDTH / 2, Ingredient[IngredientID].IngredientName), 10, Ingredient[IngredientID].IngredientName.c_str());
u8g2.setFont(u8g2_font_7x14_tf);
if ( rotaryEncoderPos.PosLocked == 1 && !modify ) {
drawFramedText(4, 30, "Pumpe: ");
//drawFramedTextSelected(4,30, "Pumpe: ");
} else {
u8g2.drawStr(4, 30, "Pumpe: ");
}
if (modify) {
u8g2.setFont(u8g2_font_7x14B_tf);
//drawFramedText(alignright(74, String(rotaryEncoderPos.Pos)), 30, String(rotaryEncoderPos.Pos));
drawFramedTextSelected(alignright(74, String(rotaryEncoderPos.Pos)), 30, String(rotaryEncoderPos.Pos));
} else {
u8g2.setFont(u8g2_font_7x14_tf);
u8g2.drawStr(alignright(74, String(Ingredient[IngredientID].PumpID)), 30, String(Ingredient[IngredientID].PumpID).c_str());
}
if (Ingredient[IngredientID].alcoholic) {
u8g2.setFont(u8g2_font_5x8_tf);
u8g2.drawStr(4, 42, "alkoholisch");
}
u8g2.setFont(u8g2_font_6x10_tf);
if ( rotaryEncoderPos.PosLocked == 2 ) {
drawFramedText(alignright(SCREEN_WIDTH - 4, "zuruck"), SCREEN_HEIGHT - 5, "zur\374ck" );
//drawFramedTextSelected(alignright(SCREEN_WIDTH-4, "zuruck"), SCREEN_HEIGHT-5, "zur\374ck" );
} else {
u8g2.drawStr(alignright(SCREEN_WIDTH - 4, "zuruck"), SCREEN_HEIGHT - 5, "zur\374ck");
}
u8g2.sendBuffer();
}
}
checkCocktails();
rotaryEncoderPos.Pos = rotaryEncoderPos.LastPos;
rotaryEncoderPos.PosLocked = rotaryEncoderPos.Pos;
rotaryEncoderAi.setEncoderValue(rotaryEncoderPos.Pos);
rotaryEncoderAi.reset(rotaryEncoderPos.LastPos);
/*
Serial.print("LastPos: ");
Serial.println(rotaryEncoderPos.LastPos);
Serial.print("Pos: ");
Serial.println(rotaryEncoderPos.Pos);
Serial.print("PosLocked: ");
Serial.println(rotaryEncoderPos.PosLocked);
*/
}
void pourCocktail(uint8_t CocktailID) {
oldmaxPos = maxPos;
maxPos=2;
rotaryEncoderAi.setBoundaries(minPos, maxPos, false);
rotaryEncoderPos.Pos = 2;
rotaryEncoderAi.setEncoderValue(rotaryEncoderPos.Pos);
unpressButton();
/**********************************************************************
* Waiting for glas
**********************************************************************/
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tpss_tn);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, Cocktail[CocktailID].CocktailName), 10, Cocktail[CocktailID].CocktailName.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
tmptxt = "Bitte leeres";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)-6, tmptxt.c_str());
tmptxt = "Glas platzieren.";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)+6, tmptxt.c_str());
u8g2.sendBuffer();
CheckForGlas();
/**********************************************************************
* TaraLoadCell
**********************************************************************/
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tpss_tn);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, Cocktail[CocktailID].CocktailName), 10, Cocktail[CocktailID].CocktailName.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
tmptxt = "Waage tarieren";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt), tmptxt.c_str());
tmptxt = "Bitte warten...";
u8g2.drawStr(alignright(SCREEN_WIDTH - 4, tmptxt), SCREEN_HEIGHT - 5, tmptxt.c_str());
u8g2.sendBuffer();
TaraLoadCellnoFeedback();
/**********************************************************************
* Icecubes
**********************************************************************/
int IceAmount = 0;
if ( AskForIce ) {
/**********************************************************************
* Check for Icecubes
**********************************************************************/
bool icecubes = false;
while (rotaryButton.ButtonPressed == false) {
curr_millis = millis();
//blink();
UpdateButton();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tpss_tn);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, Cocktail[CocktailID].CocktailName), 10, Cocktail[CocktailID].CocktailName.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
tmptxt = "Eisw\374rfel?";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, "Eiswurfel?"), aligncenter_H(tmptxt), tmptxt.c_str());
if ( rotaryEncoderPos.Pos == 1 ) {
tmptxt = "Ja";
drawFramedText(4, SCREEN_HEIGHT - 5, tmptxt );
tmptxt = "Nein";
u8g2.drawStr(alignright(SCREEN_WIDTH - 4, tmptxt), SCREEN_HEIGHT - 5, tmptxt.c_str());
icecubes = true;
} else {
tmptxt = "Ja";
u8g2.drawStr(4, SCREEN_HEIGHT - 5, tmptxt.c_str());
tmptxt = "Nein";
drawFramedText(alignright(SCREEN_WIDTH - 4, tmptxt), SCREEN_HEIGHT - 5, tmptxt );
}
u8g2.sendBuffer();
}
unpressButton();
/**********************************************************************
* Waiting for Icecubes
**********************************************************************/
if ( icecubes ) {
Serial.println("Wir wollen Eiswürfel!!!");
while (rotaryButton.ButtonPressed == false) {
curr_millis = millis();
//blink();
UpdateButton();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tpss_tn);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, Cocktail[CocktailID].CocktailName), 10, Cocktail[CocktailID].CocktailName.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
tmptxt = "Bitte Eisw\374rfel";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, "Bitte Eiswurfel"), aligncenter_H(tmptxt)-6, tmptxt.c_str());
tmptxt = "einf\374llen.";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, "einfullen."), aligncenter_H(tmptxt)+6, tmptxt.c_str());
tmptxt = "OK";
drawFramedText(alignright(SCREEN_WIDTH - 4, tmptxt), SCREEN_HEIGHT - 5, tmptxt );
u8g2.sendBuffer();
}
unpressButton();
IceAmount = getChilledLoadCellValue();
}
if ( SERIAL_CONNECTED ) {
Serial.print("Eisgewicht: ");
Serial.println(IceAmount);
}
}
/**********************************************************************
* Sum Ingredients
**********************************************************************/
int totIngredientAmount = 0;
for (int var = 0; var < NumPumps; var++) {
if (Cocktail[CocktailID].IngredientAmount[var] && Cocktail[CocktailID].IngredientName[var] != "") {
totIngredientAmount += Cocktail[CocktailID].IngredientAmount[var];
}
}
if ( SERIAL_CONNECTED ) {
Serial.print("Zutatenmenge: ");
Serial.println(totIngredientAmount);
}
/**********************************************************************
* Check for Glas size
**********************************************************************/
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tpss_tn);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, Cocktail[CocktailID].CocktailName), 10, Cocktail[CocktailID].CocktailName.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
minPos=100;
maxPos=500;
rotaryEncoderAi.setBoundaries(minPos, maxPos, false);
rotaryEncoderPos.Pos = glassize;
rotaryEncoderAi.setEncoderValue(rotaryEncoderPos.Pos);
rotaryEncoderAi.setAcceleration(250);
boolean _resume = false;
while (_resume == false) {
curr_millis = millis();
//blink();
UpdateButton();
tmptxt = "F\374llmenge:";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(0, (SCREEN_HEIGHT / 2) + (u8g2.getAscent() / 2), tmptxt.c_str());
tmptxt = String(rotaryEncoderPos.Pos) + "ml";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(alignright(SCREEN_WIDTH - 30, tmptxt), (SCREEN_HEIGHT / 2) + (u8g2.getAscent() / 2), tmptxt.c_str());
u8g2.sendBuffer();
if ( rotaryButton.ButtonPressed ) {
glassize = rotaryEncoderPos.Pos;
unpressButton();
_resume = true;
}
}
if ( SERIAL_CONNECTED ) {
Serial.print("Füllmenge (Glas): ");
Serial.println(glassize);
}
if (glassize < IceAmount) {
return;
} else {
glassize = glassize - IceAmount;
}
float relAmount = float(totIngredientAmount)/float(glassize);
if ( SERIAL_CONNECTED ) {
Serial.print("Füllmenge (Getränk): ");
Serial.println(glassize);
Serial.print("relAmount: ");
Serial.println(relAmount);
}
/**********************************************************************
* Pour Cocktail
**********************************************************************/
int pouredAmount = 0;
for (int var = 0; var < NumPumps; var++) {
if (Cocktail[CocktailID].IngredientAmount[var] && Cocktail[CocktailID].IngredientName[var] != "") {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tpss_tn);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, Cocktail[CocktailID].CocktailName), 10, Cocktail[CocktailID].CocktailName.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
tmptxt = "wird zubereitet.";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 25, tmptxt.c_str());
tmptxt = "/";
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(aligncenter((SCREEN_WIDTH / 2) - 6, tmptxt), 37, tmptxt.c_str());
uint16_t pourAmount = Cocktail[CocktailID].IngredientAmount[var] / relAmount;
tmptxt = String(pourAmount) + "ml";
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(alignright((SCREEN_WIDTH / 2) + (5 * 6), tmptxt), 37, tmptxt.c_str());
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, Cocktail[CocktailID].IngredientName[var]), 47, Cocktail[CocktailID].IngredientName[var].c_str());
tmptxt = "Bitte warten...";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(0, SCREEN_HEIGHT, tmptxt.c_str());
u8g2.sendBuffer();
for (int pump = 0; pump < NumIngredients; pump++) {
if ( Ingredient[pump].IngredientName == Cocktail[CocktailID].IngredientName[var] ) {
powerPumpOn(Ingredient[pump].PumpID, pourAmount);
}
}
pouredAmount += pourAmount;
if ( SERIAL_CONNECTED ) {
Serial.print("pouredAmount: ");
Serial.println(pouredAmount);
Serial.print("float(totIngredientAmount/relAmount):");
Serial.println(float(totIngredientAmount/relAmount));
}
float pouredAmountPerc = float(pouredAmount)/float(totIngredientAmount/relAmount);
showStatusAmount(pouredAmountPerc);
} else {
if ( SERIAL_CONNECTED ) {
Serial.println("nothing to do...");
}
}
}
/**********************************************************************
* Cocktail finished
**********************************************************************/
// CLEAR OLED BUFFER
u8g2.clearBuffer();
// HEADLINE
u8g2.setFont(u8g2_font_tpss_tn);
u8g2.drawStr(aligncenter(USABLE_SCREEN_WIDTH / 2, Cocktail[CocktailID].CocktailName), 10, Cocktail[CocktailID].CocktailName.c_str());
// MIDDLE
tmptxt = "ist fertig.";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt), tmptxt.c_str());
tmptxt = "Bitte entnehmen.";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), SCREEN_HEIGHT, tmptxt.c_str());
// SEND BUFFER
u8g2.sendBuffer();
float weight = 99999;
while ( weight > 0.0 ) {
curr_millis = millis();
//blink();
//weight = getChilledLoadCellValue();
weight = getLoadCellValue_noFeedback();
LEDCocktailFinished();
delay(100);
}
LEDsoff();
// CLEAR OLED BUFFER
u8g2.clearBuffer();
// SEND BUFFER
u8g2.sendBuffer();
/**********************************************************************
* TaraLoadCell
**********************************************************************/
TaraLoadCellnoFeedback();
unpressButton();
minPos=1;
maxPos = oldmaxPos;
rotaryEncoderAi.setBoundaries(minPos, maxPos, false);
rotaryEncoderAi.disableAcceleration();
rotaryEncoderPos.Pos = rotaryEncoderPos.LastPos;
rotaryEncoderAi.setEncoderValue(rotaryEncoderPos.LastPos);
//interrupts();
}
void emptyPumps() {
oldmaxPos = maxPos;
maxPos=2;
rotaryEncoderAi.setBoundaries(minPos, maxPos, false);
rotaryEncoderPos.Pos = 2;
rotaryEncoderAi.setEncoderValue(rotaryEncoderPos.Pos);
unpressButton();
/**********************************************************************
* Waiting for glas
**********************************************************************/
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tpss_tn);
tmptxt = "Pumpen leeren";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 10, tmptxt.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
tmptxt = "Bitte leeres";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)-6, tmptxt.c_str());
tmptxt = "Glas platzieren.";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)+6, tmptxt.c_str());
u8g2.sendBuffer();
CheckForGlas();
/**********************************************************************
* Empty Pumps
**********************************************************************/
int pouredAmount = 0;
for (int num = 0; num < NumIngredients; num++) {
if (Ingredient[num].PumpID > 0) {
u8g2.clearBuffer();
tmptxt = "Pumpen leeren";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 10, tmptxt.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
tmptxt = "Pumpe Nr.: " + String(Ingredient[num].PumpID);
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 25, tmptxt.c_str());
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, Ingredient[num].IngredientName), 47, Ingredient[num].IngredientName.c_str());
tmptxt = "Bitte warten...";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(0, SCREEN_HEIGHT, tmptxt.c_str());
u8g2.sendBuffer();
//powerPumpOnEmpty(Ingredient[num].PumpID);
pouredAmount += powerPumpOnEmpty(Ingredient[num].PumpID);
}
}
/**********************************************************************
* Empty Pumps finished
**********************************************************************/
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tpss_tn);
tmptxt = "Pumpen leeren";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 10, tmptxt.c_str());
tmptxt = "ist beendet.";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt), tmptxt.c_str());
tmptxt = "Bitte Glas entnehmen.";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), SCREEN_HEIGHT, tmptxt.c_str());
u8g2.sendBuffer();
float weight = 99999;
while ( weight > 0.0 ) {
curr_millis = millis();
weight = getLoadCellValue_noFeedback();
//LEDCocktailFinished();
delay(100);
}
//LEDsoff();
u8g2.clearBuffer();
u8g2.sendBuffer();
/**********************************************************************
* TaraLoadCell
**********************************************************************/
TaraLoadCellnoFeedback();
unpressButton();
minPos=1;
maxPos = oldmaxPos;
rotaryEncoderAi.setBoundaries(minPos, maxPos, false);
rotaryEncoderAi.disableAcceleration();
rotaryEncoderPos.Pos = rotaryEncoderPos.LastPos;
rotaryEncoderAi.setEncoderValue(rotaryEncoderPos.LastPos);
}
void primePumps() {
oldmaxPos = maxPos;
maxPos=2;
rotaryEncoderAi.setBoundaries(minPos, maxPos, false);
rotaryEncoderPos.Pos = 2;
rotaryEncoderAi.setEncoderValue(rotaryEncoderPos.Pos);
unpressButton();
/**********************************************************************
* Waiting for glas
**********************************************************************/
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tpss_tn);
tmptxt = "Pumpen f\374llen";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, "Pumpen fullen"), 10, tmptxt.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
tmptxt = "Bitte leeres";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)-6, tmptxt.c_str());
tmptxt = "Glas platzieren.";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)+6, tmptxt.c_str());
u8g2.sendBuffer();
CheckForGlas();
/**********************************************************************
* Priming
**********************************************************************/
int pouredAmount = 0;
uint16_t pourAmount = 20;
for (int num = 0; num < NumIngredients; num++) {
if (Ingredient[num].PumpID > 0) {
u8g2.clearBuffer();
tmptxt = "Pumpen f\374llen";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, "Pumpen fullen"), 10, tmptxt.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
tmptxt = "Pumpe Nr.: " + String(Ingredient[num].PumpID);
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 25, tmptxt.c_str());
tmptxt = "/";
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(aligncenter((SCREEN_WIDTH / 2) - 6, tmptxt), 37, tmptxt.c_str());
tmptxt = String(pourAmount) + "ml";
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(alignright((SCREEN_WIDTH / 2) + (5 * 6), tmptxt), 37, tmptxt.c_str());
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, Ingredient[num].IngredientName), 47, Ingredient[num].IngredientName.c_str());
tmptxt = "Bitte warten...";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(0, SCREEN_HEIGHT, tmptxt.c_str());
u8g2.sendBuffer();
powerPumpOn(Ingredient[num].PumpID, pourAmount);
pouredAmount += pourAmount;
}
}
/**********************************************************************
* Priming finished
**********************************************************************/
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tpss_tn);
tmptxt = "Pumpen f\374llen";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, "Pumpen fullen"), 10, tmptxt.c_str());
tmptxt = "ist beendet.";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt), tmptxt.c_str());
tmptxt = "Bitte Glas entnehmen.";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), SCREEN_HEIGHT, tmptxt.c_str());
u8g2.sendBuffer();
float weight = 99999;
while ( weight > 0.0 ) {
curr_millis = millis();
weight = getLoadCellValue_noFeedback();
//LEDCocktailFinished();
delay(100);
}
//LEDsoff();
u8g2.clearBuffer();
u8g2.sendBuffer();
/**********************************************************************
* TaraLoadCell
**********************************************************************/
TaraLoadCellnoFeedback();
unpressButton();
minPos=1;
maxPos = oldmaxPos;
rotaryEncoderAi.setBoundaries(minPos, maxPos, false);
rotaryEncoderAi.disableAcceleration();
rotaryEncoderPos.Pos = rotaryEncoderPos.LastPos;
rotaryEncoderAi.setEncoderValue(rotaryEncoderPos.LastPos);
}
void cleanPumps() {
/**********************************************************************
* Disconnect Pumps
**********************************************************************/
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tpss_tn);
tmptxt = "Pumpen reinigen";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 10, tmptxt.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
u8g2.setFont(u8g2_font_6x13_tf);
tmptxt = "Bitte alle";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)-6, tmptxt.c_str());
tmptxt = "Zutaten entfernen.";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)+6, tmptxt.c_str());
u8g2.sendBuffer();
while (rotaryButton.ButtonPressed == false) {
curr_millis = millis();
//blink();
UpdateButton();
tmptxt = "OK";
drawFramedText(alignright(SCREEN_WIDTH - 4, tmptxt), SCREEN_HEIGHT - 5, tmptxt );
u8g2.sendBuffer();
}
unpressButton();
/**********************************************************************
* Empty Pumps
**********************************************************************/
emptyPumps();
/**********************************************************************
* Prepare Clean Pumps
**********************************************************************/
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tpss_tn);
tmptxt = "Pumpen reinigen";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 10, tmptxt.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
u8g2.setFont(u8g2_font_6x13_tf);
tmptxt = "Bitte Pumpen an";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)-6, tmptxt.c_str());
tmptxt = "Reinigunsmittel";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)+6, tmptxt.c_str());
tmptxt = "anschliessen";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)+18, tmptxt.c_str());
u8g2.sendBuffer();
while (rotaryButton.ButtonPressed == false) {
curr_millis = millis();
//blink();
UpdateButton();
tmptxt = "OK";
drawFramedText(alignright(SCREEN_WIDTH - 4, tmptxt), SCREEN_HEIGHT - 5, tmptxt );
u8g2.sendBuffer();
}
unpressButton();
/**********************************************************************
* Prepare Clean Pumps 1/2
**********************************************************************/
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tpss_tn);
tmptxt = "Pumpen reinigen";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 10, tmptxt.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
u8g2.setFont(u8g2_font_6x13_tf);
tmptxt = "Bitte Schlauch an";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)-6, tmptxt.c_str());
tmptxt = "Ausgabe anschliessen";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)+6, tmptxt.c_str());
u8g2.sendBuffer();
while (rotaryButton.ButtonPressed == false) {
curr_millis = millis();
//blink();
UpdateButton();
tmptxt = "OK";
drawFramedText(alignright(SCREEN_WIDTH - 4, tmptxt), SCREEN_HEIGHT - 5, tmptxt );
u8g2.sendBuffer();
}
unpressButton();
/**********************************************************************
* Prepare Clean Pumps 2/2
**********************************************************************/
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tpss_tn);
tmptxt = "Pumpen reinigen";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 10, tmptxt.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
u8g2.setFont(u8g2_font_6x13_tf);
tmptxt = "Bitte Schlauch in";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)-6, tmptxt.c_str());
tmptxt = "Reinigunsmittel";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)+6, tmptxt.c_str());
tmptxt = "Behaelter fuehren";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)+18, tmptxt.c_str());
u8g2.sendBuffer();
while (rotaryButton.ButtonPressed == false) {
curr_millis = millis();
//blink();
UpdateButton();
tmptxt = "OK";
drawFramedText(alignright(SCREEN_WIDTH - 4, tmptxt), SCREEN_HEIGHT - 5, tmptxt );
u8g2.sendBuffer();
}
unpressButton();
/**********************************************************************
* Clean Pumps
**********************************************************************/
for (int num = 0; num < NumIngredients; num++) {
if (Ingredient[num].PumpID > 0) {
u8g2.clearBuffer();
tmptxt = "Pumpen reinigen";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 10, tmptxt.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
tmptxt = "Pumpe Nr.: " + String(Ingredient[num].PumpID);
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 25, tmptxt.c_str());
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, Ingredient[num].IngredientName), 47, Ingredient[num].IngredientName.c_str());
tmptxt = "Bitte warten...";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(0, SCREEN_HEIGHT, tmptxt.c_str());
u8g2.sendBuffer();
powerPumpOnOFFClean(Ingredient[num].PumpID);
}
}
/**********************************************************************
* Clean Pumps (ON)
**********************************************************************/
/*
for (int num = 0; num < NumIngredients; num++) {
if (Ingredient[num].PumpID > 0) {
u8g2.clearBuffer();
tmptxt = "Pumpen reinigen";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 10, tmptxt.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
tmptxt = "Pumpe Nr.: " + String(Ingredient[num].PumpID);
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 25, tmptxt.c_str());
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, Ingredient[num].IngredientName), 47, Ingredient[num].IngredientName.c_str());
tmptxt = "Bitte warten...";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(0, SCREEN_HEIGHT, tmptxt.c_str());
u8g2.sendBuffer();
powerPumpOnClean(Ingredient[num].PumpID);
}
}
delay(5000);
*/
/**********************************************************************
* Clean Pumps (OFF)
**********************************************************************/
/*
for (int num = 0; num < NumIngredients; num++) {
if (Ingredient[num].PumpID > 0) {
u8g2.clearBuffer();
tmptxt = "Pumpen reinigen";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 10, tmptxt.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
tmptxt = "Pumpe Nr.: " + String(Ingredient[num].PumpID);
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 25, tmptxt.c_str());
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, Ingredient[num].IngredientName), 47, Ingredient[num].IngredientName.c_str());
tmptxt = "Bitte warten...";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(0, SCREEN_HEIGHT, tmptxt.c_str());
u8g2.sendBuffer();
powerPumpOffClean(Ingredient[num].PumpID);
}
}
*/
/**********************************************************************
* Post Clean Pumps
**********************************************************************/
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tpss_tn);
tmptxt = "Pumpen reinigen";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 10, tmptxt.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
u8g2.setFont(u8g2_font_6x13_tf);
tmptxt = "Bitte Schlaeuche aus";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)-6, tmptxt.c_str());
tmptxt = "Reinigunsmittel";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)+6, tmptxt.c_str());
tmptxt = "entfernen";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt)+18, tmptxt.c_str());
u8g2.sendBuffer();
while (rotaryButton.ButtonPressed == false) {
curr_millis = millis();
//blink();
UpdateButton();
tmptxt = "OK";
drawFramedText(alignright(SCREEN_WIDTH - 4, tmptxt), SCREEN_HEIGHT - 5, tmptxt );
u8g2.sendBuffer();
}
unpressButton();
/**********************************************************************
* Empty Pumps
**********************************************************************/
//emptyPumps();
for (int num = 0; num < NumIngredients; num++) {
if (Ingredient[num].PumpID > 0) {
u8g2.clearBuffer();
tmptxt = "Pumpen reinigen";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 10, tmptxt.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
tmptxt = "Pumpe Nr.: " + String(Ingredient[num].PumpID);
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 25, tmptxt.c_str());
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, Ingredient[num].IngredientName), 47, Ingredient[num].IngredientName.c_str());
tmptxt = "Bitte warten...";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(0, SCREEN_HEIGHT, tmptxt.c_str());
u8g2.sendBuffer();
powerPumpOnEmpty(Ingredient[num].PumpID);
}
}
/**********************************************************************
* Finished Cleaning
**********************************************************************/
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_tpss_tn);
tmptxt = "Pumpen reinigen";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 10, tmptxt.c_str());
u8g2.drawHLine(0,14,SCREEN_WIDTH);
tmptxt = "beendet";
u8g2.setFont(u8g2_font_6x13_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), aligncenter_H(tmptxt), tmptxt.c_str());
u8g2.sendBuffer();
while (rotaryButton.ButtonPressed == false) {
curr_millis = millis();
//blink();
UpdateButton();
tmptxt = "OK";
drawFramedText(alignright(SCREEN_WIDTH - 4, tmptxt), SCREEN_HEIGHT - 5, tmptxt );
u8g2.sendBuffer();
}
unpressButton();
}
void powerPumpOn(uint8_t PumpID, uint16_t Amount) {
int start_weight = 0;
start_weight = getChilledLoadCellValue();
int poured = 0;
int weight = 0;
int xpos = 110;
uint8_t percent = 0 ;
//LEDsoff();
//void ControlPWM_SINGLE(uint8_t nr, uint8_t start, uint8_t ende, bool soft);
ControlPWM_SINGLE(PumpID - 1, 0, 100, false);
while ( poured < Amount ) {
weight = getLoadCellValue_noFeedback();
poured = weight - start_weight;
//map(value, fromLow, fromHigh, toLow, toHigh)
percent = map(poured, 0, Amount, 0, 100);
// => LED ANZEIGE AUFRUFEN
showPercStatusAmount(percent);
switch (poured) {
case 0 ... 9:
xpos = 110;
break;
case 10 ... 99:
xpos = 110 - 6;
break;
case 100 ... 999:
xpos = 110 - 12;
break;
case 1000 ... 9999:
xpos = 110 - 18;
break;
case -9 ... -1:
xpos = 110 - 6;
break;
case -99 ... -10:
xpos = 110 - 12;
break;
case -999 ... -100:
xpos = 110 - 18;
break;
case -9999 ... -1000:
xpos = 110 - 24;
break;
}
tmptxt = String(poured);
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(alignright((SCREEN_WIDTH / 2) - (2 * 6), tmptxt), 37, tmptxt.c_str());
u8g2.sendBuffer();
}
ControlPWM_SINGLE(PumpID - 1, 100, 0, false);
delay(1000);
LEDsoff();
}
int powerPumpOnEmpty(uint8_t PumpID) {
int start_weight = getChilledLoadCellValue();
int weight = 0;
//void ControlPWM_SINGLE(uint8_t nr, uint8_t start, uint8_t ende, bool soft);
ControlPWM_SINGLE(PumpID - 1, 0, 100, false);
tmptxt = " . ";
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 37, tmptxt.c_str());
u8g2.sendBuffer();
delay(1000);
weight = getChilledLoadCellValue();
int poured = weight - start_weight;
tmptxt = " .. ";
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 37, tmptxt.c_str());
u8g2.sendBuffer();
delay(1000);
ControlPWM_SINGLE(PumpID - 1, 100, 0, false);
tmptxt = " ... ";
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 37, tmptxt.c_str());
u8g2.sendBuffer();
if ( SERIAL_CONNECTED ) {
Serial.print("Menge: ");
Serial.println(poured);
}
delay(1000);
return poured;
}
void powerPumpOnOFFClean(uint8_t PumpID) {
//void ControlPWM_SINGLE(uint8_t nr, uint8_t start, uint8_t ende, bool soft);
ControlPWM_SINGLE(PumpID - 1, 0, 100, true);
delay(5000);
//void ControlPWM_SINGLE(uint8_t nr, uint8_t start, uint8_t ende, bool soft);
ControlPWM_SINGLE(PumpID - 1, 100, 0, true);
delay(500);
}
void powerPumpOnClean(uint8_t PumpID) {
//void ControlPWM_SINGLE(uint8_t nr, uint8_t start, uint8_t ende, bool soft);
ControlPWM_SINGLE(PumpID - 1, 0, 100, true);
}
void powerPumpOffClean(uint8_t PumpID) {
//void ControlPWM_SINGLE(uint8_t nr, uint8_t start, uint8_t ende, bool soft);
ControlPWM_SINGLE(PumpID - 1, 100, 0, true);
}
void ControlPWM_SINGLE(uint8_t nr, uint8_t start, uint8_t ende, bool soft) {
ledcAttach(PumpPIN[nr], PWMFreq, PWMResolution);
if ( soft ) {
uint8_t speed_delay = 5;
if ( start < ende ) {
for (int value = 0; value <= 100; value++) {
ControlPWMChannel(PumpPIN[nr], value);
Serial.print(millis());
Serial.print(" - Speed: ");
Serial.println(value);
delay(speed_delay);
}
} else {
for (int value = 100; value >= 0; value--) {
ControlPWMChannel(PumpPIN[nr], value);
Serial.print(millis());
Serial.print(" - Speed: ");
Serial.println(value);
delay(speed_delay);
}
}
} else {
ControlPWMChannel(PumpPIN[nr], ende);
}
if ( ende == 0 ) {
ledcDetach(PumpPIN[nr]);
digitalWrite(PumpPIN[nr], LOW);
}
}
void ControlPWMChannel(uint8_t pin, uint8_t value) {
int dutyCycle = map(value, 0, 100, 0, MAX_DUTY_CYCLE);
ledcWrite(pin, dutyCycle);
}
void checkCocktails() {
NumCocktailsAvailable = 0;
for (int CocktailID = 0; CocktailID < NumCocktails; CocktailID++) {
int soup = 0;
int soup2 = 0;
for (int var = 0; var < NumPumps; var++) {
if ( Cocktail[CocktailID].IngredientName[var] != "" ) {
soup++;
soup2++;
}
if ( Cocktail[CocktailID].IngredientAmount[var] ) {
soup--;
}
if ( soup > 0 ) {
Cocktail[CocktailID].available = false;
} else {
for (int pump = 0; pump < NumIngredients; pump++) {
if ( Ingredient[pump].IngredientName == Cocktail[CocktailID].IngredientName[var] ) {
if ( Ingredient[pump].PumpID > 0 ) soup2--;
}
}
}
}
if ( (soup > 0) || (soup2 > 0) ) {
Cocktail[CocktailID].available = false;
} else {
Cocktail[CocktailID].available = true;
NumCocktailsAvailable++;
}
}
NumCocktailsMenu = NumCocktailsAvailable + 1;
}
int getCockailIDbyName(String Name) {
uint8_t CocktailID = 0;
while (CocktailID < NumCocktails) {
if ( Cocktail[CocktailID].CocktailName == Name ) {
break;
}
CocktailID++;
}
return CocktailID;
}
int getIngredientIDbyName(String Name) {
uint8_t IngredientID = 0;
while (IngredientID < NumIngredients) {
if ( Ingredient[IngredientID].IngredientName == Name ) {
break;
}
IngredientID++;
}
return IngredientID;
}
bool checkIngredient() {
int anz[NumPumps];
for (int abc = 0; abc < NumPumps; abc++) {
anz[abc] = 0;
for (int i = 0; i < NumIngredients; i++) {
if ( Ingredient[i].PumpID == abc + 1 ) {
anz[abc]++;
}
}
if ( anz[abc] > 1 ) {
return false;
}
if ( abc == NumPumps - 1 ) {
return true;
}
}
return false;
}
void IRAM_ATTR readEncoderISR() {
rotaryEncoderAi.readEncoder_ISR();
if (rotaryEncoderAi.encoderChanged()) {
LastEncoderPosChange = millis();
rotaryEncoderPos.Pos = rotaryEncoderAi.readEncoder();
if (!rotaryEncoderPos.locked) rotaryEncoderPos.PosLocked = rotaryEncoderPos.Pos;
}
}
void UpdateButton() {
static unsigned long lastTimeButtonDown = 0;
static bool wasButtonDown = false;
bool isEncoderButtonDown = rotaryEncoderAi.isEncoderButtonDown();
if (isEncoderButtonDown) {
if (!wasButtonDown) {
lastTimeButtonDown = millis();
}
wasButtonDown = true;
return;
}
if (wasButtonDown) {
if (millis() - lastTimeButtonDown >= longPressAfterMiliseconds) {
rotaryButton.ButtonPressed = true;
rotaryButton.ButtonPressedLong = true;
} else if (millis() - lastTimeButtonDown >= shortPressAfterMiliseconds) {
rotaryButton.ButtonPressed = true;
rotaryButton.ButtonPressedLong = false;
}
rotaryButton.LastButtonChange = millis();
}
wasButtonDown = false;
}
void unpressButton() {
rotaryButton.ButtonPressed = false;
if (rotaryButton.ButtonPressedLong == true ) rotaryButton.ButtonPressedLong = false;
rotaryButton.LastButtonChange = curr_millis;
}
void TaraLoadCellnoFeedback() {
LoadCell.tareNoDelay();
boolean _resume = false;
if ( SERIAL_CONNECTED ) {
Serial.println("Starting Tara.");
}
while (_resume == false) {
LoadCell.update();
if (LoadCell.getTareStatus() == true) {
if ( SERIAL_CONNECTED ) {
Serial.println("Tare complete");
}
_resume = true;
}
}
}
float getLoadCellValue_noFeedback() {
float weight;
static boolean newDataReady = 0;
boolean _resume = false;
while (_resume == false) {
if (LoadCell.update()) newDataReady = true;
if (newDataReady) {
weight = LoadCell.getData();
newDataReady = 0;
_resume = true;
}
}
return weight;
}
float getChilledLoadCellValue() {
float tmp_weight[10];
float start_weight = 0.0;
float mid_weight = 0.0;
float delta_weight;
float weight;
boolean _resume = false;
while (_resume == false) {
curr_millis = millis();
while (!LoadCell.update())
{
}
start_weight = LoadCell.getData();
if (start_weight < 0 ) start_weight = start_weight * -1;
mid_weight = 0.0;
for ( int i = 0; i < 10 ; i++) {
curr_millis = millis();
static boolean newDataReady = 0;
while (!newDataReady) {
if (LoadCell.update()) newDataReady = true;
}
newDataReady = 0;
tmp_weight[i] = LoadCell.getData();
if ( tmp_weight[i] < 0 ) tmp_weight[i] = tmp_weight[i] * -1;
mid_weight += tmp_weight[i];
delay(100);
}
mid_weight = mid_weight / 10;
if ( mid_weight < start_weight ) {
delta_weight = start_weight - mid_weight;
} else {
delta_weight = mid_weight - start_weight;
}
if ( delta_weight < 10 ) {
if (LoadCell.update()) weight = LoadCell.getData();
_resume = true;
}
}
return weight;
}
void readIngredients() {
for ( int i = 0; i < NumDefaultIngredients; i++ ) {
Ingredient[i].PumpID = DefaultIngredient[i].PumpID;
Ingredient[i].IngredientName = DefaultIngredient[i].IngredientName;
Ingredient[i].alcoholic = DefaultIngredient[i].alcoholic;
}
NumIngredients = NumDefaultIngredients;
}
void readCocktails() {
int i = 0;
while ( DefaultCocktail[i].CocktailName ) {
Cocktail[i].CocktailName = DefaultCocktail[i].CocktailName;
for ( int z = 0; z < NumPumps; z++ ) {
if ( DefaultCocktail[i].IngredientAmount[z] > 0) {
Cocktail[i].IngredientName[z] = DefaultCocktail[i].IngredientName[z];
Cocktail[i].IngredientAmount[z] = DefaultCocktail[i].IngredientAmount[z];
}
}
i++;
}
NumCocktails = i - 1;
showAllCocktails();
}
void showAllCocktails() {
if ( SERIAL_CONNECTED ) {
Serial.println("----------------------------------------");
Serial.print("Anzahl Cocktails Rezepte: ");
Serial.println(NumCocktails);
Serial.print("Anzahl Cocktails Verfügbar: ");
Serial.println(NumCocktailsAvailable);
Serial.println("----------------------------------------");
for (int i = 0; i < NumCocktails; i++) {
Serial.print(i + 1);
Serial.print("/");
Serial.println(NumCocktails);
Serial.print(" - Cocktail: ");
Serial.println(Cocktail[i].CocktailName);
Serial.println(" - Zutaten: ");
for ( int z = 0; z < NumPumps; z++ ) {
if ( Cocktail[i].IngredientAmount[z] > 0) {
Serial.print(" - ");
Serial.print(Cocktail[i].IngredientAmount[z]);
Serial.print("ml ");
Serial.println(Cocktail[i].IngredientName[z]);
}
}
}
}
}
void showAvailableCocktails() {
if ( SERIAL_CONNECTED ) {
Serial.println("----------------------------------------");
Serial.print("Anzahl Cocktails Rezepte: ");
Serial.println(NumCocktails);
Serial.print("Anzahl Cocktails Verfügbar: ");
Serial.println(NumCocktailsAvailable);
Serial.println("----------------------------------------");
for (int i = 0; i < NumCocktails; i++) {
if (Cocktail[i].available) {
Serial.print(i + 1);
Serial.print("/");
Serial.println(NumCocktails);
Serial.print(" - Cocktail: ");
Serial.println(Cocktail[i].CocktailName);
Serial.println(" - Zutaten: ");
for ( int z = 0; z < NumPumps; z++ ) {
if ( Cocktail[i].IngredientAmount[z] > 0) {
Serial.print(" - ");
Serial.print(Cocktail[i].IngredientAmount[z]);
Serial.print("ml ");
Serial.println(Cocktail[i].IngredientName[z]);
}
}
}
}
}
}
void setup() {
for ( int i = 0; i < NumPumps; i++) {
pinMode(PumpPIN[i], OUTPUT);
digitalWrite(PumpPIN[i], LOW);
}
Serial.begin(115200);
delay(100);
int i = 0;
while (!Serial) {
delay(10);
i++;
if ( i >= 100 ) {
break;
}
}
if (Serial) {
SERIAL_CONNECTED = true;
Serial.println("Serial console connected.");
Serial.println("Starting...");
} else {
SERIAL_CONNECTED = false;
}
pinMode (PIN_LED, OUTPUT);
pinMode (PIN_WS2812B, OUTPUT);
ws2812b.begin();
ws2812b.clear();
if (!u8g2.begin()) {
for (;;); // Don't proceed, loop forever
}
SCREEN_WIDTH = u8g2.getDisplayWidth();
SCREEN_HEIGHT = u8g2.getDisplayHeight();
USABLE_SCREEN_WIDTH = SCREEN_WIDTH;
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_7x14B_tf);
tmptxt = "Booting...";
u8g2.drawStr(aligncenter(SCREEN_WIDTH / 2, tmptxt), 10, tmptxt.c_str());
u8g2.sendBuffer();
/*
if (!SD.begin(SD_CS_PIN)) {
while (true);
}
*/
LoadCell.begin();
LoadCell.powerDown();
LoadCell.begin();
unsigned long stabilizingtime = 2000;
boolean _tare = true;
LoadCell.start(stabilizingtime, _tare);
if (LoadCell.getTareTimeoutFlag() || LoadCell.getSignalTimeoutFlag()) {
for (;;);
} else {
float calibrationValue;
calibrationValue = 0.42;
EEPROM.begin(512); // uncomment this if you use ESP8266/ESP32 and want to fetch the calibration value from eeprom
EEPROM.get(calVal_eepromAdress, calibrationValue); // uncomment this if you want to fetch the calibration value from eeprom
if (calibrationValue > 0) {
if ( SERIAL_CONNECTED ) {
Serial.print("Calibration Value from EEPROM: ");
Serial.println(calibrationValue);
}
} else {
calibrationValue = 0.42;
if ( SERIAL_CONNECTED ) {
Serial.print("Calibration Value from SKETCH: ");
Serial.println(calibrationValue);
}
EEPROM.put(calVal_eepromAdress, calibrationValue);
EEPROM.commit();
EEPROM.get(calVal_eepromAdress, calibrationValue);
if ( SERIAL_CONNECTED ) {
Serial.print("Calibration Value stored: ");
Serial.println(calibrationValue);
}
}
LoadCell.setCalFactor(calibrationValue);
while (!LoadCell.update());
}
readIngredients();
if (!checkIngredient()) {
if ( SERIAL_CONNECTED ) Serial.println("something went wrong");
}
readCocktails();
checkCocktails();
showAvailableCocktails();
rotaryEncoderAi.begin();
rotaryEncoderAi.setup(readEncoderISR);
rotaryEncoderAi.setBoundaries(minPos, maxPos, circleValues);
rotaryEncoderAi.disableAcceleration();
rotaryEncoderAi.setEncoderValue(minPos);
/*
// ***********************************
// * Setup Blink Timer
// ***********************************
// Set timer frequency to 1Mhz
Blink_Timer = timerBegin(1000000);
// Attach Blink_Function_ISR function to our timer.
timerAttachInterrupt(Blink_Timer, &Blink_Function_ISR);
// Set alarm to call Blink_Function_ISR function every second (value in microseconds).
// Repeat the alarm (third parameter) with unlimited count = 0 (fourth parameter).
timerAlarm(Blink_Timer, 1000000, true, 0);
*/
mainMenu();
}
/************************************************************************
MAIN LOOP
************************************************************************/
void loop() {
curr_millis = millis();
//blink();
UpdateButton();
if (rotaryButton.ButtonPressed) {
switch (currMenu) {
case 0:
switch (rotaryEncoderPos.Pos)
{
case 1:
unpressButton();
rotaryEncoderPos.LastPos = rotaryEncoderPos.Pos;
lastMenu = currMenu;
if ( menuItems[rotaryEncoderPos.Pos] == "Zutaten" ) {
currMenu = 3;
} else {
currMenu = 1;
}
if ( lastMenu != currMenu ) {
rotaryEncoderPos.Pos = 1;
rotaryEncoderAi.setEncoderValue(rotaryEncoderPos.Pos);
}
break;
case 2:
unpressButton();
rotaryEncoderPos.LastPos = rotaryEncoderPos.Pos;
lastMenu = currMenu;
currMenu = 2;
if ( lastMenu != currMenu ) {
rotaryEncoderPos.Pos = 1;
rotaryEncoderAi.setEncoderValue(rotaryEncoderPos.Pos);
}
break;
default:
unpressButton();
rotaryEncoderPos.LastPos = rotaryEncoderPos.Pos;
break;
}
break;
case 1:
if ( menuItems[rotaryEncoderPos.Pos] == "zur\374ck" ) {
unpressButton();
rotaryEncoderPos.LastPos = rotaryEncoderPos.Pos;
lastMenu = currMenu;
currMenu = 0;
if ( lastMenu != currMenu ) {
rotaryEncoderPos.Pos = 1;
rotaryEncoderAi.setEncoderValue(rotaryEncoderPos.Pos);
}
} else {
unpressButton();
rotaryEncoderPos.LastPos = rotaryEncoderPos.Pos;
pourCocktail( getCockailIDbyName(menuItems[rotaryEncoderPos.Pos]) );
}
break;
case 2:
/*****************************************************************
Setup Menu - Actions
*****************************************************************/
switch (rotaryEncoderPos.Pos)
{
case 1:
unpressButton();
rotaryEncoderPos.LastPos = rotaryEncoderPos.Pos;
lastMenu = currMenu;
currMenu = 3;
if ( lastMenu != currMenu ) {
rotaryEncoderPos.Pos = 1;
rotaryEncoderAi.setEncoderValue(rotaryEncoderPos.Pos);
}
break;
/*
case 2:
unpressButton();
rotaryEncoderPos.LastPos = rotaryEncoderPos.Pos;
calibrateLoadCell();
break;
case 3:
unpressButton();
rotaryEncoderPos.LastPos = rotaryEncoderPos.Pos;
showLoadCellValue();
break;
case 4:
unpressButton();
rotaryEncoderPos.LastPos = rotaryEncoderPos.Pos;
TaraLoadCell();
break;
*/
case 5:
/*************************************************************
reinigen
*************************************************************/
unpressButton();
rotaryEncoderPos.LastPos = rotaryEncoderPos.Pos;
cleanPumps();
break;
case 6:
/*************************************************************
Pumpen leeren
*************************************************************/
unpressButton();
rotaryEncoderPos.LastPos = rotaryEncoderPos.Pos;
emptyPumps();
break;
case 7:
/*************************************************************
Pumpen füllen
*************************************************************/
unpressButton();
rotaryEncoderPos.LastPos = rotaryEncoderPos.Pos;
primePumps();
break;
default:
unpressButton();
rotaryEncoderPos.LastPos = rotaryEncoderPos.Pos;
lastMenu = currMenu;
currMenu = 0;
if ( lastMenu != currMenu ) {
rotaryEncoderPos.Pos = 1;
rotaryEncoderAi.setEncoderValue(rotaryEncoderPos.Pos);
}
break;
}
break;
case 3:
if ( menuItems[rotaryEncoderPos.Pos] == "zur\374ck" ) {
unpressButton();
rotaryEncoderPos.LastPos = rotaryEncoderPos.Pos;
currMenu = lastMenu;
lastMenu = 3;
if ( lastMenu != currMenu ) {
rotaryEncoderPos.Pos = 1;
rotaryEncoderAi.setEncoderValue(rotaryEncoderPos.Pos);
}
} else if ( menuItems[rotaryEncoderPos.Pos] == "reset" ) {
unpressButton();
rotaryEncoderPos.LastPos = rotaryEncoderPos.Pos;
rotaryEncoderPos.Pos = 1;
rotaryEncoderAi.setEncoderValue(rotaryEncoderPos.Pos);
//resetIngredient();
} else {
unpressButton();
rotaryEncoderPos.LastPos = rotaryEncoderPos.Pos;
modifyIngredient( getIngredientIDbyName(menuItems[rotaryEncoderPos.Pos]) );
}
break;
}
}
if ( ((curr_millis - rotaryButton.LastButtonChange) < (loop_delay + 10)) || ((curr_millis - LastEncoderPosChange) < (loop_delay + 10))) {
updateMenu();
}
delay(loop_delay);
}
Loading
ssd1306
ssd1306