coffee.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * coffee.cpp
  3. *
  4. * Created on: Sep 25, 2017
  5. * Author: sebastian
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <errno.h>
  11. #include <stdint.h>
  12. #include <wiringPi.h>
  13. #include <pthread.h>
  14. #include <unistd.h>
  15. #include <iostream>
  16. #include <csignal>
  17. #include <time.h>
  18. #include "coffee.h"
  19. #include "hal.h"
  20. #include "logger.h"
  21. #include "timer.h"
  22. int state;
  23. int sigValue;
  24. int brewTime; //Brew time in ms
  25. timer brewTimer(&brewTimeHandler);
  26. void *coffeeThread(void *threadid) {
  27. logger(V_BREW, "Initializing coffee thread...\n");
  28. //installing new Signal handler for coffeethread
  29. struct sigaction action;
  30. sigemptyset(&action.sa_mask);
  31. action.sa_flags = SA_SIGINFO;
  32. action.sa_sigaction = coffeeHandler;
  33. sigaction(SIGUSR2, &action, NULL);
  34. brewTimer.setDivider(4);
  35. brewTimer.stop();
  36. brewTime = 0;
  37. state = STATE_OFF;
  38. logger(V_BREW, "Determining inital state\n");
  39. //determine inital state
  40. if (halGetRelaisState(RELAIS_POWER) && halGetRelaisState(RELAIS_HEAT) && !halGetRelaisState(RELAIS_PUMP)) {
  41. //wait for heat relais to switch
  42. sleep(1);
  43. if (halIsHeating()) { //Heating is on
  44. logger(V_BREW, "Change state: INITALHEATING\n");
  45. state = STATE_INITALHEATING;
  46. } else {
  47. logger(V_BREW, "Change state: IDLE\n");
  48. state = STATE_IDLE;
  49. }
  50. } else if (halGetRelaisState(RELAIS_PUMP)) {
  51. logger_error("Whoops, why is the pump running...\n");
  52. state = STATE_ERROR;
  53. }
  54. logger(V_BREW, "Start Coffee FSM\n");
  55. //begin FSM
  56. while(1){
  57. switch(state){
  58. case STATE_OFF:
  59. pause();
  60. if (getSigValue() == SigInt0Rls) {
  61. if (halProxSensorCovered()) { //Check Waterlevel
  62. //turn machine on
  63. logger(V_BREW, "Turn machine on\n");
  64. halRelaisOn(RELAIS_HEAT);
  65. halRelaisOff(RELAIS_PUMP);
  66. halRelaisOn(RELAIS_POWER);
  67. sleep(1);
  68. if (halIsHeating()) { //check if System starts to heat when turned on
  69. logger(V_BREW, "Change state: INITALHEATING\n");
  70. state = STATE_INITALHEATING;
  71. } else {
  72. logger(V_BREW, "Change state: IDLE\n");
  73. state = STATE_IDLE;
  74. }
  75. } else {
  76. logger(V_BREW, "Change state: ERROR\n");
  77. state = STATE_ERROR;
  78. }
  79. break;
  80. }
  81. break;
  82. case STATE_INITALHEATING:
  83. pause();
  84. switch (getSigValue()) {
  85. case SigInt1Rls:
  86. //Turn machine off again
  87. halRelaisOff(RELAIS_HEAT);
  88. halRelaisOff(RELAIS_PUMP);
  89. halRelaisOff(RELAIS_POWER);
  90. logger(V_BREW, "Change state: OFF\n");
  91. state = STATE_OFF;
  92. break;
  93. case SigPressOpn:
  94. //Inital heating finished
  95. logger(V_BREW, "Change state: IDLE\n");
  96. state = STATE_IDLE;
  97. break;
  98. }
  99. break;
  100. case STATE_HEATING:
  101. pause();
  102. switch(getSigValue()){
  103. case SigInt1Rls:
  104. //Turn machine off again
  105. halRelaisOff(RELAIS_HEAT);
  106. halRelaisOff(RELAIS_PUMP);
  107. halRelaisOff(RELAIS_POWER);
  108. logger(V_BREW, "Change state: OFF\n");
  109. state = STATE_OFF;
  110. break;
  111. case SigPressOpn:
  112. logger(V_BREW, "Change state: IDLE\n");
  113. state = STATE_IDLE;
  114. break;
  115. case SigInt0Psh:
  116. //start to brew a delicious coffee
  117. logger(V_BREW, "Change state: BREW\n");
  118. state = STATE_BREW;
  119. break;
  120. case SigBrewOn:
  121. //someone brews manually
  122. logger(V_BREW, "Change state: BREWMANUAL\n");
  123. state = STATE_BREWMANUAL;
  124. break;
  125. }
  126. break;
  127. case STATE_IDLE:
  128. pause();
  129. switch(getSigValue()){
  130. case SigInt1Rls:
  131. //Turn machine off again
  132. halRelaisOff(RELAIS_HEAT);
  133. halRelaisOff(RELAIS_PUMP);
  134. halRelaisOff(RELAIS_POWER);
  135. logger(V_BREW, "Change state: OFF\n");
  136. state = STATE_OFF;
  137. break;
  138. case SigPressCls:
  139. logger(V_BREW, "Change state: HEATING\n");
  140. state = STATE_HEATING;
  141. break;
  142. case SigInt0Psh:
  143. //start to brew a delicious coffee
  144. logger(V_BREW, "Change state: BREW\n");
  145. state = STATE_BREW;
  146. break;
  147. case SigBrewOn:
  148. //someone brews manually
  149. logger(V_BREW, "Change state: BREWMANUAL\n");
  150. state = STATE_BREWMANUAL;
  151. break;
  152. }
  153. break;
  154. case STATE_BREW:
  155. //Preinfusion
  156. logger(V_BREW, "Starting preinfusion...\n");
  157. halRelaisOn(RELAIS_PUMP);
  158. brewTime = 0;
  159. brewTimer.start();
  160. while(brewTime < TIME_PREINFUSION){
  161. usleep(100000);
  162. }
  163. brewTimer.stop();
  164. brewTime = 0;
  165. halRelaisOff(RELAIS_PUMP);
  166. sleep(TIME_SOAK/1000);
  167. logger(V_BREW, "Starting infusion...\n");
  168. halResetFlow();
  169. halRelaisOn(RELAIS_PUMP);
  170. brewTimer.start();
  171. while(brewTime < TIME_INFUSION && halGetFlow() < TIME_DBLESPRESSO){
  172. usleep(100000);
  173. }
  174. halRelaisOff(RELAIS_PUMP);
  175. brewTimer.stop();
  176. brewTime = 0;
  177. logger(V_BREW, "Finish brewing\n");
  178. logger(V_BREW, "Change state: IDLE\n");
  179. state = STATE_IDLE;
  180. break;
  181. case STATE_BREWMANUAL:
  182. pause();
  183. break;
  184. case STATE_CLEANING:
  185. pause();
  186. break;
  187. case STATE_ERROR:
  188. pause();
  189. break;
  190. }
  191. }
  192. pthread_exit(EXIT_SUCCESS);
  193. }
  194. /*
  195. * Saves value delivered by the signal
  196. */
  197. void coffeeHandler(int signum, siginfo_t *siginfo, void *context) {
  198. sigval_t sigVal = (siginfo->si_value);
  199. sigValue = sigVal.sival_int;
  200. logger(V_BREW, "CoffeeHandler called with %d\n", sigValue);
  201. }
  202. /*
  203. * returns the Signal value from the last received Signal and clears the variable
  204. */
  205. int getSigValue(void){
  206. int tmp = sigValue;
  207. sigValue = 0;
  208. return tmp;
  209. }
  210. /*
  211. * Counter for the brew time
  212. * refresh every 200ms
  213. */
  214. void brewTimeHandler (void){
  215. brewTime += 200;
  216. }