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 PHOTO_ANALOGPIN 1
14 //movement is reported if during IR_SAMPLE_DURATION at least IR_TRESHOLD ir signals are detectd
15 #define IR_SAMPLE_DURATION 20000
16 #define IR_TRESHOLD 13000
17 //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)
18 #define PB_TRESHOLD 1000
20 OneWire onewire(ONE_WIRE_PIN);
21 DallasTemperature dallas_sensors(&onewire);
22 DeviceAddress onShieldTemp = { 0x10, 0xE7, 0x77, 0xD3, 0x01, 0x08, 0x00, 0x3F };
29 // offset is number of alphas (0.08ms)
31 const rf_bit_t zero_bit[] = { { 4, 1 },
37 const rf_bit_t one_bit[] = { { 12, 1 },
43 const rf_bit_t float_bit[] = { { 4, 1 },
49 const rf_bit_t sync_bit[] = { { 4, 1 },
53 typedef enum { ZERO = 0, ONE , FLOAT , SYNC } adbit_t;
54 typedef byte ad_bit_t;
56 typedef ad_bit_t word_t[WORD_LEN];
58 const rf_bit_t* bit_defs[] = { zero_bit, one_bit, float_bit, sync_bit };
64 const ad_bit_t* current_word;
65 byte volatile frame_finished = 1;
89 const word_t words[] = {
90 { ZERO, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // A1_ON
91 { ZERO, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // A1_OFF
92 { ZERO, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // A2_ON
93 { ZERO, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // A2_OFF
95 { FLOAT, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // B1_ON
96 { FLOAT, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // B1_OFF
97 { FLOAT, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // B2_ON
98 { FLOAT, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // B2_OFF
100 { ZERO, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // C1_ON
101 { ZERO, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // C1_OFF
102 { ZERO, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // C2_ON
103 { ZERO, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // C2_OFF
105 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // D1_ON
106 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // D1_OFF
107 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // D2_ON
108 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC } // D2_OFF
112 //********************************************************************//
117 TCCR1A = 0; // prescaler 1:8, WGM = 4 (CTC)
118 TCCR1B = 1<<WGM12 | 1<<CS11; //
119 OCR1A = 159; // (1+159)*8 = 1280 -> 0.08ms @ 16 MHz -> 1*alpha
120 // OCR1A = 207; // (1+207)*8 = 1664 -> 0.104ms @ 16 MHz -> 1*alpha
121 TCNT1 = 0; // reseting timer
122 TIMSK1 = 1<<OCIE1A; // enable Interrupt
125 void stop_timer() // stop the timer
128 TCCR1B = 0; // no clock source
129 TIMSK1 = 0; // disable timer interrupt
132 void init_word(const word_t w)
139 if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
140 digitalWrite(RF_DATA_OUT_PIN, HIGH);
142 digitalWrite(RF_DATA_OUT_PIN, LOW);
147 ISR(TIMER1_COMPA_vect)
150 if(alpha_cnt < bit_defs[current_word[bit_cnt]][chunk_cnt].offset)
154 if(bit_defs[current_word[bit_cnt]][chunk_cnt].offset != 0) {
155 if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
156 digitalWrite(RF_DATA_OUT_PIN, HIGH);
158 digitalWrite(RF_DATA_OUT_PIN, LOW);
163 if(bit_cnt < WORD_LEN) {
166 if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
167 digitalWrite(RF_DATA_OUT_PIN, HIGH);
169 digitalWrite(RF_DATA_OUT_PIN, LOW);
173 digitalWrite(RF_DATA_OUT_PIN, LOW);
176 if(word_cnt < FRAME_LEN)
177 init_word(current_word);
185 void send_frame(const word_t w)
195 Serial.println("Ok");
198 //********************************************************************//
200 void printTemperature(DeviceAddress deviceAddress)
202 dallas_sensors.requestTemperatures();
203 float tempC = dallas_sensors.getTempC(deviceAddress);
204 Serial.print("Temp C: ");
205 Serial.println(tempC);
206 //Serial.print(" Temp F: ");
207 //Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
210 //********************************************************************//
212 void printLightLevel(unsigned int pin)
214 Serial.print("Photo: ");
215 Serial.println(analogRead(pin));
218 //********************************************************************//
222 pinMode(RF_DATA_OUT_PIN, OUTPUT);
223 digitalWrite(RF_DATA_OUT_PIN, LOW);
224 pinMode(IR_MOVEMENT_PIN, INPUT); // set pin to input
225 digitalWrite(IR_MOVEMENT_PIN, LOW); // turn off pullup resistors
226 pinMode(PANIC_BUTTON_PIN, INPUT); // set pin to input
227 digitalWrite(PANIC_BUTTON_PIN, HIGH); // turn on pullup resistors
230 onewire.reset_search();
231 dallas_sensors.begin();
232 //in case we change temp sensor:
233 if (!dallas_sensors.getAddress(onShieldTemp, 0))
234 Serial.println("Error: Unable to find address for Device 0");
235 dallas_sensors.setResolution(onShieldTemp, 9);
240 unsigned int ir_time=IR_SAMPLE_DURATION;
241 unsigned int ir_count=0;
242 boolean pb_last_state=0;
244 boolean pb_postth_state=0;
245 unsigned int pb_time=0;
250 ir_count += (digitalRead(IR_MOVEMENT_PIN) == HIGH);
252 if (pb_time < PB_TRESHOLD)
254 pb_state=(digitalRead(PANIC_BUTTON_PIN) == LOW);
258 if (ir_count >= IR_TRESHOLD)
259 Serial.println("movement");
260 ir_time=IR_SAMPLE_DURATION;
264 if (pb_state == pb_last_state && pb_time >= PB_TRESHOLD)
266 if (pb_state && ! pb_postth_state)
269 Serial.println("PanicButton");
274 else if (pb_state != pb_last_state)
277 pb_last_state=pb_state;
280 if(Serial.available()) {
281 char command = Serial.read();
284 send_frame(words[A1_ON]);
285 else if(command == 'a')
286 send_frame(words[A1_OFF]);
287 else if(command == 'B')
288 send_frame(words[A2_ON]);
289 else if(command == 'b')
290 send_frame(words[A2_OFF]);
292 else if(command == 'C')
293 send_frame(words[B1_ON]);
294 else if(command == 'c')
295 send_frame(words[B1_OFF]);
296 else if(command == 'D')
297 send_frame(words[B2_ON]);
298 else if(command == 'd')
299 send_frame(words[B2_OFF]);
301 else if(command == 'E')
302 send_frame(words[C1_ON]);
303 else if(command == 'e')
304 send_frame(words[C1_OFF]);
305 else if(command == 'F')
306 send_frame(words[C2_ON]);
307 else if(command == 'f')
308 send_frame(words[C2_OFF]);
310 else if(command == 'G')
311 send_frame(words[D1_ON]);
312 else if(command == 'g')
313 send_frame(words[D1_OFF]);
314 else if(command == 'H')
315 send_frame(words[D2_ON]);
316 else if(command == 'h')
317 send_frame(words[D2_OFF]);
318 else if(command == 'T')
319 printTemperature(onShieldTemp);
320 else if(command == 'P')
321 printLightLevel(PHOTO_ANALOGPIN);
324 Serial.println("Error: unknown command");