added touchpad horizontal and vertical option
[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[] = { 64, 64, 64 }; // 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\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], 16);
97     delay(100);
98     int ldr = analogRead(ldr_pin);
99     Serial.print(ldr);
100     analogWrite(mosfet_pins[i], 0);
101   }
102
103   digitalWrite(led_pin, LOW);
104
105 }
106
107 void mosfet(int nr, int value) {
108   int pwm = mosfet_pwm[nr];
109   if ( pwm == value ) {
110     Serial.println("ignored");
111     return;
112   }
113   Serial.print("MOSFET ");
114   Serial.print(nr);
115   Serial.print(" = ");
116   Serial.println(value);
117   int sleep = 1000 / abs(pwm - value);
118   int step = pwm < value ? 1 : -1;
119   for(int i=pwm; i != value; i += step) {
120     MOSFET_PWM(nr, i);
121     delay(sleep);
122   }
123   MOSFET_PWM(nr, value);
124   mosfet_pwm[nr] = value;
125 }
126
127
128 unsigned int last_cx = 0;
129 unsigned int last_cy = 0;         
130
131 int last_ldr = 0;
132 static int ldr_sum = 0;
133 static int ldr_count = 0;
134
135 int last_pir = 0;
136 long int pir_millis = millis();
137
138
139 void loop() {
140
141 #if TOUCHPAD
142   byte mstat1;
143   byte mstat2;
144   byte mxy;
145   byte mx;                    //x coordinate
146   byte my;                    //y coordinate
147   byte mz;                    //z pressure value
148
149   unsigned int cx,cy;
150
151   mouse.write(0xeb); // read data
152   mouse.read();
153   
154   mstat1 = mouse.read();
155   mxy = mouse.read();
156   mz = mouse.read();
157   mstat2 = mouse.read();
158   mx = mouse.read();
159   my = mouse.read();
160
161
162   // collect the bits for x and y
163   cx = (((mstat2 & 0x10) << 8) | ((mxy & 0x0F) << 8) | mx ); // 1100-5800
164   cy = (((mstat2 & 0x20) << 7) | ((mxy & 0xF0) << 4) | my ); // 800-5000
165
166   if ( last_cx != cx || last_cy != cy ) {
167     last_cx = cx;
168     last_cy = cy;
169     Serial.print("X=");
170     Serial.print(cx, DEC);
171     Serial.print("\tY=");
172     Serial.print(cy, DEC);
173     Serial.print("\tZ=");
174     Serial.print(mz, DEC);
175     if ( cx > 1100 && cy > 800 ) {
176 #if TP_LANDSCAPE
177       int nr  = ( cx - 1100 ) / (( 5800 - 1100 ) / 3);
178       int pwm = ( cy - 800  ) / (( 5000 - 800  ) / 255);
179 #else
180       int pwm = ( cx - 1100 ) / (( 5800 - 1100 ) / 255);
181       int nr  = ( cy - 800  ) / (( 5000 - 800  ) / 4);
182       if ( nr > 2 ) nr -= 1;  // 0 [ 1 2 ] 3 -> 0 1 2
183 #endif
184       pwm -= 1; // allow off
185       Serial.print("\tmosfet = ");
186       Serial.print(nr);
187       Serial.print("\tpwm = ");
188       Serial.print(pwm);
189       if ( nr >= 0 && nr <= 2 && pwm >= 0 && pwm <= 255 ) {
190         Serial.println("\tOK");
191         MOSFET_PWM(nr, pwm);
192         mosfet_pwm[nr] = pwm;
193       } else {
194         Serial.println("\tIGNORED");
195       }
196     }
197   }
198 #endif
199
200
201   if (Serial.available()) {
202     digitalWrite(led_pin, HIGH);
203     int in = Serial.read();
204     switch (in) {
205       case 'b':
206         tone(buzzer_pin, 1800, 100);
207         delay(200);
208         tone(buzzer_pin, 2200, 100);
209         delay(500);
210         break;
211       case 'q': mosfet(0, 255); break;
212       case 'a': mosfet(0, 127); break;
213       case 'z': mosfet(0, 0); break;
214       case 'w': mosfet(1, 255); break;
215       case 's': mosfet(1, 127); break;
216       case 'x': mosfet(1, 0); break;
217       case 'e': mosfet(2, 255); break;
218       case 'd': mosfet(2, 127); break;
219       case 'c': mosfet(2, 0); break;
220
221       /*
222               m1 = (m1 + 10) % 255;
223               analogWrite(mosfet1_pin, m1);
224               Serial.print("MOSFET 1 = ");
225               Serial.println(m1);
226               break;
227             case 'a':
228               m1 = (m1 - 10) % 255;
229               analogWrite(mosfet1_pin, m1);
230               Serial.print("MOSFET 1 = ");
231               Serial.println(m1);
232               break;
233       */
234       default:
235         Serial.print("unknown command ");
236         Serial.println(in);
237     }
238     digitalWrite(led_pin, LOW);
239   }
240
241   int ldr = analogRead(ldr_pin);
242   ldr_sum += ldr;
243   ldr_count++;
244   if ( ldr_count > LDR_SIZE ) {
245     ldr = ldr_sum / ldr_count;
246     ldr_count = 0;
247     ldr_sum = 0;
248
249     if ( abs(ldr-last_ldr) > LDR_NOISE ) {  
250       Serial.print("LDR = ");
251       Serial.println(ldr);
252       last_ldr = ( last_ldr + ldr ) / 2;
253     }
254   }
255
256
257   int pir = digitalRead(pir_pin);
258   if ( pir != last_pir) {
259     last_pir = pir;
260     Serial.print("PIR = ");
261     Serial.println(pir);
262   }
263
264   long int ms = millis();
265   if ( pir == 0 ) {
266     if (pir_millis > 0 && ms - pir_millis > PIR_TIMEOUT * 1000 ) {
267       Serial.println("PIR timeout, fade-out");
268       pir_millis = -1; // mark that we are in timeout
269       for(int i=0; i<=2; i++) {
270         MOSFET_PWM(i, 0);
271       }
272     }
273   } else {
274     if (pir_millis < 0) {
275       Serial.println("PIR fade-in after timeout");
276       for(int i=0; i<=2; i++) {
277         MOSFET_PWM(i, mosfet_pwm[i]);
278       }
279     }
280     pir_millis = ms;
281   }
282
283 }