added Black rf433ctl remote signals for A and B. Timing is still of so it only works...
[svn42.git] / rf433ctl / rf433ctl.pde
1 #include <avr/io.h>
2 #include <avr/interrupt.h>
3 #include <inttypes.h>
4 #include <OneWire.h>
5 #include <DallasTemperature.h>
6 #include <IRremote.h>
7
8 //********************************************************************//
9
10 #define RF_DATA_OUT_PIN 13
11 #define IR_MOVEMENT_PIN 9
12 #define IR_MOVEMENT_PIN2 12
13 #define ONE_WIRE_PIN 8
14 #define PANIC_BUTTON_PIN 7
15 #define PANICLED_PWM_PIN 6
16 #define BLUELED_PWM_PIN 11
17 #define PHOTO_ANALOGPIN 0
18 //movement is reported if during IR_SAMPLE_DURATION at least IR_TRESHOLD ir signals are detectd
19 #define IR_SAMPLE_DURATION 8000
20 #define IR_TRESHOLD 7500
21 //duration PanicButton needs to be pressed before status change occurs (i.e. for two PanicButton Reports, the buttons needs to be pressed 1000 cycles, releases 1000 cycles and again pressed 1000 cycles)
22 #define PB_TRESHOLD 1000
23 #define PHOTO_SAMPLE_INTERVAL 4000
24 #define IRREMOTE_SEND_PIN 3   //hardcoded in library
25 //WARNING IRremote Lib uses TCCR2
26
27 OneWire  onewire(ONE_WIRE_PIN);
28 DallasTemperature dallas_sensors(&onewire);
29 DeviceAddress onShieldTemp = { 0x10, 0xE7, 0x77, 0xD3, 0x01, 0x08, 0x00, 0x3F };
30 IRsend irsend; 
31 #define TEMPC_OFFSET_ARDUINO_GENEREATED_HEAT 
32
33 //********************************************************************//
34 // IR Codes, 32 bit, NEC
35 const int YAMAHA_CODE_BITS = 32;
36 const unsigned long int YAMAHA_CODE_BASE = 0x0000000005EA10000;
37
38 const char YAMAHA_POWER_TOGGLE =0xF8; //Power On/Off
39 const char YAMAHA_POWER_OFF =0x78; //Power Off !!!
40 const char YAMAHA_SLEEP =0xEA; //Toggle Sleep 120/90/60/30min or Off
41
42 const char YAMAHA_CD =0xA8; //Input CD
43 const char YAMAHA_TUNER =0x68; //Input Tuner
44 const char YAMAHA_TAPE =0x18; //Input Toggle Tape/CD
45 const char YAMAHA_DVD_SPDIF =0xE8; //Input Toggle DVD Auto / DVD Analog
46 const char YAMAHA_SAT_SPDIFF =0x2A; //Input Toggle Sat-DTV Auto / Sat-DTV Analog
47 const char YAMAHA_AUX =0xAA;  //Input AUX (mode)
48 const char YAMAHA_VCR =0xF0; //Input VCR
49 const char YAMAHA_EXT51DEC =0xE1; //Input Ext. Decoder On/Off
50
51 const char YAMAHA_TUNER_PLUS =0x08; //Tuner Next Station 1-7  (of A1 - E7)
52 const char YAMAHA_TUNER_MINUS =0x88; //Tuner Prev Station 1-7  (of A1 - E7)
53 const char YAMAHA_TUNER_ABCDE =0x48; //Tuner Next Station Row A-E (of A1 - E7)
54
55 const char YAMAHA_MUTE =0x38;
56 const char YAMAHA_VOLUME_UP =0x58;
57 const char YAMAHA_VOLUME_DOWN =0xD8;
58
59 //const char YAMAHA_FRONT_LEVEL_P =0x01;  //no function
60 //const char YAMAHA_FRONT_LEVEL_M =0x81; //no function
61 //const char YAMAHA_CENTRE_LEVEL_P =0x41;  //no function
62 //const char YAMAHA_CENTRE_LEVEL_M =0xC1; //no function
63 //const char YAMAHA_REAR_LEVEL_P =0x7A; //no function
64 //const char YAMAHA_REAR_LEVEL_M =0xFA; //no function
65 const char YAMAHA_PLUS =0x4A;  //unteres Steuerkreuz: Taste Rechts (Plus)
66 const char YAMAHA_MINUS =0xCA; //unteres Steuerkreuz: Taste Links (Minus)
67 const char YAMAHA_MENU =0x39; // Menu: Settings
68 const char YAMAHA_TEST =0xA1; // Test Sounds
69 const char YAMAHA_TIME_LEVEL =0x19; //Settings for Delay, Subwfs, Right Surround, Left Surround, Center
70 const char YAMAHA_TIME_LEVEL2 =0x61; //(also) Settings for Delay, Subwfs, Right Surround, Left Surround, Center
71 const char YAMAHA_TIME_LEVEL3 =0x99; //(also) Settings for Delay, Subwfs, Right Surround, Left Surround, Center
72
73 const char YAMAHA_EFFECT_TOGGLE =0x6A; //Effect Toggle On/Off
74 const char YAMAHA_PRG_DOWN =0x9A; //Effect/DSP Programm Toggle in down direction
75 const char YAMAHA_PRG_UP =0x1A; //Effect/DSP Programm Toggle in up direction
76 const char YAMAHA_EFFECT1 =0x31; //Effect TV Sports
77 const char YAMAHA_EFFECT2 =0x71; //Effect Rock Concert
78 const char YAMAHA_EFFECT3 =0xB1;  //Effect Disco
79 const char YAMAHA_EFFECT4 =0xD1;  //Mono Movie
80 const char YAMAHA_EFFECT5 =0x91; //Effect Toggle 70mm Sci-Fi / 70mm Spectacle
81 const char YAMAHA_EFFECT6 =0x51; //Effect Toggle 70mm General / 70mm Adventure
82 const char YAMAHA_P5 =0xFB; //P5 PRT (1 Main Bypass)? (1587674115)
83
84 //********************************************************************//
85
86 typedef struct {
87   byte offset;
88   byte state;
89 } rf_bit_t;
90
91 // offset is number of alphas (0.08ms)
92
93 const rf_bit_t zero_bit[] = { {  4, 1 },
94                               { 16, 0 },
95                               { 20, 1 },
96                               { 32, 0 },
97                               {  0, 0 } };
98
99 const rf_bit_t one_bit[] = { { 12, 1 },
100                              { 16, 0 },
101                              { 28, 1 },
102                              { 32, 0 },
103                              {  0, 0 } };
104
105 const rf_bit_t float_bit[] = { {  4, 1 },
106                                { 16, 0 },
107                                { 28, 1 },
108                                { 32, 0 },
109                                {  0, 0 } };
110
111 const rf_bit_t sync_bit[] = { {   4, 1 },
112                               { 128, 0 },
113                               {   0, 0 } };
114                               
115 const rf_bit_t pwm_0_bit[] = {  {6, 1}, {17, 0}, {  0, 0 } };     // 1.86ms gesamt: { 0.46ms HIGH , 1.4ms LOW }
116 const rf_bit_t pwm_1_bit[] = {  {17, 1}, {6, 0}, {  0, 0 } };  //// 1.86ms gesamt: { 1.4ms HIGH , 0.46ms LOW }
117 const rf_bit_t pwm_pause_bit[] = {  {161, 0}, {  0, 0 } };  //// 12.9ms pause 
118
119 typedef enum { ZERO = 0, ONE , FLOAT , SYNC , PWM0, PWM1, PWM_PAUSE, WORD_END } adbit_t;
120 typedef byte ad_bit_t;
121 #define WORD_LEN 13
122 #define MAX_WORD_LEN 26
123 typedef ad_bit_t word_t[MAX_WORD_LEN+1];
124
125 const rf_bit_t* bit_defs[] = { zero_bit, one_bit, float_bit, sync_bit, pwm_0_bit, pwm_1_bit, pwm_pause_bit };
126
127 byte alpha_cnt = 0;
128 byte bit_cnt = 0;
129 byte current_word_len = WORD_LEN;
130 byte chunk_cnt = 0;
131 byte word_cnt = 0;
132 const ad_bit_t* current_word;
133 byte volatile frame_finished = 1;
134
135 #define FRAME_LEN 8
136
137 #define A1_ON  0
138 #define A1_OFF 1
139 #define A2_ON  2
140 #define A2_OFF 3
141
142 #define B1_ON  4
143 #define B1_OFF 5
144 #define B2_ON  6
145 #define B2_OFF 7
146
147 #define C1_ON  8
148 #define C1_OFF 9
149 #define C2_ON  10
150 #define C2_OFF 11
151
152 #define D1_ON  12
153 #define D1_OFF 13
154 #define D2_ON  14
155 #define D2_OFF 15
156
157 #define BLACK_A1_ON 16
158 #define BLACK_A1_OFF 17
159 #define BLACK_A2_ON 18
160 #define BLACK_A2_OFF 19
161 #define BLACK_A3_ON 20
162 #define BLACK_A3_OFF 21
163
164 #define BLACK_B1_ON 22
165 #define BLACK_B1_OFF 23
166 #define BLACK_B2_ON 24
167 #define BLACK_B2_OFF 25
168 #define BLACK_B3_ON 26
169 #define BLACK_B3_OFF 27
170
171
172 const word_t words[]  = { 
173 { ZERO,  ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC, WORD_END, WORD_END,WORD_END}, // A1_ON
174 { ZERO,  ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC, WORD_END, WORD_END,WORD_END}, // A1_OFF
175 { ZERO,  ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC, WORD_END, WORD_END,WORD_END }, // A2_ON
176 { ZERO,  ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC, WORD_END, WORD_END,WORD_END }, // A2_OFF
177
178 { FLOAT, ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC, WORD_END, WORD_END,WORD_END }, // B1_ON
179 { FLOAT, ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC, WORD_END, WORD_END,WORD_END }, // B1_OFF
180 { FLOAT, ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC, WORD_END, WORD_END,WORD_END }, // B2_ON
181 { FLOAT, ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC, WORD_END, WORD_END,WORD_END }, // B2_OFF
182
183 { ZERO,  FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC, WORD_END, WORD_END,WORD_END }, // C1_ON
184 { ZERO,  FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC, WORD_END, WORD_END,WORD_END }, // C1_OFF
185 { ZERO,  FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC, WORD_END, WORD_END,WORD_END }, // C2_ON
186 { ZERO,  FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC, WORD_END, WORD_END,WORD_END }, // C2_OFF
187
188 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC, WORD_END, WORD_END,WORD_END }, // D1_ON
189 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC, WORD_END, WORD_END,WORD_END }, // D1_OFF
190 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC, WORD_END, WORD_END,WORD_END }, // D2_ON
191 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC, WORD_END, WORD_END,WORD_END },  // D2_OFF
192
193 {PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM1,PWM1,PWM0,PWM0,PWM0, PWM_PAUSE, WORD_END}, // BLACK_A1_ON
194 {PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM1,PWM1,PWM0, PWM_PAUSE, WORD_END}, // BLACK_A1_OFF
195 {PWM1,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM1,PWM1,PWM0,PWM0,PWM0, PWM_PAUSE, WORD_END}, // BLACK_A2_ON
196 {PWM1,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM1,PWM1,PWM0, PWM_PAUSE, WORD_END}, // BLACK_A2_OFF
197 {PWM1,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM1,PWM1,PWM0,PWM0,PWM0, PWM_PAUSE, WORD_END}, // BLACK_A3_ON
198 {PWM1,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM1,PWM1,PWM0, PWM_PAUSE, WORD_END}, // BLACK_A3_OFF
199   
200 {PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM1,PWM1,PWM0,PWM0,PWM0, PWM_PAUSE, WORD_END}, // BLACK_B1_ON  
201 {PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM1,PWM1,PWM0, PWM_PAUSE, WORD_END}, // BLACK_B1_OFF  
202 {PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM1,PWM1,PWM0,PWM0,PWM0, PWM_PAUSE, WORD_END}, // BLACK_B2_ON  
203 {PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM1,PWM1,PWM0, PWM_PAUSE, WORD_END}, // BLACK_B2_OFF  
204 {PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM1,PWM1,PWM0,PWM0,PWM0, PWM_PAUSE, WORD_END}, // BLACK_B3_ON
205 {PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM1,PWM1,PWM0, PWM_PAUSE, WORD_END} // BLACK_B3_OFF
206
207 };
208
209
210 //********************************************************************//
211
212 void start_timer()
213 {
214   // timer 1: 2 ms
215   TCCR1A = 0;                    // prescaler 1:8, WGM = 4 (CTC)
216   TCCR1B = 1<<WGM12 | 1<<CS11;   // 
217   OCR1A = 159;        // (1+159)*8 = 1280 -> 0.08ms @ 16 MHz -> 1*alpha
218 //  OCR1A = 207;        // (1+207)*8 = 1664 -> 0.104ms @ 16 MHz -> 1*alpha
219   TCNT1 = 0;          // reseting timer
220   TIMSK1 = 1<<OCIE1A; // enable Interrupt
221 }
222
223 void stop_timer() // stop the timer
224 {
225   // timer1
226   TCCR1B = 0; // no clock source
227   TIMSK1 = 0; // disable timer interrupt
228 }
229
230 void init_word(const word_t w)
231 {
232   current_word = w;
233   alpha_cnt = 0;
234   chunk_cnt = 0;
235   bit_cnt = 0;
236
237   if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
238     digitalWrite(RF_DATA_OUT_PIN, LOW); //neue 12V MosFET Verstärkung invertiert Logik !
239   else
240     digitalWrite(RF_DATA_OUT_PIN, HIGH);
241
242   start_timer();
243 }
244
245 ISR(TIMER1_COMPA_vect)
246 {
247   alpha_cnt++;
248   if(alpha_cnt < bit_defs[current_word[bit_cnt]][chunk_cnt].offset)
249     return;
250
251   chunk_cnt++;
252   if(bit_defs[current_word[bit_cnt]][chunk_cnt].offset != 0) {
253     if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
254       digitalWrite(RF_DATA_OUT_PIN, LOW); //neue 12V MosFET Verstärkung invertiert Logik !
255     else
256       digitalWrite(RF_DATA_OUT_PIN, HIGH);
257     return;
258   }
259   
260   bit_cnt++;
261   if(current_word[bit_cnt] != WORD_END && bit_cnt < MAX_WORD_LEN) {
262     alpha_cnt = 0;
263     chunk_cnt = 0;
264     if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
265       digitalWrite(RF_DATA_OUT_PIN, LOW); //neue 12V MosFET Verstärkung invertiert Logik !
266     else
267       digitalWrite(RF_DATA_OUT_PIN, HIGH);
268     return;
269   }
270   stop_timer();
271   digitalWrite(RF_DATA_OUT_PIN, HIGH);
272
273   word_cnt++;
274   if(word_cnt < FRAME_LEN)
275     init_word(current_word);
276   else
277     frame_finished = 2;
278 }
279
280 //***********//
281
282
283 void send_frame(const word_t w)
284 {
285   if (frame_finished != 1)
286     for(;;) //wait until sending of previous frame finishes
287       if (frame_finished)
288       {
289         delay(150);
290         break;
291       }
292   word_cnt = 0;
293   frame_finished = 0;
294   init_word(w);
295 }
296
297 void check_frame_done()
298 {
299   if (frame_finished==2)
300   {
301     Serial.println("Ok");
302     frame_finished=1;
303     delay(120);
304   }
305 }
306
307 //********************************************************************//
308
309 void printTemperature(DeviceAddress deviceAddress)
310 {
311   dallas_sensors.requestTemperatures();
312   float tempC = dallas_sensors.getTempC(deviceAddress);
313   //Serial.print("Temp C: ");
314   Serial.println(tempC TEMPC_OFFSET_ARDUINO_GENEREATED_HEAT);
315   //Serial.print(" Temp F: ");
316   //Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
317 }
318
319 //********************************************************************//
320
321 unsigned int light_level_mean_ = 0;
322 unsigned int light_sample_time_ = 0;
323
324 void updateLightLevel(unsigned int pin)
325 {
326   light_sample_time_++;
327   if (light_sample_time_ < PHOTO_SAMPLE_INTERVAL)
328     return;
329   light_sample_time_ = 0;
330   
331   unsigned int value = analogRead(pin);
332   if (value == light_level_mean_)
333     return;
334   
335   unsigned int diff = abs(value - light_level_mean_);
336   if (diff > 100)
337     light_level_mean_ = value;
338   else
339       light_level_mean_=(unsigned int) ( ((float) light_level_mean_) * 0.90 + ((float)value)*0.10 );
340 }
341
342 void printLightLevel()
343 {
344   //Serial.print("Photo: ");
345   Serial.println(light_level_mean_);
346 }
347
348 //********************************************************************//
349
350 unsigned long wm_start_[3]={0,0,0};
351 bool wait_millis(unsigned long *start_time, unsigned long ms)
352 {
353   if (ms == 0)
354     return false;
355   else if (*start_time > 0)
356   {
357     if (millis() < *start_time || millis() > (*start_time) + ms)
358     {
359       *start_time = 0;
360       return false;
361     }
362     else
363       return true;
364   }
365   else
366   {
367     *start_time=millis();
368     return true;
369   }
370 }
371 #define NUM_LEDS 2
372 char flash_led_pins_[NUM_LEDS]={BLUELED_PWM_PIN,PANICLED_PWM_PIN};
373 unsigned int flash_led_time_[3]={0,0,0};
374 unsigned int flash_led_brightness_[3]={255,255,255};
375 unsigned int flash_led_delay_[3]={8,8,8};
376 unsigned int flash_led_initial_delay_[3]={0,0,0};
377 void calculate_led_level()
378 {
379   for (int ledid = 0; ledid < NUM_LEDS; ledid++)
380   {
381     if (flash_led_time_[ledid] == 0)
382       continue;
383     if (wait_millis(wm_start_ + ledid, flash_led_initial_delay_[ledid]))
384       continue;
385     flash_led_initial_delay_[ledid]=0;
386     if (wait_millis(wm_start_ + ledid, flash_led_delay_[ledid]))
387       continue;
388     flash_led_time_[ledid]--;
389     int c = abs(sin(float(flash_led_time_[ledid]) / 100.0)) * flash_led_brightness_[ledid];
390     //int d = abs(sin(float(flash_led_time_) / 100.0)) * flash_led_brightness_;
391     analogWrite(flash_led_pins_[ledid], 255-c);
392   }
393 }
394
395 // id: id of LED to flash (0,1)
396 // times: # of times the LED should flash
397 // brightness_divisor: 1: full brightness, 2: half brightness, ...
398 // delay_divisor: 1: slow... 8: fastest
399 // phase_divisor: 0.. same phase; 2.. pi/2 phase, 4.. pi phase, 6.. 3pi/2 phase
400 void flash_led(unsigned int id, unsigned int times, unsigned int brightness_divisor, unsigned int delay_divisor, unsigned int phase_divisor)
401 {
402   if (id >= NUM_LEDS)
403     return;
404   unsigned int new_flash_led_brightness = 255;
405   unsigned int new_flash_led_delay = 8;
406   if (times == 0)
407   {
408     analogWrite(flash_led_pins_[id],255); //off
409     return;
410   }
411   if (brightness_divisor > 1) //guard against div by zero
412     new_flash_led_brightness /= brightness_divisor;
413   if (delay_divisor > 1)  //guard against div by zero
414     new_flash_led_delay /= delay_divisor;
415   if (flash_led_time_[id] == 0 || new_flash_led_brightness > flash_led_brightness_[id])
416     flash_led_brightness_[id]=new_flash_led_brightness;
417   if (flash_led_time_[id] == 0 || new_flash_led_delay < flash_led_delay_[id])
418     flash_led_delay_[id]=new_flash_led_delay;
419   flash_led_time_[id] += 314*times;
420   flash_led_initial_delay_[id] = flash_led_delay_[id]*314*phase_divisor/8;
421 }
422
423 //********************************************************************//
424
425 int save_tcnt2=0;
426 int save_tccr2a=0;
427 int save_tccr2b=0;
428 void reset_timer2()
429 {
430   TCNT2 = save_tcnt2;
431   TCCR2A = save_tccr2a;  // normal mode
432   TCCR2B = save_tccr2b;
433   //TCNT2 = 256 - (50*(16000000/8/1000000)) + 5;
434   //TCCR2A = 0;  // normal mode
435   //TCCR2B = 0;
436 }
437
438 void send_yamaha_ir_signal(char codebyte)
439 {
440   unsigned long int code = codebyte & 0xFF;
441   code <<= 8;
442   code |= (0xff ^ codebyte) & 0xFF;
443   code |= YAMAHA_CODE_BASE;
444   
445   //irsend changes PWM Timer Frequency among other things
446   //.. doesn't go well with PWM output using the same timer
447   //.. thus we just set output to 255 so whatever frequency is used, led is off for the duration
448   //analogWrite(BLUELED_PWM_PIN,255); // switch led off
449
450   irsend.sendNEC(code,YAMAHA_CODE_BITS);
451
452   reset_timer2();
453   analogWrite(BLUELED_PWM_PIN,255); // switch off led again to be sure
454                                       //is actually not necessary, since we are not multitasking/using interrupts, but just to be sure in case this might change
455
456   Serial.println("Ok");
457 }
458
459 //********************************************************************//
460
461 void setup()
462 {
463   pinMode(RF_DATA_OUT_PIN, OUTPUT);
464   digitalWrite(RF_DATA_OUT_PIN, HIGH);
465   pinMode(IR_MOVEMENT_PIN, INPUT);      // set pin to input
466   digitalWrite(IR_MOVEMENT_PIN, LOW);  // turn off pullup resistors  
467   digitalWrite(IR_MOVEMENT_PIN2, LOW);  // turn off pullup resistors  
468   pinMode(PANIC_BUTTON_PIN, INPUT);      // set pin to input
469   digitalWrite(PANIC_BUTTON_PIN, LOW);  // turn of pullup resistors 
470   analogWrite(PANICLED_PWM_PIN,255);
471   analogWrite(BLUELED_PWM_PIN,255); //pwm sink(-) instead of pwm + (better for mosfets)
472   pinMode(IRREMOTE_SEND_PIN, OUTPUT);
473   digitalWrite(IRREMOTE_SEND_PIN, HIGH);
474   
475   Serial.begin(9600);
476   
477   onewire.reset();
478   onewire.reset_search();
479   dallas_sensors.begin();
480   //in case we change temp sensor:
481   if (!dallas_sensors.getAddress(onShieldTemp, 0)) 
482     Serial.println("Error: Unable to find address for Device 0"); 
483   dallas_sensors.setResolution(onShieldTemp, 9);  
484
485   //save prev timer states:
486   save_tcnt2 = TCNT2;
487   save_tccr2a = TCCR2A;  // normal mode
488   save_tccr2b = TCCR2B;
489 }
490
491 unsigned int ir_time=IR_SAMPLE_DURATION;
492 unsigned int ir_count=0;
493 unsigned int ir_count2=0;
494 boolean pb_last_state=0;
495 boolean pb_state=0;
496 boolean pb_postth_state=0;
497 unsigned int pb_time=0;
498
499 void sensorEchoCommand(char command)
500 {
501   Serial.print("Sensor ");
502   Serial.print(command);
503   Serial.print(": ");
504 }
505
506 void loop()
507 {
508   ir_time--;
509   ir_count += (digitalRead(IR_MOVEMENT_PIN) == HIGH);
510   ir_count2 += (digitalRead(IR_MOVEMENT_PIN2) == HIGH);
511
512   if (pb_time < PB_TRESHOLD)
513     pb_time++;
514   pb_state=(digitalRead(PANIC_BUTTON_PIN) == HIGH);
515   
516   if (ir_time == 0)
517   {
518     if (ir_count >= IR_TRESHOLD || ir_count2 >= IR_TRESHOLD)
519     {
520       flash_led(0, 1, 8, 1, 0 );
521       Serial.println("movement");
522     }
523     ir_time=IR_SAMPLE_DURATION;
524     ir_count=0;
525     ir_count2=0;
526   }
527   
528   if (pb_state == pb_last_state && pb_time >= PB_TRESHOLD)
529   {
530     if (pb_state && ! pb_postth_state)
531     {   
532       pb_postth_state=1;
533       Serial.println("PanicButton");
534       flash_led(0, 28, 1, 4, 0 );
535       flash_led(1, 28, 1, 4, 4 );
536     }
537     else if (!pb_state)
538       pb_postth_state=0;
539   }
540   else if (pb_state != pb_last_state)
541   {
542     pb_time=0;
543     pb_last_state=pb_state;
544   }
545   
546   updateLightLevel(PHOTO_ANALOGPIN);
547   calculate_led_level();
548   check_frame_done();
549   
550   if(Serial.available()) {
551     char command = Serial.read();
552     
553     if(command == 'A')
554       send_frame(words[A1_ON]);
555     else if(command == 'a')
556       send_frame(words[A1_OFF]);
557     else if(command == 'B')
558       send_frame(words[A2_ON]);
559     else if(command == 'b')
560       send_frame(words[A2_OFF]);
561
562     else if(command == 'C')
563       send_frame(words[B1_ON]);
564     else if(command == 'c')
565       send_frame(words[B1_OFF]);
566     else if(command == 'D')
567       send_frame(words[B2_ON]);
568     else if(command == 'd')
569       send_frame(words[B2_OFF]);
570
571     else if(command == 'E')
572       send_frame(words[C1_ON]);
573     else if(command == 'e')
574       send_frame(words[C1_OFF]);
575     else if(command == 'F')
576       send_frame(words[C2_ON]);
577     else if(command == 'f')
578       send_frame(words[C2_OFF]);
579
580     else if(command == 'G')
581       send_frame(words[D1_ON]);
582     else if(command == 'g')
583       send_frame(words[D1_OFF]);
584     else if(command == 'H')
585       send_frame(words[D2_ON]);
586     else if(command == 'h')
587       send_frame(words[D2_OFF]);
588     else if(command == 'I')
589       send_frame(words[BLACK_A1_ON]);
590     else if(command == 'i')
591       send_frame(words[BLACK_A1_OFF]);
592     else if(command == 'J')
593       send_frame(words[BLACK_A2_ON]);
594     else if(command == 'j')
595       send_frame(words[BLACK_A2_OFF]);
596     else if(command == 'K')
597       send_frame(words[BLACK_A3_ON]);
598     else if(command == 'k')
599       send_frame(words[BLACK_A3_OFF]);
600     else if(command == 'L')
601       send_frame(words[BLACK_B1_ON]);
602     else if(command == 'l')
603       send_frame(words[BLACK_B1_OFF]);
604     else if(command == 'M')
605       send_frame(words[BLACK_B2_ON]);
606     else if(command == 'm')
607       send_frame(words[BLACK_B2_OFF]);
608     else if(command == 'N')
609       send_frame(words[BLACK_B3_ON]);
610     else if(command == 'n')
611       send_frame(words[BLACK_B3_OFF]);
612     else if(command == 'T')
613     {
614       sensorEchoCommand(command);
615       printTemperature(onShieldTemp);
616     }
617     else if(command == 'P')
618     {
619       sensorEchoCommand(command);
620       printLightLevel();
621     }
622     else if (command == '^')
623     {
624       //flash_led(1, 1, 2, 1, 0);
625       flash_led(1, 1, 1, 1, 0);
626       Serial.println("Ok");
627     }
628     else if (command == '&')
629     {
630       flash_led(0, 1, 2, 1, 0);
631       Serial.println("Ok");
632     }
633     else if (command == '1')
634       send_yamaha_ir_signal(YAMAHA_CD);
635     else if (command == '2')
636       send_yamaha_ir_signal(YAMAHA_TUNER);
637     else if (command == '3')
638       send_yamaha_ir_signal(YAMAHA_TAPE);
639     else if (command == '4')
640       send_yamaha_ir_signal(YAMAHA_DVD_SPDIF);
641     else if (command == '5')
642       send_yamaha_ir_signal(YAMAHA_SAT_SPDIFF);
643     else if (command == '6')
644       send_yamaha_ir_signal(YAMAHA_VCR);
645 //    else if (command == '7')
646 //      send_yamaha_ir_signal();
647     else if (command == '8')
648       send_yamaha_ir_signal(YAMAHA_AUX);
649     else if (command == '9')
650       send_yamaha_ir_signal(YAMAHA_EXT51DEC);
651     else if (command == '0')
652       send_yamaha_ir_signal(YAMAHA_TEST);
653     else if (command == '/')
654       send_yamaha_ir_signal(YAMAHA_TUNER_ABCDE);
655     else if (command == '\\')
656       send_yamaha_ir_signal(YAMAHA_EFFECT_TOGGLE);
657     else if (command == '-')
658       send_yamaha_ir_signal(YAMAHA_TUNER_MINUS);
659     else if (command == '+')
660       send_yamaha_ir_signal(YAMAHA_TUNER_PLUS);
661     else if (command == ':')
662       send_yamaha_ir_signal(YAMAHA_POWER_OFF);
663     else if (command == '.')
664       send_yamaha_ir_signal(YAMAHA_POWER_TOGGLE);
665     else if (command == ';')
666       send_yamaha_ir_signal(YAMAHA_VOLUME_UP);
667     else if (command == ',')
668       send_yamaha_ir_signal(YAMAHA_VOLUME_DOWN);
669     else if (command == '_')
670       send_yamaha_ir_signal(YAMAHA_MUTE);
671     else if (command == '#')
672       send_yamaha_ir_signal(YAMAHA_MENU);
673     else if (command == '"')
674       send_yamaha_ir_signal(YAMAHA_PLUS);
675     else if (command == '!')
676       send_yamaha_ir_signal(YAMAHA_MINUS);
677     else if (command == '=')
678       send_yamaha_ir_signal(YAMAHA_TIME_LEVEL);
679     else if (command == '$')
680       send_yamaha_ir_signal(YAMAHA_PRG_DOWN);
681     else if (command == '%')
682       send_yamaha_ir_signal(YAMAHA_PRG_UP);
683     else if (command == '(')
684       send_yamaha_ir_signal(YAMAHA_SLEEP);
685     else if (command == ')')
686       send_yamaha_ir_signal(YAMAHA_P5);
687     else
688       Serial.println("Error: unknown command");
689   }
690 }