瀏覽代碼

Added Coffee.cpp and coffee.h to index

pek72 8 年之前
父節點
當前提交
f90e7dd2b0
共有 2 個文件被更改,包括 258 次插入0 次删除
  1. 224 0
      CoffeeCode/coffee.cpp
  2. 34 0
      CoffeeCode/coffee.h

+ 224 - 0
CoffeeCode/coffee.cpp

@@ -0,0 +1,224 @@
+/*
+ * coffee.cpp
+ *
+ *  Created on: Sep 25, 2017
+ *      Author: sebastian
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <wiringPi.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <iostream>
+#include <csignal>
+#include <time.h>
+#include "coffee.h"
+#include "hal.h"
+#include "logger.h"
+#include "timer.h"
+
+
+int state;
+int sigValue;
+int brewTime; //Brew time in ms
+timer brewTimer(&brewTimeHandler);
+
+void *coffeeThread(void *threadid) {
+	logger(V_BREW, "Initializing coffee thread...\n");
+
+	//installing new Signal handler for coffeethread
+	struct sigaction action;
+	sigemptyset(&action.sa_mask);
+	action.sa_flags = SA_SIGINFO;
+	action.sa_sigaction = coffeeHandler;
+	sigaction(SIGUSR2, &action, NULL);
+
+	brewTimer.setDivider(4);
+	brewTimer.stop();
+	brewTime = 0;
+
+	state = STATE_OFF;
+	logger(V_BREW, "Determining inital state\n");
+	//determine inital state
+	if (halGetRelaisState(RELAIS_POWER) && halGetRelaisState(RELAIS_HEAT) && !halGetRelaisState(RELAIS_PUMP)) {
+		//wait for heat relais to switch
+		sleep(1);
+		if (halIsHeating()) { //Heating is on
+			logger(V_BREW, "Change state: INITALHEATING\n");
+			state = STATE_INITALHEATING;
+		} else {
+			logger(V_BREW, "Change state: IDLE\n");
+			state = STATE_IDLE;
+		}
+	} else if (halGetRelaisState(RELAIS_PUMP)) {
+		logger_error("Whoops, why is the pump running...\n");
+		state = STATE_ERROR;
+	}
+
+	logger(V_BREW, "Start Coffee FSM\n");
+	//begin FSM
+	while(1){
+		switch(state){
+		case STATE_OFF:
+			pause();
+			if (getSigValue() == SigInt0Rls) {
+				if (halProxSensorCovered()) { //Check Waterlevel
+					//turn machine on
+					logger(V_BREW, "Turn machine on\n");
+					halRelaisOn(RELAIS_HEAT);
+					halRelaisOff(RELAIS_PUMP);
+					halRelaisOn(RELAIS_POWER);
+					sleep(1);
+					if (halIsHeating()) { //check if System starts to heat when turned on
+						logger(V_BREW, "Change state: INITALHEATING\n");
+						state = STATE_INITALHEATING;
+					} else {
+						logger(V_BREW, "Change state: IDLE\n");
+						state = STATE_IDLE;
+					}
+				} else {
+					logger(V_BREW, "Change state: ERROR\n");
+					state = STATE_ERROR;
+				}
+				break;
+			}
+			break;
+		case STATE_INITALHEATING:
+			pause();
+			switch (getSigValue()) {
+			case SigInt1Rls:
+				//Turn machine off again
+				halRelaisOff(RELAIS_HEAT);
+				halRelaisOff(RELAIS_PUMP);
+				halRelaisOff(RELAIS_POWER);
+				logger(V_BREW, "Change state: OFF\n");
+				state = STATE_OFF;
+				break;
+			case SigPressOpn:
+				//Inital heating finished
+				logger(V_BREW, "Change state: IDLE\n");
+				state = STATE_IDLE;
+				break;
+			}
+			break;
+		case STATE_HEATING:
+			pause();
+			switch(getSigValue()){
+			case SigInt1Rls:
+				//Turn machine off again
+				halRelaisOff(RELAIS_HEAT);
+				halRelaisOff(RELAIS_PUMP);
+				halRelaisOff(RELAIS_POWER);
+				logger(V_BREW, "Change state: OFF\n");
+				state = STATE_OFF;
+				break;
+			case SigPressOpn:
+				logger(V_BREW, "Change state: IDLE\n");
+				state = STATE_IDLE;
+				break;
+			case SigInt0Psh:
+				//start to brew a delicious coffee
+				logger(V_BREW, "Change state: BREW\n");
+				state = STATE_BREW;
+				break;
+			case SigBrewOn:
+				//someone brews manually
+				logger(V_BREW, "Change state: BREWMANUAL\n");
+				state = STATE_BREWMANUAL;
+				break;
+			}
+			break;
+		case STATE_IDLE:
+			pause();
+			switch(getSigValue()){
+			case SigInt1Rls:
+				//Turn machine off again
+				halRelaisOff(RELAIS_HEAT);
+				halRelaisOff(RELAIS_PUMP);
+				halRelaisOff(RELAIS_POWER);
+				logger(V_BREW, "Change state: OFF\n");
+				state = STATE_OFF;
+				break;
+			case SigPressCls:
+				logger(V_BREW, "Change state: HEATING\n");
+				state = STATE_HEATING;
+				break;
+			case SigInt0Psh:
+				//start to brew a delicious coffee
+				logger(V_BREW, "Change state: BREW\n");
+				state = STATE_BREW;
+				break;
+			case SigBrewOn:
+				//someone brews manually
+				logger(V_BREW, "Change state: BREWMANUAL\n");
+				state = STATE_BREWMANUAL;
+				break;
+			}
+			break;
+		case STATE_BREW:
+			//Preinfusion
+			logger(V_BREW, "Starting preinfusion...\n");
+			halRelaisOn(RELAIS_PUMP);
+			brewTime = 0;
+			brewTimer.start();
+			while(brewTime < TIME_PREINFUSION){
+				usleep(100000);
+			}
+			brewTimer.stop();
+			brewTime = 0;
+			halRelaisOff(RELAIS_PUMP);
+			sleep(TIME_SOAK/1000);
+			logger(V_BREW, "Starting infusion...\n");
+			halResetFlow();
+			halRelaisOn(RELAIS_PUMP);
+			brewTimer.start();
+			while(brewTime < TIME_INFUSION && halGetFlow() < TIME_DBLESPRESSO){
+				usleep(100000);
+			}
+			halRelaisOff(RELAIS_PUMP);
+			brewTimer.stop();
+			brewTime = 0;
+			logger(V_BREW, "Finish brewing\n");
+			logger(V_BREW, "Change state: IDLE\n");
+			state = STATE_IDLE;
+			break;
+		case STATE_BREWMANUAL:
+			pause();
+			break;
+		case STATE_CLEANING:
+			pause();
+			break;
+		case STATE_ERROR:
+			pause();
+			break;
+		}
+	}
+	pthread_exit(EXIT_SUCCESS);
+}
+/*
+ * Saves value delivered by the signal
+ */
+void coffeeHandler(int signum, siginfo_t *siginfo, void *context) {
+	sigval_t sigVal = (siginfo->si_value);
+	sigValue = sigVal.sival_int;
+	logger(V_BREW, "CoffeeHandler called with %d\n", sigValue);
+}
+/*
+ * returns the Signal value from the last received Signal and clears the variable
+ */
+int getSigValue(void){
+	int tmp = sigValue;
+	sigValue = 0;
+	return tmp;
+}
+/*
+ * Counter for the brew time
+ * refresh every 200ms
+ */
+void brewTimeHandler (void){
+	brewTime += 200;
+}

+ 34 - 0
CoffeeCode/coffee.h

@@ -0,0 +1,34 @@
+/*
+ * coffee.h
+ *
+ *  Created on: Sep 25, 2017
+ *      Author: sebastian
+ */
+
+#ifndef COFFEE_H_
+#define COFFEE_H_
+
+
+
+//define status
+#define	STATE_OFF	0
+#define	STATE_HEATING	1
+#define STATE_INITALHEATING	2
+#define STATE_IDLE	3
+#define STATE_BREW	4
+#define STATE_BREWMANUAL	5
+#define STATE_CLEANING	6
+#define STATE_ERROR	7
+
+#define TIME_PREINFUSION	3000 //Preinfusion time in ms
+#define TIME_SOAK	3000//Time between preinfusion and infusion in ms
+#define TIME_INFUSION 25000	//Infusion time in ms
+#define TIME_DBLESPRESSO	25.0	//Size of a double espresso in ml
+
+void *coffeeThread(void *threadid);
+
+void coffeeHandler (int signum, siginfo_t *siginfo, void *context);
+int getSigValue(void);
+void brewTimeHandler (void);
+
+#endif /* COFFEE_H_ */