ef1263c226c2002fcdb4e0a3baf6b03d407cc51c
[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 //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
18
19 OneWire  onewire(ONE_WIRE_PIN);
20 DallasTemperature dallas_sensors(&onewire);
21 DeviceAddress onShieldTemp = { 0x10, 0xE7, 0x77, 0xD3, 0x01, 0x08, 0x00, 0x3F };
22
23 typedef struct {
24   byte offset;
25   byte state;
26 } rf_bit_t;
27
28 // offset is number of alphas (0.08ms)
29
30 const rf_bit_t zero_bit[] = { {  4, 1 },
31                               { 16, 0 },
32                               { 20, 1 },
33                               { 32, 0 },
34                               {  0, 0 } };
35
36 const rf_bit_t one_bit[] = { { 12, 1 },
37                              { 16, 0 },
38                              { 28, 1 },
39                              { 32, 0 },
40                              {  0, 0 } };
41
42 const rf_bit_t float_bit[] = { {  4, 1 },
43                                { 16, 0 },
44                                { 28, 1 },
45                                { 32, 0 },
46                                {  0, 0 } };
47
48 const rf_bit_t sync_bit[] = { {   4, 1 },
49                               { 128, 0 },
50                               {   0, 0 } };
51
52 typedef enum { ZERO = 0, ONE , FLOAT , SYNC } adbit_t;
53 typedef byte ad_bit_t;
54 #define WORD_LEN 13
55 typedef ad_bit_t word_t[WORD_LEN];
56
57 const rf_bit_t* bit_defs[] = { zero_bit, one_bit, float_bit, sync_bit };
58
59 byte alpha_cnt = 0;
60 byte bit_cnt = 0;
61 byte chunk_cnt = 0;
62 byte word_cnt = 0;
63 const ad_bit_t* current_word;
64 byte volatile frame_finished = 1;
65
66 #define FRAME_LEN 8
67
68 #define A1_ON  0
69 #define A1_OFF 1
70 #define A2_ON  2
71 #define A2_OFF 3
72
73 #define B1_ON  4
74 #define B1_OFF 5
75 #define B2_ON  6
76 #define B2_OFF 7
77
78 #define C1_ON  8
79 #define C1_OFF 9
80 #define C2_ON  10
81 #define C2_OFF 11
82
83 #define D1_ON  12
84 #define D1_OFF 13
85 #define D2_ON  14
86 #define D2_OFF 15
87
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
93
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
98
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
103
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
108 };
109
110
111 //********************************************************************//
112
113 void start_timer()
114 {
115   // timer 1: 2 ms
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
122 }
123
124 void stop_timer() // stop the timer
125 {
126   // timer1
127   TCCR1B = 0; // no clock source
128   TIMSK1 = 0; // disable timer interrupt
129 }
130
131 void init_word(const word_t w)
132 {
133   current_word = w;
134   alpha_cnt = 0;
135   chunk_cnt = 0;
136   bit_cnt = 0;
137
138   if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
139     digitalWrite(DATA_OUT_PIN, HIGH);
140   else
141     digitalWrite(DATA_OUT_PIN, LOW);
142
143   start_timer();
144 }
145
146 ISR(TIMER1_COMPA_vect)
147 {
148   alpha_cnt++;
149   if(alpha_cnt < bit_defs[current_word[bit_cnt]][chunk_cnt].offset)
150     return;
151
152   chunk_cnt++;
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);
156     else
157       digitalWrite(DATA_OUT_PIN, LOW);
158     return;
159   }
160   
161   bit_cnt++;
162   if(bit_cnt < WORD_LEN) {
163     alpha_cnt = 0;
164     chunk_cnt = 0;
165     if(bit_defs[current_word[bit_cnt]][chunk_cnt].state)
166       digitalWrite(DATA_OUT_PIN, HIGH);
167     else
168       digitalWrite(DATA_OUT_PIN, LOW);
169     return;
170   }
171   stop_timer();
172   digitalWrite(DATA_OUT_PIN, LOW);
173
174   word_cnt++;
175   if(word_cnt < FRAME_LEN)
176     init_word(current_word);
177
178   frame_finished = 1;
179 }
180
181 //***********//
182
183
184 void send_frame(const word_t w)
185 {
186   word_cnt = 0;
187   frame_finished = 0;
188   init_word(w);
189
190   for(;;)
191     if(frame_finished)
192       break;
193 }
194
195 //********************************************************************//
196
197 void printTemperature(DeviceAddress deviceAddress)
198 {
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
205 }
206
207 //********************************************************************//
208
209 void setup()
210 {
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 
217   
218   onewire.reset();
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);
225   
226   Serial.begin(9600);
227 }
228
229 unsigned int ir_time=IR_SAMPLE_DURATION;
230 unsigned int ir_count=0;
231 boolean pb_last_state=0;
232 boolean pb_state=0;
233 boolean pb_postth_state=0;
234 unsigned int pb_time=0;
235
236 void loop()
237 {
238   ir_time--;
239   ir_count += (digitalRead(IR_MOVEMENT_PIN) == HIGH);
240
241   if (pb_time < PB_TRESHOLD)
242     pb_time++;
243   pb_state=(digitalRead(PANIC_BUTTON_PIN) == LOW);
244   
245   if (ir_time == 0)
246   {
247     if (ir_count >= IR_TRESHOLD)
248       Serial.println("movement");
249     ir_time=IR_SAMPLE_DURATION;
250     ir_count=0;
251   }
252   
253   if (pb_state == pb_last_state && pb_time >= PB_TRESHOLD)
254   {
255     if (pb_state && ! pb_postth_state)
256     {   
257       pb_postth_state=1;
258       Serial.println("PanicButton");
259     }
260     else if (!pb_state)
261       pb_postth_state=0;
262   }
263   else if (pb_state != pb_last_state)
264   {
265     pb_time=0;
266     pb_last_state=pb_state;
267   }
268     
269   if(Serial.available()) {
270     char command = Serial.read();
271     
272     if(command == 'q')
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]);
280
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]);
289
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]);
298
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);
309   }
310 }