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 -4.0
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)
199 Serial.println("Ok");
202 //********************************************************************//
204 void printTemperature(DeviceAddress deviceAddress)
206 dallas_sensors.requestTemperatures();
207 float tempC = dallas_sensors.getTempC(deviceAddress);
208 //Serial.print("Temp C: ");
209 Serial.println(tempC TEMPC_OFFSET_ARDUINO_GENEREATED_HEAT);
210 //Serial.print(" Temp F: ");
211 //Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
214 //********************************************************************//
216 unsigned int light_level_mean_ = 0;
217 unsigned int light_sample_time_ = 0;
219 void updateLightLevel(unsigned int pin)
221 light_sample_time_++;
222 if (light_sample_time_ < PHOTO_SAMPLE_INTERVAL)
224 light_sample_time_ = 0;
226 unsigned int value = analogRead(pin);
227 if (value == light_level_mean_)
230 unsigned int diff = abs(value - light_level_mean_);
232 light_level_mean_ = value;
234 light_level_mean_=(unsigned int) ( ((float) light_level_mean_) * 0.90 + ((float)value)*0.10 );
237 void printLightLevel()
239 //Serial.print("Photo: ");
240 Serial.println(light_level_mean_);
243 //********************************************************************//
245 unsigned long wm_start_=0;
246 bool wait_millis(unsigned long ms)
250 if (millis() < wm_start_ || millis() > wm_start_+ ms)
265 unsigned int flash_led_time_=0;
266 unsigned int flash_led_brightness_=255;
267 unsigned int flash_led_delay_=8;
268 void calculate_led_level(unsigned int pwm_pin)
270 if (flash_led_time_ == 0)
272 if (wait_millis(flash_led_delay_))
275 int c = abs(sin(float(flash_led_time_) / 100.0)) * flash_led_brightness_;
276 //int d = abs(sin(float(flash_led_time_) / 100.0)) * flash_led_brightness_;
277 analogWrite(BLUELED2_PWM_PIN, 255-c);
278 if (flash_led_brightness_ == 255)
281 analogWrite(BLUELED_PWM_PIN, 255-c);
283 analogWrite(BLUELED_PWM_PIN, c);
287 void flash_led(unsigned int times, unsigned int brightness_divisor, unsigned int delay_divisor)
289 unsigned int new_flash_led_brightness = 255 / brightness_divisor;
290 unsigned int new_flash_led_delay = 8 / delay_divisor;
291 if (flash_led_time_ == 0 || new_flash_led_brightness > flash_led_brightness_)
292 flash_led_brightness_=new_flash_led_brightness;
293 if (flash_led_time_ == 0 || new_flash_led_delay < flash_led_delay_)
294 flash_led_delay_=new_flash_led_delay;
295 flash_led_time_ += 314*times;
298 //********************************************************************//
302 pinMode(RF_DATA_OUT_PIN, OUTPUT);
303 digitalWrite(RF_DATA_OUT_PIN, HIGH);
304 pinMode(IR_MOVEMENT_PIN, INPUT); // set pin to input
305 digitalWrite(IR_MOVEMENT_PIN, LOW); // turn off pullup resistors
306 pinMode(PANIC_BUTTON_PIN, INPUT); // set pin to input
307 digitalWrite(PANIC_BUTTON_PIN, HIGH); // turn on pullup resistors
308 analogWrite(BLUELED_PWM_PIN,0);
309 analogWrite(BLUELED2_PWM_PIN,255); //pwm sink(-) instead of pwm + (better for mosfets)
314 onewire.reset_search();
315 dallas_sensors.begin();
316 //in case we change temp sensor:
317 if (!dallas_sensors.getAddress(onShieldTemp, 0))
318 Serial.println("Error: Unable to find address for Device 0");
319 dallas_sensors.setResolution(onShieldTemp, 9);
322 unsigned int ir_time=IR_SAMPLE_DURATION;
323 unsigned int ir_count=0;
324 boolean pb_last_state=0;
326 boolean pb_postth_state=0;
327 unsigned int pb_time=0;
329 void sensorEchoCommand(char command)
331 Serial.print("Sensor ");
332 Serial.print(command);
339 ir_count += (digitalRead(IR_MOVEMENT_PIN) == HIGH);
341 if (pb_time < PB_TRESHOLD)
343 pb_state=(digitalRead(PANIC_BUTTON_PIN) == LOW);
347 if (ir_count >= IR_TRESHOLD)
350 Serial.println("movement");
352 ir_time=IR_SAMPLE_DURATION;
356 if (pb_state == pb_last_state && pb_time >= PB_TRESHOLD)
358 if (pb_state && ! pb_postth_state)
361 Serial.println("PanicButton");
367 else if (pb_state != pb_last_state)
370 pb_last_state=pb_state;
373 updateLightLevel(PHOTO_ANALOGPIN);
374 calculate_led_level(BLUELED_PWM_PIN);
376 if(Serial.available()) {
377 char command = Serial.read();
380 send_frame(words[A1_ON]);
381 else if(command == 'a')
382 send_frame(words[A1_OFF]);
383 else if(command == 'B')
384 send_frame(words[A2_ON]);
385 else if(command == 'b')
386 send_frame(words[A2_OFF]);
388 else if(command == 'C')
389 send_frame(words[B1_ON]);
390 else if(command == 'c')
391 send_frame(words[B1_OFF]);
392 else if(command == 'D')
393 send_frame(words[B2_ON]);
394 else if(command == 'd')
395 send_frame(words[B2_OFF]);
397 else if(command == 'E')
398 send_frame(words[C1_ON]);
399 else if(command == 'e')
400 send_frame(words[C1_OFF]);
401 else if(command == 'F')
402 send_frame(words[C2_ON]);
403 else if(command == 'f')
404 send_frame(words[C2_OFF]);
406 else if(command == 'G')
407 send_frame(words[D1_ON]);
408 else if(command == 'g')
409 send_frame(words[D1_OFF]);
410 else if(command == 'H')
411 send_frame(words[D2_ON]);
412 else if(command == 'h')
413 send_frame(words[D2_OFF]);
414 else if(command == 'T')
416 sensorEchoCommand(command);
417 printTemperature(onShieldTemp);
419 else if(command == 'P')
421 sensorEchoCommand(command);
425 Serial.println("Error: unknown command");