IR Sensor, PanicButton, OneWireTempSensor
[svn42.git] / rf433ctl / rf433ctl.pde
1 #include <avr/io.h>
2 #include <avr/interrupt.h>
3 #include <inttypes.h>
4 #include <OneWire.h>
5 #include <DallasTemperature.h>
6
7 //********************************************************************//
8
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 #define IR_SAMPLE_DURATION 20000
14 #define IR_TRESHOLD 13000
15 #define PB_SAMPLE_DURATION 5000
16 #define PB_TRESHOLD 5000
17
18 OneWire  onewire(ONE_WIRE_PIN);
19 DallasTemperature dallas_sensors(&onewire);
20 DeviceAddress onShieldTemp = { 0x10, 0xE7, 0x77, 0xD3, 0x01, 0x08, 0x00, 0x3F };
21
22 typedef struct {
23   byte offset;
24   byte state;
25 } rf_bit_t;
26
27 // offset is number of alphas (0.08ms)
28
29 const rf_bit_t zero_bit[] = { {  4, 1 },
30                               { 16, 0 },
31                               { 20, 1 },
32                               { 32, 0 },
33                               {  0, 0 } };
34
35 const rf_bit_t one_bit[] = { { 12, 1 },
36                              { 16, 0 },
37                              { 28, 1 },
38                              { 32, 0 },
39                              {  0, 0 } };
40
41 const rf_bit_t float_bit[] = { {  4, 1 },
42                                { 16, 0 },
43                                { 28, 1 },
44                                { 32, 0 },
45                                {  0, 0 } };
46
47 const rf_bit_t sync_bit[] = { {   4, 1 },
48                               { 128, 0 },
49                               {   0, 0 } };
50
51 typedef enum { ZERO = 0, ONE , FLOAT , SYNC } adbit_t;
52 typedef byte ad_bit_t;
53 #define WORD_LEN 13
54 typedef ad_bit_t word_t[WORD_LEN];
55
56 const rf_bit_t* bit_defs[] = { zero_bit, one_bit, float_bit, sync_bit };
57
58 byte alpha_cnt = 0;
59 byte bit_cnt = 0;
60 byte chunk_cnt = 0;
61 byte word_cnt = 0;
62 const ad_bit_t* current_word;
63 byte volatile frame_finished = 1;
64
65 #define FRAME_LEN 8
66
67 #define A1_ON  0
68 #define A1_OFF 1
69 #define A2_ON  2
70 #define A2_OFF 3
71
72 #define B1_ON  4
73 #define B1_OFF 5
74 #define B2_ON  6
75 #define B2_OFF 7
76
77 #define C1_ON  8
78 #define C1_OFF 9
79 #define C2_ON  10
80 #define C2_OFF 11
81
82 #define D1_ON  12
83 #define D1_OFF 13
84 #define D2_ON  14
85 #define D2_OFF 15
86
87 const word_t words[]  = { 
88 { ZERO,  ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // A1_ON
89 { ZERO,  ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // A1_OFF
90 { ZERO,  ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // A2_ON
91 { ZERO,  ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // A2_OFF
92
93 { FLOAT, ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // B1_ON
94 { FLOAT, ZERO,  FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // B1_OFF
95 { FLOAT, ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // B2_ON
96 { FLOAT, ZERO,  FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // B2_OFF
97
98 { ZERO,  FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // C1_ON
99 { ZERO,  FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // C1_OFF
100 { ZERO,  FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // C2_ON
101 { ZERO,  FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // C2_OFF
102
103 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // D1_ON
104 { FLOAT, FLOAT, FLOAT, FLOAT, ZERO,  ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }, // D1_OFF
105 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, FLOAT, SYNC }, // D2_ON
106 { FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO, FLOAT, FLOAT, ZERO,  SYNC }  // D2_OFF
107 };
108
109
110 //********************************************************************//
111
112 void start_timer()
113 {
114   // timer 1: 2 ms
115   TCCR1A = 0;                    // prescaler 1:8, WGM = 4 (CTC)
116   TCCR1B = 1<<WGM12 | 1<<CS11;   // 
117   OCR1A = 159;        // (1+159)*8 = 1280 -> 0.08ms @ 16 MHz -> 1*alpha
118 //  OCR1A = 207;        // (1+207)*8 = 1664 -> 0.104ms @ 16 MHz -> 1*alpha
119   TCNT1 = 0;          // reseting timer
120   TIMSK1 = 1<<OCIE1A; // enable Interrupt
121 }
122
123 void stop_timer() // stop the timer
124 {
125   // timer1
126   TCCR1B = 0; // no clock source
127   TIMSK1 = 0; // disable timer interrupt
128 }
129
130 void init_word(const word_t w)
131 {
132   current_word = w;
133   alpha_cnt = 0;
134   chunk_cnt = 0;
135   bit_cnt = 0;
136
137   if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
138     digitalWrite(DATA_OUT_PIN, HIGH);
139   else
140     digitalWrite(DATA_OUT_PIN, LOW);
141
142   start_timer();
143 }
144
145 ISR(TIMER1_COMPA_vect)
146 {
147   alpha_cnt++;
148   if(alpha_cnt < bit_defs[current_word[bit_cnt]][chunk_cnt].offset)
149     return;
150
151   chunk_cnt++;
152   if(bit_defs[current_word[bit_cnt]][chunk_cnt].offset != 0) {
153     if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
154       digitalWrite(DATA_OUT_PIN, HIGH);
155     else
156       digitalWrite(DATA_OUT_PIN, LOW);
157     return;
158   }
159   
160   bit_cnt++;
161   if(bit_cnt < WORD_LEN) {
162     alpha_cnt = 0;
163     chunk_cnt = 0;
164     if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
165       digitalWrite(DATA_OUT_PIN, HIGH);
166     else
167       digitalWrite(DATA_OUT_PIN, LOW);
168     return;
169   }
170   stop_timer();
171   digitalWrite(DATA_OUT_PIN, LOW);
172
173   word_cnt++;
174   if(word_cnt < FRAME_LEN)
175     init_word(current_word);
176
177   frame_finished = 1;
178 }
179
180 //***********//
181
182
183 void send_frame(const word_t w)
184 {
185   word_cnt = 0;
186   frame_finished = 0;
187   init_word(w);
188
189   for(;;)
190     if(frame_finished)
191       break;
192 }
193
194 //********************************************************************//
195
196 void printTemperature(DeviceAddress deviceAddress)
197 {
198   dallas_sensors.requestTemperatures();
199   float tempC = dallas_sensors.getTempC(deviceAddress);
200   Serial.print("Temp C: ");
201   Serial.println(tempC);
202   //Serial.print(" Temp F: ");
203   //Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
204 }
205
206 //********************************************************************//
207
208 void setup()
209 {
210   pinMode(DATA_OUT_PIN, OUTPUT);
211   digitalWrite(DATA_OUT_PIN, LOW);
212   pinMode(IR_MOVEMENT_PIN, INPUT);      // set pin to input
213   digitalWrite(IR_MOVEMENT_PIN, LOW);  // turn off pullup resistors  
214   pinMode(PANIC_BUTTON_PIN, INPUT);      // set pin to input
215   digitalWrite(PANIC_BUTTON_PIN, HIGH);  // turn on pullup resistors 
216   
217   onewire.reset();
218   onewire.reset_search();
219   dallas_sensors.begin();
220   //in case we change temp sensor:
221   if (!dallas_sensors.getAddress(onShieldTemp, 0)) 
222     Serial.println("Unable to find address for Device 0"); 
223   dallas_sensors.setResolution(onShieldTemp, 9);
224   
225   Serial.begin(9600);
226 }
227
228 unsigned int ir_time=IR_SAMPLE_DURATION;
229 unsigned int ir_count=0;
230 unsigned int pb_time=PB_SAMPLE_DURATION;
231 unsigned int pb_count=0;
232
233 void loop()
234 {
235   ir_time--;
236   pb_time--;
237   ir_count += (digitalRead(IR_MOVEMENT_PIN) == HIGH);
238   pb_count += (digitalRead(PANIC_BUTTON_PIN) == LOW);
239   
240   if (ir_time == 0)
241   {
242     if (ir_count >= IR_TRESHOLD)
243       Serial.println("movement");
244     ir_time=IR_SAMPLE_DURATION;
245     ir_count=0;
246   }
247
248   if (pb_time == 0)
249   {
250     if (pb_count >= PB_TRESHOLD)
251       Serial.println("PanicButton");
252     pb_time=PB_SAMPLE_DURATION;
253     pb_count=0;
254   }
255   
256   if(Serial.available()) {
257     char command = Serial.read();
258     
259     if(command == 'q')
260       send_frame(words[A1_ON]);
261     else if(command == 'a')
262       send_frame(words[A1_OFF]);
263     else if(command == 'w')
264       send_frame(words[A2_ON]);
265     else if(command == 's')
266       send_frame(words[A2_OFF]);
267
268     else if(command == 'e')
269       send_frame(words[B1_ON]);
270     else if(command == 'd')
271       send_frame(words[B1_OFF]);
272     else if(command == 'r')
273       send_frame(words[B2_ON]);
274     else if(command == 'f')
275       send_frame(words[B2_OFF]);
276
277     else if(command == 't')
278       send_frame(words[C1_ON]);
279     else if(command == 'g')
280       send_frame(words[C1_OFF]);
281     else if(command == 'z')
282       send_frame(words[C2_ON]);
283     else if(command == 'h')
284       send_frame(words[C2_OFF]);
285
286     else if(command == 'u')
287       send_frame(words[D1_ON]);
288     else if(command == 'j')
289       send_frame(words[D1_OFF]);
290     else if(command == 'i')
291       send_frame(words[D2_ON]);
292     else if(command == 'k')
293       send_frame(words[D2_OFF]);
294     else if(command == 'T')
295       printTemperature(onShieldTemp);
296   }
297 }