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 //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 Reports, 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(RF_DATA_OUT_PIN, HIGH);
141 digitalWrite(RF_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(RF_DATA_OUT_PIN, HIGH);
157 digitalWrite(RF_DATA_OUT_PIN, LOW);
162 if(bit_cnt < WORD_LEN) {
165 if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
166 digitalWrite(RF_DATA_OUT_PIN, HIGH);
168 digitalWrite(RF_DATA_OUT_PIN, LOW);
172 digitalWrite(RF_DATA_OUT_PIN, LOW);
175 if(word_cnt < FRAME_LEN)
176 init_word(current_word);
184 void send_frame(const word_t w)
194 Serial.println("Ok");
197 //********************************************************************//
199 void printTemperature(DeviceAddress deviceAddress)
201 dallas_sensors.requestTemperatures();
202 float tempC = dallas_sensors.getTempC(deviceAddress);
203 Serial.print("Temp C: ");
204 Serial.println(tempC);
205 //Serial.print(" Temp F: ");
206 //Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
209 //********************************************************************//
213 pinMode(RF_DATA_OUT_PIN, OUTPUT);
214 digitalWrite(RF_DATA_OUT_PIN, LOW);
215 pinMode(IR_MOVEMENT_PIN, INPUT); // set pin to input
216 digitalWrite(IR_MOVEMENT_PIN, LOW); // turn off pullup resistors
217 pinMode(PANIC_BUTTON_PIN, INPUT); // set pin to input
218 digitalWrite(PANIC_BUTTON_PIN, HIGH); // turn on pullup resistors
221 onewire.reset_search();
222 dallas_sensors.begin();
223 //in case we change temp sensor:
224 if (!dallas_sensors.getAddress(onShieldTemp, 0))
225 Serial.println("Unable to find address for Device 0");
226 dallas_sensors.setResolution(onShieldTemp, 9);
231 unsigned int ir_time=IR_SAMPLE_DURATION;
232 unsigned int ir_count=0;
233 boolean pb_last_state=0;
235 boolean pb_postth_state=0;
236 unsigned int pb_time=0;
241 ir_count += (digitalRead(IR_MOVEMENT_PIN) == HIGH);
243 if (pb_time < PB_TRESHOLD)
245 pb_state=(digitalRead(PANIC_BUTTON_PIN) == LOW);
249 if (ir_count >= IR_TRESHOLD)
250 Serial.println("movement");
251 ir_time=IR_SAMPLE_DURATION;
255 if (pb_state == pb_last_state && pb_time >= PB_TRESHOLD)
257 if (pb_state && ! pb_postth_state)
260 Serial.println("PanicButton");
265 else if (pb_state != pb_last_state)
268 pb_last_state=pb_state;
271 if(Serial.available()) {
272 char command = Serial.read();
275 send_frame(words[A1_ON]);
276 else if(command == 'a')
277 send_frame(words[A1_OFF]);
278 else if(command == 'w')
279 send_frame(words[A2_ON]);
280 else if(command == 's')
281 send_frame(words[A2_OFF]);
283 else if(command == 'e')
284 send_frame(words[B1_ON]);
285 else if(command == 'd')
286 send_frame(words[B1_OFF]);
287 else if(command == 'r')
288 send_frame(words[B2_ON]);
289 else if(command == 'f')
290 send_frame(words[B2_OFF]);
292 else if(command == 't')
293 send_frame(words[C1_ON]);
294 else if(command == 'g')
295 send_frame(words[C1_OFF]);
296 else if(command == 'z')
297 send_frame(words[C2_ON]);
298 else if(command == 'h')
299 send_frame(words[C2_OFF]);
301 else if(command == 'u')
302 send_frame(words[D1_ON]);
303 else if(command == 'j')
304 send_frame(words[D1_OFF]);
305 else if(command == 'i')
306 send_frame(words[D2_ON]);
307 else if(command == 'k')
308 send_frame(words[D2_OFF]);
309 else if(command == 'T')
310 printTemperature(onShieldTemp);
313 Serial.println("Error: unknown command");