Explorar o código

added the rotary encoder to flip betweeen the menu pages, added some TODOs

Sebastian %!s(int64=6) %!d(string=hai) anos
pai
achega
bd352f92ef
Modificáronse 5 ficheiros con 172 adicións e 24 borrados
  1. 1 1
      CoffeeCode/buildno
  2. 99 19
      CoffeeCode/coffee.cpp
  3. 3 0
      CoffeeCode/coffee.h
  4. 57 3
      CoffeeCode/hal.cpp
  5. 12 1
      CoffeeCode/hal.h

+ 1 - 1
CoffeeCode/buildno

@@ -1 +1 @@
-279
+290

+ 99 - 19
CoffeeCode/coffee.cpp

@@ -29,7 +29,9 @@ coffee_mode_t mode;
 
 int sigValue;
 int brewTime; //Brew time in ms
+int menuTimeout;
 timer brewTimer(&brewTimeHandler);
+timer menuTimer(&menuTimeHandler);
 
 uint64_t totalHeatingTime; //local copies of the corresponding database entries
 uint16_t brewCounter;
@@ -64,6 +66,10 @@ void *coffeeThread(void *threadid) {
 	brewTimer.stop();
 	brewTime = 0;
 
+	menuTimer.setDivider(4);
+	menuTimer.stop();
+	menuTimeout = 0;
+
 	initalHeating = true;
 	mode = MODE_STATE; //Unless we enter the menu we start in state mode
 	page = PAGE_SOFTOFF;
@@ -138,9 +144,13 @@ void *coffeeThread(void *threadid) {
 				leaveMenu();
 				break;
 
-			case SigInt1Psh:
+			case SigRotCW:
 				changePage(PAGE_KILL);
 				break;
+
+			case SigRotCCW:
+				changePage(PAGE_EXIT);
+				break;
 			}
 			break;
 
@@ -157,13 +167,17 @@ void *coffeeThread(void *threadid) {
 				leaveMenu();
 				break;
 
-			case SigInt1Psh:
+			case SigRotCW:
 				if (state == STATE_IDLE || state == STATE_HEATING) {
 					changePage(PAGE_CLEAN);
 				} else {
 					changePage(PAGE_DEMO);
 				}
 				break;
+
+			case SigRotCCW:
+				changePage(PAGE_SOFTOFF);
+				break;
 			}
 			break;
 
@@ -183,9 +197,13 @@ void *coffeeThread(void *threadid) {
 				}
 				break;
 
-			case SigInt1Psh:
+			case SigRotCW:
 				changePage(PAGE_DEMO);
 				break;
+
+			case SigRotCCW:
+				changePage(PAGE_KILL);
+				break;
 			}
 			break;
 
@@ -194,9 +212,19 @@ void *coffeeThread(void *threadid) {
 				pause();
 
 			switch (getSigValue(MODE_MENU)) {
-			case SigInt1Psh:
+			case SigRotCW:
 				changePage(PAGE_TEMP);
 				break;
+
+			case SigRotCCW:
+				if(state == STATE_IDLE || state == STATE_HEATING){
+					changePage(PAGE_CLEAN);
+				} else if (state == STATE_ERROR || state == STATE_INITALHEATING) {
+					changePage(PAGE_KILL);
+				} else {
+					changePage(PAGE_EXIT);
+				}
+				break;
 			}
 			break;
 
@@ -205,9 +233,13 @@ void *coffeeThread(void *threadid) {
 				pause();
 
 			switch (getSigValue(MODE_MENU)) {
-			case SigInt1Psh:
+			case SigRotCW:
 				changePage(PAGE_STATS);
 				break;
+
+			case SigRotCCW:
+				changePage(PAGE_DEMO);
+				break;
 			}
 			break;
 		case PAGE_STATS:
@@ -215,9 +247,13 @@ void *coffeeThread(void *threadid) {
 				pause();
 
 			switch (getSigValue(MODE_MENU)) {
-			case SigInt1Psh:
+			case SigRotCW:
 				changePage(PAGE_STATS2);
 				break;
+
+			case SigRotCCW:
+				changePage(PAGE_TEMP);
+				break;
 			}
 			break;
 		case PAGE_STATS2:
@@ -225,9 +261,13 @@ void *coffeeThread(void *threadid) {
 				pause();
 
 			switch (getSigValue(MODE_MENU)) {
-			case SigInt1Psh:
+			case SigRotCW:
 				changePage(PAGE_DESCALING);
 				break;
+
+			case SigRotCCW:
+				changePage(PAGE_STATS);
+				break;
 			}
 			break;
 		case PAGE_DESCALING:
@@ -235,9 +275,13 @@ void *coffeeThread(void *threadid) {
 				pause();
 
 			switch (getSigValue(MODE_MENU)) {
-			case SigInt1Psh:
+			case SigRotCW:
 				changePage(PAGE_EXIT);
 				break;
+
+			case SigRotCCW:
+				changePage(PAGE_STATS2);
+				break;
 			}
 			break;
 		case PAGE_EXIT:
@@ -249,7 +293,7 @@ void *coffeeThread(void *threadid) {
 				leaveMenu();
 				break;
 
-			case SigInt1Psh:
+			case SigRotCW:
 				if (state == STATE_HEATING || state == STATE_ERROR
 						|| state == STATE_IDLE
 						|| state == STATE_INITALHEATING) {
@@ -258,6 +302,10 @@ void *coffeeThread(void *threadid) {
 					changePage(PAGE_DEMO);
 				}
 				break;
+
+			case SigRotCCW:
+				changePage(PAGE_DESCALING);
+				break;
 			}
 			break;
 		} //end switch (page)
@@ -273,6 +321,7 @@ void *coffeeThread(void *threadid) {
 			if (mode == MODE_STATE) {
 				halMachineOff();
 				writeBackCache();
+				//TODO this might be a bit confusing to change the page here even if the menu isnt actually displayed
 				changePage(PAGE_DEMO);
 				if (SigValueEmpty())
 					pause();
@@ -297,11 +346,13 @@ void *coffeeThread(void *threadid) {
 					changePage(PAGE_SOFTOFF); //the machine is on, the menu starts with the turning off page
 				break;
 
-			case SigInt1Psh:
+			case SigRotCCW:
+			case SigRotCW:
 				//Enter the menu
-				if (page != PAGE_DEMO)
-					changePage(PAGE_DEMO); //machine is off, the menu starts with the demo page
-				changeMode(MODE_MENU);
+				/* This should be not necessary!
+				 * if (page != PAGE_DEMO)
+					changePage(PAGE_DEMO); //machine is off, the menu starts with the demo page*/
+				enterMenu();
 				break;
 			}
 			break;
@@ -368,7 +419,7 @@ void *coffeeThread(void *threadid) {
 				break;
 
 			case SigInt1Psh:
-				changeMode(MODE_MENU);
+				enterMenu();
 				break;
 			}
 			break;
@@ -416,7 +467,7 @@ void *coffeeThread(void *threadid) {
 
 			case SigInt1Psh:
 				//Enter the menu
-				changeMode(MODE_MENU);
+				enterMenu();
 				break;
 			}
 			break;
@@ -460,7 +511,7 @@ void *coffeeThread(void *threadid) {
 
 			case SigInt1Psh:
 				//Enter the menu
-				changeMode(MODE_MENU);
+				enterMenu();
 				break;
 			}
 			break;
@@ -583,7 +634,10 @@ int getSigValue(coffee_mode_t mode) {
 		case SigInt1Psh:
 		case SigInt1Rls:
 		case SigInt1RlsLong:
+		case SigRotCCW:
+		case SigRotCW:
 			sigValue = 0;
+			menuTimeout = 0;
 			return tmp;
 			break;
 
@@ -644,14 +698,29 @@ void changeMode(coffee_mode_t newMode) {
  * leaving the menu
  *  sets the start page for the next menu call to softoff
  */
-void leaveMenu() {
-	//TODO leave the menu after certain time automatically
-	logger(V_BREW, "Leaving the menu again...\n");
+void leaveMenu(void) {
+	logger(V_BREW, "Leaving the menu again\n");
 	//leave the menu again
 	changeMode(MODE_STATE);
 	//change page to initial page
 	changePage(PAGE_SOFTOFF);
+
+	//stop the timeout counter
+	menuTimeout = 0;
+	menuTimer.stop();
+}
+
+/**
+ * entering the menu
+ * starts the timeoutcounter and changes the mode to the Menu Mode
+ */
+void enterMenu(void) {
+	logger(V_BREW, "Entering the menu\n");
+	changeMode(MODE_MENU);
+	menuTimeout = 0;
+	menuTimer.start();
 }
+
 /**
  * Returns the current state of the FSM
  */
@@ -695,6 +764,17 @@ void brewTimeHandler(void) {
 	brewTime += 200;
 }
 
+/**
+ * Counter for the menu timeout
+ * When no input is coming from the user the machine leaves the menu automatically after MENUTIMEOUT seconds
+ */
+void menuTimeHandler(void){
+	menuTimeout += 200;
+	if((menuTimeout/1000) >= MENUTIMEOUT)  {
+		leaveMenu();
+	}
+}
+
 /**
  * handles program termination
  */

+ 3 - 0
CoffeeCode/coffee.h

@@ -52,6 +52,7 @@ extern const char* PageName[];
 #define AMOUNT_DBLESPRESSO	59.0	//Size of a double espresso in ml
 #define DIRTY_ESPRESSO		35		//Number of espressi until the next cleaning
 #define DIRTY_TIME			90		//Number of days until the next cleaning
+#define MENUTIMEOUT			30		//timeout of the menu when no input is received from the user (in seconds)
 void *coffeeThread(void *threadid);
 
 void coffeeHandler(int signum, siginfo_t *siginfo, void *context);
@@ -60,6 +61,7 @@ void changeState(coffee_status_t newState);
 void changeMode(coffee_mode_t newMode);
 void changePage(coffee_menuPage_t newPage);
 void leaveMenu(void);
+void enterMenu(void);
 coffee_status_t getState(void);
 int getSigValue(coffee_mode_t mode);
 uint16_t getBrewCounter(void);
@@ -67,6 +69,7 @@ uint64_t getTotalHeatingTime(void);
 uint16_t getDescBrewCounter (void);
 time_t * getDescTimestamp (void);
 void brewTimeHandler(void);
+void menuTimeHandler(void);
 void writeBackCache(void);
 void coffeeTerminate(event_t *event);
 void coffeeNap (uint64_t sec, uint64_t nanosec);

+ 57 - 3
CoffeeCode/hal.cpp

@@ -34,7 +34,7 @@ bool flagIgnoreRlsInt0, flagIgnoreRlsInt1;
 int pinState[4] = {1, 1, 1, 0};
 
 //sweep counter to log every brew
-uint16_t logcycle = 0;
+uint16_t logcycle = 1;
 
 timer Int0Timer(&halInt0TimerHandler);
 timer Int1Timer(&halInt1TimerHandler);
@@ -43,6 +43,7 @@ timer idleTimer(&halIdleTimerHandler);
 time_t heatingCycle[] = {0, 0};
 timespec flowTimestep[] = {{0,0},{0,0}};
 uint8_t flowIndex = 0;
+uint16_t rotaryIndex = 0;
 
 timespec pumpCycle[] = {{0,0},{0,0}};
 
@@ -68,6 +69,9 @@ void halInit(void) {
 	pinMode(PIN_INT1, INPUT);
 	pinMode(PIN_FLOW, INPUT);
 	pinMode(PIN_DISP, OUTPUT);
+	pinMode(PIN_ROTARY1, INPUT);
+	pinMode(PIN_ROTARY2, INPUT);
+
 
 	idleTimer.setDivider(1200); //1 min
 	idleCounter = 0;
@@ -115,6 +119,12 @@ void halInit(void) {
 		logger_error("Unable to setup ISRProximity: %s\n", strerror(errno));
 		return;
 	}
+	//there are some issues with the serial port so interrupts get triggered without an external source and the program
+	//crashes
+	if (wiringPiISR(PIN_ROTARY1, INT_EDGE_RISING, &halIntRotary) < 0) {
+		logger_error("Unable to setup ISRRotary2: %s\n", strerror(errno));
+		return;
+	}
 
 	if (!(logcycle = sqlGetConf(CFGSweepCounter))) {
 		logger_error("hal.cpp: Couldn't read the  logcycle counter from the database\n");
@@ -186,6 +196,41 @@ int halGetRelaisState(int relais) {
 	return -1;
 }
 
+/**
+ *
+ */
+void halIntRotary(void){
+	//check for the status of the other pin
+	if(digitalRead(PIN_ROTARY2)) {
+		//clockwise rotation
+		rotaryIndex = (rotaryIndex + 1) % ROTARY_RESOLUTION;
+
+		if(!(rotaryIndex % ROTARY_STEPSIZE)) {
+			logger(V_HAL, "rotary encoder CW, now at %d\n", rotaryIndex);
+			halSendSignal(SigRotCW);
+		}
+	}
+	else {
+		//counterclockwise rotation
+		if(rotaryIndex) rotaryIndex--;
+		else rotaryIndex = ROTARY_RESOLUTION - 1;
+
+		if(!(rotaryIndex % ROTARY_STEPSIZE)) {
+			logger(V_HAL, "rotary encoder CCW, now at %d\n", rotaryIndex);
+			halSendSignal(SigRotCCW);
+		}
+	}
+
+}
+
+/**
+ *
+ */
+uint16_t halGetRotaryIndex (void){
+	return rotaryIndex;
+}
+
+
 /**
  * Interrupt routine for Int0 (Top button)
  */
@@ -272,13 +317,20 @@ void halInt1TimerHandler(void) {
 
 /**
  * Interrupt routine for the flow sensor
- * It counts the edgdes and stores the value in flowcnt
+ * It counts the edges and stores the value in flowcnt
  */
 void halIntFlow(void) {
 	//halRelaisOff(RELAIS_POWER);
 	logger(V_HAL, "IntFlow triggered #%d total: %.2fml\n", flowcnt, halGetFlow());
 	flowcnt++;
 
+	//detect a manual brewing process
+	//TODO to be able to detect a manual brewing process we need to have the following
+	//autoclear the flowcnt after certain idle time
+	//detect when the the flow is triggered but the pump is not started from software
+	//here we need to suppress the false alarms when the pump is turned off and slowly running out
+
+
 	//subroutine to log the flow to the database
 	timespec deltaT;
 	clock_gettime(CLOCK_REALTIME, &flowTimestep[flowIndex]);
@@ -415,6 +467,8 @@ void halSendSignal(HalSig val) {
 	case SigInt0RlsLong:
 	case SigInt1Rls:
 	case SigInt1RlsLong:
+	case SigRotCCW:
+	case SigRotCW:
 		if (idle) {
 			halLeaveIdle();
 			return;
@@ -574,7 +628,7 @@ void halTerminate(event_t *event){
  */
 void halWriteBackCache(){
 	if (sqlSetConf(CFGSweepCounter, logcycle)) {
-		logger_error("hall.cpp: Couldn't write logcycle to database");
+		logger_error("hal.cpp: Couldn't write logcycle to database");
 		return;
 	}
 	logger(V_BREW, "Writing back logcycle %d\n", logcycle);

+ 12 - 1
CoffeeCode/hal.h

@@ -10,6 +10,8 @@
 
 #include "events.h"
 
+
+//these are the wPi numberings
 #define RELAIS_HEAT		29
 #define RELAIS_PUMP		25
 #define RELAIS_POWER	28
@@ -20,6 +22,11 @@
 #define PIN_FLOW		3 // Flow sensor
 #define PIN_DISP		4
 #define FLOW_ML_PULSE	(1000.0/2219) // Flow sensor: volume (ml) per pulse
+#define PIN_ROTARY1		15
+#define PIN_ROTARY2		16
+
+#define ROTARY_RESOLUTION	127
+#define ROTARY_STEPSIZE		7
 
 #define TIME_BUTTONLONGPRESS	3	//Time in s until a Signal for a long pressed button is sent
 /*
@@ -54,7 +61,9 @@ enum HalSig {
 	SigBrewOn = 11,
 	SigBrewOff = 12,
 	SigPowerUp = 13,
-	SigPowerDown = 14
+	SigPowerDown = 14,
+	SigRotCW = 15,
+	SigRotCCW = 16
 };
 
 
@@ -66,6 +75,8 @@ void halRelaisOn(int relais);
 void halRelaisOff(int relais);
 void halRelaisSet(int relais, int state);
 int halGetRelaisState(int relais);
+void halIntRotary(void);
+uint16_t halGetRotaryIndex (void);
 void halInt0(void);
 void halInt1(void);
 void halIntFlow(void);