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