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