--bug, physically present was not set on manual open/close -> light
[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 6000
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 typedef enum { ZERO = 0, ONE , FLOAT , SYNC } adbit_t;
116 typedef byte ad_bit_t;
117 #define WORD_LEN 13
118 typedef ad_bit_t word_t[WORD_LEN];
119
120 const rf_bit_t* bit_defs[] = { zero_bit, one_bit, float_bit, sync_bit };
121
122 byte alpha_cnt = 0;
123 byte bit_cnt = 0;
124 byte chunk_cnt = 0;
125 byte word_cnt = 0;
126 const ad_bit_t* current_word;
127 byte volatile frame_finished = 1;
128
129 #define FRAME_LEN 8
130
131 #define A1_ON  0
132 #define A1_OFF 1
133 #define A2_ON  2
134 #define A2_OFF 3
135
136 #define B1_ON  4
137 #define B1_OFF 5
138 #define B2_ON  6
139 #define B2_OFF 7
140
141 #define C1_ON  8
142 #define C1_OFF 9
143 #define C2_ON  10
144 #define C2_OFF 11
145
146 #define D1_ON  12
147 #define D1_OFF 13
148 #define D2_ON  14
149 #define D2_OFF 15
150
151 const word_t words[]  = { 
152 { ZERO,  ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // A1_ON
153 { ZERO,  ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // A1_OFF
154 { ZERO,  ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // A2_ON
155 { ZERO,  ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // A2_OFF
156
157 { FLOAT, ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // B1_ON
158 { FLOAT, ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // B1_OFF
159 { FLOAT, ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // B2_ON
160 { FLOAT, ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // B2_OFF
161
162 { ZERO,  FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // C1_ON
163 { ZERO,  FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // C1_OFF
164 { ZERO,  FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // C2_ON
165 { ZERO,  FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // C2_OFF
166
167 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // D1_ON
168 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // D1_OFF
169 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // D2_ON
170 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }  // D2_OFF
171 };
172
173
174 //********************************************************************//
175
176 void start_timer()
177 {
178   // timer 1: 2 ms
179   TCCR1A = 0;                    // prescaler 1:8, WGM = 4 (CTC)
180   TCCR1B = 1<<WGM12 | 1<<CS11;   // 
181   OCR1A = 159;        // (1+159)*8 = 1280 -> 0.08ms @ 16 MHz -> 1*alpha
182 //  OCR1A = 207;        // (1+207)*8 = 1664 -> 0.104ms @ 16 MHz -> 1*alpha
183   TCNT1 = 0;          // reseting timer
184   TIMSK1 = 1<<OCIE1A; // enable Interrupt
185 }
186
187 void stop_timer() // stop the timer
188 {
189   // timer1
190   TCCR1B = 0; // no clock source
191   TIMSK1 = 0; // disable timer interrupt
192 }
193
194 void init_word(const word_t w)
195 {
196   current_word = w;
197   alpha_cnt = 0;
198   chunk_cnt = 0;
199   bit_cnt = 0;
200
201   if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
202     digitalWrite(RF_DATA_OUT_PIN, LOW); //neue 12V MosFET Verstärkung invertiert Logik !
203   else
204     digitalWrite(RF_DATA_OUT_PIN, HIGH);
205
206   start_timer();
207 }
208
209 ISR(TIMER1_COMPA_vect)
210 {
211   alpha_cnt++;
212   if(alpha_cnt < bit_defs[current_word[bit_cnt]][chunk_cnt].offset)
213     return;
214
215   chunk_cnt++;
216   if(bit_defs[current_word[bit_cnt]][chunk_cnt].offset != 0) {
217     if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
218       digitalWrite(RF_DATA_OUT_PIN, LOW); //neue 12V MosFET Verstärkung invertiert Logik !
219     else
220       digitalWrite(RF_DATA_OUT_PIN, HIGH);
221     return;
222   }
223   
224   bit_cnt++;
225   if(bit_cnt < WORD_LEN) {
226     alpha_cnt = 0;
227     chunk_cnt = 0;
228     if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
229       digitalWrite(RF_DATA_OUT_PIN, LOW); //neue 12V MosFET Verstärkung invertiert Logik !
230     else
231       digitalWrite(RF_DATA_OUT_PIN, HIGH);
232     return;
233   }
234   stop_timer();
235   digitalWrite(RF_DATA_OUT_PIN, HIGH);
236
237   word_cnt++;
238   if(word_cnt < FRAME_LEN)
239     init_word(current_word);
240   else
241     frame_finished = 2;
242 }
243
244 //***********//
245
246
247 void send_frame(const word_t w)
248 {
249   if (frame_finished != 1)
250     for(;;) //wait until sending of previous frame finishes
251       if (frame_finished)
252       {
253         delay(150);
254         break;
255       }
256   word_cnt = 0;
257   frame_finished = 0;
258   init_word(w);
259 }
260
261 void check_frame_done()
262 {
263   if (frame_finished==2)
264   {
265     Serial.println("Ok");
266     frame_finished=1;
267     delay(120);
268   }
269 }
270
271 //********************************************************************//
272
273 void printTemperature(DeviceAddress deviceAddress)
274 {
275   dallas_sensors.requestTemperatures();
276   float tempC = dallas_sensors.getTempC(deviceAddress);
277   //Serial.print("Temp C: ");
278   Serial.println(tempC TEMPC_OFFSET_ARDUINO_GENEREATED_HEAT);
279   //Serial.print(" Temp F: ");
280   //Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
281 }
282
283 //********************************************************************//
284
285 unsigned int light_level_mean_ = 0;
286 unsigned int light_sample_time_ = 0;
287
288 void updateLightLevel(unsigned int pin)
289 {
290   light_sample_time_++;
291   if (light_sample_time_ < PHOTO_SAMPLE_INTERVAL)
292     return;
293   light_sample_time_ = 0;
294   
295   unsigned int value = analogRead(pin);
296   if (value == light_level_mean_)
297     return;
298   
299   unsigned int diff = abs(value - light_level_mean_);
300   if (diff > 100)
301     light_level_mean_ = value;
302   else
303       light_level_mean_=(unsigned int) ( ((float) light_level_mean_) * 0.90 + ((float)value)*0.10 );
304 }
305
306 void printLightLevel()
307 {
308   //Serial.print("Photo: ");
309   Serial.println(light_level_mean_);
310 }
311
312 //********************************************************************//
313
314 unsigned long wm_start_[3]={0,0,0};
315 bool wait_millis(unsigned long *start_time, unsigned long ms)
316 {
317   if (ms == 0)
318     return false;
319   else if (*start_time > 0)
320   {
321     if (millis() < *start_time || millis() > (*start_time) + ms)
322     {
323       *start_time = 0;
324       return false;
325     }
326     else
327       return true;
328   }
329   else
330   {
331     *start_time=millis();
332     return true;
333   }
334 }
335 #define NUM_LEDS 2
336 char flash_led_pins_[NUM_LEDS]={BLUELED_PWM_PIN,PANICLED_PWM_PIN};
337 unsigned int flash_led_time_[3]={0,0,0};
338 unsigned int flash_led_brightness_[3]={255,255,255};
339 unsigned int flash_led_delay_[3]={8,8,8};
340 unsigned int flash_led_initial_delay_[3]={0,0,0};
341 void calculate_led_level()
342 {
343   for (int ledid = 0; ledid < NUM_LEDS; ledid++)
344   {
345     if (flash_led_time_[ledid] == 0)
346       continue;
347     if (wait_millis(wm_start_ + ledid, flash_led_initial_delay_[ledid]))
348       continue;
349     flash_led_initial_delay_[ledid]=0;
350     if (wait_millis(wm_start_ + ledid, flash_led_delay_[ledid]))
351       continue;
352     flash_led_time_[ledid]--;
353     int c = abs(sin(float(flash_led_time_[ledid]) / 100.0)) * flash_led_brightness_[ledid];
354     //int d = abs(sin(float(flash_led_time_) / 100.0)) * flash_led_brightness_;
355     analogWrite(flash_led_pins_[ledid], 255-c);
356   }
357 }
358
359 // id: id of LED to flash (0,1)
360 // times: # of times the LED should flash
361 // brightness_divisor: 1: full brightness, 2: half brightness, ...
362 // delay_divisor: 1: slow... 8: fastest
363 // phase_divisor: 0.. same phase; 2.. pi/2 phase, 4.. pi phase, 6.. 3pi/2 phase
364 void flash_led(unsigned int id, unsigned int times, unsigned int brightness_divisor, unsigned int delay_divisor, unsigned int phase_divisor)
365 {
366   if (id >= NUM_LEDS)
367     return;
368   unsigned int new_flash_led_brightness = 255;
369   unsigned int new_flash_led_delay = 8;
370   if (times == 0)
371   {
372     analogWrite(flash_led_pins_[id],255); //off
373     return;
374   }
375   if (brightness_divisor > 1) //guard against div by zero
376     new_flash_led_brightness /= brightness_divisor;
377   if (delay_divisor > 1)  //guard against div by zero
378     new_flash_led_delay /= delay_divisor;
379   if (flash_led_time_[id] == 0 || new_flash_led_brightness > flash_led_brightness_[id])
380     flash_led_brightness_[id]=new_flash_led_brightness;
381   if (flash_led_time_[id] == 0 || new_flash_led_delay < flash_led_delay_[id])
382     flash_led_delay_[id]=new_flash_led_delay;
383   flash_led_time_[id] += 314*times;
384   flash_led_initial_delay_[id] = flash_led_delay_[id]*314*phase_divisor/8;
385 }
386
387 //********************************************************************//
388
389 int save_tcnt2=0;
390 int save_tccr2a=0;
391 int save_tccr2b=0;
392 void reset_timer2()
393 {
394   TCNT2 = save_tcnt2;
395   TCCR2A = save_tccr2a;  // normal mode
396   TCCR2B = save_tccr2b;
397   //TCNT2 = 256 - (50*(16000000/8/1000000)) + 5;
398   //TCCR2A = 0;  // normal mode
399   //TCCR2B = 0;
400 }
401
402 void send_yamaha_ir_signal(char codebyte)
403 {
404   unsigned long int code = codebyte & 0xFF;
405   code <<= 8;
406   code |= (0xff ^ codebyte) & 0xFF;
407   code |= YAMAHA_CODE_BASE;
408   
409   //irsend changes PWM Timer Frequency among other things
410   //.. doesn't go well with PWM output using the same timer
411   //.. thus we just set output to 255 so whatever frequency is used, led is off for the duration
412   //analogWrite(BLUELED_PWM_PIN,255); // switch led off
413
414   irsend.sendNEC(code,YAMAHA_CODE_BITS);
415
416   reset_timer2();
417   analogWrite(BLUELED_PWM_PIN,255); // switch off led again to be sure
418                                       //is actually not necessary, since we are not multitasking/using interrupts, but just to be sure in case this might change
419
420   Serial.println("Ok");
421 }
422
423 //********************************************************************//
424
425 void setup()
426 {
427   pinMode(RF_DATA_OUT_PIN, OUTPUT);
428   digitalWrite(RF_DATA_OUT_PIN, HIGH);
429   pinMode(IR_MOVEMENT_PIN, INPUT);      // set pin to input
430   digitalWrite(IR_MOVEMENT_PIN, LOW);  // turn off pullup resistors  
431   digitalWrite(IR_MOVEMENT_PIN2, LOW);  // turn off pullup resistors  
432   pinMode(PANIC_BUTTON_PIN, INPUT);      // set pin to input
433   digitalWrite(PANIC_BUTTON_PIN, LOW);  // turn of pullup resistors 
434   analogWrite(PANICLED_PWM_PIN,255);
435   analogWrite(BLUELED_PWM_PIN,255); //pwm sink(-) instead of pwm + (better for mosfets)
436   pinMode(IRREMOTE_SEND_PIN, OUTPUT);
437   digitalWrite(IRREMOTE_SEND_PIN, HIGH);
438   
439   Serial.begin(9600);
440   
441   onewire.reset();
442   onewire.reset_search();
443   dallas_sensors.begin();
444   //in case we change temp sensor:
445   if (!dallas_sensors.getAddress(onShieldTemp, 0)) 
446     Serial.println("Error: Unable to find address for Device 0"); 
447   dallas_sensors.setResolution(onShieldTemp, 9);  
448
449   //save prev timer states:
450   save_tcnt2 = TCNT2;
451   save_tccr2a = TCCR2A;  // normal mode
452   save_tccr2b = TCCR2B;
453 }
454
455 unsigned int ir_time=IR_SAMPLE_DURATION;
456 unsigned int ir_count=0;
457 unsigned int ir_count2=0;
458 boolean pb_last_state=0;
459 boolean pb_state=0;
460 boolean pb_postth_state=0;
461 unsigned int pb_time=0;
462
463 void sensorEchoCommand(char command)
464 {
465   Serial.print("Sensor ");
466   Serial.print(command);
467   Serial.print(": ");
468 }
469
470 void loop()
471 {
472   ir_time--;
473   ir_count += (digitalRead(IR_MOVEMENT_PIN) == HIGH);
474   ir_count2 += (digitalRead(IR_MOVEMENT_PIN2) == HIGH);
475
476   if (pb_time < PB_TRESHOLD)
477     pb_time++;
478   pb_state=(digitalRead(PANIC_BUTTON_PIN) == HIGH);
479   
480   if (ir_time == 0)
481   {
482     if (ir_count >= IR_TRESHOLD || ir_count2 >= IR_TRESHOLD)
483     {
484       flash_led(0, 1, 8, 1, 0 );
485       Serial.println("movement");
486     }
487     ir_time=IR_SAMPLE_DURATION;
488     ir_count=0;
489     ir_count2=0;
490   }
491   
492   if (pb_state == pb_last_state && pb_time >= PB_TRESHOLD)
493   {
494     if (pb_state && ! pb_postth_state)
495     {   
496       pb_postth_state=1;
497       Serial.println("PanicButton");
498       flash_led(0, 28, 1, 4, 0 );
499       flash_led(1, 28, 1, 4, 4 );
500     }
501     else if (!pb_state)
502       pb_postth_state=0;
503   }
504   else if (pb_state != pb_last_state)
505   {
506     pb_time=0;
507     pb_last_state=pb_state;
508   }
509   
510   updateLightLevel(PHOTO_ANALOGPIN);
511   calculate_led_level();
512   check_frame_done();
513   
514   if(Serial.available()) {
515     char command = Serial.read();
516     
517     if(command == 'A')
518       send_frame(words[A1_ON]);
519     else if(command == 'a')
520       send_frame(words[A1_OFF]);
521     else if(command == 'B')
522       send_frame(words[A2_ON]);
523     else if(command == 'b')
524       send_frame(words[A2_OFF]);
525
526     else if(command == 'C')
527       send_frame(words[B1_ON]);
528     else if(command == 'c')
529       send_frame(words[B1_OFF]);
530     else if(command == 'D')
531       send_frame(words[B2_ON]);
532     else if(command == 'd')
533       send_frame(words[B2_OFF]);
534
535     else if(command == 'E')
536       send_frame(words[C1_ON]);
537     else if(command == 'e')
538       send_frame(words[C1_OFF]);
539     else if(command == 'F')
540       send_frame(words[C2_ON]);
541     else if(command == 'f')
542       send_frame(words[C2_OFF]);
543
544     else if(command == 'G')
545       send_frame(words[D1_ON]);
546     else if(command == 'g')
547       send_frame(words[D1_OFF]);
548     else if(command == 'H')
549       send_frame(words[D2_ON]);
550     else if(command == 'h')
551       send_frame(words[D2_OFF]);
552     else if(command == 'T')
553     {
554       sensorEchoCommand(command);
555       printTemperature(onShieldTemp);
556     }
557     else if(command == 'P')
558     {
559       sensorEchoCommand(command);
560       printLightLevel();
561     }
562     else if (command == '^')
563     {
564       //flash_led(1, 1, 2, 1, 0);
565       flash_led(1, 1, 1, 1, 0);
566       Serial.println("Ok");
567     }
568     else if (command == '&')
569     {
570       flash_led(0, 1, 2, 1, 0);
571       Serial.println("Ok");
572     }
573     else if (command == '1')
574       send_yamaha_ir_signal(YAMAHA_CD);
575     else if (command == '2')
576       send_yamaha_ir_signal(YAMAHA_TUNER);
577     else if (command == '3')
578       send_yamaha_ir_signal(YAMAHA_TAPE);
579     else if (command == '4')
580       send_yamaha_ir_signal(YAMAHA_DVD_SPDIF);
581     else if (command == '5')
582       send_yamaha_ir_signal(YAMAHA_SAT_SPDIFF);
583     else if (command == '6')
584       send_yamaha_ir_signal(YAMAHA_VCR);
585 //    else if (command == '7')
586 //      send_yamaha_ir_signal();
587     else if (command == '8')
588       send_yamaha_ir_signal(YAMAHA_AUX);
589     else if (command == '9')
590       send_yamaha_ir_signal(YAMAHA_EXT51DEC);
591     else if (command == '0')
592       send_yamaha_ir_signal(YAMAHA_TEST);
593     else if (command == '/')
594       send_yamaha_ir_signal(YAMAHA_TUNER_ABCDE);
595     else if (command == '\\')
596       send_yamaha_ir_signal(YAMAHA_EFFECT_TOGGLE);
597     else if (command == '-')
598       send_yamaha_ir_signal(YAMAHA_TUNER_MINUS);
599     else if (command == '+')
600       send_yamaha_ir_signal(YAMAHA_TUNER_PLUS);
601     else if (command == ':')
602       send_yamaha_ir_signal(YAMAHA_POWER_OFF);
603     else if (command == '.')
604       send_yamaha_ir_signal(YAMAHA_POWER_TOGGLE);
605     else if (command == ';')
606       send_yamaha_ir_signal(YAMAHA_VOLUME_UP);
607     else if (command == ',')
608       send_yamaha_ir_signal(YAMAHA_VOLUME_DOWN);
609     else if (command == '_')
610       send_yamaha_ir_signal(YAMAHA_MUTE);
611     else if (command == '#')
612       send_yamaha_ir_signal(YAMAHA_MENU);
613     else if (command == '"')
614       send_yamaha_ir_signal(YAMAHA_PLUS);
615     else if (command == '!')
616       send_yamaha_ir_signal(YAMAHA_MINUS);
617     else if (command == '=')
618       send_yamaha_ir_signal(YAMAHA_TIME_LEVEL);
619     else if (command == '$')
620       send_yamaha_ir_signal(YAMAHA_PRG_DOWN);
621     else if (command == '%')
622       send_yamaha_ir_signal(YAMAHA_PRG_UP);
623     else if (command == '(')
624       send_yamaha_ir_signal(YAMAHA_SLEEP);
625     else if (command == ')')
626       send_yamaha_ir_signal(YAMAHA_P5);
627     else
628       Serial.println("Error: unknown command");
629   }
630 }