FSM thermostat
fsm_thermostat.c
Go to the documentation of this file.
1 
9 /* Includes ------------------------------------------------------------------*/
10 /* Standard C includes */
11 #include <stdlib.h>
12 #include <string.h>
13 
14 /* Project includes */
15 #include "fsm_thermostat.h"
16 #include "port_thermostat.h"
17 #include "port_led.h"
18 #include "port_temp_sensor.h"
19 
20 /* State machine input or transition functions */
21 
28 bool check_heat(fsm_t *p_this)
29 {
30  // Retrieve the FSM structure and get the temperature sensor
31  fsm_thermostat_t *p_fsm = (fsm_thermostat_t *)p_this;
32 
33  // Get the temperature from the sensor
35  {
36  return true;
37  }
38  else
39  {
40  return false;
41  }
42 }
43 
50 bool check_comfort(fsm_t *p_this)
51 {
52  return !check_heat(p_this);
53 }
54 
55 /* State machine output or action functions */
56 
62 void do_thermostat_on(fsm_t *p_this)
63 {
64  // Retrieve the FSM structure and get the LED
65  fsm_thermostat_t *p_fsm = (fsm_thermostat_t *)p_this;
66 
67  // Set the LEDs according to the thermostat status
68  port_led_on(p_fsm->p_led_heat);
70 
71  // Store the event
72  p_fsm->last_events[p_fsm->event_idx] = ACTIVATION;
74  p_fsm->event_idx = (p_fsm->event_idx + 1) % THERMOSTAT_HISTORY;
75 }
76 
82 void do_thermostat_off(fsm_t *p_this)
83 {
84  // Retrieve the FSM structure and get the LED
85  fsm_thermostat_t *p_fsm = (fsm_thermostat_t *)p_this;
86 
87  // Set the LEDs according to the thermostat status
88  port_led_off(p_fsm->p_led_heat);
89  port_led_on(p_fsm->p_led_comfort);
90 
91  // Store the event
92  p_fsm->last_events[p_fsm->event_idx] = DEACTIVATION;
94  p_fsm->event_idx = (p_fsm->event_idx + 1) % THERMOSTAT_HISTORY;
95 }
96 
97 /* Transitions table ---------------------------------------------------------*/
102 fsm_trans_t fsm_trans_thermostat[] = {
105  {-1, NULL, -1, NULL},
106 };
107 
108 uint32_t fsm_thermostat_get_last_time_event(fsm_t *p_this, uint8_t event)
109 {
110  fsm_thermostat_t *p_fsm = (fsm_thermostat_t *)p_this;
111 
112  // Look for the last time the event was detected, if it was detected. If not, return 0
113  for (int i = 0; i < THERMOSTAT_HISTORY; i++)
114  {
115  if (p_fsm->last_events[i] == event)
116  {
117  return p_fsm->last_time_events[i];
118  }
119  }
120  return 0;
121 }
122 
123 uint8_t fsm_thermostat_get_status(fsm_t *p_this)
124 {
125  fsm_thermostat_t *p_fsm = (fsm_thermostat_t *)p_this;
126  return p_fsm->last_events[p_fsm->event_idx];
127 }
128 
129 /* Initialize the FSM */
130 
139 void fsm_thermostat_init(fsm_t *p_this, port_led_hw_t *p_led_heat, port_led_hw_t *p_led_comfort, port_temp_hw_t *p_temp)
140 {
141  fsm_thermostat_t *p_fsm = (fsm_thermostat_t *)(p_this);
142  fsm_init(p_this, fsm_trans_thermostat);
143 
144  // Assign the peripherals to the FSM
145  p_fsm->p_led_heat = p_led_heat;
146  p_fsm->p_led_comfort = p_led_comfort;
147  p_fsm->p_temp_sensor = p_temp;
148 
149  // Initialize the last time the thermostat was activated
150  memset(p_fsm->last_time_events, 0, sizeof(p_fsm->last_time_events));
151 
152  // Initialize the thermostat status
153  memset(p_fsm->last_events, UNKNOWN, sizeof(p_fsm->last_events));
154 
155  // Initialize the event index
156  p_fsm->event_idx = 0;
157 
158  // Initialize the threshold temperature
160 
161  // Initialize the timer to measure the temperature
163 
164  // Initialize the timer
166 
167  // Initialize the peripherals
168  port_led_init(p_led_heat);
169  port_led_init(p_led_comfort);
170  port_temp_sensor_init(p_temp);
171 }
172 
173 /* Create FSM */
174 fsm_t *fsm_thermostat_new(port_led_hw_t *p_led_heat, port_led_hw_t *p_led_comfort, port_temp_hw_t *p_temp)
175 {
176  // Do malloc for the whole FSM structure to reserve memory for the rest of the FSM, although I interpret it as fsm_t which is the first field of the structure so that the FSM library can work with it
177  fsm_t *p_fsm = malloc(sizeof(fsm_thermostat_t));
178 
179  // Initialize the FSM
180  fsm_thermostat_init(p_fsm, p_led_heat, p_led_comfort, p_temp);
181 
182  return p_fsm;
183 }
check_comfort
bool check_comfort(fsm_t *p_this)
Check if the temperature is hot enough to deactivate the thermostat.
Definition: fsm_thermostat.c:50
do_thermostat_on
void do_thermostat_on(fsm_t *p_this)
Turn off the thermostat.
Definition: fsm_thermostat.c:62
fsm_thermostat_t::p_temp_sensor
port_temp_hw_t * p_temp_sensor
Definition: fsm_thermostat.h:58
fsm_thermostat_get_status
uint8_t fsm_thermostat_get_status(fsm_t *p_this)
Gets the thermostat status.
Definition: fsm_thermostat.c:123
UNKNOWN
@ UNKNOWN
Definition: fsm_thermostat.h:44
ACTIVATION
@ ACTIVATION
Definition: fsm_thermostat.h:45
port_temp_sensor_get_temperature
double port_temp_sensor_get_temperature(port_temp_hw_t *pir_sensor)
Gets the temperature in Celsius of the temperature sensor.
Definition: port_temp_sensor.c:37
port_led_init
void port_led_init(port_led_hw_t *p_led)
Initializes the LED.
Definition: port_led.c:41
THERMOSTAT_DEFAULT_THRESHOLD
#define THERMOSTAT_DEFAULT_THRESHOLD
Definition: fsm_thermostat.h:25
port_led_hw_t
Structure to define the HW dependencies of a LED.
Definition: port_led.h:30
fsm_thermostat_t
Structure to define the thermostat FSM.
Definition: fsm_thermostat.h:53
fsm_thermostat_t::threshold_temp_celsius
double threshold_temp_celsius
Definition: fsm_thermostat.h:62
fsm_thermostat_new
fsm_t * fsm_thermostat_new(port_led_hw_t *p_led_heat, port_led_hw_t *p_led_comfort, port_temp_hw_t *p_temp)
Creates a new thermostat FSM.
Definition: fsm_thermostat.c:174
fsm_thermostat_t::last_events
bool last_events[THERMOSTAT_HISTORY]
Definition: fsm_thermostat.h:59
fsm_thermostat.h
Header file for the thermostat FSM.
port_led_off
void port_led_off(port_led_hw_t *p_led)
Turn off the LED.
Definition: port_led.c:31
port_temp_sensor_init
void port_temp_sensor_init(port_temp_hw_t *pir_sensor)
Initializes the temperature sensor.
Definition: port_temp_sensor.c:52
port_temp_sensor.h
Header file for the temperature sensor port layer.
port_led.h
Header file for the LED port layer.
DEACTIVATION
@ DEACTIVATION
Definition: fsm_thermostat.h:46
fsm_thermostat_get_last_time_event
uint32_t fsm_thermostat_get_last_time_event(fsm_t *p_this, uint8_t event)
Gets the last time there was an event in the thermostat. If the event is not found,...
Definition: fsm_thermostat.c:108
port_thermostat_timer_setup
void port_thermostat_timer_setup(fsm_thermostat_t *p_thermostat)
Initializes the timer of the thermostat.
Definition: port_thermostat.c:19
THERMOSTAT_TIMEOUT_SEC
#define THERMOSTAT_TIMEOUT_SEC
Definition: fsm_thermostat.h:23
port_system_get_millis
uint32_t port_system_get_millis(void)
Get the count of the System tick in milliseconds.
Definition: port_system.c:125
do_thermostat_off
void do_thermostat_off(fsm_t *p_this)
Turn on the thermostat.
Definition: fsm_thermostat.c:82
fsm_thermostat_t::timer_period_sec
uint32_t timer_period_sec
Definition: fsm_thermostat.h:63
port_temp_hw_t
Structure to define the HW dependencies of a temperature sensor.
Definition: port_temp_sensor.h:31
fsm_thermostat_t::p_led_comfort
port_led_hw_t * p_led_comfort
Definition: fsm_thermostat.h:57
port_thermostat.h
Header file for the thermostat system port layer.
fsm_trans_thermostat
fsm_trans_t fsm_trans_thermostat[]
Transitions table for the thermostat.
Definition: fsm_thermostat.c:102
fsm_thermostat_init
void fsm_thermostat_init(fsm_t *p_this, port_led_hw_t *p_led_heat, port_led_hw_t *p_led_comfort, port_temp_hw_t *p_temp)
Initialize the thermostat FSM.
Definition: fsm_thermostat.c:139
THERMOSTAT_HISTORY
#define THERMOSTAT_HISTORY
Definition: fsm_thermostat.h:24
fsm_thermostat_t::last_time_events
uint32_t last_time_events[THERMOSTAT_HISTORY]
Definition: fsm_thermostat.h:60
fsm_thermostat_t::event_idx
uint8_t event_idx
Definition: fsm_thermostat.h:61
port_led_on
void port_led_on(port_led_hw_t *p_led)
Turn on the LED.
Definition: port_led.c:26
fsm_thermostat_t::p_led_heat
port_led_hw_t * p_led_heat
Definition: fsm_thermostat.h:56
check_heat
bool check_heat(fsm_t *p_this)
Check if the temperature is cold enough to activate the thermostat.
Definition: fsm_thermostat.c:28
THERMOSTAT_ON
@ THERMOSTAT_ON
Definition: fsm_thermostat.h:35
THERMOSTAT_OFF
@ THERMOSTAT_OFF
Definition: fsm_thermostat.h:34