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 10
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 15000
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, HIGH);
146 digitalWrite(RF_DATA_OUT_PIN, LOW);
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, HIGH);
162 digitalWrite(RF_DATA_OUT_PIN, LOW);
167 if(bit_cnt < WORD_LEN) {
170 if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
171 digitalWrite(RF_DATA_OUT_PIN, HIGH);
173 digitalWrite(RF_DATA_OUT_PIN, LOW);
177 digitalWrite(RF_DATA_OUT_PIN, LOW);
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_);
231 if (light_level_mean_ < 6 || diff > 250)
232 light_level_mean_ = value;
234 light_level_mean_=(unsigned int) ( ((float) light_level_mean_) * 0.98 + ((float)value)*0.02 );
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_=256;
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 analogWrite(BLUELED_PWM_PIN,c);
277 analogWrite(BLUELED2_PWM_PIN,c);
280 void flash_led(unsigned int times, unsigned int brightness_divisor, unsigned int delay_divisor)
282 unsigned int new_flash_led_brightness = 256 / brightness_divisor;
283 unsigned int new_flash_led_delay = 8 / delay_divisor;
284 if (flash_led_time_ == 0 || new_flash_led_brightness > flash_led_brightness_)
285 flash_led_brightness_=new_flash_led_brightness;
286 if (flash_led_time_ == 0 || new_flash_led_delay < flash_led_delay_)
287 flash_led_delay_=new_flash_led_delay;
288 flash_led_time_ += 314*times;
291 //********************************************************************//
295 pinMode(RF_DATA_OUT_PIN, OUTPUT);
296 digitalWrite(RF_DATA_OUT_PIN, LOW);
297 pinMode(IR_MOVEMENT_PIN, INPUT); // set pin to input
298 digitalWrite(IR_MOVEMENT_PIN, LOW); // turn off pullup resistors
299 pinMode(PANIC_BUTTON_PIN, INPUT); // set pin to input
300 digitalWrite(PANIC_BUTTON_PIN, HIGH); // turn on pullup resistors
301 analogWrite(BLUELED_PWM_PIN,0);
306 onewire.reset_search();
307 dallas_sensors.begin();
308 //in case we change temp sensor:
309 if (!dallas_sensors.getAddress(onShieldTemp, 0))
310 Serial.println("Error: Unable to find address for Device 0");
311 dallas_sensors.setResolution(onShieldTemp, 9);
314 unsigned int ir_time=IR_SAMPLE_DURATION;
315 unsigned int ir_count=0;
316 boolean pb_last_state=0;
318 boolean pb_postth_state=0;
319 unsigned int pb_time=0;
321 void sensorEchoCommand(char command)
323 Serial.print("Sensor ");
324 Serial.print(command);
331 ir_count += (digitalRead(IR_MOVEMENT_PIN) == HIGH);
333 if (pb_time < PB_TRESHOLD)
335 pb_state=(digitalRead(PANIC_BUTTON_PIN) == LOW);
339 if (ir_count >= IR_TRESHOLD)
342 Serial.println("movement");
344 ir_time=IR_SAMPLE_DURATION;
348 if (pb_state == pb_last_state && pb_time >= PB_TRESHOLD)
350 if (pb_state && ! pb_postth_state)
353 Serial.println("PanicButton");
359 else if (pb_state != pb_last_state)
362 pb_last_state=pb_state;
365 updateLightLevel(PHOTO_ANALOGPIN);
366 calculate_led_level(BLUELED_PWM_PIN);
368 if(Serial.available()) {
369 char command = Serial.read();
372 send_frame(words[A1_ON]);
373 else if(command == 'a')
374 send_frame(words[A1_OFF]);
375 else if(command == 'B')
376 send_frame(words[A2_ON]);
377 else if(command == 'b')
378 send_frame(words[A2_OFF]);
380 else if(command == 'C')
381 send_frame(words[B1_ON]);
382 else if(command == 'c')
383 send_frame(words[B1_OFF]);
384 else if(command == 'D')
385 send_frame(words[B2_ON]);
386 else if(command == 'd')
387 send_frame(words[B2_OFF]);
389 else if(command == 'E')
390 send_frame(words[C1_ON]);
391 else if(command == 'e')
392 send_frame(words[C1_OFF]);
393 else if(command == 'F')
394 send_frame(words[C2_ON]);
395 else if(command == 'f')
396 send_frame(words[C2_OFF]);
398 else if(command == 'G')
399 send_frame(words[D1_ON]);
400 else if(command == 'g')
401 send_frame(words[D1_OFF]);
402 else if(command == 'H')
403 send_frame(words[D2_ON]);
404 else if(command == 'h')
405 send_frame(words[D2_OFF]);
406 else if(command == 'T')
408 sensorEchoCommand(command);
409 printTemperature(onShieldTemp);
411 else if(command == 'P')
413 sensorEchoCommand(command);
417 Serial.println("Error: unknown command");