Microprocessor and peripheral 2 assignments for AUTH
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

207 lines
4.8 KiB

  1. /*!
  2. * \file
  3. * main.c
  4. * \brief
  5. * Main application file
  6. *
  7. * Author: Christos Choutouridis AEM: 8997
  8. * email : <cchoutou@ece.auth.gr>
  9. */
  10. #include <hal.h>
  11. #include "thermostat.h"
  12. #include "console.h"
  13. /*
  14. * Zero initialized globals
  15. */
  16. app_data_t app_data;
  17. state_en state;
  18. // Value initialized globals
  19. settings_t _Init_settings(settings);
  20. /*
  21. * helper api
  22. */
  23. float_t temp_get_current (void) {
  24. return (app_data.cur) ? app_data.T[app_data.cur-1] : app_data.T[MEASUREMENTS-1];
  25. }
  26. /*!
  27. * Control functionality
  28. * Handles:
  29. * * Sensor reading
  30. * * Temp averaging
  31. * * Output calculation
  32. * \note Non-blocking
  33. */
  34. void control (void) {
  35. static time_t sample =0;
  36. time_t now = time(0); // get time
  37. // Proximity
  38. if (proximity(&prox) < settings.Pset)
  39. app_data.flag_proximity = 1;
  40. else if (proximity(&prox) < settings.Pset + settings.Physt)
  41. ;
  42. else
  43. app_data.flag_proximity = 0;
  44. // Temperature calculation
  45. if (now - sample >= MEAS_INTERVAL) {
  46. sample = now;
  47. app_data.T[app_data.cur] = temp_read();
  48. if (++app_data.cur >= MEASUREMENTS) {
  49. app_data.cur =0;
  50. float_t f =0;
  51. for (int i=0 ; i<MEASUREMENTS ; ++i) {
  52. f += app_data.T[i];
  53. }
  54. app_data.Tav = f / MEASUREMENTS;
  55. app_data.signal_cycle = 1;
  56. app_data.flag_init = 0;
  57. }
  58. }
  59. // Output handling
  60. if (!app_data.flag_init) {
  61. switch (settings.mode) {
  62. case HEATING: {
  63. if (app_data.Tav <= settings.Tset)
  64. app_data.flag_output = 1;
  65. else if (app_data.Tav < settings.Tset + settings.Thyst)
  66. ;
  67. else
  68. app_data.flag_output = 0;
  69. }
  70. break;
  71. case COOLING: {
  72. if (app_data.Tav <= settings.Tset - settings.Thyst)
  73. app_data.flag_output = 0;
  74. else if (app_data.Tav < settings.Tset)
  75. ;
  76. else
  77. app_data.flag_output = 1;
  78. }
  79. break;
  80. }
  81. }
  82. }
  83. /*!
  84. * Display functionality
  85. * Implement a state machine for lcd display
  86. * \note Non-blocking
  87. */
  88. void display (void) {
  89. static time_t mark =0;
  90. char line1[18];
  91. char line2[18];
  92. time_t now = time(0);
  93. switch (state) {
  94. case ST_INIT:
  95. sprintf(line1, "\fInitializing %c ", (time(0)%2) ? '*' : ' ');
  96. sprintf(line2, "\n ");
  97. // escapes
  98. if (app_data.flag_proximity)
  99. state = ST_USER;
  100. else if (app_data.signal_cycle) {
  101. app_data.signal_cycle =0;
  102. mark = now;
  103. state = ST_AVERAGE;
  104. }
  105. break;
  106. case ST_COUNT:
  107. sprintf(line1, "\fMeasuring %c ", (time(0)%2) ? '*' : ' ');
  108. sprintf(line2, "\n%s: %s ",
  109. (settings.mode == HEATING) ? "Heating" : "Cooling",
  110. (app_data.flag_output) ? "On " : "Off"
  111. );
  112. // escapes
  113. if (app_data.flag_proximity)
  114. state = ST_USER;
  115. else if (app_data.signal_cycle) {
  116. app_data.signal_cycle =0;
  117. mark = now;
  118. state = ST_AVERAGE;
  119. }
  120. break;
  121. case ST_AVERAGE:
  122. sprintf(line1, "\fTav=%4.1f ", app_data.Tav);
  123. sprintf(line2, "\n%s: %s ",
  124. (settings.mode == HEATING) ? "Heating" : "Cooling",
  125. (app_data.flag_output) ? "On " : "Off"
  126. );
  127. // escapes
  128. if (app_data.flag_proximity)
  129. state = ST_USER;
  130. else if (now - mark >= UI_AVERAGE_TIME)
  131. state = ST_COUNT;
  132. break;
  133. case ST_USER:
  134. sprintf(line1, "\fTav=%4.1f T=%4.1f", app_data.Tav, temp_get_current());
  135. sprintf(line2, "\n%s: %s ",
  136. (settings.mode == HEATING) ? "Heating" : "Cooling",
  137. (app_data.flag_output) ? "On " : "Off"
  138. );
  139. // escapes
  140. if (!app_data.flag_proximity)
  141. state = ST_COUNT;
  142. break;
  143. }
  144. lcd_puts(line1);
  145. lcd_puts(line2);
  146. }
  147. /*!
  148. * Set outputs
  149. * \note Non-blocking
  150. */
  151. void outputs (void) {
  152. static uint8_t pr_output =0;
  153. if (app_data.flag_init)
  154. return;
  155. led_green(app_data.flag_output && settings.mode == COOLING);
  156. led_red (app_data.flag_output && settings.mode == HEATING);
  157. if (app_data.flag_output != pr_output) {
  158. relay(app_data.flag_output);
  159. pr_output = app_data.flag_output;
  160. }
  161. }
  162. /*
  163. * Main loop
  164. */
  165. int main(void) {
  166. hal_hw_init ();
  167. lcd_init ();
  168. proximity_init(&prox);
  169. temp_init (TEMP_11_BIT);
  170. lcd_enable(1);
  171. app_data.flag_init = 1;
  172. while (1) {
  173. control ();
  174. display ();
  175. outputs();
  176. console ();
  177. HAL_Delay(10);
  178. }
  179. }