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