-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.c
302 lines (260 loc) · 10 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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
/*
* File: main.c
* Author: Guillaume Fournier-Mayer
*
* The main module that holds all the logic that is needed to
* Created on 8. Juli 2020, 15:02
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include "debug.h"
#include "mpu6050.h"
#include "timer.h"
#include "led.h"
#include "types.h"
#include "config.h"
#define DEBUG 0
// #############################################################################
float a_x = 0, a_y = 0, a_z = 1;
#define MOVEMENT (a_x >= X_THRESHOLD) || (a_x <= -X_THRESHOLD) || (a_y >= Y_THRESHOLD) || (a_y <= -Y_THRESHOLD) || (a_z >= Z_UP_THRESHOLD) || (a_z <= Z_DOWN_THRESHOLD)
#define UP (a_z >= Z_UP_THRESHOLD)
#define DOWN (a_z <= -Z_DOWN_THRESHOLD)
#define LEFT (a_y <= LEFT_TRESHOLD)
#define RIGHT (a_y >= RIGHT_TRESHOLD)
#define FORWARD (a_x <= FORWARD_TRESHOLD)
#define BACKWARD (a_x >= BACKWARD_TRESHOLD)
bool lock;
State state;
Config config;
uint8_t setup_index = SETUP_DEFAULT_INDEX;
/**
* An Array that holds all the setup colors presets
*/
const Color setup_colors[SETUP_MAX_INDEX + 1] = {
{.red = DELAY_1_COLOR_RED, .green = DELAY_1_COLOR_GREEN, .blue = DELAY_1_COLOR_BLUE},
{.red = DELAY_2_COLOR_RED, .green = DELAY_2_COLOR_GREEN, .blue = DELAY_2_COLOR_BLUE},
{.red = DELAY_3_COLOR_RED, .green = DELAY_3_COLOR_GREEN, .blue = DELAY_3_COLOR_BLUE},
};
/**
* An Array that holds all the lantern switch-off delays
*/
const Delay lantern_delays[SETUP_MAX_INDEX + 1] = {
{.minutes = DELAY_WALK_1_MINUTES, .hours = DELAY_WALK_1_HOURS},
{.minutes = DELAY_WALK_2_MINUTES, .hours = DELAY_WALK_2_HOURS},
{.minutes = DELAY_WALK_3_MINUTES, .hours = DELAY_WALK_3_HOURS},
};
/**
* An Array that holds all the decoration switch-off delays
*/
const Delay deco_delays[SETUP_MAX_INDEX + 1] = {
{.minutes = DELAY_DECO_1_MINUTES, .hours = DELAY_DECO_1_HOURS},
{.minutes = DELAY_DECO_2_MINUTES, .hours = DELAY_DECO_2_HOURS},
{.minutes = DELAY_DECO_3_MINUTES, .hours = DELAY_DECO_3_HOURS},
};
/**
* An Array that holds all the led color presets
*/
const Color led_colors[SETUP_MAX_INDEX + 1] = {
{.red = COLOR_1_RED, .green = COLOR_1_GREEN, .blue = COLOR_1_BLUE},
{.red = COLOR_2_RED, .green = COLOR_2_GREEN, .blue = COLOR_2_BLUE},
{.red = COLOR_3_RED, .green = COLOR_3_GREEN, .blue = COLOR_3_BLUE},
};
// #############################################################################
/*
* Initialize Setup with default values
*/
void init_config() {
config.brightness = BRIGHTNESS_DEFAULT;
config.color = led_colors[CONFIG_INDEX_DEFAULT];
config.lantern_delay = lantern_delays[CONFIG_INDEX_DEFAULT];
config.deco_delay = deco_delays[CONFIG_INDEX_DEFAULT];
}
/*
* Initialize the sleep mode and actiavte external interrupt INT0
*/
void init_sleep_mode() {
set_sleep_mode(SLEEP_MODE_STANDBY);
// interrupt on rising edge of INT0
EICRA |= (1 << ISC01) | (1 << ISC00);
EIMSK |= (1 << INT0);
}
/**
* Sets the Cpu to sleep while eliminating any race conditions
*/
void sleep() {
cli();
EIMSK |= (1 << INT0);
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
}
/*
* Initialize all needed modules
*/
void setup() {
#if DEBUG
usart_init();
#endif
mpu6050_init();
led_init();
init_sleep_mode();
lock = false;
state = LED_OFF;
init_config();
sei();
}
/**
* The external interrupt wakeup ISR
*/
ISR(INT0_vect) {
//Deactivate INT0 external interrupt
EIMSK &= ~(1 << INT0);
}
/*
* The main function
*/
int main(int argc, char** argv) {
setup();
while (true) {
// Get new acceldata
mpu6050_get_accel_data(&a_x, &a_y, &a_z);
debug_print("Lock: %dtState: %d\r\n", lock, state);
//Check if Lock can be reseted
if (lock && a_x <= X_THRESHOLD && a_x >= -X_THRESHOLD && a_y <= Y_THRESHOLD && a_y >= -Y_THRESHOLD && a_z <= Z_UP_THRESHOLD && a_z >= Z_DOWN_THRESHOLD) {
lock = false;
led_blink_stop();
} else {
//Reactivate external interrupt INT0
EIMSK |= (1 << INT0);
}
if (!lock) {
switch (state) {
case LED_OFF:
{
if (FORWARD) { // Enter dealy setup menu
lock = true;
led_on(BRIGHTNESS_DEFAULT, setup_colors[SETUP_DEFAULT_INDEX]);
led_blink_start(LED_BLINK);
config.lantern_delay = lantern_delays[SETUP_DEFAULT_INDEX];
config.deco_delay = deco_delays[SETUP_DEFAULT_INDEX];
state = SETUP_DELAY;
} else if (UP) { // Enter Lantern Mode
lock = true;
timer_clock_start();
led_on(config.brightness, config.color);
state = LED_ON_LANTERN;
} else if (BACKWARD) { // Enter Decoration mode
lock = true;
timer_clock_start();
led_on(config.brightness, config.color);
state = LED_ON_DECORATION;
}
sleep();
break;
}
case LED_ON_LANTERN:
{
if (MOVEMENT) { //Reset Timer if there is any movement
timer_clock_reset();
}
//Switch-off if times up or if switch-off movement has benen triggeredtime decay
if (DOWN || (timer_minutes >= config.lantern_delay.minutes && timer_hours >= config.lantern_delay.hours)) {
lock = true;
timer_clock_stop();
timer_clock_reset();
led_off();
state = LED_OFF;
}
debug_print("Clock: %d:%d:%d\r\n", timer_hours, timer_minutes, timer_seconds);
break;
}
case LED_ON_DECORATION:
{
//Switch-off if times up or if switch-off movement has benen triggeredtime decay
if (DOWN || (timer_minutes >= config.deco_delay.minutes && timer_hours >= config.deco_delay.hours)) {
lock = true;
timer_clock_stop();
timer_clock_reset();
led_off();
state = LED_OFF;
}
debug_print("Clock: %d:%d:%d\r\n", timer_hours, timer_minutes, timer_seconds);
break;
}
case SETUP_DELAY:
{
if (FORWARD) { // Enter color setup menu
lock = true;
setup_index = SETUP_DEFAULT_INDEX;
led_on(config.brightness, led_colors[setup_index]);
led_blink_start(LED_BLINK);
state = SETUP_COLOR;
} else if (RIGHT && setup_index < SETUP_MAX_INDEX) {
// Get a smaller delay value by decrementing the index
lock = true;
setup_index++;
config.lantern_delay = lantern_delays[setup_index];
config.deco_delay = deco_delays[setup_index];
led_on(DELAY_BRIGHTNESS, setup_colors[setup_index]);
} else if (LEFT && setup_index > 0) {
// Get a bigger delay value by incrementing the index
lock = true;
setup_index--;
config.lantern_delay = lantern_delays[setup_index];
config.deco_delay = deco_delays[setup_index];
led_on(DELAY_BRIGHTNESS, setup_colors[setup_index]);
}
break;
}
case SETUP_COLOR:
{
if (FORWARD) { // Enter brightness setup menu
lock = true;
config.color = led_colors[setup_index];
led_blink_start(LED_BLINK);
setup_index = SETUP_DEFAULT_INDEX;
state = SETUP_BRIGHTNESS;
} else if (RIGHT && setup_index < SETUP_MAX_INDEX) {
// Get the next color by incrementing the index
lock = true;
setup_index++;
led_on(config.brightness, led_colors[setup_index]);
} else if (LEFT && setup_index > 0) {
// Get the previous color by decrementing the index
lock = true;
setup_index--;
led_on(config.brightness, led_colors[setup_index]);
}
break;
}
case SETUP_BRIGHTNESS:
{
if (FORWARD) { // Setup is completed. Swtich-off!
lock = true;
timer_clock_stop();
timer_clock_reset();
led_off();
state = LED_OFF;
} else if (RIGHT && config.brightness < BRIGHTNESS_MAX) {
// Get a higher brightness value by incrementing the index
lock = true;
config.brightness += BRIGHTNESS_STEP;
led_on(config.brightness, config.color);
} else if (LEFT && config.brightness > BRIGHTNESS_STEP) {
// Get a deeper brightness value by decrementing the index
lock = true;
config.brightness -= BRIGHTNESS_STEP;
led_on(config.brightness, config.color);
}
break;
}
}
}
}
return (EXIT_SUCCESS);
}