2 #include <avr/interrupt.h>
5 #include <DallasTemperature.h>
7 //********************************************************************//
9 #define DATA_OUT_PIN 13
10 #define IR_MOVEMENT_PIN 9
11 #define ONE_WIRE_PIN 8
12 #define PANIC_BUTTON_PIN 7
13 //movement is reported if during IR_SAMPLE_DURATION at least IR_TRESHOLD ir signals are detectd
14 #define IR_SAMPLE_DURATION 20000
15 #define IR_TRESHOLD 13000
16 //duration PanicButton needs to be pressed before status change occurs (i.e. for two PanicButton Repots, the buttons needs to be pressed 1000 cycles, releases 1000 cycles and again pressed 1000 cycles)
17 #define PB_TRESHOLD 1000
19 OneWire onewire(ONE_WIRE_PIN);
20 DallasTemperature dallas_sensors(&onewire);
21 DeviceAddress onShieldTemp = { 0x10, 0xE7, 0x77, 0xD3, 0x01, 0x08, 0x00, 0x3F };
28 // offset is number of alphas (0.08ms)
30 const rf_bit_t zero_bit[] = { { 4, 1 },
36 const rf_bit_t one_bit[] = { { 12, 1 },
42 const rf_bit_t float_bit[] = { { 4, 1 },
48 const rf_bit_t sync_bit[] = { { 4, 1 },
52 typedef enum { ZERO = 0, ONE , FLOAT , SYNC } adbit_t;
53 typedef byte ad_bit_t;
55 typedef ad_bit_t word_t[WORD_LEN];
57 const rf_bit_t* bit_defs[] = { zero_bit, one_bit, float_bit, sync_bit };
63 const ad_bit_t* current_word;
64 byte volatile frame_finished = 1;
88 const word_t words[] = {
89 { ZERO, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // A1_ON
90 { ZERO, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // A1_OFF
91 { ZERO, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // A2_ON
92 { ZERO, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // A2_OFF
94 { FLOAT, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // B1_ON
95 { FLOAT, ZERO, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // B1_OFF
96 { FLOAT, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // B2_ON
97 { FLOAT, ZERO, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // B2_OFF
99 { ZERO, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // C1_ON
100 { ZERO, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // C1_OFF
101 { ZERO, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // C2_ON
102 { ZERO, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // C2_OFF
104 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // D1_ON
105 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC }, // D1_OFF
106 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // D2_ON
107 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, SYNC } // D2_OFF
111 //********************************************************************//
116 TCCR1A = 0; // prescaler 1:8, WGM = 4 (CTC)
117 TCCR1B = 1<<WGM12 | 1<<CS11; //
118 OCR1A = 159; // (1+159)*8 = 1280 -> 0.08ms @ 16 MHz -> 1*alpha
119 // OCR1A = 207; // (1+207)*8 = 1664 -> 0.104ms @ 16 MHz -> 1*alpha
120 TCNT1 = 0; // reseting timer
121 TIMSK1 = 1<<OCIE1A; // enable Interrupt
124 void stop_timer() // stop the timer
127 TCCR1B = 0; // no clock source
128 TIMSK1 = 0; // disable timer interrupt
131 void init_word(const word_t w)
138 if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
139 digitalWrite(DATA_OUT_PIN, HIGH);
141 digitalWrite(DATA_OUT_PIN, LOW);
146 ISR(TIMER1_COMPA_vect)
149 if(alpha_cnt < bit_defs[current_word[bit_cnt]][chunk_cnt].offset)
153 if(bit_defs[current_word[bit_cnt]][chunk_cnt].offset != 0) {
154 if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
155 digitalWrite(DATA_OUT_PIN, HIGH);
157 digitalWrite(DATA_OUT_PIN, LOW);
162 if(bit_cnt < WORD_LEN) {
165 if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
166 digitalWrite(DATA_OUT_PIN, HIGH);
168 digitalWrite(DATA_OUT_PIN, LOW);
172 digitalWrite(DATA_OUT_PIN, LOW);
175 if(word_cnt < FRAME_LEN)
176 init_word(current_word);
184 void send_frame(const word_t w)
195 //********************************************************************//
197 void printTemperature(DeviceAddress deviceAddress)
199 dallas_sensors.requestTemperatures();
200 float tempC = dallas_sensors.getTempC(deviceAddress);
201 Serial.print("Temp C: ");
202 Serial.println(tempC);
203 //Serial.print(" Temp F: ");
204 //Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
207 //********************************************************************//
211 pinMode(DATA_OUT_PIN, OUTPUT);
212 digitalWrite(DATA_OUT_PIN, LOW);
213 pinMode(IR_MOVEMENT_PIN, INPUT); // set pin to input
214 digitalWrite(IR_MOVEMENT_PIN, LOW); // turn off pullup resistors
215 pinMode(PANIC_BUTTON_PIN, INPUT); // set pin to input
216 digitalWrite(PANIC_BUTTON_PIN, HIGH); // turn on pullup resistors
219 onewire.reset_search();
220 dallas_sensors.begin();
221 //in case we change temp sensor:
222 if (!dallas_sensors.getAddress(onShieldTemp, 0))
223 Serial.println("Unable to find address for Device 0");
224 dallas_sensors.setResolution(onShieldTemp, 9);
229 unsigned int ir_time=IR_SAMPLE_DURATION;
230 unsigned int ir_count=0;
231 boolean pb_last_state=0;
233 boolean pb_postth_state=0;
234 unsigned int pb_time=0;
239 ir_count += (digitalRead(IR_MOVEMENT_PIN) == HIGH);
241 if (pb_time < PB_TRESHOLD)
243 pb_state=(digitalRead(PANIC_BUTTON_PIN) == LOW);
247 if (ir_count >= IR_TRESHOLD)
248 Serial.println("movement");
249 ir_time=IR_SAMPLE_DURATION;
253 if (pb_state == pb_last_state && pb_time >= PB_TRESHOLD)
255 if (pb_state && ! pb_postth_state)
258 Serial.println("PanicButton");
263 else if (pb_state != pb_last_state)
266 pb_last_state=pb_state;
269 if(Serial.available()) {
270 char command = Serial.read();
273 send_frame(words[A1_ON]);
274 else if(command == 'a')
275 send_frame(words[A1_OFF]);
276 else if(command == 'w')
277 send_frame(words[A2_ON]);
278 else if(command == 's')
279 send_frame(words[A2_OFF]);
281 else if(command == 'e')
282 send_frame(words[B1_ON]);
283 else if(command == 'd')
284 send_frame(words[B1_OFF]);
285 else if(command == 'r')
286 send_frame(words[B2_ON]);
287 else if(command == 'f')
288 send_frame(words[B2_OFF]);
290 else if(command == 't')
291 send_frame(words[C1_ON]);
292 else if(command == 'g')
293 send_frame(words[C1_OFF]);
294 else if(command == 'z')
295 send_frame(words[C2_ON]);
296 else if(command == 'h')
297 send_frame(words[C2_OFF]);
299 else if(command == 'u')
300 send_frame(words[D1_ON]);
301 else if(command == 'j')
302 send_frame(words[D1_OFF]);
303 else if(command == 'i')
304 send_frame(words[D2_ON]);
305 else if(command == 'k')
306 send_frame(words[D2_OFF]);
307 else if(command == 'T')
308 printTemperature(onShieldTemp);