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