-
Notifications
You must be signed in to change notification settings - Fork 0
/
sunlightAlarmClock.c
155 lines (132 loc) · 3.37 KB
/
sunlightAlarmClock.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
/* Sunrise Alarm Clock */
//Including required libraries
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "USART.h"
#include "pinDefines.h"
//Defining buzzer related ports
#define ABuzz PB0
#define ABuzz_DDR DDRB
#define ABuzz_PORT PORTB
//Defining bit changer for buzzer
#define setBit(sfr, bit) (_SFR_BYTE(sfr) |= (1 << bit))
#define clearBit(sfr, bit) (_SFR_BYTE(sfr) &= ~(1 << bit))
#define toggleBit(sfr, bit) (_SFR_BYTE(sfr) ^= (1 << bit))
//Declaring and initializing global variables
volatile int enabled = 1;
int printed = 0;
uint8_t sensitivity;
int delay;
void setSensitivity();
void setDelay();
//Button interrupt
ISR(PCINT2_vect)
{
//Check if it the alarm is on
if (bit_is_set(ABuzz_PORT, ABuzz))
{
//Turn the buzzer off
clearBit(ABuzz_PORT, ABuzz);
//Stop the loop
enabled = 0;
}
else
{
/* I found this to be too annoying personally so I decided to comment it out
//Ask user if to reset sensitivity
printString("Would you like to reset the sensor's sensitivity? (Yes = 1)\n");
uint8_t toReset = getNumber();
receiveByte();
if (toReset == 1) { setSensitivity(); }
//Ask user if to reset delay
printString("Would you like to reset the interrupt's delay? (Yes = 1)\n");
toReset = getNumber();
receiveByte();
if (toReset == 1) { setDelay(); }
*/
//Set and print success message
enabled = 1;
printString("You're all set! Off to sleep!\n");
}
/* Attempted to use delay to skip the second interrupt input but it didn't
work as I hoped. So I decided to embrace it as a feature instead.
*/
//Delay between interrupts to turn off alarm
for(int i = 0; i < delay; i++)
{
_delay_ms(10);
}
//Reset the sensor to run again
printed = 0;
PCIFR |= (1 << PCIF2);
}
int main(void)
{
//Setting up for light sensor
ADMUX |= (1 << REFS0);
ADCSRA |= (1 << ADPS2);
ADCSRA |= (1 << ADEN);
//Setting up the button interrupt
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PD2);
MCUCR |= (1 << PUD);
sei();
//Initializing USART
initUSART();
//Print title to string
printString("---- Sunrise Alarm Clock ------\r\n");
//Declaring variables
uint16_t adcValue;
uint8_t brightness;
//Initialize buzzer
setBit(ABuzz_DDR, ABuzz);
setSensitivity();
setDelay();
//Main Loop
while (1)
{
if (enabled > 0)
{
//Start ADC conversion
ADCSRA |= (1 << ADSC);
//Wait for the conversion to complete
loop_until_bit_is_clear(ADCSRA, ADSC);
//Get the ADC value
adcValue = ADC;
//Map it into a scale of 7
brightness = (adcValue >> 7);
//Check if the light is brighter than the selected sensitivity
if (brightness > sensitivity)
{
if (printed == 0)
{
setBit(ABuzz_PORT, ABuzz);
printString("WAKEUP!!!!\n");
printed = 1;
}
}
}
}
return 0;
}
void setSensitivity()
{
do
{
//Get sensitivity input from user
printString("What sensitivity do you want it to be? (Scale of 1 - 6)\n");
sensitivity = getNumber();
receiveByte();
} while (sensitivity > 6 || sensitivity < 1);
}
void setDelay()
{
do
{
//Get delay input from user
printString("How long do you want the delay to be? (1 = 10ms, Scale of 0 - 200)\n");
delay = getNumber();
receiveByte();
} while (delay > 200 || delay < 0);
}