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 int flash_led_time_=0;
244 void calculate_led_level(unsigned int pwm_pin)
246 if (flash_led_time_ == 0)
251 int c = abs(sin(float(flash_led_time_) / 100.0)) * 256;
252 analogWrite(pwm_pin,c);
255 void flash_led(int times)
257 flash_led_time_=314*times;
260 //********************************************************************//
264 pinMode(RF_DATA_OUT_PIN, OUTPUT);
265 digitalWrite(RF_DATA_OUT_PIN, LOW);
266 pinMode(IR_MOVEMENT_PIN, INPUT); // set pin to input
267 digitalWrite(IR_MOVEMENT_PIN, LOW); // turn off pullup resistors
268 pinMode(PANIC_BUTTON_PIN, INPUT); // set pin to input
269 digitalWrite(PANIC_BUTTON_PIN, HIGH); // turn on pullup resistors
270 analogWrite(BLUELED_PWM_PIN,0);
273 onewire.reset_search();
274 dallas_sensors.begin();
275 //in case we change temp sensor:
276 if (!dallas_sensors.getAddress(onShieldTemp, 0))
277 Serial.println("Error: Unable to find address for Device 0");
278 dallas_sensors.setResolution(onShieldTemp, 9);
283 unsigned int ir_time=IR_SAMPLE_DURATION;
284 unsigned int ir_count=0;
285 boolean pb_last_state=0;
287 boolean pb_postth_state=0;
288 unsigned int pb_time=0;
293 ir_count += (digitalRead(IR_MOVEMENT_PIN) == HIGH);
295 if (pb_time < PB_TRESHOLD)
297 pb_state=(digitalRead(PANIC_BUTTON_PIN) == LOW);
301 if (ir_count >= IR_TRESHOLD)
304 Serial.println("movement");
306 ir_time=IR_SAMPLE_DURATION;
310 if (pb_state == pb_last_state && pb_time >= PB_TRESHOLD)
312 if (pb_state && ! pb_postth_state)
315 Serial.println("PanicButton");
321 else if (pb_state != pb_last_state)
324 pb_last_state=pb_state;
327 updateLightLevel(PHOTO_ANALOGPIN);
328 calculate_led_level(BLUELED_PWM_PIN);
330 if(Serial.available()) {
331 char command = Serial.read();
334 send_frame(words[A1_ON]);
335 else if(command == 'a')
336 send_frame(words[A1_OFF]);
337 else if(command == 'B')
338 send_frame(words[A2_ON]);
339 else if(command == 'b')
340 send_frame(words[A2_OFF]);
342 else if(command == 'C')
343 send_frame(words[B1_ON]);
344 else if(command == 'c')
345 send_frame(words[B1_OFF]);
346 else if(command == 'D')
347 send_frame(words[B2_ON]);
348 else if(command == 'd')
349 send_frame(words[B2_OFF]);
351 else if(command == 'E')
352 send_frame(words[C1_ON]);
353 else if(command == 'e')
354 send_frame(words[C1_OFF]);
355 else if(command == 'F')
356 send_frame(words[C2_ON]);
357 else if(command == 'f')
358 send_frame(words[C2_OFF]);
360 else if(command == 'G')
361 send_frame(words[D1_ON]);
362 else if(command == 'g')
363 send_frame(words[D1_OFF]);
364 else if(command == 'H')
365 send_frame(words[D2_ON]);
366 else if(command == 'h')
367 send_frame(words[D2_OFF]);
368 else if(command == 'T')
369 printTemperature(onShieldTemp);
370 else if(command == 'P')
374 Serial.println("Error: unknown command");