Cleaned up what's actually gitted.
[arduino-intervalometer.git] / Intervalometer.pde
blob944d4db56c8ce4706c5106b7adeafd3b26a9b428
1 /*
2  *  Arduino Intervalometer
3  *  Tim Horton, 2008
4  */
6 /*
7  *  Pin Assignment
8  */
10 #define INTERVAL         0
11 #define BULB             1
12 #define INTERVALBULB 2
13 #define TRIGGER          3
15 #define ENCSPEED         5
17 int buttonA =           0; // Left pushbutton
19 //int inputTrigger =  2; // Input trigger interrupt
21 int encoderPinA =       2;
22 int encoderPinB =       3;
23 int encoderButton =     4;
25 int buttonB =           5; // Right pushbutton
27 int lcdEnable =         6;
28 int lcdDataBus[] =      { 7, 8, 9, 10 };
29 int lcdDataClock =      11;
30 int lcdDataInt =        12;
32 int cameraTrigger = 13; // Pulse low for shutter release
34 /////////////////////////////
36 int currentMode = INTERVAL, selected = 0;
37 int running = 0;
38 unsigned long lastToggleRunning = 0;
39 unsigned long lastModeUpdate = 0;
40 unsigned long lastSelectedUpdate = 0;
41 unsigned long lastShutter = 0;
44 int updateHeader = 1, updateEncoder = 1;
45 volatile long exposureTime = 0, lapseTime = 0;
46 int exposureRepresentation = 0, lapseRepresentation = 0;
47 int n = LOW;
50  *  Higher level hardware functions
51  */
53 void pulsePin(int pin, int value)
55         digitalWrite(pin, !value);
56         delay(1);
57         digitalWrite(pin, value);
58         delay(1);
59         digitalWrite(pin, !value);
60         delay(1);
64  *  lcd Control Functions
65  */
67 void lcdCommandWrite(int value)
69         int i = 0;
70         int value1 = value;
72         value1 >>= 4;
73         
74         for (i = lcdDataBus[0]; i <= lcdDataInt; i++)
75         {
76                 digitalWrite(i,value1 & 01);
77                 value1 >>= 1;
78         }
79         
80         pulsePin(lcdEnable, HIGH);
81         delay(1);
83         for (i = lcdDataBus[0]; i <= lcdDataBus[3]; i++)
84         {
85                 digitalWrite(i, value & 01);
86                 value >>= 1; 
87         }
88         
89         value >>= 4;
90         
91         for (i = lcdDataClock; i <= lcdDataInt; i++)
92         {
93                 digitalWrite(i, value & 01);
94                 value >>= 1;
95         }
96         
97         pulsePin(lcdEnable, HIGH);
100 void lcdDataWrite(int value)
102         int i = 0;
103         int value1 = value;
104         
105         digitalWrite(lcdDataInt, HIGH);
106         digitalWrite(lcdDataClock, LOW);
107         
108         value1 >>= 4;
109         
110         for (i=lcdDataBus[0]; i <= lcdDataBus[3]; i++)
111         {
112                 digitalWrite(i,value1 & 01);
113                 value1 >>= 1;
114         }
115         
116         pulsePin(lcdEnable, HIGH);
117         delay(1);
118         
119         digitalWrite(lcdDataInt, HIGH);
120         digitalWrite(lcdDataClock, LOW);
121         
122         for (i=lcdDataBus[0]; i <= lcdDataBus[3]; i++)
123         {
124                 digitalWrite(i,value & 01);
125                 value >>= 1;
126         }
127         
128         pulsePin(lcdEnable, HIGH);
131 void lcdNumberWrite(int nr)
133         // We don't need negatives, but if you do:
134         /*if(nr < 0)
135         {
136                 lcdCommandWrite(557);
137                 nr = abs(nr);
138         }
139         else
140         {
141                 lcdCommandWrite(544);
142         }*/
143         
144         int n1 = nr/100;
145         int n2 = (nr - n1 * 100) / 10;
146         
147         if(n2)
148                 lcdCommandWrite(560 + n2);
149         
150         nr = nr - n1 * 100 - n2 * 10;
151         lcdCommandWrite(560 + nr);
154 void lcdHome(int row)
156         lcdCommandWrite(0x02);
157         
158         delay(4);
159         
160         if(row == 1)
161                 lcdCommandWrite(0xC0);
162                 
163         delay(1);
166 void lcdClear()
168         lcdCommandWrite(0x01);
169         delay(4);
173  *  Hardware initialization functions
174  */
176 void lcdInit()
178         int i = 0;
179         
180         for (i = lcdEnable; i <= lcdDataInt; i++)
181                 pinMode(i, OUTPUT);
183         lcdCommandWrite(0x03); delay(64);
184         lcdCommandWrite(0x03); delay(50);
185         lcdCommandWrite(0x03); delay(50);
186         lcdCommandWrite(0x02); delay(50);
187         lcdCommandWrite(0x2C); delay(20);
188         lcdCommandWrite(0x06); delay(20);
189         lcdCommandWrite(0x0C); delay(20);
190         lcdCommandWrite(0x01); delay(100);
191         lcdCommandWrite(0x80); delay(30);
194 void encoderInit()
196         pinMode(encoderPinA, INPUT); 
197         digitalWrite(encoderPinA, HIGH);
198         pinMode(encoderPinB, INPUT); 
199         digitalWrite(encoderPinB, HIGH);
201         attachInterrupt(0, doEncoderA, CHANGE);
202         attachInterrupt(1, doEncoderB, CHANGE);
205 void buttonInit()
207         pinMode(buttonA, INPUT);
208         digitalWrite(buttonA, HIGH);
209         pinMode(buttonB, INPUT);
210         digitalWrite(buttonB, HIGH);
211         
212         pinMode(encoderButton, INPUT);
213         digitalWrite(encoderButton, HIGH);
217 void setup (void)
219         pinMode(cameraTrigger, OUTPUT);
220         digitalWrite(cameraTrigger, HIGH);
222         lcdInit();
223         encoderInit();
224         buttonInit();
227 void incrementValue()
229         if(selected == 0)
230         {
231                 if(lapseRepresentation == 0)
232                         lapseTime++;
233                 else
234                         lapseTime += 60;
235         }
236         else
237         {
238                 if(exposureRepresentation == 0)
239                         exposureTime++;
240                 else
241                         exposureTime += 60;
242                 
243                 if(exposureTime > lapseTime)
244                         lapseTime = exposureTime;
245         }
248 void decrementValue()
250         if(selected == 0)
251         {
252                 if(lapseRepresentation == 0 || ceil(lapseTime/ENCSPEED) == 60) // careful around transition; thanks, nate
253                         lapseTime--;
254                 else
255                         lapseTime -= 60;
256                 
257                 if(lapseTime < 0)
258                         lapseTime = 0;
259         }
260         else
261         {
262                 if(exposureRepresentation == 0 || ceil(exposureTime/ENCSPEED) == 60)
263                         exposureTime--;
264                 else
265                         exposureTime -= 60;
266                 
267                 if(exposureTime < 0)
268                         exposureTime = 0;
269         }
272 void doEncoderA()
274         noInterrupts();
275         delayMicroseconds(3000);
276         if (digitalRead(encoderPinA) == HIGH)
277         { 
278                 if (digitalRead(encoderPinB) == LOW)
279                         incrementValue();
280                 else
281                         decrementValue();
282         }
283         else                                       
284         {
285                 if (digitalRead(encoderPinB) == HIGH)
286                         incrementValue();
287                 else
288                         decrementValue();
289         }
290         
291         updateEncoder = 1;
292         interrupts();
295 void doEncoderB()
297         noInterrupts();
298         delayMicroseconds(3000);
299         if (digitalRead(encoderPinB) == HIGH)
300         {
301                 if (digitalRead(encoderPinA) == HIGH)
302                         incrementValue();
303                 else
304                         decrementValue();
305         }
306         else
307         {
308                 if (digitalRead(encoderPinA) == LOW)
309                         incrementValue();
310                 else
311                         decrementValue();
312         }
313         
314         updateEncoder = 1;
315         interrupts();
318 void switchModes()
320         unsigned long diff = (millis() - lastModeUpdate);
321         
322         if(diff < 300) // careful about the overflow...
323         {
324                 lastModeUpdate = millis();
325                 return;
326         }
327         else
328                 lastModeUpdate = millis();
329         
330         currentMode++;
331         if(currentMode > 3)
332                 currentMode = 0;
333         
334         if(currentMode == BULB)
335                 selected = 1;
336         else
337                 selected = 0;
338         
339         updateHeader = 1;
342 void switchSelected()
344         if(currentMode == INTERVALBULB)
345         {
346                 unsigned long diff = (millis() - lastSelectedUpdate);
347                 
348                 if(diff < 300) // careful about the overflow...
349                 {
350                         lastSelectedUpdate = millis();
351                         return;
352                 }
353                 else
354                         lastSelectedUpdate = millis();
356                 selected = !selected;
357         }
358         
359         updateEncoder = 1;
362 void toggleRunning()
364         unsigned long diff = (millis() - lastToggleRunning);
365         
366         if(diff < 300) // careful about the overflow...
367         {
368                 lastToggleRunning = millis();
369                 return;
370         }
371         else
372                 lastToggleRunning = millis();
373         
374         running = !running;
377 void drawTimecode(int secs, int rep)
379         secs = secs/ENCSPEED;
380         if(rep == 0)
381         {
382                 lcdNumberWrite(secs);
383                 lcdDataWrite('"');
384         }
385         else
386         {
387                 lcdNumberWrite(secs/60);
388                 lcdDataWrite('\'');
389         }
392 int timecodeLength(int secs, int rep)
394         int count = 2;
395         
396         secs = secs/ENCSPEED;
397         
398         if(rep)
399                 secs = secs/60;
400         
401         int n1 = secs/100;
402         int n2 = (secs - n1 * 100) / 10;
404         if(n2)
405                 count++;
406         
407         return count;
410 char *modeHeader[4] = {"Interval", "            Bulb", "Interval    Bulb", "Trigger"};
412 void loop(void)
414         if(updateHeader)
415         {
416                 lcdHome(0);
417                 
418                 int count;
419                 for (count = 0; modeHeader[currentMode][count] != 0; count++)
420                         lcdDataWrite(modeHeader[currentMode][count]);
421                 for (; count < 16; count++)
422                         lcdDataWrite(' ');
423                 
424                 updateHeader = 0;
425                 updateEncoder = 1;
426         }
428         if(updateEncoder)
429         {
430                 if((lapseTime/ENCSPEED) >= 60)
431                         lapseRepresentation = 1;
432                 else
433                         lapseRepresentation = 0;
435                 if((exposureTime/ENCSPEED) >= 60)
436                         exposureRepresentation = 1;
437                 else
438                         exposureRepresentation = 0;
439                 
440                 /////////////////////////////////////
441                 
442                 lcdHome(1);
443                 
444                 if(currentMode != BULB)
445                         drawTimecode(lapseTime, lapseRepresentation);
446                 
447                 int width = 0;
448                 
449                 if(currentMode != BULB)
450                         width += timecodeLength(lapseTime, lapseRepresentation);
451                 if(currentMode != INTERVAL && currentMode != TRIGGER)
452                         width += timecodeLength(exposureTime, exposureRepresentation);
453                         
454                 if(selected == 0)
455                 {
456                         lcdDataWrite(' '); width++;
457                         lcdDataWrite(127); width++;
458                 }
459                 else
460                 {
461                         width += 2;
462                 }
463                                 
464                 for(int i = 16; i > width; i--)
465                         lcdDataWrite(' ');
466                 
467                 if(selected == 1)
468                 {
469                         lcdDataWrite(126);
470                         lcdDataWrite(' ');
471                 }
472                 
473                 if(currentMode != INTERVAL && currentMode != TRIGGER)
474                         drawTimecode(exposureTime, exposureRepresentation);
476                 updateEncoder = 0;
477         }
478         
479         if(digitalRead(buttonA) == LOW)
480                 toggleRunning();
481         
482         if(running)
483         {
484                 if(currentMode == TRIGGER)
485                 {
486                         // do special trigger stuff
487                         return;
488                 }
489                 
490                 unsigned long diff = millis() - lastShutter;
491                 
492                 int adjustedLapseTime = lapseTime / ENCSPEED;
493                 if(currentMode != INTERVAL)
494                         adjustedLapseTime -= exposureTime;
495                 
496                 if(diff > (adjustedLapseTime * 1000)) // careful about the overflow...
497                 {
498                         digitalWrite(cameraTrigger, LOW);
499                         
500                         if(currentMode == INTERVAL)
501                                 delay(100);
502                         else
503                                 delay((exposureTime / ENCSPEED) * 1000); //delay for length of exposure
504                                 
505                         digitalWrite(cameraTrigger, HIGH);
506                         lastShutter = millis();
507                         
508                         if(currentMode == BULB)
509                                 running = 0;
510                 }
511         }
512         else
513         {
514                 if(digitalRead(buttonB) == LOW)
515                         switchModes();
516                 
517                 if(digitalRead(encoderButton) == LOW)
518                         switchSelected();
519         }