-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.c
204 lines (181 loc) · 5.38 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#include "main.h"
// Global Variables
unsigned int DATE_REGISTER = 0x0;
unsigned int TIME_REGISTER = 0x0;
DateNode *dateList = NULL;
TimeNode *timeList = NULL;
unsigned int time = 0;
unsigned short booleanFlagSet = 0;
unsigned short TICKS = 1000;
short minimum_limit = 20; // Minimum temperature limit
short maximum_limit = 25; // Maximum temperature limit
// Local Variables
unsigned int darkCounter = 0;
unsigned int sunCounter = 0;
short temperature;
int main(void) {
// Setup all the pins and configs of all the components needed
config();
// Start initial View
view_select_date();
// reset the darkCounter and sunCounter
darkCounter = sunCounter = 0;
// Setup the 7 days so that we know we don't run out of memory for them
for (int i = 0; i < 7; i++)
Insert_First(&dateList, Create_DateNode(&dateList, &timeList, DATE_REGISTER));
// Read the initial temperature so the first value isn't 0'c
temperature = Read_Temp();
while(1){
// Check for a time update
if (Get_Boolean_Flag(NEW_SECOND) == 1)
update_every_second();
else if (Get_Boolean_Flag(NEW_MINUTE) == 1)
update_every_minute();
else if (Get_Boolean_Flag(NEW_HOUR) == 1)
update_every_hour();
else if (Get_Boolean_Flag(NEW_DAY) == 1)
update_every_day();
else if (Get_Boolean_Flag(NEW_MONTH) == 1)
update_every_month();
else if (Get_Boolean_Flag(NEW_YEAR) == 1)
update_every_year();
// Check for keypress associated with menu
menu_selection();
}
}
/**
* Function to handle everything that must happen every second
*/
void update_every_second(){
// Update time once a second
count_time();
// Read the light
Read_Light();
// if 8 hours of darkness in the day has passed
if ((darkCounter / 3600) >= 8)
Sunlamp();
// Stuff to happen every "real" second
if (time >= 1000){
temperature = Read_Temp();
Alarm();
// If we are faster than one cycle we need to get back the proper time
time %= 1000;
}
// Set the boolean NEW_SECOND to false
Set_Boolean_Flag(0, NEW_SECOND);
}
/**
* Function to handle everything that must happen every minute
*/
void update_every_minute(){
unsigned int save = 0x0;
// Set the hours and minutes aswell as the temperature to the save variable
// Bytes correspond to -> 0xhhmmTTTT
Set_2_Bytes(&save, Get_2_Bytes(&TIME_REGISTER, HOURS), DAY);
Set_2_Bytes(&save, Get_2_Bytes(&TIME_REGISTER, MINUTES), MONTH);
Set_4_Signed_Bytes(&save, temperature, 1);
// Add a new temperature measure to the list
Put_First(&timeList, Create_TimeNode(&timeList, save));
// Display the sun degree's on display
Display_Sundegree_2_Display(darkCounter, sunCounter);
// Set the boolean NEW_MINUTE to false
Set_Boolean_Flag(0, NEW_MINUTE);
}
/**
* Function to handle everything that must happen every hour
*/
void update_every_hour(){
// Set the boolean NEW_HOUR to false
Set_Boolean_Flag(0, NEW_HOUR);
}
/**
* Function to handle everything that must happen every day
*/
void update_every_day(){
// Reset the Counters to start counting for the new day
darkCounter = sunCounter = 0;
// Set the timelist with temperatures into the datelist (Day)
Insert_First(&dateList, Create_DateNode(&dateList, &timeList, DATE_REGISTER));
// Display the everyday records if we are on that view
if (Get_Boolean_Flag(VIEW_RECORDS) == 1)
Display_Everyday_Record();
// Set the boolean NEW_DAY to false
Set_Boolean_Flag(0, NEW_DAY);
}
/**
* Function to handle everything that must happen every month
*/
void update_every_month(){
// Set the boolean NEW_MONTH to false
Set_Boolean_Flag(0, NEW_MONTH);
}
/**
* Function to handle everything that must happen every year
*/
void update_every_year(){
// Set the boolean NEW_YEAR to false
Set_Boolean_Flag(0, NEW_YEAR);
}
/**
* Setup all the initial settings such as pins
* @return void
*/
void config() {
SystemInit();
SysTick_Config((int) (SystemCoreClock * 0.001)); // 1 ms Initiate Pulse (0.001)
Init_Keypad();
Init_Display();
Init_Temp();
Init_LightSensor();
Init_Servo_Motor();
Init_Light_LED();
}
/**
* a function to delay [x] ns,
* not exact science without checking with electric tools
* @param value: The amount of ns to delay
* @return void
*/
void Delay(int value) {
for (int i = 0; i < value; i++)
__asm("nop");
// asm() Doesn't work in newer versions of c, c99 does not
// support asm(); command
}
/**
* An interrupt that activates every ms
* @return void
*/
void SysTick_Handler() {
time++;
// Placed in SysTick_Handler because of the speed(precision) needed...
if ((time % TICKS) == 0){
// Increment the seconds
Increment_2_Bytes(&TIME_REGISTER, SECONDS);
// We have a new second
Set_Boolean_Flag(1, NEW_SECOND);
// Increment corresponding counter dependent on if we have light or not
if (Get_Boolean_Flag(NO_LIGHT) == 1)
darkCounter++;
else
sunCounter++;
}
}
/**
* Set a specific boolean flag (Bit)
* @param flag: the bit that needs to be set
* @return void
*/
void Set_Boolean_Flag(char x, FLAG flag){
booleanFlagSet = (booleanFlagSet & ~(1 << flag)) | (x << flag);
}
/**
* Get a specific boolean flag (Bit)
* @param flag: the bit that needs to be retrieved
* @return the bit's value
*/
char Get_Boolean_Flag(FLAG flag){
if (booleanFlagSet & (1 << flag))
return 1;
return 0;
}