Subversion Repositories Projects

Rev

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