123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- /*
- * 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;
- }
|