1 | /*
|
2 | *
|
3 | * Program for a door watch with sleep mode and pin change interrupt wake up
|
4 | * 2024
|
5 | *
|
6 | */
|
7 |
|
8 |
|
9 | #include <stdint.h> // Integer variable
|
10 | #include <avr/io.h> // I/O ports
|
11 | #include <util/delay.h> // Delay function
|
12 | #include <avr/sleep.h> // Sleep mode
|
13 | #include <avr/interrupt.h> // Interrupt implemention
|
14 | #include <avr/wdt.h> // Watchdog timer
|
15 |
|
16 | #ifndef F_CPU // Include guards
|
17 | #define F_CPU 8000000UL // AT90USB162 runs at 8 MHz clock speed - unsigned long
|
18 | #endif // Include guards
|
19 |
|
20 |
|
21 | /***************************************************
|
22 | * Name: ISR(PCINT0_vect)
|
23 | *
|
24 | * Returns: Nothing.
|
25 | *
|
26 | * Parameters: None.
|
27 | *
|
28 | * Description: Interrupt service routine
|
29 | *
|
30 | ***************************************************/
|
31 | ISR(PCINT0_vect){ // Port B, PCINT0 - PCINT7
|
32 | }
|
33 |
|
34 |
|
35 | /***************************************************
|
36 | * Name: status
|
37 | *
|
38 | * Returns: Nothing.
|
39 | *
|
40 | * Parameters: None.
|
41 | *
|
42 | * Description: Status indication.
|
43 | *
|
44 | ***************************************************/
|
45 | void status (){
|
46 | PORTB |= (1 << PB5);
|
47 | _delay_ms (1000);
|
48 | PORTB &= ~(1 << PB5);
|
49 | _delay_ms (1000);
|
50 | }
|
51 |
|
52 |
|
53 | /***************************************************
|
54 | * Name: open
|
55 | *
|
56 | * Returns: Nothing.
|
57 | *
|
58 | * Parameters: None.
|
59 | *
|
60 | * Description: Indication for door is open.
|
61 | *
|
62 | ***************************************************/
|
63 | void open (){
|
64 | PORTB |= (1 << PB6);
|
65 | _delay_ms (1000);
|
66 | PORTB &= ~(1 << PB6);
|
67 | _delay_ms (1000);
|
68 | }
|
69 |
|
70 |
|
71 | /***************************************************
|
72 | * Name: alarm
|
73 | *
|
74 | * Returns: Nothing.
|
75 | *
|
76 | * Parameters: None.
|
77 | *
|
78 | * Description: Alarm.
|
79 | *
|
80 | ***************************************************/
|
81 | void alarm (){
|
82 | PORTB |= (1 << PB5);
|
83 | PORTB |= (1 << PB6);
|
84 | _delay_ms (1000);
|
85 | PORTB &= ~(1 << PB5);
|
86 | PORTB &= ~(1 << PB6);
|
87 | _delay_ms (1000);
|
88 | }
|
89 |
|
90 |
|
91 | /***************************************************
|
92 | * Name: main(void)
|
93 | *
|
94 | * Returns: Nothing.
|
95 | *
|
96 | * Parameters: None.
|
97 | *
|
98 | * Description: Main program
|
99 | *
|
100 | ***************************************************/
|
101 | int main(void){
|
102 |
|
103 | // I/O Pin setup
|
104 | DDRB &= ~(1 << PB4); // Pin PB4 as input - Button
|
105 | DDRB |= (1 << PB5); // Pin PB5 as output - green LED
|
106 | DDRB |= (1 << PB6); // Pin PB6 as output - Buzzer/ red LED
|
107 |
|
108 | // Variables
|
109 | uint8_t counter = 0; // Variable for counting the clock cycles how long the door was open
|
110 |
|
111 | // Main loop
|
112 | while (1){
|
113 |
|
114 | status(); // Status blink
|
115 |
|
116 | if (PINB & (1 << PB4) && (counter < 2)){ // If button PB4 pressed = door open (HIGH -> LOW)
|
117 | for (uint8_t i = 0; i <= 2; i++){ // Loop until it checks input again (2 times)
|
118 | open(); // Door open indication
|
119 | }
|
120 | counter += 1; // Counts up for how many times is input "door open" checked
|
121 | }
|
122 |
|
123 | if (PINB & (1 << PB4) && (counter == 2)){ // If button PB4 still pressed = door still open (HIGH -> LOW)
|
124 | for (uint8_t i = 0; i <= 2; i++){ // Loop until it checks input again (2 times)
|
125 | alarm(); // Door to long open -> alarm
|
126 | }
|
127 | }
|
128 |
|
129 | if ((!(PINB & (1 << PB4))) && (counter <= 2)){ // If button PB4 released = door closed and wasn't open before or closed for a while (LOW -> HIGH)
|
130 | counter = 0; // Reset counter
|
131 |
|
132 | // Pin change interrupt setup
|
133 | cli(); // Disable interrupt for programming
|
134 | PCICR |= (1<<PCIE0); // Turn on port b
|
135 | PCMSK0 |= (1 << PB4); // Turn on pin PB4, which is PCINT4
|
136 | sei(); // Enable interrupt
|
137 |
|
138 | // Sleep mode list
|
139 | set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
140 | // set_sleep_mode(SLEEP_MODE_PWR_SAVE);
|
141 | // set_sleep_mode(SLEEP_MODE_STANDBY);
|
142 | // set_sleep_mode(SLEEP_MODE_EXT_STANDBY);
|
143 | // set_sleep_mode(SLEEP_MODE_IDLE);
|
144 | // set_sleep_mode(SLEEP_MODE_ADC);
|
145 |
|
146 | sleep_mode(); // Start sleep mode
|
147 | }
|
148 | }
|
149 | }
|