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