L(dr) and P(ir) readings
[Arduino] / Desk_LED_dimmer / Desk_LED_dimmer.ino
1 /*
2     Over complicated desk LED dimmer
3     2016-01-10 Dobrica Pavlinusic <dpavlin@rot13.org>
4 */
5
6 const int led_pin = 13;
7 const int buzzer_pin = 4;
8 const int mosfet_pins[] = { 9, 10, 6 }; // PWM pins: 3,5,6,9,10,11
9 const int ldr_pin = A3; // LDR +5 -- A3 -[10K]- GND
10 const int pir_pin = A2;
11
12
13 #define TOUCHPAD 1 // set this to 0 if debugging without touchpad
14
15 int LDR_SIZE = 1;       // 1 number of LDR reading to average
16 int LDR_NOISE = 6;      // 6 calibrate LDR noise level 
17
18 #define PIR_TIMEOUT 10 // s
19
20 #if TOUCHPAD
21 #include <ps2.h>
22 PS2 mouse(8, 7); // PS2 synaptics clock, data
23 #endif
24 #define TP_LANDSCAPE 0
25
26
27 int mosfet_pwm[] = { 1, 1, 1 }; // initial and current state of mosfet pwm
28
29 void MOSFET_PWM(int i, int pwm) {
30         analogWrite(mosfet_pins[i], pwm);
31         Serial.print("MOSFET=");
32         Serial.print(i);
33         Serial.print(":");
34         Serial.println(pwm);
35 }
36
37
38 void setup() {
39   Serial.begin(115200);
40   Serial.println("setup");
41
42   pinMode(led_pin, OUTPUT);
43   digitalWrite(led_pin, HIGH); // signal reset
44
45   pinMode(buzzer_pin, OUTPUT);
46
47   for(int i=0; i<=2; i++) {
48     pinMode(mosfet_pins[i], OUTPUT);
49     analogWrite(mosfet_pins[i], 0);
50   }
51
52   pinMode(ldr_pin, INPUT);
53
54   pinMode(pir_pin, INPUT);
55
56 #if TOUCHPAD
57   Serial.println("Synaptics touchpad init");
58
59   mouse.write(0xff);  // reset
60   mouse.read();  // ack byte
61   mouse.read();  // blank */
62
63   mouse.read();  // blank */
64   mouse.write(0xf0);  // remote mode -- send motion data only on $EB (read data) command
65   mouse.read();  // ack
66   delayMicroseconds(100);
67   mouse.write(0xe8); // set resolution
68   mouse.read();  // ack byte
69   mouse.write(0x03); // rr  ( rr * 64  +  ss * 16  +  tt * 4  +  uu  == modebyte )
70   mouse.read();  // ack byte
71   mouse.write(0xe8);
72   mouse.read();  // ack byte
73   mouse.write(0x00); // ss
74   mouse.read();  // ack byte
75   mouse.write(0xe8);
76   mouse.read();  // ack byte
77   mouse.write(0x01); // tt
78   mouse.read();  // ack byte
79   mouse.write(0xe8);
80   mouse.read();  // ack byte
81   mouse.write(0x00); // uu
82   mouse.read();  // ack byte
83   mouse.write(0xf3); // set samplerate 20 (stores mode) 
84   mouse.read();  // ack byte
85   mouse.write(0x14);
86   mouse.read();  // ack byte
87   delayMicroseconds(100); 
88
89 #endif
90
91   Serial.print("Commands: b - beep, qwe/asd/zxc - MOSFETs, hjkl - single step fade, L - LDR, P - PIR\nLDR = ");
92   int ldr = analogRead(ldr_pin);
93   Serial.println(ldr);
94
95   for(int i=0; i<=2; i++) {
96     analogWrite(mosfet_pins[i], 1);
97     delay(100);
98     int ldr = analogRead(ldr_pin);
99     Serial.println(ldr);
100     analogWrite(mosfet_pins[i], 0);
101   }
102
103   // recall startup values
104   for(int i=0; i<=2; i++) {
105     analogWrite(mosfet_pins[i], mosfet_pwm[i]);
106   }
107
108   digitalWrite(led_pin, LOW);
109
110 }
111
112 void mosfet(int nr, int value) {
113   int pwm = mosfet_pwm[nr];
114   if ( pwm == value ) {
115     Serial.println("ignored");
116     return;
117   }
118   int sleep = 200 / abs(pwm - value); // changes bigger than 200 (on/off) will be instant
119   int step = pwm < value ? 1 : -1;
120   for(int i=pwm + step; i != value; i += step) {
121     //MOSFET_PWM(nr, i);
122     analogWrite(mosfet_pins[nr], i);
123     delay(sleep);
124   }
125   MOSFET_PWM(nr, value);
126   mosfet_pwm[nr] = value;
127 }
128
129
130 unsigned int last_cx = 0;
131 unsigned int last_cy = 0;         
132
133 int last_ldr = 0;
134 static int ldr_sum = 0;
135 static int ldr_count = 0;
136
137 int last_pir = 0;
138 long int pir_millis = millis();
139
140 int vi_nr = 0; // mosfet to fade with vi binadings
141
142
143 void loop() {
144
145 #if TOUCHPAD
146   byte mstat1;
147   byte mstat2;
148   byte mxy;
149   byte mx;                    //x coordinate
150   byte my;                    //y coordinate
151   byte mz;                    //z pressure value
152
153   unsigned int cx,cy;
154
155   mouse.write(0xeb); // read data
156   mouse.read();
157   
158   mstat1 = mouse.read();
159   mxy = mouse.read();
160   mz = mouse.read();
161   mstat2 = mouse.read();
162   mx = mouse.read();
163   my = mouse.read();
164
165
166   // collect the bits for x and y
167   cx = (((mstat2 & 0x10) << 8) | ((mxy & 0x0F) << 8) | mx ); // 1100-5800
168   cy = (((mstat2 & 0x20) << 7) | ((mxy & 0xF0) << 4) | my ); // 800-5000
169
170   if ( last_cx != cx || last_cy != cy ) {
171     last_cx = cx;
172     last_cy = cy;
173     Serial.print("X=");
174     Serial.print(cx, DEC);
175     Serial.print("\tY=");
176     Serial.print(cy, DEC);
177     Serial.print("\tZ=");
178     Serial.print(mz, DEC);
179     if ( cx > 1100 && cy > 800 ) {
180 #if TP_LANDSCAPE
181       int nr  = ( cx - 1100 ) / (( 5800 - 1100 ) / 3);
182       int pwm = ( cy - 800  ) / (( 5000 - 800  ) / 255);
183 #else
184       int pwm = ( cx - 1100 ) / (( 5800 - 1100 ) / 255);
185       int nr  = ( cy - 800  ) / (( 5000 - 800  ) / 4);
186       if ( nr > 2 ) nr -= 1;  // 0 [ 1 2 ] 3 -> 0 1 2
187 #endif
188       pwm -= 1; // allow off
189       Serial.print("\tmosfet = ");
190       Serial.print(nr);
191       Serial.print("\tpwm = ");
192       Serial.print(pwm);
193       if ( nr >= 0 && nr <= 2 && pwm >= 0 && pwm <= 255 ) {
194         Serial.println("\tOK");
195         MOSFET_PWM(nr, pwm);
196         mosfet_pwm[nr] = pwm;
197       } else {
198         Serial.println("\tIGNORED");
199       }
200     }
201   }
202 #endif
203
204
205   int ldr = analogRead(ldr_pin);
206   ldr_sum += ldr;
207   ldr_count++;
208   if ( ldr_count > LDR_SIZE ) {
209     ldr = ldr_sum / ldr_count;
210     ldr_count = 0;
211     ldr_sum = 0;
212
213     if ( abs(ldr-last_ldr) > LDR_NOISE ) {  
214       Serial.print("LDR = ");
215       Serial.println(ldr);
216       last_ldr = ( last_ldr + ldr ) / 2;
217     }
218   }
219
220
221   int pir = digitalRead(pir_pin);
222   if ( pir != last_pir) {
223     last_pir = pir;
224     Serial.print("PIR = ");
225     Serial.println(pir);
226   }
227
228   long int ms = millis();
229   if ( pir == 0 ) {
230     if (pir_millis > 0 && ms - pir_millis > PIR_TIMEOUT * 1000 ) {
231       Serial.println("PIR timeout, fade-out");
232       pir_millis = -1; // mark that we are in timeout
233       for(int i=0; i<=2; i++) {
234         MOSFET_PWM(i, 0);
235       }
236     }
237   } else {
238     if (pir_millis < 0) {
239       Serial.println("PIR fade-in after timeout");
240       for(int i=0; i<=2; i++) {
241         MOSFET_PWM(i, mosfet_pwm[i]);
242       }
243     }
244     pir_millis = ms;
245   }
246
247
248   if (Serial.available()) {
249     digitalWrite(led_pin, HIGH);
250     int in = Serial.read();
251     switch (in) {
252       case 'b':
253         tone(buzzer_pin, 1800, 100);
254         delay(200);
255         tone(buzzer_pin, 2200, 100);
256         delay(500);
257         break;
258       case 'q': mosfet(0, 255); break;
259       case 'a': mosfet(0, 127); break;
260       case 'z': mosfet(0, 0); break;
261       case 'w': mosfet(1, 255); break;
262       case 's': mosfet(1, 127); break;
263       case 'x': mosfet(1, 0); break;
264       case 'e': mosfet(2, 255); break;
265       case 'd': mosfet(2, 127); break;
266       case 'c': mosfet(2, 0); break;
267
268       // vi mappings
269       case 'h': vi_nr = ( vi_nr - 1 + 3 ) % 3; Serial.println(vi_nr); break;
270       case 'j': mosfet(vi_nr, (mosfet_pwm[vi_nr]-1+255)%255 ); break;
271       case 'k': mosfet(vi_nr, (mosfet_pwm[vi_nr]+1)%255 ); break;
272       case 'l': vi_nr = ( vi_nr + 1 ) % 3; Serial.println(vi_nr); break;
273
274       case 'L': Serial.println(ldr); break;
275       case 'P': Serial.println(pir); break;
276
277       /*
278               m1 = (m1 + 10) % 255;
279               analogWrite(mosfet1_pin, m1);
280               Serial.print("MOSFET 1 = ");
281               Serial.println(m1);
282               break;
283             case 'a':
284               m1 = (m1 - 10) % 255;
285               analogWrite(mosfet1_pin, m1);
286               Serial.print("MOSFET 1 = ");
287               Serial.println(m1);
288               break;
289       */
290       default:
291         Serial.print("unknown command ");
292         Serial.println(in);
293     }
294     digitalWrite(led_pin, LOW);
295   }
296
297 }