Rev 838 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 838 | Rev 841 | ||
---|---|---|---|
1 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
1 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
2 | * main.c - Servo controlled infrared transmitter |
2 | * main.c - Servo controlled infrared transmitter |
3 | * |
3 | * |
4 | * Copyright (c) 2010-0xFFFF Stefan Pendsa |
4 | * Copyright (c) 2010-0xFFFF Stefan Pendsa |
5 | * Based on the nice IR decoder/encoder routines (IRMP/IRSND) from Frank Meyer => http://www.mikrocontroller.net/articles/IRMP |
5 | * Based on the nice IR decoder/encoder routines (IRMP/IRSND) from Frank Meyer => http://www.mikrocontroller.net/articles/IRMP |
6 | * |
6 | * |
7 | * ATMEGA8 @ 16 MHz |
7 | * ATMEGA8 @ 16 MHz |
8 | * |
8 | * |
9 | * Fuses: lfuse:0xAE hfuse:0xD9 |
9 | * Fuses: lfuse:0xAE hfuse:0xD9 |
10 | * |
10 | * |
11 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
11 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
12 | * This program is free software; you can redistribute it and/or modify |
12 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License as published by |
13 | * it under the terms of the GNU General Public License as published by |
14 | * the Free Software Foundation; either version 2 of the License, or |
14 | * the Free Software Foundation; either version 2 of the License, or |
15 | * (at your option) any later version. |
15 | * (at your option) any later version. |
16 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
16 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
17 | */ |
17 | */ |
18 | 18 | ||
19 | #include <inttypes.h> |
19 | #include <inttypes.h> |
20 | #include <avr/io.h> |
20 | #include <avr/io.h> |
21 | #include <util/delay.h> |
21 | #include <util/delay.h> |
22 | #include <avr/pgmspace.h> |
22 | #include <avr/pgmspace.h> |
23 | #include <avr/interrupt.h> |
23 | #include <avr/interrupt.h> |
24 | #include <avr/eeprom.h> |
24 | #include <avr/eeprom.h> |
25 | #include "irmp.h" |
25 | #include "irmp.h" |
26 | #include "irsndconfig.h" |
26 | #include "irsndconfig.h" |
27 | #include "irsnd.h" |
27 | #include "irsnd.h" |
28 | 28 | ||
29 | #ifndef F_CPU |
29 | #ifndef F_CPU |
30 | #error F_CPU unkown |
30 | #error F_CPU unkown |
31 | #endif |
31 | #endif |
32 | 32 | ||
33 | 33 | ||
34 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
34 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
35 | * Global variables |
35 | * Global variables |
36 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
36 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
37 | */ |
37 | */ |
38 | unsigned char key=0; // goes 1 when key was pressed |
38 | unsigned char key=0; // goes 1 when key was pressed |
39 | unsigned char ee_dummy EEMEM; // don't use the first byte in EEPROM, causes problems on some old AVRs... |
39 | unsigned char ee_dummy EEMEM; // don't use the first byte in EEPROM, causes problems on some old AVRs... |
40 | unsigned char ee_check EEMEM; // Check-Byte to see if EEPROM is initialized |
40 | unsigned char ee_check EEMEM; // Check-Byte to see if EEPROM is initialized |
41 | unsigned char active[5][5]; // Array to see which servo-combinations were populated with valid IR-codes |
41 | unsigned char active[5][5]; // Array to see which servo-combinations were populated with valid IR-codes |
42 | unsigned char ee_active[5][5] EEMEM; // Array to see which servo-combinations were populated with valid IR-codes (in EEPROM) |
42 | unsigned char ee_active[5][5] EEMEM; // Array to see which servo-combinations were populated with valid IR-codes (in EEPROM) |
43 | 43 | ||
44 | IRMP_DATA ir_data[5][5]; // Array with IR-codes for every servo-combination |
44 | IRMP_DATA ir_data[5][5]; // Array with IR-codes for every servo-combination |
45 | IRMP_DATA ee_ir_data[5][5] EEMEM; // Array with IR-codes for every servo-combination (in EEPROM) |
45 | IRMP_DATA ee_ir_data[5][5] EEMEM; // Array with IR-codes for every servo-combination (in EEPROM) |
46 | IRMP_DATA ir_temp; // Received IR-codes goes into here |
46 | IRMP_DATA ir_temp; // Received IR-codes goes into here |
47 | 47 | ||
48 | 48 | ||
49 | 49 | ||
50 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
50 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
51 | * timer 1 initialization |
51 | * timer 1 initialization |
52 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
52 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
53 | */ |
53 | */ |
54 | void timer_init (void) |
54 | void timer_init (void) |
55 | { |
55 | { |
56 | OCR1A = (F_CPU / F_INTERRUPTS) - 1; // compare value: 1/10000 of CPU frequency |
56 | OCR1A = (F_CPU / F_INTERRUPTS) - 1; // compare value: 1/10000 of CPU frequency |
57 | TCCR1B = (1 << WGM12) | (1 << CS10); // switch CTC Mode on, set prescaler to 1 |
57 | TCCR1B = (1 << WGM12) | (1 << CS10); // switch CTC Mode on, set prescaler to 1 |
58 | 58 | ||
59 | #if defined (__AVR_ATmega8__) || defined (__AVR_ATmega16__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega64__) || defined (__AVR_ATmega162__) |
59 | #if defined (__AVR_ATmega8__) || defined (__AVR_ATmega16__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega64__) || defined (__AVR_ATmega162__) |
60 | TIMSK = 1 << OCIE1A; // OCIE1A: Interrupt by timer compare (use TIMSK for ATMEGA162) |
60 | TIMSK = 1 << OCIE1A; // OCIE1A: Interrupt by timer compare (use TIMSK for ATMEGA162) |
61 | #else |
61 | #else |
62 | TIMSK1 = 1 << OCIE1A; // OCIE1A: Interrupt by timer compare (use TIMSK for ATMEGA162) |
62 | TIMSK1 = 1 << OCIE1A; // OCIE1A: Interrupt by timer compare (use TIMSK for ATMEGA162) |
63 | #endif // __AVR... |
63 | #endif // __AVR... |
64 | } |
64 | } |
65 | 65 | ||
66 | 66 | ||
67 | 67 | ||
68 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
68 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
69 | * timer 1 compare handler, called every 1/20000 sec |
69 | * timer 1 compare handler, called every 1/20000 sec |
70 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
70 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
71 | */ |
71 | */ |
72 | ISR(TIMER1_COMPA_vect) |
72 | ISR(TIMER1_COMPA_vect) |
73 | { |
73 | { |
74 | if (!irsnd_ISR()) // call irsnd ISR |
74 | if (!irsnd_ISR()) // call irsnd ISR |
75 | { // if not busy... |
75 | { // if not busy... |
76 | irmp_ISR(); // call irmp ISR |
76 | irmp_ISR(); // call irmp ISR |
77 | } |
77 | } |
78 | } |
78 | } |
79 | 79 | ||
80 | 80 | ||
81 | 81 | ||
82 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
82 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
83 | * LED control: 0 = off, >0 = on |
83 | * LED control: 0 = off, >0 = on |
84 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
84 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
85 | */ |
85 | */ |
86 | void LED(unsigned char bit) |
86 | void LED(unsigned char bit) |
87 | { |
87 | { |
88 | if (bit == 0) PORTD |= 1<<PORTD7; |
88 | if (bit == 0) PORTD |= 1<<PORTD7; |
89 | else PORTD &= ~(1<<PORTD7); |
89 | else PORTD &= ~(1<<PORTD7); |
90 | } |
90 | } |
91 | 91 | ||
92 | 92 | ||
93 | 93 | ||
94 | 94 | ||
95 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
95 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
96 | * LED Flash (on for time1, off for time2, repeated). Keypressing is checked in background |
96 | * LED Flash (on for time1, off for time2, repeated). Keypressing is checked in background |
97 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
97 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
98 | */ |
98 | */ |
99 | void Flash(unsigned char time1, unsigned char time2, unsigned char repeat) |
99 | void Flash(unsigned char time1, unsigned char time2, unsigned char repeat) |
100 | { |
100 | { |
101 | unsigned char i,j; |
101 | unsigned char i,j; |
102 | key = 0; |
102 | key = 0; |
103 | for (i=0;i<repeat;i++) |
103 | for (i=0;i<repeat;i++) |
104 | { |
104 | { |
105 | PORTD &= ~(1<<PORTD7); |
105 | PORTD &= ~(1<<PORTD7); |
106 | for (j=0;j<time1;j++) |
106 | for (j=0;j<time1;j++) |
107 | { |
107 | { |
108 | _delay_ms(1); |
108 | _delay_ms(1); |
109 | if (!(PINB & (1<<PINB2))) key = 1; |
109 | if (!(PINB & (1<<PINB2))) key = 1; |
110 | } |
110 | } |
111 | PORTD |= 1<<PORTD7; |
111 | PORTD |= 1<<PORTD7; |
112 | for (j=0;j<time2;j++) |
112 | for (j=0;j<time2;j++) |
113 | { |
113 | { |
114 | _delay_ms(1); |
114 | _delay_ms(1); |
115 | if (!(PINB & (1<<PINB2))) key = 1; |
115 | if (!(PINB & (1<<PINB2))) key = 1; |
116 | } |
116 | } |
117 | } |
117 | } |
118 | } |
118 | } |
119 | 119 | ||
120 | 120 | ||
121 | 121 | ||
122 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
122 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
123 | * LED Flash2 (on/off for time1, repeated, followed by delay of time2). Keypressing is checked in background |
123 | * LED Flash2 (on/off for time1, repeated, followed by delay of time2). Keypressing is checked in background |
124 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
124 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
125 | */ |
125 | */ |
126 | void Flash2(unsigned char time1, unsigned int time2, unsigned char repeat) |
126 | void Flash2(unsigned char time1, unsigned int time2, unsigned char repeat) |
127 | { |
127 | { |
128 | unsigned int i,j; |
128 | unsigned int i,j; |
129 | key = 0; |
129 | key = 0; |
130 | 130 | ||
131 | for (i=0;i<repeat;i++) |
131 | for (i=0;i<repeat;i++) |
132 | { |
132 | { |
133 | PORTD &= ~(1<<PORTD7); |
133 | PORTD &= ~(1<<PORTD7); |
134 | for (j=0;j<time1;j++) |
134 | for (j=0;j<time1;j++) |
135 | { |
135 | { |
136 | _delay_ms(1); |
136 | _delay_ms(1); |
137 | if (!(PINB & (1<<PINB2))) key = 1; |
137 | if (!(PINB & (1<<PINB2))) key = 1; |
138 | } |
138 | } |
139 | PORTD |= 1<<PORTD7; |
139 | PORTD |= 1<<PORTD7; |
140 | for (j=0;j<time1;j++) |
140 | for (j=0;j<time1;j++) |
141 | { |
141 | { |
142 | _delay_ms(1); |
142 | _delay_ms(1); |
143 | if (!(PINB & (1<<PINB2))) key = 1; |
143 | if (!(PINB & (1<<PINB2))) key = 1; |
144 | } |
144 | } |
145 | } |
145 | } |
146 | 146 | ||
147 | for (j=0;j<time2;j++) |
147 | for (j=0;j<time2;j++) |
148 | { |
148 | { |
149 | _delay_ms(1); |
149 | _delay_ms(1); |
150 | if (!(PINB & (1<<PINB2))) key = 1; |
150 | if (!(PINB & (1<<PINB2))) key = 1; |
151 | } |
151 | } |
152 | } |
152 | } |
153 | 153 | ||
154 | 154 | ||
155 | 155 | ||
156 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
156 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
157 | * Waits for button release followed by a debounce delay |
157 | * Waits for button release followed by a debounce delay |
158 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
158 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
159 | */ |
159 | */ |
160 | void WaitForKeyRelease(void) |
160 | void WaitForKeyRelease(void) |
161 | { |
161 | { |
162 | while(!(PINB & (1<<PINB2))); |
162 | while(!(PINB & (1<<PINB2))); |
163 | _delay_ms(50); |
163 | _delay_ms(50); |
164 | } |
164 | } |
165 | 165 | ||
166 | 166 | ||
167 | 167 | ||
168 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
168 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
169 | * Get position from servo inputs 1 and 2. Returns 1/2/3 for down/middle/up and 0 for invalid signal |
169 | * Get position from servo inputs 1 and 2. Returns 1/2/3 for down/middle/up, 0 for GND and 4 for VCC |
170 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
170 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
171 | */ |
171 | */ |
172 | unsigned char Servo(unsigned char chan) |
172 | unsigned char Servo(unsigned char chan) |
173 | { |
173 | { |
174 | cli(); |
174 | cli(); |
175 | unsigned int i=0; |
175 | unsigned int i=0; |
176 | 176 | ||
177 | for (i=0;i<7500;i++) // wait max. 75 ms for signal going down |
177 | for (i=0;i<7500;i++) // wait max. 75 ms for signal going down |
178 | { |
178 | { |
179 | _delay_us(10); |
179 | _delay_us(10); |
180 | if (!(PINC & (1<<(chan+1)))) break; |
180 | if (!(PINC & (1<<(chan+1)))) break; |
181 | } |
181 | } |
182 | 182 | ||
183 | for (i=0;i<7500;i++) // wait max. 75 ms for signal going up |
183 | for (i=0;i<7500;i++) // wait max. 75 ms for signal going up |
184 | { |
184 | { |
185 | _delay_us(10); |
185 | _delay_us(10); |
186 | if (PINC & (1<<(chan+1))) break; |
186 | if (PINC & (1<<(chan+1))) break; |
187 | } |
187 | } |
188 | 188 | ||
189 | for (i=0;i<255;i++) // measure time until signal goes down |
189 | for (i=0;i<255;i++) // measure time until signal goes down |
190 | { |
190 | { |
191 | if (!(PINC & (1<<(chan+1)))) break; |
191 | if (!(PINC & (1<<(chan+1)))) break; |
192 | _delay_us(10); |
192 | _delay_us(10); |
193 | } |
193 | } |
194 | 194 | ||
195 | 195 | ||
196 | sei(); |
196 | sei(); |
197 | if (i < 75) return 0; // 0,00 - 0,74 ms => 0 (switch to GND) |
197 | if (i < 75) return 0; // 0,00 - 0,74 ms => 0 (switch to GND) |
198 | else if (i > 74 && i < 125) return 1; // 0,75 - 1,24 ms => 1 (stick down) |
198 | else if (i > 74 && i < 125) return 1; // 0,75 - 1,24 ms => 1 (stick down) |
199 | else if (i > 124 && i < 175) return 2; // 1,25 - 1,74 ms => 2 (stick middle) |
199 | else if (i > 124 && i < 175) return 2; // 1,25 - 1,74 ms => 2 (stick middle) |
200 | else if (i > 174 && i < 225) return 3; // 1,75 - 2,24 ms => 3 (stick up) |
200 | else if (i > 174 && i < 225) return 3; // 1,75 - 2,24 ms => 3 (stick up) |
201 | else if (i > 224) return 4; // 2,25 - ever ms => 4 (switch to VCC or open input) |
201 | else if (i > 224) return 4; // 2,25 - ever ms => 4 (switch to VCC or open input) |
202 | return 0; |
202 | return 0; |
203 | } |
203 | } |
204 | 204 | ||
205 | 205 | ||
206 | 206 | ||
207 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
207 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
208 | * Learning-Mode: When an IR signal arrives, it is saved in an array position related to the actual servo positions |
208 | * Learning-Mode: When an IR signal arrives, it is saved in an array position related to the actual servo positions |
209 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
209 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
210 | */ |
210 | */ |
211 | void Learn(void) |
211 | void Learn(void) |
212 | { |
212 | { |
213 | unsigned char i,j,Servo1,Servo2,mode=1; |
213 | unsigned char i,j,Servo1,Servo2,mode=1; |
214 | for (i=0;i<5;i++) // first, forget every assignment |
214 | for (i=0;i<5;i++) // first, forget every assignment |
215 | { |
215 | { |
216 | for (j=0;j<5;j++) |
216 | for (j=0;j<5;j++) |
217 | { |
217 | { |
218 | active[i][j] = 0; |
218 | active[i][j] = 0; |
219 | } |
219 | } |
220 | } |
220 | } |
221 | 221 | ||
222 | WaitForKeyRelease(); |
222 | WaitForKeyRelease(); |
223 | 223 | ||
224 | while(1) |
224 | while(1) |
225 | { |
225 | { |
226 | if (irmp_get_data (&ir_temp)) // when IR code is decoded, |
226 | if (irmp_get_data (&ir_temp)) // when IR code is decoded, |
227 | { |
227 | { |
228 | Servo1 = Servo(1); // get Servo positions |
228 | Servo1 = Servo(1); // get Servo positions |
229 | Servo2 = Servo(2); |
229 | Servo2 = Servo(2); |
230 | ir_temp.flags = 0; // ignore reapeat-flag |
230 | ir_temp.flags = 0; // ignore repeat-flag |
231 | ir_data[Servo1][Servo2] = ir_temp; // populate the array |
231 | ir_data[Servo1][Servo2] = ir_temp; // populate the array |
232 | active[Servo1][Servo2] = mode; // and flag it with the actually mode |
232 | active[Servo1][Servo2] = mode; // and flag it with the actually mode |
233 | Flash(25,25,10); // fast flash LED 10 times to indicate a learned code |
233 | Flash(25,25,10); // fast flash LED 10 times to indicate a learned code |
234 | } |
234 | } |
235 | 235 | ||
236 | Flash2(100,500,mode); // slow flash LED whole time to indicate we are in learning mode (flashing 1 or 2 times, depends on mode) |
236 | Flash2(100,500,mode); // slow flash LED whole time to indicate we are in learning mode (flashing 1 or 2 times, depends on mode) |
237 | 237 | ||
238 | if (key) // toggle mode: single -> multi -> single -> multi ... |
238 | if (key) // toggle mode: single -> multi -> single -> multi ... |
239 | { |
239 | { |
240 | if (mode == 1) mode = 2; |
240 | if (mode == 1) mode = 2; |
241 | else mode = 1; |
241 | else mode = 1; |
242 | 242 | ||
243 | _delay_ms(500); |
243 | _delay_ms(500); |
244 | if (!(PINB & (1<<PINB2))) break; // Leave learning mode when button is pressed for 500 ms |
244 | if (!(PINB & (1<<PINB2))) break; // Leave learning mode when button is pressed for 500 ms |
245 | } |
245 | } |
246 | 246 | ||
247 | } |
247 | } |
248 | 248 | ||
249 | // Write to EEPROM |
249 | // Write to EEPROM |
250 | eeprom_write_block(&ir_data,&ee_ir_data,sizeof(unsigned char)*25*6); |
250 | eeprom_write_block(&ir_data,&ee_ir_data,sizeof(unsigned char)*25*6); |
251 | eeprom_write_block(&active,&ee_active,sizeof(unsigned char)*25); |
251 | eeprom_write_block(&active,&ee_active,sizeof(unsigned char)*25); |
252 | 252 | ||
253 | Flash(25,25,10); // fast flash LED 10 times to indicate that we are leaving the learning mode |
253 | Flash(25,25,10); // fast flash LED 10 times to indicate that we are leaving the learning mode |
254 | WaitForKeyRelease(); |
254 | WaitForKeyRelease(); |
255 | } |
255 | } |
256 | 256 | ||
257 | 257 | ||
258 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
258 | /*--------------------------------------------------------------------------------------------------------------------------------------------------- |
259 | * MAIN: main routine |
259 | * MAIN: main routine |
260 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
260 | *--------------------------------------------------------------------------------------------------------------------------------------------------- |
261 | */ |
261 | */ |
262 | int main (void) |
262 | int main (void) |
263 | { |
263 | { |
264 | unsigned char i,j,Servo1,Servo2,Servo1old=99,Servo2old=99; |
264 | unsigned char i,j,Servo1,Servo2,Servo1old=99,Servo2old=99; |
265 | 265 | ||
266 | DDRB = 0b00001000; // IRED output, Switch input |
266 | DDRB = 0b00001000; // IRED output, Switch input |
267 | PORTB = 0b00000100; // PullUp for Switch |
267 | PORTB = 0b00000100; // PullUp for Switch |
268 | 268 | ||
269 | DDRC = 0b00000000; // Input for Servo-Signals |
269 | DDRC = 0b00000000; // Input for Servo-Signals |
270 | PORTC = 0b00001100; // PullUp for (unused) Servos |
270 | PORTC = 0b00001100; // PullUp for (unused) Servos |
271 | 271 | ||
272 | DDRD = 0b10000000; // Input for received IR, output for LED |
272 | DDRD = 0b10000000; // Input for received IR, output for LED |
273 | PORTD = 0b11000000; // PullUp for received IR, LED off |
273 | PORTD = 0b11000000; // PullUp for received IR, LED off |
274 | 274 | ||
275 | 275 | ||
276 | if (eeprom_read_byte(&ee_check)!=0xE7) // When EEPROM is uninitialized, do it now |
276 | if (eeprom_read_byte(&ee_check)!=0xE7) // When EEPROM is uninitialized, do it now |
277 | { |
277 | { |
278 | for (i=0;i<5;i++) |
278 | for (i=0;i<5;i++) |
279 | { |
279 | { |
280 | for (j=0;j<5;j++) |
280 | for (j=0;j<5;j++) |
281 | { |
281 | { |
282 | active[i][j] = 0; |
282 | active[i][j] = 0; |
283 | } |
283 | } |
284 | } |
284 | } |
285 | 285 | ||
286 | eeprom_write_byte(&ee_check, 0xE7); |
286 | eeprom_write_byte(&ee_check, 0xE7); |
287 | eeprom_write_block(&active,&ee_active,sizeof(unsigned char)*25); |
287 | eeprom_write_block(&active,&ee_active,sizeof(unsigned char)*25); |
288 | } |
288 | } |
289 | 289 | ||
290 | else // else, read in the contents |
290 | else // else, read in the contents |
291 | { |
291 | { |
292 | eeprom_read_block(&ir_data,&ee_ir_data,sizeof(unsigned char)*25*6); |
292 | eeprom_read_block(&ir_data,&ee_ir_data,sizeof(unsigned char)*25*6); |
293 | eeprom_read_block(&active,&ee_active,sizeof(unsigned char)*25); |
293 | eeprom_read_block(&active,&ee_active,sizeof(unsigned char)*25); |
294 | } |
294 | } |
295 | 295 | ||
296 | 296 | ||
297 | irmp_init(); // initialize irmp |
297 | irmp_init(); // initialize irmp |
298 | irsnd_init(); // initialize irsnd |
298 | irsnd_init(); // initialize irsnd |
299 | timer_init(); // initialize timer |
299 | timer_init(); // initialize timer |
300 | WaitForKeyRelease(); |
300 | WaitForKeyRelease(); |
301 | sei (); // enable interrupts |
301 | sei(); // enable interrupts |
302 | 302 | ||
303 | 303 | ||
304 | while(1) // Main loop |
304 | while(1) // Main loop |
305 | { |
305 | { |
306 | if (!(PINB & (1<<PINB2))) Learn(); // Enter learning mode when the button is pressed |
306 | if (!(PINB & (1<<PINB2))) Learn(); // Enter learning mode when the button is pressed |
307 | 307 | ||
308 | Servo1 = Servo(1); // get servo positions |
308 | Servo1 = Servo(1); // get servo positions |
309 | Servo2 = Servo(2); |
309 | Servo2 = Servo(2); |
310 | 310 | ||
311 | // when the actual posision was saved before, and the inputs are in a new position, send out its IR-code (single mode) |
311 | // when the actual posision was saved before, and the inputs are in a new position, send out its IR-code (single mode) |
312 | if (active[Servo1][Servo2] == 1 && (Servo1old != Servo1 || Servo2old != Servo2)) |
312 | if (active[Servo1][Servo2] == 1 && (Servo1old != Servo1 || Servo2old != Servo2)) |
313 | { |
313 | { |
314 | LED(1); // light up LED while sending IR-code |
314 | LED(1); // light up LED while sending IR-code |
315 | irsnd_send_data(&ir_data[Servo1][Servo2],FALSE); |
315 | irsnd_send_data(&ir_data[Servo1][Servo2],FALSE); |
316 | while (irsnd_is_busy()); // wait until the frame was sent |
316 | while (irsnd_is_busy()); // wait until the frame was sent |
317 | _delay_ms(100); |
317 | _delay_ms(100); |
318 | LED(0); |
318 | LED(0); |
319 | } |
319 | } |
320 | 320 | ||
321 | if (active[Servo1][Servo2] == 2) // when the actual position was saved before, send out its IR-code (multi-mode) |
321 | if (active[Servo1][Servo2] == 2) // when the actual position was saved before, send out its IR-code (multi-mode) |
322 | { |
322 | { |
323 | LED(1); // light up LED while sending IR-code |
323 | LED(1); // light up LED while sending IR-code |
324 | irsnd_send_data(&ir_data[Servo1][Servo2],FALSE); |
324 | irsnd_send_data(&ir_data[Servo1][Servo2],FALSE); |
325 | while (irsnd_is_busy()); // wait until the frame was sent |
325 | while (irsnd_is_busy()); // wait until the frame was sent |
326 | LED(0); |
326 | LED(0); |
327 | } |
327 | } |
328 | 328 | ||
329 | Servo1old = Servo1; // save old positions for single-mode |
329 | Servo1old = Servo1; // save old positions for single-mode |
330 | Servo2old = Servo2; |
330 | Servo2old = Servo2; |
331 | } |
331 | } |
332 | 332 | ||
333 | } |
333 | } |
334 | 334 | ||
335 | 335 | ||
336 | 336 |