Initial import.
[arduino-intervalometer.git] / applet / Intervalometer.cpp
blob46ec32ef147a9588c0052206012b953702382e57
1 #include "WProgram.h"
2 /*
3 * Arduino Intervalometer
4 * Tim Horton, 2008
5 */
7 /*
8 * Pin Assignment
9 */
11 #define INTERVAL 0
12 #define BULB 1
13 #define INTERVALBULB 2
14 #define TRIGGER 3
16 void pulsePin(int pin, int value);
17 void lcdCommandWrite(int value);
18 void lcdDataWrite(int value);
19 void lcdNumberWrite(int nr);
20 void lcdHome(int row);
21 void lcdClear();
22 void lcdInit();
23 void encoderInit();
24 void buttonInit();
25 void setup (void);
26 void incrementValue();
27 void decrementValue();
28 void updateEncoderValue();
29 void switchModes();
30 void switchSelected();
31 void toggleRunning();
32 void drawTimecode(int secs, int rep);
33 int timecodeLength(int secs, int rep);
34 void loop(void);
35 int buttonA = 0; // Left pushbutton
36 int buttonB = 1; // Right pushbutton
38 int inputTrigger = 2; // Input trigger interrupt
40 int encoderButton = 3;
41 int encoderPinA = 4;
42 int encoderPinB = 5;
44 int lcdEnable = 6;
45 int lcdDataBus[] = { 7, 8, 9, 10 };
46 int lcdDataClock = 11;
47 int lcdDataInt = 12;
49 int cameraTrigger = 13; // Pulse low for shutter release
51 /////////////////////////////
53 int currentMode = INTERVAL, selected = 0;
54 int running = 0;
55 unsigned long lastToggleRunning = 0;
56 unsigned long lastModeUpdate = 0;
57 unsigned long lastSelectedUpdate = 0;
58 unsigned long lastShutter = 0;
61 int updateHeader = 1, updateEncoder = 1;
62 int exposureTime = 0, lapseTime = 0;
63 int exposureRepresentation = 0, lapseRepresentation = 0;
64 int encoderPinALast = LOW;
65 int n = LOW;
68 * Higher level hardware functions
71 void pulsePin(int pin, int value)
73 digitalWrite(pin, !value);
74 delay(1);
75 digitalWrite(pin, value);
76 delay(1);
77 digitalWrite(pin, !value);
78 delay(1);
82 * lcd Control Functions
85 void lcdCommandWrite(int value)
87 int i = 0;
88 int value1 = value;
90 value1 >>= 4;
92 for (i = lcdDataBus[0]; i <= lcdDataInt; i++)
94 digitalWrite(i,value1 & 01);
95 value1 >>= 1;
98 pulsePin(lcdEnable, HIGH);
99 delay(1);
101 for (i = lcdDataBus[0]; i <= lcdDataBus[3]; i++)
103 digitalWrite(i, value & 01);
104 value >>= 1;
107 value >>= 4;
109 for (i = lcdDataClock; i <= lcdDataInt; i++)
111 digitalWrite(i, value & 01);
112 value >>= 1;
115 pulsePin(lcdEnable, HIGH);
118 void lcdDataWrite(int value)
120 int i = 0;
121 int value1 = value;
123 digitalWrite(lcdDataInt, HIGH);
124 digitalWrite(lcdDataClock, LOW);
126 value1 >>= 4;
128 for (i=lcdDataBus[0]; i <= lcdDataBus[3]; i++)
130 digitalWrite(i,value1 & 01);
131 value1 >>= 1;
134 pulsePin(lcdEnable, HIGH);
135 delay(1);
137 digitalWrite(lcdDataInt, HIGH);
138 digitalWrite(lcdDataClock, LOW);
140 for (i=lcdDataBus[0]; i <= lcdDataBus[3]; i++)
142 digitalWrite(i,value & 01);
143 value >>= 1;
146 pulsePin(lcdEnable, HIGH);
149 void lcdNumberWrite(int nr)
151 // We don't need negatives, but if you do:
152 /*if(nr < 0)
154 lcdCommandWrite(557);
155 nr = abs(nr);
157 else
159 lcdCommandWrite(544);
162 int n1 = nr/100;
163 int n2 = (nr - n1 * 100) / 10;
165 if(n2)
166 lcdCommandWrite(560 + n2);
168 nr = nr - n1 * 100 - n2 * 10;
169 lcdCommandWrite(560 + nr);
172 void lcdHome(int row)
174 lcdCommandWrite(0x02);
176 delay(4);
178 if(row == 1)
179 lcdCommandWrite(0xC0);
181 delay(1);
184 void lcdClear()
186 lcdCommandWrite(0x01);
187 delay(4);
191 * Hardware initialization functions
194 void lcdInit()
196 int i = 0;
198 for (i = lcdEnable; i <= lcdDataInt; i++)
199 pinMode(i, OUTPUT);
201 lcdCommandWrite(0x03); delay(64);
202 lcdCommandWrite(0x03); delay(50);
203 lcdCommandWrite(0x03); delay(50);
204 lcdCommandWrite(0x02); delay(50);
205 lcdCommandWrite(0x2C); delay(20);
206 lcdCommandWrite(0x06); delay(20);
207 lcdCommandWrite(0x0C); delay(20);
208 lcdCommandWrite(0x01); delay(100);
209 lcdCommandWrite(0x80); delay(30);
212 void encoderInit()
214 pinMode (encoderPinA, INPUT);
215 digitalWrite(encoderPinA, HIGH);
216 pinMode (encoderPinB, INPUT);
217 digitalWrite(encoderPinB, HIGH);
220 void buttonInit()
222 pinMode(buttonA, INPUT);
223 digitalWrite(buttonA, HIGH);
224 pinMode(buttonB, INPUT);
225 digitalWrite(buttonB, HIGH);
227 pinMode(encoderButton, INPUT);
228 digitalWrite(encoderButton, HIGH);
232 void setup (void)
234 pinMode(cameraTrigger, OUTPUT);
235 digitalWrite(cameraTrigger, HIGH);
237 lcdInit();
238 encoderInit();
239 buttonInit();
242 void incrementValue()
244 if(selected == 0)
246 if(lapseRepresentation == 0)
247 lapseTime++;
248 else
249 lapseTime += 60;
251 else
253 if(exposureRepresentation == 0)
254 exposureTime++;
255 else
256 exposureTime += 60;
258 if(exposureTime > lapseTime)
259 lapseTime = exposureTime;
263 void decrementValue()
265 if(selected == 0)
267 if(lapseRepresentation == 0)
268 lapseTime--;
269 else
270 lapseTime -= 60;
272 else
274 if(exposureRepresentation == 0)
275 exposureTime--;
276 else
277 exposureTime -= 60;
281 void updateEncoderValue()
283 n = digitalRead(encoderPinA);
284 if ((encoderPinALast == LOW) && (n == HIGH))
286 if (digitalRead(encoderPinB) == LOW)
287 decrementValue();
288 else
289 incrementValue();
291 if(lapseTime < 0)
292 lapseTime = 0;
293 if(exposureTime < 0)
294 exposureTime = 0;
296 if(lapseTime >= 60)
297 lapseRepresentation = 1;
298 else
299 lapseRepresentation = 0;
301 if(exposureTime >= 60)
302 exposureRepresentation = 1;
303 else
304 exposureRepresentation = 0;
306 updateEncoder = 1;
308 encoderPinALast = n;
311 void switchModes()
313 unsigned long diff = (millis() - lastModeUpdate);
315 if(diff < 300) // careful about the overflow...
317 lastModeUpdate = millis();
318 return;
320 else
321 lastModeUpdate = millis();
323 currentMode++;
324 if(currentMode > 3)
325 currentMode = 0;
327 if(currentMode == BULB)
328 selected = 1;
329 else
330 selected = 0;
332 updateHeader = 1;
335 void switchSelected()
337 if(currentMode == INTERVALBULB)
339 unsigned long diff = (millis() - lastSelectedUpdate);
341 if(diff < 300) // careful about the overflow...
343 lastSelectedUpdate = millis();
344 return;
346 else
347 lastSelectedUpdate = millis();
349 selected = !selected;
352 updateEncoder = 1;
355 void toggleRunning()
357 unsigned long diff = (millis() - lastToggleRunning);
358 if(diff < 300) // careful about the overflow...
360 lastToggleRunning = millis();
361 return;
363 else
364 lastToggleRunning = millis();
366 running = !running;
369 void drawTimecode(int secs, int rep)
371 if(rep == 0)
373 lcdNumberWrite(secs);
374 lcdDataWrite('"');
376 else
378 lcdNumberWrite(secs/60);
379 lcdDataWrite('\'');
383 int timecodeLength(int secs, int rep)
385 int count = 2;
387 if(rep)
388 secs = secs/60;
390 int n1 = secs/100;
391 int n2 = (secs - n1 * 100) / 10;
393 if(n2)
394 count++;
396 return count;
399 char *modeHeader[4] = {"Interval", " Bulb", "Interval Bulb", "Trigger"};
401 void loop(void)
403 if(updateHeader)
405 lcdHome(0);
407 int count;
408 for (count = 0; modeHeader[currentMode][count] != 0; count++)
409 lcdDataWrite(modeHeader[currentMode][count]);
410 for (; count < 16; count++)
411 lcdDataWrite(544);
413 updateHeader = 0;
414 updateEncoder = 1;
417 if(updateEncoder)
419 lcdHome(1);
421 if(currentMode != BULB)
422 drawTimecode(lapseTime, lapseRepresentation);
424 int width = 0;
426 if(currentMode != BULB)
427 width += timecodeLength(lapseTime, lapseRepresentation);
428 if(currentMode != INTERVAL && currentMode != TRIGGER)
429 width += timecodeLength(exposureTime, exposureRepresentation);
431 for(int i = 16; i > width; i--)
432 lcdDataWrite(' ');
434 if(currentMode != INTERVAL && currentMode != TRIGGER)
435 drawTimecode(exposureTime, exposureRepresentation);
437 updateEncoder = 0;
440 if(digitalRead(buttonA) == LOW)
441 toggleRunning();
443 if(running)
445 if(currentMode == TRIGGER)
447 // do special trigger stuff
448 return;
451 unsigned long diff = millis() - lastShutter;
453 int adjustedLapseTime = lapseTime;
454 if(currentMode != INTERVAL)
455 adjustedLapseTime -= exposureTime;
457 if(diff > (adjustedLapseTime * 1000)) // careful about the overflow...
459 digitalWrite(cameraTrigger, LOW);
461 if(currentMode == INTERVAL)
462 delay(100);
463 else
464 delay(exposureTime * 1000); //delay for length of exposure
466 digitalWrite(cameraTrigger, HIGH);
467 lastShutter = millis();
469 if(currentMode == BULB)
470 running = 0;
473 else
475 updateEncoderValue();
477 if(digitalRead(buttonB) == LOW)
478 switchModes();
480 if(digitalRead(encoderButton) == LOW)
481 switchSelected();
485 int main(void)
487 init();
489 setup();
491 for (;;)
492 loop();
494 return 0;