2 #include <avr/interrupt.h>
5 #include <DallasTemperature.h>
8 //********************************************************************//
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 BLUELED_PWM_PIN 6
15 #define BLUELED2_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 10000
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
26 OneWire onewire(ONE_WIRE_PIN);
27 DallasTemperature dallas_sensors(&onewire);
28 DeviceAddress onShieldTemp = { 0x10, 0xE7, 0x77, 0xD3, 0x01, 0x08, 0x00, 0x3F };
30 #define TEMPC_OFFSET_ARDUINO_GENEREATED_HEAT
32 //********************************************************************//
33 // IR Codes, 32 bit, NEC
34 const int YAMAHA_CODE_BITS=32;
35 const unsigned long int YAMAHA_POWER = 0x000000005EA1F807;
36 const unsigned long int YAMAHA_CD = 0x000000005EA1A857;
37 const unsigned long int YAMAHA_TUNER = 0x000000005EA16897;
38 const unsigned long int YAMAHA_SAT = 0x000000005EA19867;
39 const unsigned long int YAMAHA_DVD = 0x000000005EA118E7;
40 const unsigned long int YAMAHA_DVD_SPDIF = 0x000000005EA1E817;
41 const unsigned long int YAMAHA_VCR_1 = 0x000000005EA1F00F;
42 const unsigned long int YAMAHA_TUNER_PLUS = 0x000000005EA108F7;
43 const unsigned long int YAMAHA_TUNER_ABCDE = 0x000000005EA148B7;
44 const unsigned long int YAMAHA_FRONT_LEVEL_P = 0x000000005EA101FE;
45 const unsigned long int YAMAHA_FRONT_LEVEL_M = 0x000000005EA1817E;
46 const unsigned long int YAMAHA_CENTRE_LEVEL_P = 0x000000005EA141BE;
47 const unsigned long int YAMAHA_CENTRE_LEVEL_M = 0x000000005EA1C13E;
48 const unsigned long int YAMAHA_REAR_LEVEL_P = 0x000000005EA17A85;
49 const unsigned long int YAMAHA_REAR_LEVEL_M = 0x000000005EA1FA05;
50 const unsigned long int YAMAHA_DELAY_TIME_P = 0x000000005EA14AB5;
51 const unsigned long int YAMAHA_DELAY_TIME_M = 0x000000005EA1CA35;
52 const unsigned long int YAMAHA_MUTE = 0x000000005EA138C7;
53 const unsigned long int YAMAHA_VOLUME_UP = 0x000000005EA158A7;
54 const unsigned long int YAMAHA_VOLUME_DOWN = 0x000000005EA1D827;
56 //********************************************************************//
63 // offset is number of alphas (0.08ms)
65 const rf_bit_t zero_bit[] = { { 4, 1 },
71 const rf_bit_t one_bit[] = { { 12, 1 },
77 const rf_bit_t float_bit[] = { { 4, 1 },
83 const rf_bit_t sync_bit[] = { { 4, 1 },
87 typedef enum { ZERO = 0, ONE , FLOAT , SYNC } adbit_t;
88 typedef byte ad_bit_t;
90 typedef ad_bit_t word_t[WORD_LEN];
92 const rf_bit_t* bit_defs[] = { zero_bit, one_bit, float_bit, sync_bit };
98 const ad_bit_t* current_word;
99 byte volatile frame_finished = 1;
123 const word_t words[] = {
124 { ZERO, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // A1_ON
125 { ZERO, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // A1_OFF
126 { ZERO, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // A2_ON
127 { ZERO, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // A2_OFF
129 { FLOAT, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // B1_ON
130 { FLOAT, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // B1_OFF
131 { FLOAT, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // B2_ON
132 { FLOAT, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // B2_OFF
134 { ZERO, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // C1_ON
135 { ZERO, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // C1_OFF
136 { ZERO, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // C2_ON
137 { ZERO, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // C2_OFF
139 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // D1_ON
140 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // D1_OFF
141 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // D2_ON
142 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC } // D2_OFF
146 //********************************************************************//
151 TCCR1A = 0; // prescaler 1:8, WGM = 4 (CTC)
152 TCCR1B = 1<<WGM12 | 1<<CS11; //
153 OCR1A = 159; // (1+159)*8 = 1280 -> 0.08ms @ 16 MHz -> 1*alpha
154 // OCR1A = 207; // (1+207)*8 = 1664 -> 0.104ms @ 16 MHz -> 1*alpha
155 TCNT1 = 0; // reseting timer
156 TIMSK1 = 1<<OCIE1A; // enable Interrupt
159 void stop_timer() // stop the timer
162 TCCR1B = 0; // no clock source
163 TIMSK1 = 0; // disable timer interrupt
166 void init_word(const word_t w)
173 if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
174 digitalWrite(RF_DATA_OUT_PIN, LOW); //neue 12V MosFET Verstärkung invertiert Logik !
176 digitalWrite(RF_DATA_OUT_PIN, HIGH);
181 ISR(TIMER1_COMPA_vect)
184 if(alpha_cnt < bit_defs[current_word[bit_cnt]][chunk_cnt].offset)
188 if(bit_defs[current_word[bit_cnt]][chunk_cnt].offset != 0) {
189 if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
190 digitalWrite(RF_DATA_OUT_PIN, LOW); //neue 12V MosFET Verstärkung invertiert Logik !
192 digitalWrite(RF_DATA_OUT_PIN, HIGH);
197 if(bit_cnt < WORD_LEN) {
200 if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
201 digitalWrite(RF_DATA_OUT_PIN, LOW); //neue 12V MosFET Verstärkung invertiert Logik !
203 digitalWrite(RF_DATA_OUT_PIN, HIGH);
207 digitalWrite(RF_DATA_OUT_PIN, HIGH);
210 if(word_cnt < FRAME_LEN)
211 init_word(current_word);
219 void send_frame(const word_t w)
221 if (frame_finished == 0)
233 void check_frame_done()
235 if (frame_finished==2)
237 Serial.println("Ok");
242 //********************************************************************//
244 void printTemperature(DeviceAddress deviceAddress)
246 dallas_sensors.requestTemperatures();
247 float tempC = dallas_sensors.getTempC(deviceAddress);
248 //Serial.print("Temp C: ");
249 Serial.println(tempC TEMPC_OFFSET_ARDUINO_GENEREATED_HEAT);
250 //Serial.print(" Temp F: ");
251 //Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
254 //********************************************************************//
256 unsigned int light_level_mean_ = 0;
257 unsigned int light_sample_time_ = 0;
259 void updateLightLevel(unsigned int pin)
261 light_sample_time_++;
262 if (light_sample_time_ < PHOTO_SAMPLE_INTERVAL)
264 light_sample_time_ = 0;
266 unsigned int value = analogRead(pin);
267 if (value == light_level_mean_)
270 unsigned int diff = abs(value - light_level_mean_);
272 light_level_mean_ = value;
274 light_level_mean_=(unsigned int) ( ((float) light_level_mean_) * 0.90 + ((float)value)*0.10 );
277 void printLightLevel()
279 //Serial.print("Photo: ");
280 Serial.println(light_level_mean_);
283 //********************************************************************//
285 unsigned long wm_start_=0;
286 bool wait_millis(unsigned long ms)
290 if (millis() < wm_start_ || millis() > wm_start_+ ms)
305 unsigned int flash_led_time_=0;
306 unsigned int flash_led_brightness_=255;
307 unsigned int flash_led_delay_=8;
308 void calculate_led_level(unsigned int pwm_pin)
310 if (flash_led_time_ == 0)
312 if (wait_millis(flash_led_delay_))
315 int c = abs(sin(float(flash_led_time_) / 100.0)) * flash_led_brightness_;
316 //int d = abs(sin(float(flash_led_time_) / 100.0)) * flash_led_brightness_;
317 analogWrite(BLUELED2_PWM_PIN, 255-c);
318 if (flash_led_brightness_ == 255)
321 analogWrite(BLUELED_PWM_PIN, 255-c);
323 analogWrite(BLUELED_PWM_PIN, c);
327 void flash_led(unsigned int times, unsigned int brightness_divisor, unsigned int delay_divisor)
329 unsigned int new_flash_led_brightness = 255 / brightness_divisor;
330 unsigned int new_flash_led_delay = 8 / delay_divisor;
331 if (flash_led_time_ == 0 || new_flash_led_brightness > flash_led_brightness_)
332 flash_led_brightness_=new_flash_led_brightness;
333 if (flash_led_time_ == 0 || new_flash_led_delay < flash_led_delay_)
334 flash_led_delay_=new_flash_led_delay;
335 flash_led_time_ += 314*times;
338 //********************************************************************//
342 pinMode(RF_DATA_OUT_PIN, OUTPUT);
343 digitalWrite(RF_DATA_OUT_PIN, HIGH);
344 pinMode(IR_MOVEMENT_PIN, INPUT); // set pin to input
345 digitalWrite(IR_MOVEMENT_PIN, LOW); // turn off pullup resistors
346 pinMode(PANIC_BUTTON_PIN, INPUT); // set pin to input
347 digitalWrite(PANIC_BUTTON_PIN, HIGH); // turn on pullup resistors
348 analogWrite(BLUELED_PWM_PIN,0);
349 analogWrite(BLUELED2_PWM_PIN,255); //pwm sink(-) instead of pwm + (better for mosfets)
354 onewire.reset_search();
355 dallas_sensors.begin();
356 //in case we change temp sensor:
357 if (!dallas_sensors.getAddress(onShieldTemp, 0))
358 Serial.println("Error: Unable to find address for Device 0");
359 dallas_sensors.setResolution(onShieldTemp, 9);
362 unsigned int ir_time=IR_SAMPLE_DURATION;
363 unsigned int ir_count=0;
364 boolean pb_last_state=0;
366 boolean pb_postth_state=0;
367 unsigned int pb_time=0;
369 void sensorEchoCommand(char command)
371 Serial.print("Sensor ");
372 Serial.print(command);
379 ir_count += (digitalRead(IR_MOVEMENT_PIN) == HIGH);
381 if (pb_time < PB_TRESHOLD)
383 pb_state=(digitalRead(PANIC_BUTTON_PIN) == LOW);
387 if (ir_count >= IR_TRESHOLD)
390 Serial.println("movement");
392 ir_time=IR_SAMPLE_DURATION;
396 if (pb_state == pb_last_state && pb_time >= PB_TRESHOLD)
398 if (pb_state && ! pb_postth_state)
401 Serial.println("PanicButton");
407 else if (pb_state != pb_last_state)
410 pb_last_state=pb_state;
413 updateLightLevel(PHOTO_ANALOGPIN);
414 calculate_led_level(BLUELED_PWM_PIN);
417 if(Serial.available()) {
418 char command = Serial.read();
421 send_frame(words[A1_ON]);
422 else if(command == 'a')
423 send_frame(words[A1_OFF]);
424 else if(command == 'B')
425 send_frame(words[A2_ON]);
426 else if(command == 'b')
427 send_frame(words[A2_OFF]);
429 else if(command == 'C')
430 send_frame(words[B1_ON]);
431 else if(command == 'c')
432 send_frame(words[B1_OFF]);
433 else if(command == 'D')
434 send_frame(words[B2_ON]);
435 else if(command == 'd')
436 send_frame(words[B2_OFF]);
438 else if(command == 'E')
439 send_frame(words[C1_ON]);
440 else if(command == 'e')
441 send_frame(words[C1_OFF]);
442 else if(command == 'F')
443 send_frame(words[C2_ON]);
444 else if(command == 'f')
445 send_frame(words[C2_OFF]);
447 else if(command == 'G')
448 send_frame(words[D1_ON]);
449 else if(command == 'g')
450 send_frame(words[D1_OFF]);
451 else if(command == 'H')
452 send_frame(words[D2_ON]);
453 else if(command == 'h')
454 send_frame(words[D2_OFF]);
455 else if(command == 'T')
457 sensorEchoCommand(command);
458 printTemperature(onShieldTemp);
460 else if(command == 'P')
462 sensorEchoCommand(command);
465 else if (command == '1')
467 irsend.sendNEC(YAMAHA_POWER,YAMAHA_CODE_BITS);
468 Serial.println("Ok");
470 else if (command == '2')
472 irsend.sendNEC(YAMAHA_CD,YAMAHA_CODE_BITS);
473 Serial.println("Ok");
475 else if (command == '3')
477 irsend.sendNEC(YAMAHA_DVD_SPDIF,YAMAHA_CODE_BITS);
478 Serial.println("Ok");
480 else if (command == '4')
482 irsend.sendNEC(YAMAHA_TUNER,YAMAHA_CODE_BITS);
483 Serial.println("Ok");
485 else if (command == '5')
487 irsend.sendNEC(YAMAHA_VOLUME_UP,YAMAHA_CODE_BITS);
488 Serial.println("Ok");
490 else if (command == '6')
492 irsend.sendNEC(YAMAHA_VOLUME_DOWN,YAMAHA_CODE_BITS);
493 Serial.println("Ok");
495 else if (command == '7')
497 irsend.sendNEC(YAMAHA_MUTE,YAMAHA_CODE_BITS);
498 Serial.println("Ok");
501 Serial.println("Error: unknown command");