Przeglądaj źródła

added functionality to display information during state, mode or page transitions
Now displaying the elapsed time at the end of the brewing
Using the divider of the timer to control the refresh rate of the display

Sebastian Vendt 6 lat temu
rodzic
commit
8303e6db0d
6 zmienionych plików z 220 dodań i 109 usunięć
  1. 10 1
      CoffeeCode/coffee.cpp
  2. 7 3
      CoffeeCode/coffee.h
  3. 180 81
      CoffeeCode/display2.cpp
  4. 12 22
      CoffeeCode/display2.h
  5. 10 2
      CoffeeCode/hal.cpp
  6. 1 0
      CoffeeCode/hal.h

+ 10 - 1
CoffeeCode/coffee.cpp

@@ -28,7 +28,8 @@ coffee_menuPage_t page;
 coffee_mode_t mode;
 coffee_mode_t mode;
 
 
 int sigValue;
 int sigValue;
-int brewTime; //Brew time in ms
+uint16_t brewTime; //Brew time in ms
+uint16_t lastBrewTime;
 timer brewTimer(&brewTimeHandler);
 timer brewTimer(&brewTimeHandler);
 
 
 uint64_t totalHeatingTime; //local copies of the corresponding database entries
 uint64_t totalHeatingTime; //local copies of the corresponding database entries
@@ -659,6 +660,13 @@ coffee_status_t getState(void) {
 	return state;
 	return state;
 }
 }
 
 
+/**
+ * Returns the last elapsed brew time in ms
+ */
+uint16_t getLastBrewTime(void) {
+	return lastBrewTime;
+}
+
 /**
 /**
  * Returns the local up-to-date brewcounter
  * Returns the local up-to-date brewcounter
  */
  */
@@ -836,6 +844,7 @@ void coffeeBrew(void) {
 void stopBrewing() {
 void stopBrewing() {
 	halPumpOff();
 	halPumpOff();
 	brewTimer.stop();
 	brewTimer.stop();
+	lastBrewTime = brewTime;
 	brewTime = 0;
 	brewTime = 0;
 	halResetFlow();
 	halResetFlow();
 }
 }

+ 7 - 3
CoffeeCode/coffee.h

@@ -22,12 +22,14 @@ typedef enum {
 	STATE_CLEANING,
 	STATE_CLEANING,
 	STATE_ERROR,
 	STATE_ERROR,
 	STATE_WAIT_OFF,
 	STATE_WAIT_OFF,
-	STATE_FULLTANK
+	STATE_FULLTANK,
+	STATE_NULL
 } coffee_status_t;
 } coffee_status_t;
 
 
 typedef enum {
 typedef enum {
 	MODE_STATE,
 	MODE_STATE,
-	MODE_MENU
+	MODE_MENU,
+	MODE_NULL
 } coffee_mode_t;
 } coffee_mode_t;
 
 
 typedef enum {
 typedef enum {
@@ -39,7 +41,8 @@ typedef enum {
 	PAGE_TEMP,
 	PAGE_TEMP,
 	PAGE_CLEAN,
 	PAGE_CLEAN,
 	PAGE_DEMO,
 	PAGE_DEMO,
-	PAGE_EXIT
+	PAGE_EXIT,
+	PAGE_NULL
 } coffee_menuPage_t;
 } coffee_menuPage_t;
 
 
 extern const char* StateName[];
 extern const char* StateName[];
@@ -61,6 +64,7 @@ void changeMode(coffee_mode_t newMode);
 void changePage(coffee_menuPage_t newPage);
 void changePage(coffee_menuPage_t newPage);
 void leaveMenu(void);
 void leaveMenu(void);
 coffee_status_t getState(void);
 coffee_status_t getState(void);
+uint16_t getLastBrewTime(void);
 int getSigValue(coffee_mode_t mode);
 int getSigValue(coffee_mode_t mode);
 uint16_t getBrewCounter(void);
 uint16_t getBrewCounter(void);
 uint64_t getTotalHeatingTime(void);
 uint64_t getTotalHeatingTime(void);

+ 180 - 81
CoffeeCode/display2.cpp

@@ -22,15 +22,39 @@
 #include "events.h"
 #include "events.h"
 #include "DS18B20.h"
 #include "DS18B20.h"
 
 
+#define CURRENT	0
+#define NEXT	1
+
+//timeouts for the transitions in ms
+#define TIMEOUT_PREBREW		1000
+#define TIMEOUT_POSTBREW	4000
+
 display_lang_t displayLang;
 display_lang_t displayLang;
 timer displayTimer(displayTimerHandler);
 timer displayTimer(displayTimerHandler);
 int lcd = 0;
 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;
+// currently only the history of states is of interest
+coffee_status_t coffeeState[] = {STATE_OFF, STATE_NULL}; // current - next state
+coffee_mode_t coffeeMode[] = {MODE_STATE, MODE_NULL};
+coffee_menuPage_t coffeePage[] = {PAGE_SOFTOFF, PAGE_NULL};
 bool coffeeDescaling = false;
 bool coffeeDescaling = false;
+refreshRate_t currentRefreshRate = refresh_std;
+uint16_t holdNext[3] = {0, 0, 0}; 	//holdtime of the new {state, Mode, Page} in ms
+uint16_t nextWaitTime[3] = {0, 0, 0}; //actual waiting time of the new {state, Mode, Page}
+
+
+typedef enum {
+	state_idx = 0,
+	mode_idx = 1,
+	page_idx = 2
+} idx_t;
+
+void track(idx_t idx);
+void switchToNextPage(coffee_menuPage_t* history);
+void switchToNextMode(coffee_mode_t* history);
+void switchToNextState(coffee_status_t* history);
+void setRefreshRate(refreshRate_t rate);
+void setSwitchToNextTimeout(idx_t idx, uint16_t millis);
+
 
 
 /**
 /**
  * Prints out the current time in a centered position
  * Prints out the current time in a centered position
@@ -58,6 +82,8 @@ void displayPrintTemp(int line) {
 	//after the first refresh the right temperature is displayed
 	//after the first refresh the right temperature is displayed
 	//no idea where this comes from, datasheet says nothing about dummy readouts.
 	//no idea where this comes from, datasheet says nothing about dummy readouts.
 	//no old values are used, conversion is started before every readout...
 	//no old values are used, conversion is started before every readout...
+	//Quick fix:
+	DS18B20_readTemp();
 	if (line > DISPLAY_ROWS)
 	if (line > DISPLAY_ROWS)
 		line = 0;
 		line = 0;
 
 
@@ -94,13 +120,25 @@ void displayPrintStats2(int line) {
  */
  */
 void displayPrintNextDesc(int line) {
 void displayPrintNextDesc(int line) {
 	char buffer[17];
 	char buffer[17];
-	if (line > DISPLAY_ROWS)
-		line = 0;
+	if (line > DISPLAY_ROWS) line = 0;
 
 
 	sprintf(buffer, "%d d or %d C", checkDirtyTime(), checkDirtyEspresso());
 	sprintf(buffer, "%d d or %d C", checkDirtyTime(), checkDirtyEspresso());
 	displayPrintLn(line, buffer, true);
 	displayPrintLn(line, buffer, true);
 }
 }
 
 
+/**
+ *
+ */
+void displayPrintPostBrew(int line){
+	char buffer[17];
+	if (line > DISPLAY_ROWS) line = 0;
+
+	float brewTime = (float)getLastBrewTime();
+
+	sprintf(buffer, "%.1f ml / %.1f s", halGetLastFlow(), brewTime / 1000);
+	displayPrintLn(line, buffer, true);
+}
+
 /**
 /**
  * Prints out the total volume flow
  * Prints out the total volume flow
  * @param line Target line in display
  * @param line Target line in display
@@ -166,13 +204,8 @@ void displayStateUpdated(event_t *event) {
 		return;
 		return;
 	}
 	}
 	coffee_status_t state = *(coffee_status_t*) event->data;
 	coffee_status_t state = *(coffee_status_t*) event->data;
-	if (state != coffeeState) {
-		coffeeState = state;
-		if (timerScaler)
-			timerScaler--;
-		elapsedCnt = 0;
-		displayTimer.call();
-	}
+	coffeeState[NEXT] = state;
+	displayTimer.call();
 }
 }
 
 
 /**
 /**
@@ -186,17 +219,16 @@ void displayModeUpdated(event_t *event) {
 		return;
 		return;
 	}
 	}
 	coffee_mode_t mode = *(coffee_mode_t*) event->data;
 	coffee_mode_t mode = *(coffee_mode_t*) event->data;
-	if (mode != coffeeMode) {
-		coffeeMode = mode;
-		if (timerScaler)
-			timerScaler--;
-		elapsedCnt = 0;
-		displayTimer.call();
-	}
+	coffeeMode[NEXT] = mode;
+	displayTimer.call();
 }
 }
 
 
 /**
 /**
  * Updates the display state to the matching coffee display page
  * Updates the display state to the matching coffee display page
+ * The new state is put on hold (next) and the display can decided if it immediately makes the
+ * new state to the current one or if a timeout is specified in which the new state is put on hold and the
+ * state transition is processed.
+ * One initial asynchronous call
  * @param event Event data
  * @param event Event data
  */
  */
 
 
@@ -206,12 +238,8 @@ void displayPageUpdated(event_t *event) {
 		return;
 		return;
 	}
 	}
 	coffee_menuPage_t page = *(coffee_menuPage_t*) event->data;
 	coffee_menuPage_t page = *(coffee_menuPage_t*) event->data;
-	if (page != coffeePage) {
-		coffeePage = page;
-		timerScaler = REFRESH_RATE;
-		elapsedCnt = 0;
-		displayTimer.call();
-	}
+	coffeePage[NEXT] = page;
+	displayTimer.call();
 }
 }
 
 
 /**
 /**
@@ -230,7 +258,7 @@ void displayDescaling(event_t *event) {
  */
  */
 void displayPrintLogo(void) {
 void displayPrintLogo(void) {
 	char buffer[17];
 	char buffer[17];
-	switch (coffeeState) {
+	switch (coffeeState[CURRENT]) {
 		case STATE_HEATING:
 		case STATE_HEATING:
 		case STATE_INITALHEATING:
 		case STATE_INITALHEATING:
 		case STATE_IDLE:
 		case STATE_IDLE:
@@ -246,7 +274,6 @@ void displayPrintLogo(void) {
 /**
 /**
  * Handles cleanup before program termination
  * Handles cleanup before program termination
  */
  */
-
 void displayTerminate(event_t *e) {
 void displayTerminate(event_t *e) {
 	logger(V_BASIC, "display.cpp: Terminating\n");
 	logger(V_BASIC, "display.cpp: Terminating\n");
 	displayPrintLn(0, "CoffeePi", true);
 	displayPrintLn(0, "CoffeePi", true);
@@ -257,14 +284,12 @@ void displayTerminate(event_t *e) {
  * Main thread to handle display data
  * Main thread to handle display data
  * @param *threadid Thread ID
  * @param *threadid Thread ID
  */
  */
-
 void* displayThread(void* threadid) {
 void* displayThread(void* threadid) {
 	//sleep(1); // Wait for other components to initialize
 	//sleep(1); // Wait for other components to initialize
 	displayTimer.start();
 	displayTimer.start();
 	while (1) {
 	while (1) {
 		pause();
 		pause();
 		if (1) {
 		if (1) {
-			timerScaler = REFRESH_RATE;
 			displayTimer.call();
 			displayTimer.call();
 		}
 		}
 	}
 	}
@@ -275,52 +300,42 @@ void* displayThread(void* threadid) {
  * Timer handler for display update
  * Timer handler for display update
  * @param *threadid Thread ID
  * @param *threadid Thread ID
  */
  */
-
 void* displayTimerHandler(void* threadid) {
 void* displayTimerHandler(void* threadid) {
-	int scale1Hz = 0;
-	if (timerScaler++ >= REFRESH_RATE) { // 1s elapsed, reset
-		timerScaler = 0;
-		scale1Hz = 1;
-	}
+	//track time of the new state in hold and switch if necessary
+	track(state_idx);
+	track(page_idx);
+	track(mode_idx);
+
+	displayRefresh();
+	pthread_exit(EXIT_SUCCESS);
+}
+
+/**
+ * Tracks the elapsed time in ms of the new state waiting to become the current one if a hold time is specified
+ */
 
 
-	if (scale1Hz) {
-		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();
+void track(idx_t idx){
+	if (holdNext[idx] != 0) {
+		nextWaitTime[idx] += 1000 / currentRefreshRate;
+		if (holdNext[idx] <= nextWaitTime[idx]) {
+			switch(idx){
+			case state_idx:
+				switchToNextState(coffeeState);
+				break;
+			case page_idx:
+				switchToNextPage(coffeePage);
 				break;
 				break;
-			default:
+			case mode_idx:
+				switchToNextMode(coffeeMode);
 				break;
 				break;
 			}
 			}
-		} else if (coffeeMode == MODE_MENU) {
-			displayRefresh();
 		}
 		}
 	}
 	}
-
-	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);
 }
 }
 
 
 /**
 /**
  * Initializes display
  * Initializes display
  */
  */
-
 void displayInit(void) {
 void displayInit(void) {
 	lcd = lcdInit();
 	lcd = lcdInit();
 	if (lcd < 0)
 	if (lcd < 0)
@@ -331,11 +346,11 @@ void displayInit(void) {
 	displayPrintLn(1, (char*) "booting...", true);
 	displayPrintLn(1, (char*) "booting...", true);
 	//lcdPrintf(lcd, "    CoffeePi       booting...");
 	//lcdPrintf(lcd, "    CoffeePi       booting...");
 
 
-	timerScaler = 0;
-	displayTimer.setDivider((1000000 / TIMER_DELAY_US) / REFRESH_RATE);
 
 
-	logger(V_BASIC, "Initialized display with a refresh rate of %d Hz\n",
-	REFRESH_RATE);
+	setRefreshRate(refresh_std);
+
+	logger(V_BASIC, "display2.cpp Initialized display with a refresh rate of %d Hz\n",
+			refresh_std);
 	/**The following block comes from void* displayThread(void* threadid)
 	/**The following block comes from void* displayThread(void* threadid)
 	 * The idea is that the initialization functions get the component ready to react on external events
 	 * The idea is that the initialization functions get the component ready to react on external events
 	 * once the threads start, events might be triggered and every component can process them
 	 * once the threads start, events might be triggered and every component can process them
@@ -362,13 +377,92 @@ void displaySetLang(display_lang_t lang) {
 	displayLang = lang;
 	displayLang = lang;
 }
 }
 
 
+/*
+ *
+ */
+void switchToNextPage(coffee_menuPage_t* history){
+	if(history[NEXT] != PAGE_NULL) {
+		history[CURRENT] = history[NEXT];
+		history[NEXT] = PAGE_NULL;
+
+		holdNext[page_idx] = 0;
+		nextWaitTime[page_idx] = 0;
+	}
+}
+
+/*
+ *
+ */
+void switchToNextMode(coffee_mode_t* history){
+	if(history[NEXT] != MODE_NULL) {
+		history[CURRENT] = history[NEXT];
+		history[NEXT] = MODE_NULL;
+
+		holdNext[mode_idx] = 0;
+		nextWaitTime[mode_idx] = 0;
+	}
+}
+
+/*
+ *
+ */
+void switchToNextState(coffee_status_t* history){
+	if(history[NEXT] != STATE_NULL) {
+		history[CURRENT] = history[NEXT];
+		history[NEXT] = STATE_NULL;
+
+		holdNext[state_idx] = 0;
+		nextWaitTime[state_idx] = 0;
+	}
+}
+
+/**
+ * sets the refresh rate of the the display
+ * to one of the predefined refresh rates.
+ */
+void setRefreshRate(refreshRate_t rate) {
+	currentRefreshRate = rate;
+	displayTimer.setDivider(20 / rate);
+}
+
+/**
+ * specifies a timeout at which the new state will be made to the current one
+ * This function is necessary for the special state transitions which hold the new state while they
+ * process the current transition. These cases set a timeout specifying how long the state transition should be paused.
+ * After the time specified in the timeout the timerhandler of the display will switch the states and makes the new one to the current one.
+ */
+void setSwitchToNextTimeout(idx_t idx, uint16_t millis) {
+	holdNext[idx] = millis;
+}
+
 /**
 /**
- * Refreshed the display content and outputs it
+ * The core description of what will be displayed in what displaystate
  */
  */
 
 
 void displayRefresh(void) {
 void displayRefresh(void) {
-	if (coffeeMode == MODE_STATE) {
-		switch (coffeeState) { //coffeeGetState()
+	//handle mode trainsitions
+	switchToNextMode(coffeeMode);
+
+	//FSM of the display
+	if (coffeeMode[CURRENT] == MODE_STATE) {
+		//handle state transitions
+		if (coffeeState[NEXT] == STATE_BREW) { //Pre brew
+			//check how long the new state is already in hold ... and either switch or process transition
+			setSwitchToNextTimeout(state_idx, TIMEOUT_PREBREW);
+			setRefreshRate(refresh_fast);
+			displayPrintLogo();
+			displayPrintLn(1, displayGetString(str_brewing), true);
+			return;
+		} else if (coffeeState[CURRENT] == STATE_BREW && coffeeState[NEXT] != STATE_NULL) { //Post brew
+			setSwitchToNextTimeout(state_idx, TIMEOUT_POSTBREW);
+			setRefreshRate(refresh_std);
+			displayPrintPostBrew(1);
+			return;
+		} else { //no special state transition -> make new state to the current one
+			switchToNextState(coffeeState);
+		}
+
+		switch (coffeeState[CURRENT]) { //coffeeGetState()
 		case STATE_IDLE:
 		case STATE_IDLE:
 			displayPrintLogo();
 			displayPrintLogo();
 			displayPrintLn(1, displayGetString(str_ready), true);
 			displayPrintLn(1, displayGetString(str_ready), true);
@@ -385,13 +479,8 @@ void displayRefresh(void) {
 			break;
 			break;
 
 
 		case STATE_BREW:
 		case STATE_BREW:
-			if (elapsedCnt <= 2 * REFRESH_RATE) {
-				displayPrintLogo();
-				displayPrintLn(1, displayGetString(str_brewing), true);
-			} else {
-				displayPrintLn(0, displayGetString(str_brewing), true);
-				displayPrintFlow(1);
-			}
+			displayPrintLn(0, displayGetString(str_brewing), true);
+			displayPrintFlow(1);
 			break;
 			break;
 
 
 		case STATE_BREWMANUAL:
 		case STATE_BREWMANUAL:
@@ -420,8 +509,18 @@ void displayRefresh(void) {
 			displayPrintTime(1);
 			displayPrintTime(1);
 			break;
 			break;
 		}
 		}
-	} else if (coffeeMode == MODE_MENU) {
-		switch (coffeePage) {
+	} else if (coffeeMode[CURRENT] == MODE_MENU) {
+		//handle page transitions
+		if(coffeePage[NEXT] == PAGE_EXIT) {
+			setSwitchToNextTimeout(page_idx, 2000);
+			displayPrintLn(0, "test vor exit", true);
+			displayPrintLn(1, "Test", true);
+			return;
+		} else {
+			switchToNextPage(coffeePage);
+		}
+
+		switch (coffeePage[CURRENT]) {
 		case PAGE_SOFTOFF:
 		case PAGE_SOFTOFF:
 			displayPrintLn(0, displayGetString(str_menu), true);
 			displayPrintLn(0, displayGetString(str_menu), true);
 			displayPrintLn(1, displayGetString(str_menu_softoff), true);
 			displayPrintLn(1, displayGetString(str_menu_softoff), true);

+ 12 - 22
CoffeeCode/display2.h

@@ -10,13 +10,15 @@
 #include <string>
 #include <string>
 #include "coffee.h"
 #include "coffee.h"
 
 
-#define DEFAULT_LANG 	lang_en /**< Default display language */
-#define REFRESH_RATE	5 /**< Display refresh rate in Hz when active */
+#define DEFAULT_LANG 	lang_en // Default display language
+
+
+#define REFRESH_FAST	5
+#define REFRESH_STD		2
+
 #define DISPLAY_ROWS	2
 #define DISPLAY_ROWS	2
 #define DISPLAY_COLS	16
 #define DISPLAY_COLS	16
 
 
-#define MAX_PAGENAME	20
-
 void *displayThread(void *threadid);
 void *displayThread(void *threadid);
 void *displayTimerHandler(void *threadid);
 void *displayTimerHandler(void *threadid);
 void displayInit(void);
 void displayInit(void);
@@ -27,6 +29,12 @@ void displayPushState(coffee_status_t state);
 void displayRefresh(void);
 void displayRefresh(void);
 
 
 
 
+//(DO NOT change the following values unless you know what you do -> Integer division)
+typedef enum {
+	refresh_fast = 5, 	// Display refresh rate in Hz when active
+	refresh_std = 2 	// Display refresh rate in Hz when not active
+} refreshRate_t;
+
 typedef enum {
 typedef enum {
 	lang_de,
 	lang_de,
 	lang_en,
 	lang_en,
@@ -56,24 +64,6 @@ typedef enum {
 	str_last
 	str_last
 } display_strings_t;
 } display_strings_t;
 
 
-typedef struct {
-	const char * const pagename[MAX_PAGENAME];
-	void (*ContentFunction)(void);
-	uint16_t refreshrate;
-	uint16_t timeToDisplay;
-	uint16_t displayTime;
-}display2_page_t;
-
-static const display2_page_t pages[] =
-{
-		{
-				{"demopage"},
-				displayInit,
-				10,
-				19,
-				10
-		}
-};
 
 
 typedef struct {
 typedef struct {
 	char const * const text[lang_last];
 	char const * const text[lang_last];

+ 10 - 2
CoffeeCode/hal.cpp

@@ -23,7 +23,7 @@
 typedef struct timespec timespec;
 typedef struct timespec timespec;
 
 
 volatile int flowcnt = 0;
 volatile int flowcnt = 0;
-
+int lastFlowcnt = 0;
 
 
 int Int0Time, Int1Time;
 int Int0Time, Int1Time;
 int idleCounter;
 int idleCounter;
@@ -43,6 +43,7 @@ time_t heatingCycle[] = {0, 0};
 timespec flowTimestep[] = {{0,0},{0,0}};
 timespec flowTimestep[] = {{0,0},{0,0}};
 uint8_t flowIndex = 0;
 uint8_t flowIndex = 0;
 
 
+
 timespec pumpCycle[] = {{0,0},{0,0}};
 timespec pumpCycle[] = {{0,0},{0,0}};
 
 
 //delay of the debounce in milliseconds
 //delay of the debounce in milliseconds
@@ -335,17 +336,24 @@ void halIntProximity(void) {
 }
 }
 
 
 /**
 /**
- * Returns total flow trough sensor in ml
+ * Returns total flow through sensor in ml
  */
  */
 float halGetFlow(void) {
 float halGetFlow(void) {
 	return flowcnt * FLOW_ML_PULSE;
 	return flowcnt * FLOW_ML_PULSE;
 }
 }
 
 
+/*
+ * Returns the last total flow through the sensor in ml after reset
+ */
+float halGetLastFlow(void) {
+	return lastFlowcnt * FLOW_ML_PULSE;
+}
 /**
 /**
  * Resets the Flow counter
  * Resets the Flow counter
  */
  */
 void halResetFlow(void) {
 void halResetFlow(void) {
 	logger(V_HAL, "Flow counter reset, amount so far: %.2f ml\n", halGetFlow());
 	logger(V_HAL, "Flow counter reset, amount so far: %.2f ml\n", halGetFlow());
+	lastFlowcnt = flowcnt;
 	flowcnt = 0;
 	flowcnt = 0;
 }
 }
 
 

+ 1 - 0
CoffeeCode/hal.h

@@ -71,6 +71,7 @@ void halIntPressure(void);
 double halgetHeatingTime(void);
 double halgetHeatingTime(void);
 void halIntProximity(void);
 void halIntProximity(void);
 float halGetFlow(void);
 float halGetFlow(void);
+float halGetLastFlow(void);
 void halResetFlow(void);
 void halResetFlow(void);
 bool halIsHeating(void);
 bool halIsHeating(void);
 bool halProxSensorCovered(void);
 bool halProxSensorCovered(void);