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)
350 pinMode(IRREMOTE_SEND_PIN, OUTPUT);
351 digitalWrite(IRREMOTE_SEND_PIN, HIGH);
356 onewire.reset_search();
357 dallas_sensors.begin();
358 //in case we change temp sensor:
359 if (!dallas_sensors.getAddress(onShieldTemp, 0))
360 Serial.println("Error: Unable to find address for Device 0");
361 dallas_sensors.setResolution(onShieldTemp, 9);
364 unsigned int ir_time=IR_SAMPLE_DURATION;
365 unsigned int ir_count=0;
366 boolean pb_last_state=0;
368 boolean pb_postth_state=0;
369 unsigned int pb_time=0;
371 void sensorEchoCommand(char command)
373 Serial.print("Sensor ");
374 Serial.print(command);
381 ir_count += (digitalRead(IR_MOVEMENT_PIN) == HIGH);
383 if (pb_time < PB_TRESHOLD)
385 pb_state=(digitalRead(PANIC_BUTTON_PIN) == LOW);
389 if (ir_count >= IR_TRESHOLD)
392 Serial.println("movement");
394 ir_time=IR_SAMPLE_DURATION;
398 if (pb_state == pb_last_state && pb_time >= PB_TRESHOLD)
400 if (pb_state && ! pb_postth_state)
403 Serial.println("PanicButton");
409 else if (pb_state != pb_last_state)
412 pb_last_state=pb_state;
415 updateLightLevel(PHOTO_ANALOGPIN);
416 calculate_led_level(BLUELED_PWM_PIN);
419 if(Serial.available()) {
420 char command = Serial.read();
423 send_frame(words[A1_ON]);
424 else if(command == 'a')
425 send_frame(words[A1_OFF]);
426 else if(command == 'B')
427 send_frame(words[A2_ON]);
428 else if(command == 'b')
429 send_frame(words[A2_OFF]);
431 else if(command == 'C')
432 send_frame(words[B1_ON]);
433 else if(command == 'c')
434 send_frame(words[B1_OFF]);
435 else if(command == 'D')
436 send_frame(words[B2_ON]);
437 else if(command == 'd')
438 send_frame(words[B2_OFF]);
440 else if(command == 'E')
441 send_frame(words[C1_ON]);
442 else if(command == 'e')
443 send_frame(words[C1_OFF]);
444 else if(command == 'F')
445 send_frame(words[C2_ON]);
446 else if(command == 'f')
447 send_frame(words[C2_OFF]);
449 else if(command == 'G')
450 send_frame(words[D1_ON]);
451 else if(command == 'g')
452 send_frame(words[D1_OFF]);
453 else if(command == 'H')
454 send_frame(words[D2_ON]);
455 else if(command == 'h')
456 send_frame(words[D2_OFF]);
457 else if(command == 'T')
459 sensorEchoCommand(command);
460 printTemperature(onShieldTemp);
462 else if(command == 'P')
464 sensorEchoCommand(command);
467 else if (command == '1')
469 irsend.sendNEC(YAMAHA_POWER,YAMAHA_CODE_BITS);
470 Serial.println("Ok");
472 else if (command == '2')
474 irsend.sendNEC(YAMAHA_CD,YAMAHA_CODE_BITS);
475 Serial.println("Ok");
477 else if (command == '3')
479 irsend.sendNEC(YAMAHA_DVD_SPDIF,YAMAHA_CODE_BITS);
480 Serial.println("Ok");
482 else if (command == '4')
484 irsend.sendNEC(YAMAHA_TUNER,YAMAHA_CODE_BITS);
485 Serial.println("Ok");
487 else if (command == '5')
489 irsend.sendNEC(YAMAHA_VOLUME_UP,YAMAHA_CODE_BITS);
490 Serial.println("Ok");
492 else if (command == '6')
494 irsend.sendNEC(YAMAHA_VOLUME_DOWN,YAMAHA_CODE_BITS);
495 Serial.println("Ok");
497 else if (command == '7')
499 irsend.sendNEC(YAMAHA_MUTE,YAMAHA_CODE_BITS);
500 Serial.println("Ok");
503 Serial.println("Error: unknown command");