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 PHOTO_ANALOGPIN 0
15 //movement is reported if during IR_SAMPLE_DURATION at least IR_TRESHOLD ir signals are detectd
16 #define IR_SAMPLE_DURATION 20000
17 #define IR_TRESHOLD 13000
18 //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)
19 #define PB_TRESHOLD 1000
20 #define PHOTO_SAMPLE_INTERVAL 4000
22 OneWire onewire(ONE_WIRE_PIN);
23 DallasTemperature dallas_sensors(&onewire);
24 DeviceAddress onShieldTemp = { 0x10, 0xE7, 0x77, 0xD3, 0x01, 0x08, 0x00, 0x3F };
31 // offset is number of alphas (0.08ms)
33 const rf_bit_t zero_bit[] = { { 4, 1 },
39 const rf_bit_t one_bit[] = { { 12, 1 },
45 const rf_bit_t float_bit[] = { { 4, 1 },
51 const rf_bit_t sync_bit[] = { { 4, 1 },
55 typedef enum { ZERO = 0, ONE , FLOAT , SYNC } adbit_t;
56 typedef byte ad_bit_t;
58 typedef ad_bit_t word_t[WORD_LEN];
60 const rf_bit_t* bit_defs[] = { zero_bit, one_bit, float_bit, sync_bit };
66 const ad_bit_t* current_word;
67 byte volatile frame_finished = 1;
91 const word_t words[] = {
92 { ZERO, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // A1_ON
93 { ZERO, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // A1_OFF
94 { ZERO, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // A2_ON
95 { ZERO, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // A2_OFF
97 { FLOAT, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // B1_ON
98 { FLOAT, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // B1_OFF
99 { FLOAT, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // B2_ON
100 { FLOAT, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // B2_OFF
102 { ZERO, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // C1_ON
103 { ZERO, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // C1_OFF
104 { ZERO, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // C2_ON
105 { ZERO, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // C2_OFF
107 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // D1_ON
108 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // D1_OFF
109 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // D2_ON
110 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC } // D2_OFF
114 //********************************************************************//
119 TCCR1A = 0; // prescaler 1:8, WGM = 4 (CTC)
120 TCCR1B = 1<<WGM12 | 1<<CS11; //
121 OCR1A = 159; // (1+159)*8 = 1280 -> 0.08ms @ 16 MHz -> 1*alpha
122 // OCR1A = 207; // (1+207)*8 = 1664 -> 0.104ms @ 16 MHz -> 1*alpha
123 TCNT1 = 0; // reseting timer
124 TIMSK1 = 1<<OCIE1A; // enable Interrupt
127 void stop_timer() // stop the timer
130 TCCR1B = 0; // no clock source
131 TIMSK1 = 0; // disable timer interrupt
134 void init_word(const word_t w)
141 if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
142 digitalWrite(RF_DATA_OUT_PIN, HIGH);
144 digitalWrite(RF_DATA_OUT_PIN, LOW);
149 ISR(TIMER1_COMPA_vect)
152 if(alpha_cnt < bit_defs[current_word[bit_cnt]][chunk_cnt].offset)
156 if(bit_defs[current_word[bit_cnt]][chunk_cnt].offset != 0) {
157 if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
158 digitalWrite(RF_DATA_OUT_PIN, HIGH);
160 digitalWrite(RF_DATA_OUT_PIN, LOW);
165 if(bit_cnt < WORD_LEN) {
168 if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
169 digitalWrite(RF_DATA_OUT_PIN, HIGH);
171 digitalWrite(RF_DATA_OUT_PIN, LOW);
175 digitalWrite(RF_DATA_OUT_PIN, LOW);
178 if(word_cnt < FRAME_LEN)
179 init_word(current_word);
187 void send_frame(const word_t w)
197 Serial.println("Ok");
200 //********************************************************************//
202 void printTemperature(DeviceAddress deviceAddress)
204 dallas_sensors.requestTemperatures();
205 float tempC = dallas_sensors.getTempC(deviceAddress);
206 Serial.print("Temp C: ");
207 Serial.println(tempC);
208 //Serial.print(" Temp F: ");
209 //Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
212 //********************************************************************//
214 unsigned int light_level_mean_ = 0;
215 unsigned int light_sample_time_ = 0;
217 void updateLightLevel(unsigned int pin)
219 light_sample_time_++;
220 if (light_sample_time_ < PHOTO_SAMPLE_INTERVAL)
222 light_sample_time_ = 0;
224 unsigned int value = analogRead(pin);
225 if (value == light_level_mean_)
228 unsigned int diff = abs(value - light_level_mean_);
230 light_level_mean_ = value;
232 light_level_mean_=(unsigned int) ( ((float) light_level_mean_) * 0.98 + ((float)value)*0.02 );
235 void printLightLevel()
237 Serial.print("Photo: ");
238 Serial.println(light_level_mean_);
241 //********************************************************************//
243 unsigned long wm_start_=0;
244 bool wait_millis(unsigned long ms)
248 if (millis() < wm_start_ || millis() > wm_start_+ ms)
263 unsigned int flash_led_time_=0;
264 void calculate_led_level(unsigned int pwm_pin)
266 if (flash_led_time_ == 0)
271 int c = abs(sin(float(flash_led_time_) / 100.0)) * 256;
272 analogWrite(pwm_pin,c);
275 void flash_led(int times)
277 flash_led_time_=314*times;
280 //********************************************************************//
284 pinMode(RF_DATA_OUT_PIN, OUTPUT);
285 digitalWrite(RF_DATA_OUT_PIN, LOW);
286 pinMode(IR_MOVEMENT_PIN, INPUT); // set pin to input
287 digitalWrite(IR_MOVEMENT_PIN, LOW); // turn off pullup resistors
288 pinMode(PANIC_BUTTON_PIN, INPUT); // set pin to input
289 digitalWrite(PANIC_BUTTON_PIN, HIGH); // turn on pullup resistors
290 analogWrite(BLUELED_PWM_PIN,0);
293 onewire.reset_search();
294 dallas_sensors.begin();
295 //in case we change temp sensor:
296 if (!dallas_sensors.getAddress(onShieldTemp, 0))
297 Serial.println("Error: Unable to find address for Device 0");
298 dallas_sensors.setResolution(onShieldTemp, 9);
303 unsigned int ir_time=IR_SAMPLE_DURATION;
304 unsigned int ir_count=0;
305 boolean pb_last_state=0;
307 boolean pb_postth_state=0;
308 unsigned int pb_time=0;
313 ir_count += (digitalRead(IR_MOVEMENT_PIN) == HIGH);
315 if (pb_time < PB_TRESHOLD)
317 pb_state=(digitalRead(PANIC_BUTTON_PIN) == LOW);
321 if (ir_count >= IR_TRESHOLD)
324 Serial.println("movement");
326 ir_time=IR_SAMPLE_DURATION;
330 if (pb_state == pb_last_state && pb_time >= PB_TRESHOLD)
332 if (pb_state && ! pb_postth_state)
335 Serial.println("PanicButton");
341 else if (pb_state != pb_last_state)
344 pb_last_state=pb_state;
347 updateLightLevel(PHOTO_ANALOGPIN);
348 calculate_led_level(BLUELED_PWM_PIN);
350 if(Serial.available()) {
351 char command = Serial.read();
354 send_frame(words[A1_ON]);
355 else if(command == 'a')
356 send_frame(words[A1_OFF]);
357 else if(command == 'B')
358 send_frame(words[A2_ON]);
359 else if(command == 'b')
360 send_frame(words[A2_OFF]);
362 else if(command == 'C')
363 send_frame(words[B1_ON]);
364 else if(command == 'c')
365 send_frame(words[B1_OFF]);
366 else if(command == 'D')
367 send_frame(words[B2_ON]);
368 else if(command == 'd')
369 send_frame(words[B2_OFF]);
371 else if(command == 'E')
372 send_frame(words[C1_ON]);
373 else if(command == 'e')
374 send_frame(words[C1_OFF]);
375 else if(command == 'F')
376 send_frame(words[C2_ON]);
377 else if(command == 'f')
378 send_frame(words[C2_OFF]);
380 else if(command == 'G')
381 send_frame(words[D1_ON]);
382 else if(command == 'g')
383 send_frame(words[D1_OFF]);
384 else if(command == 'H')
385 send_frame(words[D2_ON]);
386 else if(command == 'h')
387 send_frame(words[D2_OFF]);
388 else if(command == 'T')
389 printTemperature(onShieldTemp);
390 else if(command == 'P')
394 Serial.println("Error: unknown command");