hal.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. * hal.cpp
  3. *
  4. * Created on: Aug 3, 2016
  5. * Author: Philipp Hinz
  6. */
  7. #include <wiringPi.h>
  8. #include <stdlib.h>
  9. #include <errno.h>
  10. #include <string.h>
  11. #include <signal.h>
  12. #include "lcd.h"
  13. #include "hal.h"
  14. #include "global.h"
  15. #include "logger.h"
  16. int flowcnt = 0;
  17. /**
  18. * Initializes HAL
  19. */
  20. void halInit(void) {
  21. if (optPower) {
  22. halRelaisOn(RELAIS_HEAT);
  23. halRelaisOff(RELAIS_PUMP);
  24. halRelaisOn(RELAIS_POWER);
  25. } else {
  26. halRelaisOff(RELAIS_HEAT);
  27. halRelaisOff(RELAIS_PUMP);
  28. halRelaisOff(RELAIS_POWER);
  29. }
  30. pinMode(RELAIS_HEAT, OUTPUT);
  31. pinMode(RELAIS_PUMP, OUTPUT);
  32. pinMode(RELAIS_POWER, OUTPUT);
  33. pinMode(PIN_PRESSURE_CTRL, INPUT);
  34. pinMode(PIN_PROXIMITY_SENSOR, INPUT);
  35. pinMode(PIN_INT0, INPUT);
  36. pinMode(PIN_INT1, INPUT);
  37. pinMode(PIN_FLOW, INPUT);
  38. if (wiringPiISR(PIN_INT0, INT_EDGE_BOTH, &halInt0) < 0) {
  39. logger_error("Unable to setup ISR0: %s\n", strerror(errno));
  40. return;
  41. }
  42. if (wiringPiISR(PIN_INT1, INT_EDGE_BOTH, &halInt1) < 0) {
  43. logger_error("Unable to setup ISR1: %s\n", strerror(errno));
  44. return;
  45. }
  46. if (wiringPiISR(PIN_FLOW, INT_EDGE_FALLING, &halIntFlow) < 0) {
  47. logger_error("Unable to setup ISRFLOW: %s\n", strerror(errno));
  48. return;
  49. }
  50. if(wiringPiISR(PIN_PRESSURE_CTRL, INT_EDGE_BOTH, &halIntPressure) < 0) {
  51. logger_error("Unable to setup ISRPressure: %s\n", strerror(errno));
  52. return;
  53. }
  54. if(wiringPiISR(PIN_PROXIMITY_SENSOR, INT_EDGE_BOTH, &halIntProximity) < 0) {
  55. logger_error("Unable to setup ISRProximity: %s\n", strerror(errno));
  56. return;
  57. }
  58. }
  59. /**
  60. * Switches relais on
  61. * @param relais Relais ID
  62. */
  63. void halRelaisOn(int relais) {
  64. halRelaisSet(relais, LOW);
  65. }
  66. /**
  67. * Switches relais off
  68. * @param relais Relais ID
  69. */
  70. void halRelaisOff(int relais) {
  71. halRelaisSet(relais, HIGH);
  72. }
  73. /**
  74. * Switches relais to state
  75. * @param relais Relais ID
  76. * @param state LOW(0) or HIGH(1)
  77. */
  78. void halRelaisSet(int relais, int state) {
  79. if (state != HIGH && state != LOW)
  80. return;
  81. switch (relais) {
  82. case RELAIS_POWER:
  83. case RELAIS_HEAT:
  84. case RELAIS_PUMP:
  85. digitalWrite(relais, state);
  86. break;
  87. }
  88. }
  89. /**
  90. * Returns the state of the relais relais
  91. * Returns HIGH when Relais is ON
  92. * @param relais Relais ID
  93. */
  94. int halGetRelaisState(int relais) {
  95. switch (relais) {
  96. case RELAIS_POWER:
  97. case RELAIS_HEAT:
  98. case RELAIS_PUMP:
  99. return !digitalRead(relais);
  100. break;
  101. }
  102. return -1;
  103. }
  104. /**
  105. * Interrupt routine for Int0 (bottom button)
  106. */
  107. void halInt0(void) {
  108. logger(V_BASIC, "Int0 triggered\n");
  109. if (halGetInt0()) {
  110. halSendSignal(SigInt0Rls);
  111. } else {
  112. halSendSignal(SigInt0Psh);
  113. }
  114. }
  115. /**
  116. * Interrupt routine for Int1 (top button)
  117. */
  118. void halInt1(void) {
  119. logger(V_BASIC, "Int1 triggered\n");
  120. if (halGetInt1()) {
  121. halSendSignal(SigInt1Rls);
  122. } else {
  123. halSendSignal(SigInt1Psh);
  124. }
  125. }
  126. /**
  127. * Interrupt routine for the flow sensor
  128. * It counts the edgdes and stores the value in flowcnt
  129. */
  130. void halIntFlow(void) {
  131. //halRelaisOff(RELAIS_POWER);
  132. logger(V_BASIC, "IntFlow triggered #%d total: %.2fml\n", flowcnt, halGetFlow());
  133. lcdPosition(lcd, 0, 0);
  134. lcdPrintf(lcd, "ml = %.2f ", halGetFlow());
  135. if (flowcnt == 99) {
  136. halRelaisOff(RELAIS_PUMP);
  137. }
  138. flowcnt++;
  139. }
  140. /**
  141. * Interrupt routine for the pressure control
  142. */
  143. void halIntPressure(void) {
  144. logger(V_BASIC, "IntPressure Control triggered\n");
  145. if (halIsHeating()) {
  146. halSendSignal(SigPressCls);
  147. } else {
  148. halSendSignal(SigPressOpn);
  149. }
  150. }
  151. /**
  152. * Method to handle toggle of the proximity sensor
  153. */
  154. void halIntProximity(void) {
  155. logger(V_BASIC, "IntProximity triggered\n");
  156. if (halProxSensorCovered()) {
  157. halSendSignal(SigProxCvrd);
  158. } else {
  159. halSendSignal(SigProxOpn);
  160. }
  161. }
  162. /**
  163. * Returns total flow trough sensor in ml
  164. */
  165. float halGetFlow(void) {
  166. return flowcnt*FLOW_ML_PULSE;
  167. }
  168. /**
  169. * Resets the Flow counter
  170. */
  171. void halResetFlow(void){
  172. flowcnt = 0;
  173. }
  174. /**
  175. * Reads the status of the Pressure Control
  176. * @return 0 for closed Pressure Control(heating) and 1 for open
  177. */
  178. bool halIsHeating(void) {
  179. if(digitalRead(PIN_PRESSURE_CTRL) == 0){
  180. return true;
  181. } else {
  182. return false;
  183. }
  184. }
  185. /**
  186. * Returns status of the proximity switch
  187. * @return 1 if the proximity switch is covered and 0 if uncovered
  188. */
  189. bool halProxSensorCovered(void){
  190. //for legacy till sensor is installed
  191. /*if(digitalRead(PROXIMITY_SENSOR) == 0){
  192. return false;
  193. } else {
  194. return true;
  195. }*/
  196. return true;
  197. }
  198. /**
  199. * Returns the value of the top button Int0 (low active)
  200. * @return LOW or HIGH
  201. */
  202. int halGetInt0(void){
  203. return digitalRead(PIN_INT0);
  204. }
  205. /**
  206. * Returns the value of the bottom button Int1 (low active)
  207. * @return LOW or HIGH
  208. */
  209. int halGetInt1(void){
  210. return digitalRead(PIN_INT1);
  211. }
  212. /**
  213. * send Signal to coffee thread
  214. * @param val Integer value assigned to signal
  215. */
  216. void halSendSignal(int val){
  217. sigval value = {0};
  218. value.sival_int = (int) val;
  219. if(pthread_sigqueue(thread[THREAD_COFFEE], SIGUSR2, value)) {
  220. logger_error("Failed to queue signal %d %s", val, strerror(errno));
  221. //No Signals reach the state machine anymore...
  222. exit(EXIT_FAILURE);
  223. }
  224. }