2 #include <avr/interrupt.h>
5 #include <DallasTemperature.h>
7 //********************************************************************//
9 #define RF_DATA_OUT_PIN 13
10 #define IR_MOVEMENT_PIN 9
11 #define ONE_WIRE_PIN 8
12 #define PANIC_BUTTON_PIN 7
13 #define BLUELED_PWM_PIN 6
14 #define BLUELED2_PWM_PIN 11
15 #define PHOTO_ANALOGPIN 0
16 //movement is reported if during IR_SAMPLE_DURATION at least IR_TRESHOLD ir signals are detectd
17 #define IR_SAMPLE_DURATION 12000
18 #define IR_TRESHOLD 10000
19 //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)
20 #define PB_TRESHOLD 1000
21 #define PHOTO_SAMPLE_INTERVAL 4000
23 OneWire onewire(ONE_WIRE_PIN);
24 DallasTemperature dallas_sensors(&onewire);
25 DeviceAddress onShieldTemp = { 0x10, 0xE7, 0x77, 0xD3, 0x01, 0x08, 0x00, 0x3F };
26 #define TEMPC_OFFSET_ARDUINO_GENEREATED_HEAT
33 // offset is number of alphas (0.08ms)
35 const rf_bit_t zero_bit[] = { { 4, 1 },
41 const rf_bit_t one_bit[] = { { 12, 1 },
47 const rf_bit_t float_bit[] = { { 4, 1 },
53 const rf_bit_t sync_bit[] = { { 4, 1 },
57 typedef enum { ZERO = 0, ONE , FLOAT , SYNC } adbit_t;
58 typedef byte ad_bit_t;
60 typedef ad_bit_t word_t[WORD_LEN];
62 const rf_bit_t* bit_defs[] = { zero_bit, one_bit, float_bit, sync_bit };
68 const ad_bit_t* current_word;
69 byte volatile frame_finished = 1;
93 const word_t words[] = {
94 { ZERO, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // A1_ON
95 { ZERO, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // A1_OFF
96 { ZERO, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // A2_ON
97 { ZERO, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // A2_OFF
99 { FLOAT, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // B1_ON
100 { FLOAT, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // B1_OFF
101 { FLOAT, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // B2_ON
102 { FLOAT, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // B2_OFF
104 { ZERO, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // C1_ON
105 { ZERO, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // C1_OFF
106 { ZERO, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // C2_ON
107 { ZERO, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // C2_OFF
109 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // D1_ON
110 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // D1_OFF
111 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // D2_ON
112 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC } // D2_OFF
116 //********************************************************************//
121 TCCR1A = 0; // prescaler 1:8, WGM = 4 (CTC)
122 TCCR1B = 1<<WGM12 | 1<<CS11; //
123 OCR1A = 159; // (1+159)*8 = 1280 -> 0.08ms @ 16 MHz -> 1*alpha
124 // OCR1A = 207; // (1+207)*8 = 1664 -> 0.104ms @ 16 MHz -> 1*alpha
125 TCNT1 = 0; // reseting timer
126 TIMSK1 = 1<<OCIE1A; // enable Interrupt
129 void stop_timer() // stop the timer
132 TCCR1B = 0; // no clock source
133 TIMSK1 = 0; // disable timer interrupt
136 void init_word(const word_t w)
143 if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
144 digitalWrite(RF_DATA_OUT_PIN, LOW); //neue 12V MosFET Verstärkung invertiert Logik !
146 digitalWrite(RF_DATA_OUT_PIN, HIGH);
151 ISR(TIMER1_COMPA_vect)
154 if(alpha_cnt < bit_defs[current_word[bit_cnt]][chunk_cnt].offset)
158 if(bit_defs[current_word[bit_cnt]][chunk_cnt].offset != 0) {
159 if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
160 digitalWrite(RF_DATA_OUT_PIN, LOW); //neue 12V MosFET Verstärkung invertiert Logik !
162 digitalWrite(RF_DATA_OUT_PIN, HIGH);
167 if(bit_cnt < WORD_LEN) {
170 if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
171 digitalWrite(RF_DATA_OUT_PIN, LOW); //neue 12V MosFET Verstärkung invertiert Logik !
173 digitalWrite(RF_DATA_OUT_PIN, HIGH);
177 digitalWrite(RF_DATA_OUT_PIN, HIGH);
180 if(word_cnt < FRAME_LEN)
181 init_word(current_word);
189 void send_frame(const word_t w)
191 if (frame_finished == 0)
203 void check_frame_done()
205 if (frame_finished==2)
207 Serial.println("Ok");
212 //********************************************************************//
214 void printTemperature(DeviceAddress deviceAddress)
216 dallas_sensors.requestTemperatures();
217 float tempC = dallas_sensors.getTempC(deviceAddress);
218 //Serial.print("Temp C: ");
219 Serial.println(tempC TEMPC_OFFSET_ARDUINO_GENEREATED_HEAT);
220 //Serial.print(" Temp F: ");
221 //Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
224 //********************************************************************//
226 unsigned int light_level_mean_ = 0;
227 unsigned int light_sample_time_ = 0;
229 void updateLightLevel(unsigned int pin)
231 light_sample_time_++;
232 if (light_sample_time_ < PHOTO_SAMPLE_INTERVAL)
234 light_sample_time_ = 0;
236 unsigned int value = analogRead(pin);
237 if (value == light_level_mean_)
240 unsigned int diff = abs(value - light_level_mean_);
242 light_level_mean_ = value;
244 light_level_mean_=(unsigned int) ( ((float) light_level_mean_) * 0.90 + ((float)value)*0.10 );
247 void printLightLevel()
249 //Serial.print("Photo: ");
250 Serial.println(light_level_mean_);
253 //********************************************************************//
255 unsigned long wm_start_=0;
256 bool wait_millis(unsigned long ms)
260 if (millis() < wm_start_ || millis() > wm_start_+ ms)
275 unsigned int flash_led_time_=0;
276 unsigned int flash_led_brightness_=255;
277 unsigned int flash_led_delay_=8;
278 void calculate_led_level(unsigned int pwm_pin)
280 if (flash_led_time_ == 0)
282 if (wait_millis(flash_led_delay_))
285 int c = abs(sin(float(flash_led_time_) / 100.0)) * flash_led_brightness_;
286 //int d = abs(sin(float(flash_led_time_) / 100.0)) * flash_led_brightness_;
287 analogWrite(BLUELED2_PWM_PIN, 255-c);
288 if (flash_led_brightness_ == 255)
291 analogWrite(BLUELED_PWM_PIN, 255-c);
293 analogWrite(BLUELED_PWM_PIN, c);
297 void flash_led(unsigned int times, unsigned int brightness_divisor, unsigned int delay_divisor)
299 unsigned int new_flash_led_brightness = 255 / brightness_divisor;
300 unsigned int new_flash_led_delay = 8 / delay_divisor;
301 if (flash_led_time_ == 0 || new_flash_led_brightness > flash_led_brightness_)
302 flash_led_brightness_=new_flash_led_brightness;
303 if (flash_led_time_ == 0 || new_flash_led_delay < flash_led_delay_)
304 flash_led_delay_=new_flash_led_delay;
305 flash_led_time_ += 314*times;
308 //********************************************************************//
312 pinMode(RF_DATA_OUT_PIN, OUTPUT);
313 digitalWrite(RF_DATA_OUT_PIN, HIGH);
314 pinMode(IR_MOVEMENT_PIN, INPUT); // set pin to input
315 digitalWrite(IR_MOVEMENT_PIN, LOW); // turn off pullup resistors
316 pinMode(PANIC_BUTTON_PIN, INPUT); // set pin to input
317 digitalWrite(PANIC_BUTTON_PIN, HIGH); // turn on pullup resistors
318 analogWrite(BLUELED_PWM_PIN,0);
319 analogWrite(BLUELED2_PWM_PIN,255); //pwm sink(-) instead of pwm + (better for mosfets)
324 onewire.reset_search();
325 dallas_sensors.begin();
326 //in case we change temp sensor:
327 if (!dallas_sensors.getAddress(onShieldTemp, 0))
328 Serial.println("Error: Unable to find address for Device 0");
329 dallas_sensors.setResolution(onShieldTemp, 9);
332 unsigned int ir_time=IR_SAMPLE_DURATION;
333 unsigned int ir_count=0;
334 boolean pb_last_state=0;
336 boolean pb_postth_state=0;
337 unsigned int pb_time=0;
339 void sensorEchoCommand(char command)
341 Serial.print("Sensor ");
342 Serial.print(command);
349 ir_count += (digitalRead(IR_MOVEMENT_PIN) == HIGH);
351 if (pb_time < PB_TRESHOLD)
353 pb_state=(digitalRead(PANIC_BUTTON_PIN) == LOW);
357 if (ir_count >= IR_TRESHOLD)
360 Serial.println("movement");
362 ir_time=IR_SAMPLE_DURATION;
366 if (pb_state == pb_last_state && pb_time >= PB_TRESHOLD)
368 if (pb_state && ! pb_postth_state)
371 Serial.println("PanicButton");
377 else if (pb_state != pb_last_state)
380 pb_last_state=pb_state;
383 updateLightLevel(PHOTO_ANALOGPIN);
384 calculate_led_level(BLUELED_PWM_PIN);
387 if(Serial.available()) {
388 char command = Serial.read();
391 send_frame(words[A1_ON]);
392 else if(command == 'a')
393 send_frame(words[A1_OFF]);
394 else if(command == 'B')
395 send_frame(words[A2_ON]);
396 else if(command == 'b')
397 send_frame(words[A2_OFF]);
399 else if(command == 'C')
400 send_frame(words[B1_ON]);
401 else if(command == 'c')
402 send_frame(words[B1_OFF]);
403 else if(command == 'D')
404 send_frame(words[B2_ON]);
405 else if(command == 'd')
406 send_frame(words[B2_OFF]);
408 else if(command == 'E')
409 send_frame(words[C1_ON]);
410 else if(command == 'e')
411 send_frame(words[C1_OFF]);
412 else if(command == 'F')
413 send_frame(words[C2_ON]);
414 else if(command == 'f')
415 send_frame(words[C2_OFF]);
417 else if(command == 'G')
418 send_frame(words[D1_ON]);
419 else if(command == 'g')
420 send_frame(words[D1_OFF]);
421 else if(command == 'H')
422 send_frame(words[D2_ON]);
423 else if(command == 'h')
424 send_frame(words[D2_OFF]);
425 else if(command == 'T')
427 sensorEchoCommand(command);
428 printTemperature(onShieldTemp);
430 else if(command == 'P')
432 sensorEchoCommand(command);
436 Serial.println("Error: unknown command");