Преглед на файлове

Fixed a few bugs, implemented menu texts on display, see FIXMEs in code for more bugs

Philipp Hinz преди 7 години
родител
ревизия
f168f2d865
променени са 8 файла, в които са добавени 314 реда и са изтрити 144 реда
  1. 2 2
      CoffeeCode/DS18B20.cpp
  2. 1 1
      CoffeeCode/buildno
  3. 75 66
      CoffeeCode/coffee.cpp
  4. 2 2
      CoffeeCode/coffee.h
  5. 163 67
      CoffeeCode/display.cpp
  6. 58 2
      CoffeeCode/display.h
  7. 4 4
      CoffeeCode/main.cpp
  8. 9 0
      CoffeeCode/stripe.cpp

+ 2 - 2
CoffeeCode/DS18B20.cpp

@@ -30,7 +30,7 @@ double deviceID;
 void DS18B20_init(void){
 	OneWire_init();
 	if(OW_reset()){
-		logger_error("Unable to reset 1-Wire Bus, no device present %s\n", strerror(errno));
+		logger_error("Unable to reset 1-Wire Bus, no device present\n");
 		return;
 	}
 	logger(V_HAL, "Checking 1-Wire Bus for sensors..\n");
@@ -57,7 +57,7 @@ void DS18B20_readRom(void){
 
 void DS18B20_cmd(uint8_t cmd) {
 	if(OW_reset()){
-		logger_error("Unable to reset 1-Wire Bus, no device present %s\n", strerror(errno));
+		logger_error("Unable to reset 1-Wire Bus, no device present\n");
 	}
 	OW_writeByte(SKIP_ROM);
 	OW_writeByte(cmd);

+ 1 - 1
CoffeeCode/buildno

@@ -1 +1 @@
-219
+225

+ 75 - 66
CoffeeCode/coffee.cpp

@@ -23,7 +23,6 @@
 #include "timer.h"
 #include "database.h"
 
-
 coffee_status_t state;
 coffee_menuPage_t page;
 coffee_mode_t mode;
@@ -37,10 +36,10 @@ uint16_t brewCounter;
 bool initalHeating;
 bool descaling; //flag to indicate descaling and cleaning
 
-
-
-const char* PageName[] = {"SoftOff", "Kill", "Stats", "Temp", "Clean", "Demo", "Exit"};
-const char* StateName[] = {"OFF", "HEATING", "INITHEAT", "IDLE", "BREW", "BREWMAN", "CLEAN", "ERROR", "WAITOFF"};
+const char* PageName[] = { "SoftOff", "Kill", "Stats", "Temp", "Clean", "Demo",
+		"Exit" };
+const char* StateName[] = { "OFF", "HEATING", "INITHEAT", "IDLE", "BREW",
+		"BREWMAN", "CLEAN", "ERROR", "WAITOFF" };
 
 /**
  * Thread for the finite state machine
@@ -69,13 +68,15 @@ void *coffeeThread(void *threadid) {
 	descaling = false;
 
 	//read the database values
-	if(!(totalHeatingTime = sqlGetConf(CFGHeatingTime))){
-		logger_error("coffee.cpp: Couldn't read the heating time from the database");
+	if (!(totalHeatingTime = sqlGetConf(CFGHeatingTime))) {
+		logger_error(
+				"coffee.cpp: Couldn't read the heating time from the database");
 		//pthread_exit(EXIT_SUCCESS);
 		exit(EXIT_FAILURE);
 	}
-	if(!(brewCounter = sqlGetConf(CFGbrewcounter))){
-		logger_error("coffee.cpp: Couldn't read the brew counter from the database");
+	if (!(brewCounter = sqlGetConf(CFGbrewcounter))) {
+		logger_error(
+				"coffee.cpp: Couldn't read the brew counter from the database");
 		//pthread_exit(EXIT_SUCCESS);
 		exit(EXIT_FAILURE);
 	}
@@ -131,7 +132,7 @@ void *coffeeThread(void *threadid) {
 
 			switch (getSigValue(MODE_MENU)) {
 			case SigInt0Psh:
-				if(halIsHeating()){
+				if (halIsHeating()) {
 					coffeeIncreaseHeatingTime(halgetHeatingTime());
 				}
 				changeState(STATE_OFF);
@@ -139,10 +140,9 @@ void *coffeeThread(void *threadid) {
 				break;
 
 			case SigInt1Psh:
-				if(state == STATE_IDLE || state == STATE_HEATING){
+				if (state == STATE_IDLE || state == STATE_HEATING) {
 					changePage(PAGE_CLEAN);
-				}
-				else {
+				} else {
 					changePage(PAGE_DEMO);
 				}
 				break;
@@ -156,11 +156,10 @@ void *coffeeThread(void *threadid) {
 			switch (getSigValue(MODE_MENU)) {
 			case SigInt0Psh:
 				changeMode(MODE_STATE);
-				if(!halProxSensorCovered()){
+				if (!halProxSensorCovered()) {
 					changeState(STATE_CLEANING);
 					leaveMenu();
-				}
-				else {
+				} else {
 					changeState(STATE_FULLTANK);
 					leaveMenu();
 				}
@@ -215,10 +214,11 @@ void *coffeeThread(void *threadid) {
 				break;
 
 			case SigInt1Psh:
-				if(state == STATE_HEATING || state == STATE_ERROR || state == STATE_IDLE || state == STATE_INITALHEATING){
+				if (state == STATE_HEATING || state == STATE_ERROR
+						|| state == STATE_IDLE
+						|| state == STATE_INITALHEATING) {
 					changePage(PAGE_SOFTOFF);
-				}
-				else {
+				} else {
 					changePage(PAGE_DEMO);
 				}
 				break;
@@ -226,6 +226,9 @@ void *coffeeThread(void *threadid) {
 			break;
 		} //end switch (page)
 
+		/* FIXME: Display events are reacting on Psh signal, leads to instant
+		 * machine turn on when leave menu is pressed */
+
 		/*
 		 * Hardware FSM
 		 */
@@ -234,12 +237,13 @@ void *coffeeThread(void *threadid) {
 		 *
 		 */
 		case STATE_OFF:
-			halMachineOff();
-			writeBackCache();
-			page = PAGE_DEMO; //machine is off, the menu starts with the demo page
+			if (mode == MODE_STATE) {
+				halMachineOff();
+				writeBackCache();
+				if (SigValueEmpty())
+					pause();
+			}
 
-			if (SigValueEmpty() && mode == MODE_STATE)
-				pause();
 			switch (getSigValue(MODE_STATE)) {
 			case SigInt0Rls:
 				//Check waterlevel in gray water tank
@@ -248,18 +252,20 @@ void *coffeeThread(void *threadid) {
 				sleep(1);
 				if (halIsHeating() && !halProxSensorCovered()) { //check if System starts to heat when turned on
 					changeState(STATE_INITALHEATING);
-				} else if (!halIsHeating() && !halProxSensorCovered()){
+				} else if (!halIsHeating() && !halProxSensorCovered()) {
 					changeState(STATE_IDLE);
-				}
-				else if (halProxSensorCovered()) {
+				} else if (halProxSensorCovered()) {
 					logger_error("Empty Tank please!\n");
 					changeState(STATE_FULLTANK);
 				}
-				page = PAGE_SOFTOFF; //the machine is on, the menu starts with the turning off page
+				if (page != PAGE_SOFTOFF)
+					changePage(PAGE_SOFTOFF); //the machine is on, the menu starts with the turning off page
 				break;
 
 			case SigInt1Psh:
 				//Enter the menu
+				if (page != PAGE_DEMO)
+					changePage(PAGE_DEMO); //machine is off, the menu starts with the demo page
 				changeMode(MODE_MENU);
 				break;
 			}
@@ -267,13 +273,13 @@ void *coffeeThread(void *threadid) {
 
 			/*
 			 *
-			*/
+			 */
 		case STATE_WAIT_OFF:
 			if (SigValueEmpty() && mode == MODE_STATE)
 				pause();
 			switch (getSigValue(MODE_STATE)) {
 			case SigPressOpn:
-				usleep(100000);//wait so no load will be switched
+				usleep(100000); //wait so no load will be switched
 				coffeeIncreaseHeatingTime(halgetHeatingTime());
 				changeState(STATE_OFF);
 				break;
@@ -471,9 +477,9 @@ void *coffeeThread(void *threadid) {
 			switch (getSigValue(MODE_STATE)) {
 			case SigInt1Psh:
 			case SigInt0Psh:
-				if(halIsHeating() && initalHeating){
+				if (halIsHeating() && initalHeating) {
 					changeState(STATE_INITALHEATING);
-				} else if (halIsHeating() && !initalHeating){
+				} else if (halIsHeating() && !initalHeating) {
 					changeState(STATE_HEATING);
 				} else {
 					changeState(STATE_IDLE);
@@ -488,15 +494,15 @@ void *coffeeThread(void *threadid) {
 		case STATE_ERROR:
 			if (SigValueEmpty() && mode == MODE_STATE)
 				pause();
-		switch (getSigValue(MODE_STATE)) {
-		case SigInt1RlsLong:
-		case SigInt0RlsLong:
-			if(halIsHeating()){
-				coffeeIncreaseHeatingTime(halgetHeatingTime());
+			switch (getSigValue(MODE_STATE)) {
+			case SigInt1RlsLong:
+			case SigInt0RlsLong:
+				if (halIsHeating()) {
+					coffeeIncreaseHeatingTime(halgetHeatingTime());
+				}
+				changeState(STATE_OFF);
+				break;
 			}
-			changeState(STATE_OFF);
-			break;
-		}
 		}
 	}
 	pthread_exit(EXIT_SUCCESS);
@@ -512,7 +518,8 @@ void *coffeeThread(void *threadid) {
 void coffeeHandler(int signum, siginfo_t *siginfo, void *context) {
 	sigval_t sigVal = (siginfo->si_value);
 	sigValue = sigVal.sival_int;
-	logger(V_BREW, "coffee.cpp: CoffeeHandler called with Signal %d\n", sigValue);
+	logger(V_BREW, "coffee.cpp: CoffeeHandler called with Signal %d\n",
+			sigValue);
 }
 
 /**
@@ -520,28 +527,29 @@ void coffeeHandler(int signum, siginfo_t *siginfo, void *context) {
  * @return value sent with the last signal
  */
 int getSigValue(coffee_mode_t mode) {
-	if(mode == MODE_MENU) {
-		switch (sigValue){
+	int tmp = sigValue;
+	if (mode == MODE_MENU) {
+		switch (sigValue) {
 		case SigInt0Psh:
 		case SigInt0Rls:
 		case SigInt0RlsLong:
 		case SigInt1Psh:
 		case SigInt1Rls:
 		case SigInt1RlsLong:
-			int tmp = sigValue;
 			sigValue = 0;
 			return tmp;
+
+		default:
 			break;
 		}
-	}
-	else { //State Mode
-		int tmp = sigValue;
+	} else { //State Mode
 		sigValue = 0;
 		return tmp;
 	}
-	int tmp = sigValue;
-	sigValue = 0;
-	return tmp;
+	//int tmp = sigValue;
+	//sigValue = 0;
+	//return tmp;
+	return 0;
 }
 
 bool SigValueEmpty(void) {
@@ -565,27 +573,29 @@ void changeState(coffee_status_t newState) {
 /*
  * Change Page to new menu page
  */
-void changePage(coffee_menuPage_t newPage){
-	logger(V_BREW, "Change Page to %s", PageName[newPage]);
+void changePage(coffee_menuPage_t newPage) {
+	logger(V_BREW, "Change Page to %s\n", PageName[newPage]);
+	event_trigger("pagechange", &newPage, sizeof(newPage));
 	page = newPage;
 }
 
 /*
  * Changes the mode of the machine to the given mode
  */
-void changeMode(coffee_mode_t newmode){
-	if(mode == MODE_MENU)
+void changeMode(coffee_mode_t newMode) {
+	if (newMode == MODE_MENU)
 		logger(V_BREW, "Changing to menu mode\n");
 	else
 		logger(V_BREW, "Changing to state mode\n");
 
-	mode = newmode;
+	event_trigger("modechange", &newMode, sizeof(newMode));
+	mode = newMode;
 }
 
 /*
  * leaving the menu
  */
-void leaveMenu(){
+void leaveMenu() {
 	logger(V_BREW, "Leaving the menu again...\n");
 	//leave the menu again
 	changeMode(MODE_STATE);
@@ -623,7 +633,7 @@ void coffeeTerminate(event_t *event) {
  * brewCounter and totalHeatingTime
  *
  */
-void writeBackCache(void){
+void writeBackCache(void) {
 	if (sqlSetConf(CFGbrewcounter, brewCounter)) {
 		logger_error("coffee.cpp: Couldn't write brewcounter to database");
 		return;
@@ -637,9 +647,9 @@ void writeBackCache(void){
 /*
  * Procedure for cleaning the machine
  */
-void coffeeClean(void){
+void coffeeClean(void) {
 	logger(V_BREW, "Cleaning...\n");
-	for(int i = 0; i < 20; i++){
+	for (int i = 0; i < 20; i++) {
 		halRelaisOn(RELAIS_PUMP);
 		sleep(3);
 		halRelaisOff(RELAIS_PUMP);
@@ -665,7 +675,7 @@ void coffeeBrew(void) {
 		usleep(50000);
 		if (getSigValue(MODE_STATE) == SigInt0Psh)
 			stopBrewing();
-			return;
+		return;
 	}
 	stopBrewing();
 
@@ -675,9 +685,10 @@ void coffeeBrew(void) {
 	brewTimer.start();
 	while (brewTime < TIME_SOAK) {
 		usleep(100000);
-		if (getSigValue(MODE_STATE) == SigInt0Psh)
+		if (getSigValue(MODE_STATE) == SigInt0Psh) {
 			stopBrewing();
 			return;
+		}
 	}
 	stopBrewing();
 
@@ -690,8 +701,7 @@ void coffeeBrew(void) {
 	while (brewTime < TIME_INFUSION && halGetFlow() < AMOUNT_DBLESPRESSO) {
 		usleep(100000);
 		if (getSigValue(MODE_STATE) == SigInt0Psh)
-			stopBrewing();
-			return;
+			break;
 	}
 	stopBrewing();
 	return;
@@ -701,7 +711,7 @@ void coffeeBrew(void) {
  * Wrapper function for the end of a brewing process
  * this function stops the pump, brewtimer and resets the flow and brew time to zero
  */
-void stopBrewing(){
+void stopBrewing() {
 	halRelaisOff(RELAIS_PUMP);
 	brewTimer.stop();
 	brewTime = 0;
@@ -713,11 +723,10 @@ void stopBrewing(){
  */
 void coffeeIncreaseBrewCounter(void) {
 	brewCounter++;
-	if((brewCounter % DIRTY_ESPRESSO) == 0)
+	if ((brewCounter % DIRTY_ESPRESSO) == 0)
 		descaling = true;
 }
 
-
 /**
  *
  */

+ 2 - 2
CoffeeCode/coffee.h

@@ -43,7 +43,7 @@ typedef enum {
 extern const char* StateName[];
 extern const char* PageName[];
 
-#define AMOUNT_PREINFUSION	25 		//Preinfusion amount in ml
+#define AMOUNT_PREINFUSION	24 		//Preinfusion amount in ml
 #define TIME_SOAK			5000 	//Time between preinfusion and infusion in ms
 #define TIME_INFUSION 		25000	//Infusion time in ms
 #define AMOUNT_DBLESPRESSO	59.0	//Size of a double espresso in ml
@@ -53,7 +53,7 @@ void *coffeeThread(void *threadid);
 void coffeeHandler(int signum, siginfo_t *siginfo, void *context);
 bool SigValueEmpty(void);
 void changeState(coffee_status_t newState);
-void changeMode(coffee_mode_t mode);
+void changeMode(coffee_mode_t newMode);
 void changePage(coffee_menuPage_t newPage);
 void leaveMenu(void);
 coffee_status_t getState(void);

+ 163 - 67
CoffeeCode/display.cpp

@@ -19,7 +19,7 @@
 #include "coffee.h"
 #include "hal.h"
 #include "events.h"
-
+#include "DS18B20.h"
 
 display_lang_t displayLang;
 timer displayTimer(displayTimerHandler);
@@ -27,6 +27,8 @@ int lcd = 0;
 volatile int timerScaler = 0;
 volatile int elapsedCnt = 0;
 coffee_status_t coffeeState = STATE_OFF;
+coffee_mode_t coffeeMode = MODE_STATE;
+coffee_menuPage_t coffeePage = PAGE_SOFTOFF;
 
 /**
  * Prints out the current time in a centered position
@@ -46,6 +48,19 @@ void displayPrintTime(int line) {
 			timeinfo->tm_min, timeinfo->tm_sec);
 }
 
+/**
+ * Prints out the current temperature in a centered position
+ * @param line Target line in display
+ */
+
+void displayPrintTemp(int line) {
+	if (line > DISPLAY_ROWS)
+		line = 0;
+
+	lcdPosition(lcd, 0, line);
+	lcdPrintf(lcd, "       %d C      ", DS18B20_readTemp());
+}
+
 /**
  * Prints out the total volume flow
  * @param line Target line in display
@@ -107,10 +122,48 @@ void displayStateUpdated(event_t *event) {
 		logger_error("Invalid use of event %s\n", event->event);
 		return;
 	}
-	coffee_status_t state = *(coffee_status_t*)event->data;
+	coffee_status_t state = *(coffee_status_t*) event->data;
 	if (state != coffeeState) {
 		coffeeState = state;
-		timerScaler--;
+		timerScaler = REFRESH_RATE;
+		elapsedCnt = 0;
+		displayTimer.call();
+	}
+}
+
+/**
+ * Updates the display state to the matching coffee display mode
+ * @param event Event data
+ */
+
+void displayModeUpdated(event_t *event) {
+	if (event->len != sizeof(coffee_mode_t)) {
+		logger_error("Invalid use of event %s\n", event->event);
+		return;
+	}
+	coffee_mode_t mode = *(coffee_mode_t*) event->data;
+	if (mode != coffeeMode) {
+		coffeeMode = mode;
+		timerScaler = REFRESH_RATE;
+		elapsedCnt = 0;
+		displayTimer.call();
+	}
+}
+
+/**
+ * Updates the display state to the matching coffee display page
+ * @param event Event data
+ */
+
+void displayPageUpdated(event_t *event) {
+	if (event->len != sizeof(coffee_menuPage_t)) {
+		logger_error("Invalid use of event %s\n", event->event);
+		return;
+	}
+	coffee_menuPage_t page = *(coffee_menuPage_t*) event->data;
+	if (page != coffeePage) {
+		coffeePage = page;
+		timerScaler = REFRESH_RATE;
 		elapsedCnt = 0;
 		displayTimer.call();
 	}
@@ -138,11 +191,13 @@ void* displayThread(void* threadid) {
 	displaySetLang((display_lang_t) tmp);
 	displayTimer.start();
 	event_subscribe("statechange", &displayStateUpdated);
+	event_subscribe("modechange", &displayModeUpdated);
+	event_subscribe("pagechange", &displayPageUpdated);
 	event_subscribe("terminate", &displayTerminate);
 	while (1) {
 		pause();
 		if (1) {
-			timerScaler--;
+			timerScaler = REFRESH_RATE;
 			displayTimer.call();
 		}
 	}
@@ -160,32 +215,36 @@ void* displayTimerHandler(void* threadid) {
 		timerScaler = 0;
 		scale1Hz = 1;
 	}
-	int scale5Hz = (timerScaler == (REFRESH_RATE / 5) ? 0 : 1);
+
 	if (scale1Hz) {
-		switch (coffeeState) {
-		case STATE_OFF:
-		case STATE_HEATING:
-		case STATE_INITALHEATING:
-		case STATE_IDLE:
-		case STATE_CLEANING:
-		case STATE_ERROR:
-		case STATE_WAIT_OFF:
+		if (coffeeMode == MODE_STATE) {
+			switch (coffeeState) {
+			case STATE_OFF:
+			case STATE_HEATING:
+			case STATE_INITALHEATING:
+			case STATE_IDLE:
+			case STATE_CLEANING:
+			case STATE_ERROR:
+			case STATE_WAIT_OFF:
+				displayRefresh();
+				break;
+			default:
+				break;
+			}
+		} else if (coffeeMode == MODE_MENU) {
 			displayRefresh();
-			break;
-		default:
-			break;
 		}
 	}
-	if (scale5Hz) {
-		switch (coffeeState) {
-		case STATE_BREW:
-		case STATE_BREWMANUAL:
-			displayRefresh();
-			break;
-		default:
-			break;
-		}
+
+	switch (coffeeState) {
+	case STATE_BREW:
+	case STATE_BREWMANUAL:
+		displayRefresh();
+		break;
+	default:
+		break;
 	}
+
 	if (elapsedCnt < (5 * REFRESH_RATE)) // Don't let it grow too large
 		elapsedCnt++;
 	pthread_exit(EXIT_SUCCESS);
@@ -226,57 +285,94 @@ void displaySetLang(display_lang_t lang) {
  */
 
 void displayRefresh(void) {
-	switch (coffeeState) { //coffeeGetState()
-	case STATE_IDLE:
-		displayPrintLn(0, "CoffeePi", true);
-		displayPrintLn(1, displayGetString(str_ready), true);
-		break;
-
-	case STATE_INITALHEATING:
-		displayPrintLn(0, "CoffeePi", true);
-		displayPrintLn(1, displayGetString(str_heating), true);
-		break;
+	if (coffeeMode == MODE_STATE) {
+		switch (coffeeState) { //coffeeGetState()
+		case STATE_IDLE:
+			displayPrintLn(0, "CoffeePi", true);
+			displayPrintLn(1, displayGetString(str_ready), true);
+			break;
 
-	case STATE_HEATING:
-		displayPrintLn(0, "CoffeePi", true);
-		displayPrintLn(1, displayGetString(str_heatingready), true);
-		break;
+		case STATE_INITALHEATING:
+			displayPrintLn(0, "CoffeePi", true);
+			displayPrintLn(1, displayGetString(str_heating), true);
+			break;
 
-	case STATE_BREW:
-		if (elapsedCnt <= 2 * REFRESH_RATE) {
+		case STATE_HEATING:
 			displayPrintLn(0, "CoffeePi", true);
-			displayPrintLn(1, displayGetString(str_brewing), true);
-		} else {
+			displayPrintLn(1, displayGetString(str_heatingready), true);
+			break;
+
+		case STATE_BREW:
+			if (elapsedCnt <= 2 * REFRESH_RATE) {
+				displayPrintLn(0, "CoffeePi", true);
+				displayPrintLn(1, displayGetString(str_brewing), true);
+			} else {
+				displayPrintLn(0, displayGetString(str_brewing), true);
+				displayPrintFlow(1);
+			}
+			break;
+
+		case STATE_BREWMANUAL:
 			displayPrintLn(0, displayGetString(str_brewing), true);
 			displayPrintFlow(1);
-		}
-		break;
-
-	case STATE_BREWMANUAL:
-		displayPrintLn(0, displayGetString(str_brewing), true);
-		displayPrintFlow(1);
-		break;
+			break;
 
-	case STATE_CLEANING:
-		displayPrintLn(0, "CoffeePi", true);
-		displayPrintLn(1, displayGetString(str_cleaning), true);
-		break;
+		case STATE_CLEANING:
+			displayPrintLn(0, "CoffeePi", true);
+			displayPrintLn(1, displayGetString(str_cleaning), true);
+			break;
 
-	case STATE_ERROR:
-		displayPrintLn(0, "CoffeePi", true);
-		displayPrintLn(1, displayGetString(str_error), true);
-		break;
+		case STATE_ERROR:
+			displayPrintLn(0, "CoffeePi", true);
+			displayPrintLn(1, displayGetString(str_error), true);
+			break;
 
-	case STATE_WAIT_OFF:
-		displayPrintLn(0, "CoffeePi", true);
-		displayPrintLn(1, displayGetString(str_waitoff), true);
-		break;
+		case STATE_WAIT_OFF:
+			displayPrintLn(0, "CoffeePi", true);
+			displayPrintLn(1, displayGetString(str_waitoff), true);
+			break;
 
-	case STATE_OFF:
-	default:
-		displayPrintLn(0, "CoffeePi", true);
-		displayPrintTime(1);
-		break;
+		case STATE_OFF:
+		default:
+			displayPrintLn(0, "CoffeePi", true);
+			displayPrintTime(1);
+			break;
+		}
+	} else if (coffeeMode == MODE_MENU) {
+		switch (coffeePage) {
+		case PAGE_SOFTOFF:
+			displayPrintLn(0, displayGetString(str_menu), true);
+			displayPrintLn(1, displayGetString(str_menu_softoff), true);
+			break;
+		case PAGE_KILL:
+			displayPrintLn(0, displayGetString(str_menu), true);
+			displayPrintLn(1, displayGetString(str_menu_kill), true);
+			break;
+		case PAGE_STATS:
+			displayPrintLn(0, displayGetString(str_menu), true);
+			displayPrintLn(1, displayGetString(str_menu_stats), true); // FIXME: Show stats
+			break;
+		case PAGE_TEMP:
+			displayPrintLn(0, displayGetString(str_menu_temp), true);
+			displayPrintTemp(1);
+			break;
+		case PAGE_CLEAN:
+			displayPrintLn(0, displayGetString(str_menu), true);
+			displayPrintLn(1, displayGetString(str_menu_clean), true);
+			break;
+		case PAGE_DEMO:
+			displayPrintLn(0, displayGetString(str_menu), true);
+			displayPrintLn(1, displayGetString(str_menu_demo), true);
+			break;
+		case PAGE_EXIT:
+			displayPrintLn(0, displayGetString(str_menu), true);
+			displayPrintLn(1, displayGetString(str_menu_exit), true);
+			break;
+		default:
+			displayPrintLn(0, displayGetString(str_menu), true);
+			displayPrintLn(1, "???", true);
+			break;
+		}
 	}
 }
 

+ 58 - 2
CoffeeCode/display.h

@@ -26,6 +26,14 @@ typedef enum {
 	str_flow,
 	str_bye,
 	str_waitoff,
+	str_menu,
+	str_menu_softoff,
+	str_menu_kill,
+	str_menu_stats,
+	str_menu_temp,
+	str_menu_clean,
+	str_menu_demo,
+	str_menu_exit,
 	str_last
 } display_strings_t;
 
@@ -83,16 +91,64 @@ static const display_string_t display_strings[str_last] =
 						"Good bye"
 				}
 		},
-		{
+		{ // waitoff
 				{
 						"Ausschalten...",
 						"Turning off..."
 				}
+		},
+		{ // str_menu
+				{
+						"CoffeePi Menü",
+						"CoffeePi Menu"
+				}
+		},
+		{ // str_menu_softoff
+				{
+						"Ausschalten",
+						"Turn off"
+				}
+		},
+		{ // str_menu_kill
+				{
+						"Sofort ausschalten",
+						"Turn off now"
+				}
+		},
+		{ // str_menu_stats
+				{
+						"Stats",
+						"Stats"
+				}
+		},
+		{ // str_menu_temp
+				{
+						"Temperatur",
+						"Temperature"
+				}
+		},
+		{ //  str_menu_clean
+				{
+						"Reinigen",
+						"Clean"
+				}
+		},
+		{ // str_menu_demo
+				{
+						"Demo",
+						"Demo"
+				}
+		},
+		{ // str_menu_exit
+				{
+						"Menü verlassen",
+						"Leave menu"
+				}
 		}
 };
 
 #define DEFAULT_LANG 	lang_en /**< Default display language */
-#define REFRESH_RATE	10 /**< Display refresh rate in Hz */
+#define REFRESH_RATE	5 /**< Display refresh rate in Hz when active */
 #define DISPLAY_ROWS	2
 #define DISPLAY_COLS	16
 

+ 4 - 4
CoffeeCode/main.cpp

@@ -125,11 +125,11 @@ int main(int argc, char *argv[]) {
 
 	logger_reset();
 	initTimers();
+	sqlOpen();
+	sqlSetup();
 	displayInit();
 	//temperatur_init();
 	DS18B20_init();
-	sqlOpen();
-	sqlSetup();
 
 
 	// http://www.tutorialspoint.com/cplusplus/cpp_multithreading.htm
@@ -244,8 +244,8 @@ void *mainLoop(void *threadid) {
 	// Do more stuff here
 	while (1){
 		sleep(4);
-		int8_t temp = DS18B20_readTemp();
-		logger(V_BASIC, "Temperature: %d\n", temp);
+		/*int8_t temp = DS18B20_readTemp();
+		logger(V_BASIC, "Temperature: %d\n", temp);*/
 	}
 
 	logger(V_BASIC, "Thread goes Sleeping..\n");

+ 9 - 0
CoffeeCode/stripe.cpp

@@ -64,6 +64,7 @@ void *stripeThread(void *threadid) {
 			case STATE_HEATING:
 			case STATE_BREW:
 			case STATE_BREWMANUAL:
+			case STATE_FULLTANK:
 			case STATE_CLEANING:
 				col.red = 255;
 				col.green = 0;
@@ -91,6 +92,14 @@ void *stripeThread(void *threadid) {
 				stripeSetRGB(0, 0, 0);
 				stripeSetRGB(0, 0, 0); // do it twice, else it doesn't work?! dafuq..
 				break;
+
+			case STATE_WAIT_OFF:
+				col.red = 255;
+				col.green = 0;
+				col.blue = 0;
+				stripeEffectPulse(col);
+				stripeSetTransient(TRANS_FAST);
+				break;
 			}
 		}
 		usleep(100000);