/*
* Adjustable intervalometer for my hacked Canon A75
*/
int camPowerPin = 5; // pin to short power on/off lines
int halfPin = 11; // pin to trigger half shutter
int shutterPin = 10; // pin to trigger the shutter
int camPowerPinTime = 1000; // time to hold down power pin
int halfPinTime = 500; // time to hold down the hald shutter
int shutterPinTime = 2500; // time of hold down the shutter
long camPowerOnMax = 15000; // if period is this or longer, camera will power cycle
int potPin = 0; // pin for analog read of potentiometer to determine period
int goPin = 4; // pin for the start/stop button
int isRunning = 0; // status of whether or not the system is running
int i;
long j;
int ledPin = 13;
long delayMs = 500; // delay between shots, in ms
long lastShutter = 0;
long periods[13] = { 5000, 7000, 10000, 15000, 30000, 45000, 60000, 120000, 300000, 600000, 900000, 1800000, 3600000 };
// 5s 7s 10s 15s 30s 45s 1min 2min 5min 10min 15min 30min 1hr
int numPeriods = 13; // number of periods to choose from
int potVal = 0;
int goVal = 0;
//debounce
long time = 0; // the last time the output pin was toggled
long debounce = 500; // the debounce time, increase if the output flickers
int previous = 0;
void setup()
{
Serial.begin(4800);
serLcdStartup();
delay(500);
backlightLevel(25);
pinMode(camPowerPin, OUTPUT);
pinMode(halfPin, OUTPUT);
pinMode(shutterPin, OUTPUT);
digitalWrite(camPowerPin, LOW);
digitalWrite(halfPin, LOW);
digitalWrite(shutterPin, LOW);
pinMode(ledPin, OUTPUT);
pinMode(potPin, INPUT);
pinMode(goPin, INPUT);
lastShutter = millis();
delay(1000);
}
void loop(){
// Debounce start/stop button and toggle the mode and backlight
goVal = digitalRead(goPin);
if (goVal == HIGH && previous == LOW && millis() - time > debounce) {
if (isRunning == 0) {
isRunning = 1;
backlightLevel(0);
delay(50);
lastShutter = 2000 + millis() - delayMs;
}
else {
isRunning = 0;
backlightLevel(25);
delay(50);
}
time = millis();
}
previous = goVal;
// If we're running...
if (isRunning == 1) {
// See if it's time to take a shot
if ( (millis() - lastShutter) >= delayMs ) {
lastShutter = millis();
if (delayMs >= camPowerOnMax) {
gotoLineTwo();
Serial.print("A75 ON... ");
toggleCamPower();
}
gotoLineTwo();
Serial.print("Half shutter... ");
halfShutter();
gotoLineTwo();
Serial.print(" ** SHUTTER ** ");
shutterRelease();
if (delayMs >= camPowerOnMax) {
gotoLineTwo();
Serial.print("A75 OFF... ");
delay(1000);
toggleCamPower();
}
reportPeriod( delayMs );
}
}
// If we're stopped
if (isRunning == 0) {
// Figure out delay from the input pot
potVal = 1023-analogRead(potPin); // read value from the pot
for (int i=0; i<numPeriods; i++) {
if ( (1024*i)/numPeriods < potVal && (1024*(i+1))/numPeriods >= potVal ) delayMs = periods[i];
}
reportPeriod( delayMs );
}
// Report the status on the second line
gotoLineTwo();
if (isRunning == 1) {
Serial.print(" ");
j = (delayMs - (millis() - lastShutter))/1000;
Serial.print( j );
Serial.print("s to go...");
}
else if (isRunning == 0) Serial.print(" ** STOPPED ** ");
delay(50); // just a little breathing room...
}
void reportPeriod( long periodMs ) {
// Report the delay period
gotoLineOne();
Serial.print(" Period: ");
if (periodMs < 1000) {
Serial.print(periodMs);
Serial.print("ms ");
}
else if (periodMs < 60000) {
j = periodMs/1000;
Serial.print(j);
Serial.print("s ");
}
else if (periodMs < 3600000) {
j = periodMs/60000;
Serial.print(j);
Serial.print("min ");
}
else {
j = periodMs/3600000;
Serial.print(j);
Serial.print("hr ");
}
}
void toggleCamPower(){
digitalWrite(camPowerPin, HIGH);
digitalWrite(ledPin, HIGH);
delay(camPowerPinTime);
digitalWrite(camPowerPin, LOW);
digitalWrite(ledPin, LOW);
}
void halfShutter(){
digitalWrite(halfPin, HIGH);
delay(halfPinTime);
digitalWrite(halfPin, LOW);
}
void shutterRelease(){
digitalWrite(shutterPin, HIGH);
delay(shutterPinTime);
digitalWrite(shutterPin, LOW);
}
I wonder if your sketch will suffer from the millis overflow problem when running for more than 9.5 hours. Time calculation using millis give incorrect values when millis reaches 34,359,739ms, but there are a number of solutions to this that you can find in this forum.
One solution that minimizes changes to your code is to reset the count before it overflows. In your application you could reset the value every time you fire the shutter.
Here is reset code:
extern volatile unsigned long timer0_overflow_count;
Yes, it will suffer the millis() rollover strangeness, but I have a simple solution: not to run it for more than a few hours! Heh... [w/dunce cap] I'll patch it asap-- thanks for the how-to!
Hi salsaman, I'm very interested in the dirty details of how did you hack your Canon A75... do you have any additional pictures / posts regarding which cable goes where? I have a Canon A60 and I'd like to implant a 2,5mm jack to do what you did, in a "not-so-spaghetti-looking" fashion...
Thanks!
Nicely done! I'm fascinated by arduino-camera interfaces. Thanks for sharing
Can you think of any Arduino camera interfaces besides an intervalometer or some form of tripwire/tripsound/etc? I'm trying to think of a new project.
A few months ago I built an IR intervalometer for my Nikon D90. Then after I had it working but not assembled into a housing, I did some quick math and at 24 frames per second, five minute of time-lapse will need 7200 exposures. I just can't bring myself to put that kind of wear and tear on the mechanics of the camera. It's rated for 100,000 exposures and I don't want to wear out the $1000 body prematurely.
I'm starting with Arduino and did not know this project is very good.
I would like to make one could you indicate how well the circuit?
How can you connect the LCD with a few cables?
I built an Arduino intervalometer (and more) a couple of years ago. I've included a schematic that you might use as a source of ideas for your own design.