black remote works, all codes included now
[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 //WORKS @ alpha=0.0775ms
116 //const rf_bit_t pwm_0_bit[] = {  {7, 1}, {24, 0}, {  0, 0 } };     // 1.86ms gesamt: { 0.46ms HIGH , 1.4ms LOW }
117 //const rf_bit_t pwm_1_bit[] = {  {18, 1}, {24, 0}, {  0, 0 } };    // 1.86ms gesamt: { 1.4ms HIGH , 0.46ms LOW }
118 //const rf_bit_t pwm_pause_bit[] = {  {168, 0}, {  0, 0 } };        // 13ms pause 
119
120 //WORKS @ alpha=0.08ms
121 const rf_bit_t pwm_0_bit[] = {  {6, 1}, {23, 0}, {  0, 0 } };   // 1.86ms gesamt: { 0.46ms HIGH , 1.4ms LOW }
122 const rf_bit_t pwm_1_bit[] = {  {18, 1}, {23, 0}, {  0, 0 } };  // 1.86ms gesamt: { 1.4ms HIGH , 0.46ms LOW }
123 const rf_bit_t pwm_pause_bit[] = {  {162, 0}, {  0, 0 } };      // 13ms pause 
124
125 typedef enum { ZERO = 0, ONE , FLOAT , SYNC , PWM0, PWM1, PWM_PAUSE, WORD_END } adbit_t;
126 typedef byte ad_bit_t;
127 #define MAX_WORD_LEN 27
128 typedef ad_bit_t word_t[MAX_WORD_LEN];
129
130 const rf_bit_t* bit_defs[] = { zero_bit, one_bit, float_bit, sync_bit, pwm_0_bit, pwm_1_bit, pwm_pause_bit };
131
132 byte alpha_cnt = 0;
133 byte bit_cnt = 0;
134 byte chunk_cnt = 0;
135 byte word_cnt = 0;
136 const ad_bit_t* current_word;
137 byte volatile frame_finished = 1;
138
139 #define FRAME_LEN 10
140
141 #define A1_ON  0
142 #define A1_OFF 1
143 #define A2_ON  2
144 #define A2_OFF 3
145
146 #define B1_ON  4
147 #define B1_OFF 5
148 #define B2_ON  6
149 #define B2_OFF 7
150
151 #define C1_ON  8
152 #define C1_OFF 9
153 #define C2_ON  10
154 #define C2_OFF 11
155
156 #define D1_ON  12
157 #define D1_OFF 13
158 #define D2_ON  14
159 #define D2_OFF 15
160
161 #define BLACK_A1_ON 16
162 #define BLACK_A1_OFF 17
163 #define BLACK_A2_ON 18
164 #define BLACK_A2_OFF 19
165 #define BLACK_A3_ON 20
166 #define BLACK_A3_OFF 21
167
168 #define BLACK_B1_ON 22
169 #define BLACK_B1_OFF 23
170 #define BLACK_B2_ON 24
171 #define BLACK_B2_OFF 25
172 #define BLACK_B3_ON 26
173 #define BLACK_B3_OFF 27
174
175 #define BLACK_C1_ON 28
176 #define BLACK_C1_OFF 29
177 #define BLACK_C2_ON 30
178 #define BLACK_C2_OFF 31
179 #define BLACK_C3_ON 32
180 #define BLACK_C3_OFF 33
181
182 #define BLACK_D1_ON 34
183 #define BLACK_D1_OFF 35
184 #define BLACK_D2_ON 36
185 #define BLACK_D2_OFF 37
186 #define BLACK_D3_ON 38
187 #define BLACK_D3_OFF 39
188
189
190 const word_t words[]  = { 
191 { ZERO,  ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC, WORD_END, WORD_END,WORD_END}, // A1_ON
192 { ZERO,  ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC, WORD_END, WORD_END,WORD_END}, // A1_OFF
193 { ZERO,  ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC, WORD_END, WORD_END,WORD_END }, // A2_ON
194 { ZERO,  ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC, WORD_END, WORD_END,WORD_END }, // A2_OFF
195
196 { FLOAT, ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC, WORD_END, WORD_END,WORD_END }, // B1_ON
197 { FLOAT, ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC, WORD_END, WORD_END,WORD_END }, // B1_OFF
198 { FLOAT, ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC, WORD_END, WORD_END,WORD_END }, // B2_ON
199 { FLOAT, ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC, WORD_END, WORD_END,WORD_END }, // B2_OFF
200
201 { ZERO,  FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC, WORD_END, WORD_END,WORD_END }, // C1_ON
202 { ZERO,  FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC, WORD_END, WORD_END,WORD_END }, // C1_OFF
203 { ZERO,  FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC, WORD_END, WORD_END,WORD_END }, // C2_ON
204 { ZERO,  FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC, WORD_END, WORD_END,WORD_END }, // C2_OFF
205
206 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC, WORD_END, WORD_END,WORD_END }, // D1_ON
207 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC, WORD_END, WORD_END,WORD_END }, // D1_OFF
208 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC, WORD_END, WORD_END,WORD_END }, // D2_ON
209 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC, WORD_END, WORD_END,WORD_END }, // D2_OFF
210
211 {PWM1,PWM1,PWM0,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_A1_ON
212 {PWM1,PWM1,PWM0,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_A1_OFF
213 {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
214 {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
215 {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
216 {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
217
218 {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  
219 {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  
220 {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  
221 {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  
222 {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
223 {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
224   
225 {PWM0,PWM1,PWM0,PWM1,PWM1,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_C1_ON  
226 {PWM0,PWM1,PWM0,PWM1,PWM1,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_C1_OFF  
227 {PWM0,PWM1,PWM0,PWM1,PWM1,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_C2_ON  
228 {PWM0,PWM1,PWM0,PWM1,PWM1,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_C2_OFF  
229 {PWM0,PWM1,PWM0,PWM1,PWM1,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_C3_ON
230 {PWM0,PWM1,PWM0,PWM1,PWM1,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_C3_OFF  
231   
232 {PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM1,PWM1,PWM0,PWM0,PWM0, PWM_PAUSE, WORD_END}, // BLACK_D1_ON  
233 {PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM1,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM1,PWM1,PWM0, PWM_PAUSE, WORD_END}, // BLACK_D1_OFF  
234 {PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM1,PWM1,PWM0,PWM0,PWM0, PWM_PAUSE, WORD_END}, // BLACK_D2_ON  
235 {PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM1,PWM1,PWM0, PWM_PAUSE, WORD_END}, // BLACK_D2_OFF  
236 {PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM1,PWM1,PWM0,PWM0,PWM0, PWM_PAUSE, WORD_END}, // BLACK_D3_ON
237 {PWM0,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM1,PWM0,PWM1,PWM1,PWM1,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM0,PWM1,PWM1,PWM0, PWM_PAUSE, WORD_END}  // BLACK_D3_OFF
238 };
239
240
241 //********************************************************************//
242
243 void start_timer()
244 {
245   // timer 1: 2 ms
246   TCCR1A = 0;                    // prescaler 1:8, WGM = 4 (CTC)
247   TCCR1B = 1<<WGM12 | 1<<CS11;   // 
248 //  OCR1A = 39;        // (1+39)*8 = 320 -> 0.02ms @ 16 MHz -> 1*alpha
249 //default: alpha=0.08  
250   OCR1A = 159;        // (1+159)*8 = 1280 -> 0.08ms @ 16 MHz -> 1*alpha
251 //  OCR1A = 154;        // (1+154)*8 = 1240 -> 0.0775ms @ 16 MHz -> 1*alpha
252 //  OCR1A = 207;        // (1+207)*8 = 1664 -> 0.104ms @ 16 MHz -> 1*alpha
253   TCNT1 = 0;          // reseting timer
254   TIMSK1 = 1<<OCIE1A; // enable Interrupt
255 }
256
257 void stop_timer() // stop the timer
258 {
259   // timer1
260   TCCR1B = 0; // no clock source
261   TIMSK1 = 0; // disable timer interrupt
262 }
263
264 void init_word(const word_t w)
265 {
266   current_word = w;
267   alpha_cnt = 0;
268   chunk_cnt = 0;
269   bit_cnt = 0;
270
271   if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
272     digitalWrite(RF_DATA_OUT_PIN, LOW); //neue 12V MosFET Verstärkung invertiert Logik !
273   else
274     digitalWrite(RF_DATA_OUT_PIN, HIGH);
275
276   start_timer();
277 }
278
279 ISR(TIMER1_COMPA_vect)
280 {
281   alpha_cnt++;
282   if(alpha_cnt < bit_defs[current_word[bit_cnt]][chunk_cnt].offset)
283     return;
284
285   chunk_cnt++;
286   if(bit_defs[current_word[bit_cnt]][chunk_cnt].offset != 0) {
287     if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
288       digitalWrite(RF_DATA_OUT_PIN, LOW); //neue 12V MosFET Verstärkung invertiert Logik !
289     else
290       digitalWrite(RF_DATA_OUT_PIN, HIGH);
291     return;
292   }
293   
294   bit_cnt++;
295   if(current_word[bit_cnt] != WORD_END && bit_cnt < MAX_WORD_LEN) {
296     alpha_cnt = 0;
297     chunk_cnt = 0;
298     if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
299       digitalWrite(RF_DATA_OUT_PIN, LOW); //neue 12V MosFET Verstärkung invertiert Logik !
300     else
301       digitalWrite(RF_DATA_OUT_PIN, HIGH);
302     return;
303   }
304   stop_timer();
305   digitalWrite(RF_DATA_OUT_PIN, HIGH);
306
307   word_cnt++;
308   if(word_cnt < FRAME_LEN)
309     init_word(current_word);
310   else
311     frame_finished = 2;
312 }
313
314 //***********//
315
316
317 void send_frame(const word_t w)
318 {
319   if (frame_finished != 1)
320     for(;;) //wait until sending of previous frame finishes
321       if (frame_finished)
322       {
323         delay(150);
324         break;
325       }
326   word_cnt = 0;
327   frame_finished = 0;
328   init_word(w);
329 }
330
331 void check_frame_done()
332 {
333   if (frame_finished==2)
334   {
335     Serial.println("Ok");
336     frame_finished=1;
337     delay(120);
338   }
339 }
340
341 //********************************************************************//
342
343 void printTemperature(DeviceAddress deviceAddress)
344 {
345   dallas_sensors.requestTemperatures();
346   float tempC = dallas_sensors.getTempC(deviceAddress);
347   //Serial.print("Temp C: ");
348   Serial.println(tempC TEMPC_OFFSET_ARDUINO_GENEREATED_HEAT);
349   //Serial.print(" Temp F: ");
350   //Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
351 }
352
353 //********************************************************************//
354
355 unsigned int light_level_mean_ = 0;
356 unsigned int light_sample_time_ = 0;
357
358 void updateLightLevel(unsigned int pin)
359 {
360   light_sample_time_++;
361   if (light_sample_time_ < PHOTO_SAMPLE_INTERVAL)
362     return;
363   light_sample_time_ = 0;
364   
365   unsigned int value = analogRead(pin);
366   if (value == light_level_mean_)
367     return;
368   
369   unsigned int diff = abs(value - light_level_mean_);
370   if (diff > 100)
371     light_level_mean_ = value;
372   else
373       light_level_mean_=(unsigned int) ( ((float) light_level_mean_) * 0.90 + ((float)value)*0.10 );
374 }
375
376 void printLightLevel()
377 {
378   //Serial.print("Photo: ");
379   Serial.println(light_level_mean_);
380 }
381
382 //********************************************************************//
383
384 unsigned long wm_start_[3]={0,0,0};
385 bool wait_millis(unsigned long *start_time, unsigned long ms)
386 {
387   if (ms == 0)
388     return false;
389   else if (*start_time > 0)
390   {
391     if (millis() < *start_time || millis() > (*start_time) + ms)
392     {
393       *start_time = 0;
394       return false;
395     }
396     else
397       return true;
398   }
399   else
400   {
401     *start_time=millis();
402     return true;
403   }
404 }
405 #define NUM_LEDS 2
406 char flash_led_pins_[NUM_LEDS]={BLUELED_PWM_PIN,PANICLED_PWM_PIN};
407 unsigned int flash_led_time_[3]={0,0,0};
408 unsigned int flash_led_brightness_[3]={255,255,255};
409 unsigned int flash_led_delay_[3]={8,8,8};
410 unsigned int flash_led_initial_delay_[3]={0,0,0};
411 void calculate_led_level()
412 {
413   for (int ledid = 0; ledid < NUM_LEDS; ledid++)
414   {
415     if (flash_led_time_[ledid] == 0)
416       continue;
417     if (wait_millis(wm_start_ + ledid, flash_led_initial_delay_[ledid]))
418       continue;
419     flash_led_initial_delay_[ledid]=0;
420     if (wait_millis(wm_start_ + ledid, flash_led_delay_[ledid]))
421       continue;
422     flash_led_time_[ledid]--;
423     int c = abs(sin(float(flash_led_time_[ledid]) / 100.0)) * flash_led_brightness_[ledid];
424     //int d = abs(sin(float(flash_led_time_) / 100.0)) * flash_led_brightness_;
425     analogWrite(flash_led_pins_[ledid], 255-c);
426   }
427 }
428
429 // id: id of LED to flash (0,1)
430 // times: # of times the LED should flash
431 // brightness_divisor: 1: full brightness, 2: half brightness, ...
432 // delay_divisor: 1: slow... 8: fastest
433 // phase_divisor: 0.. same phase; 2.. pi/2 phase, 4.. pi phase, 6.. 3pi/2 phase
434 void flash_led(unsigned int id, unsigned int times, unsigned int brightness_divisor, unsigned int delay_divisor, unsigned int phase_divisor)
435 {
436   if (id >= NUM_LEDS)
437     return;
438   unsigned int new_flash_led_brightness = 255;
439   unsigned int new_flash_led_delay = 8;
440   if (times == 0)
441   {
442     analogWrite(flash_led_pins_[id],255); //off
443     return;
444   }
445   if (brightness_divisor > 1) //guard against div by zero
446     new_flash_led_brightness /= brightness_divisor;
447   if (delay_divisor > 1)  //guard against div by zero
448     new_flash_led_delay /= delay_divisor;
449   if (flash_led_time_[id] == 0 || new_flash_led_brightness > flash_led_brightness_[id])
450     flash_led_brightness_[id]=new_flash_led_brightness;
451   if (flash_led_time_[id] == 0 || new_flash_led_delay < flash_led_delay_[id])
452     flash_led_delay_[id]=new_flash_led_delay;
453   flash_led_time_[id] += 314*times;
454   flash_led_initial_delay_[id] = flash_led_delay_[id]*314*phase_divisor/8;
455 }
456
457 //********************************************************************//
458
459 int save_tcnt2=0;
460 int save_tccr2a=0;
461 int save_tccr2b=0;
462 void reset_timer2()
463 {
464   TCNT2 = save_tcnt2;
465   TCCR2A = save_tccr2a;  // normal mode
466   TCCR2B = save_tccr2b;
467   //TCNT2 = 256 - (50*(16000000/8/1000000)) + 5;
468   //TCCR2A = 0;  // normal mode
469   //TCCR2B = 0;
470 }
471
472 void send_yamaha_ir_signal(char codebyte)
473 {
474   unsigned long int code = codebyte & 0xFF;
475   code <<= 8;
476   code |= (0xff ^ codebyte) & 0xFF;
477   code |= YAMAHA_CODE_BASE;
478   
479   //irsend changes PWM Timer Frequency among other things
480   //.. doesn't go well with PWM output using the same timer
481   //.. thus we just set output to 255 so whatever frequency is used, led is off for the duration
482   //analogWrite(BLUELED_PWM_PIN,255); // switch led off
483
484   irsend.sendNEC(code,YAMAHA_CODE_BITS);
485
486   reset_timer2();
487   analogWrite(BLUELED_PWM_PIN,255); // switch off led again to be sure
488                                       //is actually not necessary, since we are not multitasking/using interrupts, but just to be sure in case this might change
489
490   Serial.println("Ok");
491 }
492
493 //********************************************************************//
494
495 void setup()
496 {
497   pinMode(RF_DATA_OUT_PIN, OUTPUT);
498   digitalWrite(RF_DATA_OUT_PIN, HIGH);
499   pinMode(IR_MOVEMENT_PIN, INPUT);      // set pin to input
500   digitalWrite(IR_MOVEMENT_PIN, LOW);  // turn off pullup resistors  
501   digitalWrite(IR_MOVEMENT_PIN2, LOW);  // turn off pullup resistors  
502   pinMode(PANIC_BUTTON_PIN, INPUT);      // set pin to input
503   digitalWrite(PANIC_BUTTON_PIN, LOW);  // turn of pullup resistors 
504   analogWrite(PANICLED_PWM_PIN,255);
505   analogWrite(BLUELED_PWM_PIN,255); //pwm sink(-) instead of pwm + (better for mosfets)
506   pinMode(IRREMOTE_SEND_PIN, OUTPUT);
507   digitalWrite(IRREMOTE_SEND_PIN, HIGH);
508   
509   Serial.begin(9600);
510   
511   onewire.reset();
512   onewire.reset_search();
513   dallas_sensors.begin();
514   //in case we change temp sensor:
515   if (!dallas_sensors.getAddress(onShieldTemp, 0)) 
516     Serial.println("Error: Unable to find address for Device 0"); 
517   dallas_sensors.setResolution(onShieldTemp, 9);  
518
519   //save prev timer states:
520   save_tcnt2 = TCNT2;
521   save_tccr2a = TCCR2A;  // normal mode
522   save_tccr2b = TCCR2B;
523 }
524
525 unsigned int ir_time=IR_SAMPLE_DURATION;
526 unsigned int ir_count=0;
527 unsigned int ir_count2=0;
528 boolean pb_last_state=0;
529 boolean pb_state=0;
530 boolean pb_postth_state=0;
531 unsigned int pb_time=0;
532
533 void sensorEchoCommand(char command)
534 {
535   Serial.print("Sensor ");
536   Serial.print(command);
537   Serial.print(": ");
538 }
539
540 void loop()
541 {
542   ir_time--;
543   ir_count += (digitalRead(IR_MOVEMENT_PIN) == HIGH);
544   ir_count2 += (digitalRead(IR_MOVEMENT_PIN2) == HIGH);
545
546   if (pb_time < PB_TRESHOLD)
547     pb_time++;
548   pb_state=(digitalRead(PANIC_BUTTON_PIN) == HIGH);
549   
550   if (ir_time == 0)
551   {
552     if (ir_count >= IR_TRESHOLD || ir_count2 >= IR_TRESHOLD)
553     {
554       flash_led(0, 1, 8, 1, 0 );
555       Serial.println("movement");
556     }
557     ir_time=IR_SAMPLE_DURATION;
558     ir_count=0;
559     ir_count2=0;
560   }
561   
562   if (pb_state == pb_last_state && pb_time >= PB_TRESHOLD)
563   {
564     if (pb_state && ! pb_postth_state)
565     {   
566       pb_postth_state=1;
567       Serial.println("PanicButton");
568       flash_led(0, 28, 1, 4, 0 );
569       flash_led(1, 28, 1, 4, 4 );
570     }
571     else if (!pb_state)
572       pb_postth_state=0;
573   }
574   else if (pb_state != pb_last_state)
575   {
576     pb_time=0;
577     pb_last_state=pb_state;
578   }
579   
580   updateLightLevel(PHOTO_ANALOGPIN);
581   calculate_led_level();
582   check_frame_done();
583   
584   if(Serial.available()) {
585     char command = Serial.read();
586     
587     if(command == 'A')
588       send_frame(words[A1_ON]);
589     else if(command == 'a')
590       send_frame(words[A1_OFF]);
591     else if(command == 'B')
592       send_frame(words[A2_ON]);
593     else if(command == 'b')
594       send_frame(words[A2_OFF]);
595
596     else if(command == 'C')
597       send_frame(words[B1_ON]);
598     else if(command == 'c')
599       send_frame(words[B1_OFF]);
600     else if(command == 'D')
601       send_frame(words[B2_ON]);
602     else if(command == 'd')
603       send_frame(words[B2_OFF]);
604
605     else if(command == 'E')
606       send_frame(words[C1_ON]);
607     else if(command == 'e')
608       send_frame(words[C1_OFF]);
609     else if(command == 'F')
610       send_frame(words[C2_ON]);
611     else if(command == 'f')
612       send_frame(words[C2_OFF]);
613
614     else if(command == 'G')
615       send_frame(words[D1_ON]);
616     else if(command == 'g')
617       send_frame(words[D1_OFF]);
618     else if(command == 'H')
619       send_frame(words[D2_ON]);
620     else if(command == 'h')
621       send_frame(words[D2_OFF]);
622       
623     else if(command == 'I')
624       send_frame(words[BLACK_A1_ON]);
625     else if(command == 'i')
626       send_frame(words[BLACK_A1_OFF]);
627     else if(command == 'J')
628       send_frame(words[BLACK_A2_ON]);
629     else if(command == 'j')
630       send_frame(words[BLACK_A2_OFF]);
631     else if(command == 'K')
632       send_frame(words[BLACK_A3_ON]);
633     else if(command == 'k')
634       send_frame(words[BLACK_A3_OFF]);
635       
636     else if(command == 'L')
637       send_frame(words[BLACK_B1_ON]);
638     else if(command == 'l')
639       send_frame(words[BLACK_B1_OFF]);
640     else if(command == 'M')
641       send_frame(words[BLACK_B2_ON]);
642     else if(command == 'm')
643       send_frame(words[BLACK_B2_OFF]);
644     else if(command == 'N')
645       send_frame(words[BLACK_B3_ON]);
646     else if(command == 'n')
647       send_frame(words[BLACK_B3_OFF]);
648       
649     else if(command == 'O')
650       send_frame(words[BLACK_C1_ON]);
651     else if(command == 'o')
652       send_frame(words[BLACK_C1_OFF]);
653     else if(command == 'P')
654       send_frame(words[BLACK_C2_ON]);
655     else if(command == 'p')
656       send_frame(words[BLACK_C2_OFF]);
657     else if(command == 'Q')
658       send_frame(words[BLACK_C3_ON]);
659     else if(command == 'q')
660       send_frame(words[BLACK_C3_OFF]);
661             
662     else if(command == 'R')
663       send_frame(words[BLACK_D1_ON]);
664     else if(command == 'r')
665       send_frame(words[BLACK_D1_OFF]);
666     else if(command == 'S')
667       send_frame(words[BLACK_D2_ON]);
668     else if(command == 's')
669       send_frame(words[BLACK_D2_OFF]);
670     else if(command == 'T')
671       send_frame(words[BLACK_D3_ON]);
672     else if(command == 't')
673       send_frame(words[BLACK_D3_OFF]);
674       
675     else if(command == '*')
676     {
677       sensorEchoCommand(command);
678       printTemperature(onShieldTemp);
679     }
680     else if(command == '?')
681     {
682       sensorEchoCommand(command);
683       printLightLevel();
684     }
685     else if (command == '^')
686     {
687       //flash_led(1, 1, 2, 1, 0);
688       flash_led(1, 1, 1, 1, 0);
689       Serial.println("Ok");
690     }
691     else if (command == '&')
692     {
693       flash_led(0, 1, 2, 1, 0);
694       Serial.println("Ok");
695     }
696     else if (command == '1')
697       send_yamaha_ir_signal(YAMAHA_CD);
698     else if (command == '2')
699       send_yamaha_ir_signal(YAMAHA_TUNER);
700     else if (command == '3')
701       send_yamaha_ir_signal(YAMAHA_TAPE);
702     else if (command == '4')
703       send_yamaha_ir_signal(YAMAHA_DVD_SPDIF);
704     else if (command == '5')
705       send_yamaha_ir_signal(YAMAHA_SAT_SPDIFF);
706     else if (command == '6')
707       send_yamaha_ir_signal(YAMAHA_VCR);
708 //    else if (command == '7')
709 //      send_yamaha_ir_signal();
710     else if (command == '8')
711       send_yamaha_ir_signal(YAMAHA_AUX);
712     else if (command == '9')
713       send_yamaha_ir_signal(YAMAHA_EXT51DEC);
714     else if (command == '0')
715       send_yamaha_ir_signal(YAMAHA_TEST);
716     else if (command == '/')
717       send_yamaha_ir_signal(YAMAHA_TUNER_ABCDE);
718     else if (command == '\\')
719       send_yamaha_ir_signal(YAMAHA_EFFECT_TOGGLE);
720     else if (command == '-')
721       send_yamaha_ir_signal(YAMAHA_TUNER_MINUS);
722     else if (command == '+')
723       send_yamaha_ir_signal(YAMAHA_TUNER_PLUS);
724     else if (command == ':')
725       send_yamaha_ir_signal(YAMAHA_POWER_OFF);
726     else if (command == '.')
727       send_yamaha_ir_signal(YAMAHA_POWER_TOGGLE);
728     else if (command == ';')
729       send_yamaha_ir_signal(YAMAHA_VOLUME_UP);
730     else if (command == ',')
731       send_yamaha_ir_signal(YAMAHA_VOLUME_DOWN);
732     else if (command == '_')
733       send_yamaha_ir_signal(YAMAHA_MUTE);
734     else if (command == '#')
735       send_yamaha_ir_signal(YAMAHA_MENU);
736     else if (command == '"')
737       send_yamaha_ir_signal(YAMAHA_PLUS);
738     else if (command == '!')
739       send_yamaha_ir_signal(YAMAHA_MINUS);
740     else if (command == '=')
741       send_yamaha_ir_signal(YAMAHA_TIME_LEVEL);
742     else if (command == '$')
743       send_yamaha_ir_signal(YAMAHA_PRG_DOWN);
744     else if (command == '%')
745       send_yamaha_ir_signal(YAMAHA_PRG_UP);
746     else if (command == '(')
747       send_yamaha_ir_signal(YAMAHA_SLEEP);
748     else if (command == ')')
749       send_yamaha_ir_signal(YAMAHA_P5);
750     else
751       Serial.println("Error: unknown command");
752   }
753 }