2 * Arduino Intervalometer
12 #define INTERVALBULB 2
17 int buttonA = 0; // Left pushbutton
19 //int inputTrigger = 2; // Input trigger interrupt
23 int encoderButton = 4;
25 int buttonB = 5; // Right pushbutton
28 int lcdDataBus[] = { 7, 8, 9, 10 };
29 int lcdDataClock = 11;
32 int cameraTrigger = 13; // Pulse low for shutter release
34 /////////////////////////////
36 int currentMode = INTERVAL, selected = 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;
50 * Higher level hardware functions
53 void pulsePin(int pin, int value)
55 digitalWrite(pin, !value);
57 digitalWrite(pin, value);
59 digitalWrite(pin, !value);
64 * lcd Control Functions
67 void lcdCommandWrite(int value)
74 for (i = lcdDataBus[0]; i <= lcdDataInt; i++)
76 digitalWrite(i,value1 & 01);
80 pulsePin(lcdEnable, HIGH);
83 for (i = lcdDataBus[0]; i <= lcdDataBus[3]; i++)
85 digitalWrite(i, value & 01);
91 for (i = lcdDataClock; i <= lcdDataInt; i++)
93 digitalWrite(i, value & 01);
97 pulsePin(lcdEnable, HIGH);
100 void lcdDataWrite(int value)
105 digitalWrite(lcdDataInt, HIGH);
106 digitalWrite(lcdDataClock, LOW);
110 for (i=lcdDataBus[0]; i <= lcdDataBus[3]; i++)
112 digitalWrite(i,value1 & 01);
116 pulsePin(lcdEnable, HIGH);
119 digitalWrite(lcdDataInt, HIGH);
120 digitalWrite(lcdDataClock, LOW);
122 for (i=lcdDataBus[0]; i <= lcdDataBus[3]; i++)
124 digitalWrite(i,value & 01);
128 pulsePin(lcdEnable, HIGH);
131 void lcdNumberWrite(int nr)
133 // We don't need negatives, but if you do:
136 lcdCommandWrite(557);
141 lcdCommandWrite(544);
145 int n2 = (nr - n1 * 100) / 10;
148 lcdCommandWrite(560 + n2);
150 nr = nr - n1 * 100 - n2 * 10;
151 lcdCommandWrite(560 + nr);
154 void lcdHome(int row)
156 lcdCommandWrite(0x02);
161 lcdCommandWrite(0xC0);
168 lcdCommandWrite(0x01);
173 * Hardware initialization functions
180 for (i = lcdEnable; i <= lcdDataInt; i++)
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);
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);
207 pinMode(buttonA, INPUT);
208 digitalWrite(buttonA, HIGH);
209 pinMode(buttonB, INPUT);
210 digitalWrite(buttonB, HIGH);
212 pinMode(encoderButton, INPUT);
213 digitalWrite(encoderButton, HIGH);
219 pinMode(cameraTrigger, OUTPUT);
220 digitalWrite(cameraTrigger, HIGH);
227 void incrementValue()
231 if(lapseRepresentation == 0)
238 if(exposureRepresentation == 0)
243 if(exposureTime > lapseTime)
244 lapseTime = exposureTime;
248 void decrementValue()
252 if(lapseRepresentation == 0 || ceil(lapseTime/ENCSPEED) == 60) // careful around transition; thanks, nate
262 if(exposureRepresentation == 0 || ceil(exposureTime/ENCSPEED) == 60)
275 delayMicroseconds(3000);
276 if (digitalRead(encoderPinA) == HIGH)
278 if (digitalRead(encoderPinB) == LOW)
285 if (digitalRead(encoderPinB) == HIGH)
298 delayMicroseconds(3000);
299 if (digitalRead(encoderPinB) == HIGH)
301 if (digitalRead(encoderPinA) == HIGH)
308 if (digitalRead(encoderPinA) == LOW)
320 unsigned long diff = (millis() - lastModeUpdate);
322 if(diff < 300) // careful about the overflow...
324 lastModeUpdate = millis();
328 lastModeUpdate = millis();
334 if(currentMode == BULB)
342 void switchSelected()
344 if(currentMode == INTERVALBULB)
346 unsigned long diff = (millis() - lastSelectedUpdate);
348 if(diff < 300) // careful about the overflow...
350 lastSelectedUpdate = millis();
354 lastSelectedUpdate = millis();
356 selected = !selected;
364 unsigned long diff = (millis() - lastToggleRunning);
366 if(diff < 300) // careful about the overflow...
368 lastToggleRunning = millis();
372 lastToggleRunning = millis();
377 void drawTimecode(int secs, int rep)
379 secs = secs/ENCSPEED;
382 lcdNumberWrite(secs);
387 lcdNumberWrite(secs/60);
392 int timecodeLength(int secs, int rep)
396 secs = secs/ENCSPEED;
402 int n2 = (secs - n1 * 100) / 10;
410 char *modeHeader[4] = {"Interval", " Bulb", "Interval Bulb", "Trigger"};
419 for (count = 0; modeHeader[currentMode][count] != 0; count++)
420 lcdDataWrite(modeHeader[currentMode][count]);
421 for (; count < 16; count++)
430 if((lapseTime/ENCSPEED) >= 60)
431 lapseRepresentation = 1;
433 lapseRepresentation = 0;
435 if((exposureTime/ENCSPEED) >= 60)
436 exposureRepresentation = 1;
438 exposureRepresentation = 0;
440 /////////////////////////////////////
444 if(currentMode != BULB)
445 drawTimecode(lapseTime, lapseRepresentation);
449 if(currentMode != BULB)
450 width += timecodeLength(lapseTime, lapseRepresentation);
451 if(currentMode != INTERVAL && currentMode != TRIGGER)
452 width += timecodeLength(exposureTime, exposureRepresentation);
456 lcdDataWrite(' '); width++;
457 lcdDataWrite(127); width++;
464 for(int i = 16; i > width; i--)
473 if(currentMode != INTERVAL && currentMode != TRIGGER)
474 drawTimecode(exposureTime, exposureRepresentation);
479 if(digitalRead(buttonA) == LOW)
484 if(currentMode == TRIGGER)
486 // do special trigger stuff
490 unsigned long diff = millis() - lastShutter;
492 int adjustedLapseTime = lapseTime / ENCSPEED;
493 if(currentMode != INTERVAL)
494 adjustedLapseTime -= exposureTime;
496 if(diff > (adjustedLapseTime * 1000)) // careful about the overflow...
498 digitalWrite(cameraTrigger, LOW);
500 if(currentMode == INTERVAL)
503 delay((exposureTime / ENCSPEED) * 1000); //delay for length of exposure
505 digitalWrite(cameraTrigger, HIGH);
506 lastShutter = millis();
508 if(currentMode == BULB)
514 if(digitalRead(buttonB) == LOW)
517 if(digitalRead(encoderButton) == LOW)