Canon Intervalometer with countdown timer

So I have been coding this intervalometer for timelapse photos, and am using an LCD that will display the time entered from a matrix keypad that is stored to an array. I’ve got most of the code done, but am still working on one part that I just can’t seem to figure out. I need to make a countdown timer on the screen that counts down until the next picture.

I made a function that takes the picture, that I include in my loop when the pound key is pressed. I think it should go in there. I have been playing around with millis() but have gotten nowhere. What I essentially want this to do is count down from whatever time has been entered all the way to 0, which times when the next picture will be taken. This loops every time a picture has been taken. (In this case the variable shuttertime is used for the time entered, which can range from 1 to 999,999).

I can supply the full code if you want to see that.

void takepicture(){ //Function that takes pictures pretty much forever
lcd.setCursor(6,1);
lcd.print("Pics Taken");
lcd.setCursor(0,1);
int var = 0; //start with 0 pictures
while(var < 10000000){ //do this until you get to a lot of pictures
  digitalWrite(shutterpin, HIGH); //Take the picture
  delay(100);
  digitalWrite(shutterpin, LOW);
  var++; //Add 1 to the variable
  picstaken++; //Increase the number of pictures 1 more
  lcd.setCursor(0,1);
  lcd.print(picstaken);// Print the number of pitures taken so far
  lcd.setCursor(0,1); //Reset the cursor
  delay(shuttertime); //Delay until the next picture

}
}

Cosmonaut:
I can supply the full code if you want to see that.

That would be nice.

Sorry let me rephrase that. That would be essential :slight_smile:

Alright, it’s pretty long, and totally unstreamlined so sorry if it is all messy and doesn’t make sense.

Here goes…

#include <Keypad.h> //Includes the library for keypad
#include <LiquidCrystal.h> //Includes the library for LCD screens

LiquidCrystal lcd(13, 12, 3, 2, 1, 0); //Pins that control the LCD

int timearray[6]; //Make an array to store the keypresses to convert to time 
int arrayplace = 5; // Allows you to write to the first spot of the array
int keypresses = 0; //number of times a number key is pressed

const byte ROWS = 4; // The keypad has four rows
const byte COLS = 3; // They keypad has three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}};
byte rowPins[ROWS] = {4, 5, 6, 7}; // Connects Rows 0, 1, 2, 3 respectivley (Whatever pin makes that row activate)
byte colPins[COLS] = {8, 9, 11}; // Connects columns 0, 1, 2 respectivley (Whatever pin makes that column activate)

Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

int shutterpin = A0; //The pin that controls the shutter is Analog 0
int shuttertime = 1; //The default shutter time is 1 second
int picstaken = 0000; //The number of pictures taken so far

void setup() {
  
pinMode(shutterpin, OUTPUT); //The pin to the shutter is an output

lcd.begin(16, 2); //Define 16x2 LCD size
lcd.setCursor(1,0); //set cursor to the 2nd column, first row (Everthing starts at 0)
lcd.print("Intervalometer"); //Display text
lcd.setCursor(1,1); // Set cursor tp 5th column, 2nd row
lcd.print("Set Time (sec)"); //Display text
delay(2500); //Wait 2 seconds
lcd.clear(); //Clear the LCD

lcd.clear();
lcd.setCursor(0,0);
lcd.print("*=Clear  #=Start"); //A command that tells you what to do.
lcd.setCursor(9,1);
lcd.print("Seconds");
lcd.setCursor(0,1);

}

void loop() {


 char key = kpd.getKey();
  if(key)  // Check for a valid key.
  {
    switch (key)
    {
      case '*': //If asterisk is entered
      {
        int timearray[6] = {'0','0','0','0','0','0'}; //Set all the digits in the array to 0
        keypresses = 0;  //Reset the keypress counter
        lcd.clear(); //Clear everything that has been typed in
        lcd.setCursor(0,0);
        lcd.print("*=Clear  #=Start");
        lcd.setCursor(9,1);
        lcd.print("Seconds");
        lcd.setCursor(0,1);
      }
        break;
      case '#': //If pound is entered
       {
        
     
        int a = timearray[0]; //Set the spots in an array as a letter
        int b = timearray[1];
        int c = timearray[2];
        int d = timearray[3];
        int e = timearray[4];
        int f = timearray[5];
        
        if(keypresses == 1){ //If the key is pressed once
           shuttertime = (f-48); //Make the shutter time equal to the output minus 48
        }
        
        else if(keypresses == 2){ //If the key is pressed twice
           shuttertime = (f-48) + ((e-48)*10); //Multiplies the 2nd keypress by 10
        }
        
        else if(keypresses == 3){ //If the key is pressed three times
           shuttertime = (f-48) + ((e-48)*10) + ((d-48)*100); //Multiplies the 3rd keypress by 100
        }
         
         else if(keypresses == 4){ //If the key is pressed four times
           shuttertime = (f-48) + ((e-48)*10) + ((d-48)*100) + ((c-48)*1000); //Multiplies the 4th keypress by 1,000
        }

        
         else if(keypresses == 5){ //If the key is pressed five times
           shuttertime = (f-48) + ((e-48)*10) + ((d-48)*100) + ((c-48)*1000) + ((b-48)*10000); //Multiplies the 5th keypress by 10,000
        }
        
        else if(keypresses == 6){ //If the key is pressed six times
           shuttertime = (f-48) + ((e-48)*10) + ((d-48)*100) + ((c-48)*1000) + ((b-48)*10000) + ((a-48)*100000); //Multiplies the 6th keypress by 100,000
        }
        
        shuttertime = shuttertime*1000; //Converts the number so that the delay can read it in miliseconds
        
        lcd.clear(); //Clear the screen
       
        takepicture(); //run the takepicture function
        
        
      
       
        
        
        break;}
      default:
        if(keypresses == 0){ //If no keys have been pressed so far
          timearray[5] = key; //Put the muber pressed in the 1st spot
          lcd.print(key); //Print the keypress on the screen
          keypresses++; //Add one keypress to the counter
        }
        
        else if(keypresses == 1) { //This part basically shifts the number up one so a new key can be added
          timearray[4] = timearray[5];
          timearray[5] = key;
          lcd.print(key); 
          keypresses++;
        }
        
        else if(keypresses == 2) {
          timearray[3] = timearray[4];
          timearray[4] = timearray[5];
          timearray[5] = key;
          lcd.print(key);
          keypresses++;
        }
        
         else if(keypresses == 3) {
          timearray[2] = timearray[3]; 
          timearray[3] = timearray[4];
          timearray[4] = timearray[5];
          timearray[5] = key;
          lcd.print(key);
          keypresses++;
        }
        
          else if(keypresses == 4) {
          timearray[1] = timearray[2];  
          timearray[2] = timearray[3]; 
          timearray[3] = timearray[4];
          timearray[4] = timearray[5];
          timearray[5] = key;
          lcd.print(key);
          keypresses++;
        }
        
          else if(keypresses == 5) {  //Still the same thing as I said up there^^
          timearray[0] = timearray[1];
          timearray[1] = timearray[2];  
          timearray[2] = timearray[3]; 
          timearray[3] = timearray[4];
          timearray[4] = timearray[5];
          timearray[5] = key;
          lcd.print(key);
          keypresses++;
        }
      
          break;
    }
  } 
}

void takepicture(){ //Function that takes pictures pretty much forever
lcd.setCursor(6,1);
lcd.print("Pics Taken");
lcd.setCursor(0,1);
int var = 0; //start with 0 pictures
while(var < 10000000){ //do this until you get to a lot of pictures
  digitalWrite(shutterpin, HIGH); //Take the picture
  delay(100);
  digitalWrite(shutterpin, LOW); //Stop taking the picture
  var++; //Add 1 to the variable
  picstaken++; //Increase the number of pictures 1 more
  lcd.setCursor(0,1);
  lcd.print(picstaken);// Print the number of pictures taken so far
  lcd.setCursor(0,1); //Reset the cursor
  delay(shuttertime); //Delay until the next picture

}
}

Cosmonaut:
Alright, it's pretty long

Pft.. Call that long? Nah THIS is long (said with a crocodile Dundee voice).

But seriously I get the impression that you're going to be taking a kinda time lapse sequence? So the value entered on the screen, is that the number of shots to take, or the time between shots? I'm sort of confused over this issue.

Alright, So basically, I have a keypad. I type in up to 6 digits, which get stored in an array. When I hit the pound key, it will start the timelapse.

It takes each of the numbers and depending on how many keys are pressed, multiplies them by their place (so if 2 keys are pressed, the first one is the 10s place and the second is the ones.)

It then takes those numbers and adds them (so a 10 and a 5 become a 15, for example). After adding, the new number is multiplied by 1000.

This number is now stored as a variable. When the function to take a picture runs, the number typed in is the delay in seconds between pictures. For example, you type in 6 and 0, that becomes 60, which means there is a 1-minute gap between pictures.

What I want to do is during the gap, have a timer that I can print to the LCD that will tell me how many seconds until the next picture will be taken.

...Speaking of which, I was testing what I had built and so far, and it won't take more than 1 picture after 35 seconds. Any amount of time before that and it will basically take more than I would ever need. Why could this be?

Cosmonaut:
...Speaking of which, I was testing what I had built and so far, and it won't take more than 1 picture after 35 seconds. Any amount of time before that and it will basically take more than I would ever need. Why could this be?

Oh wait!! int only stores up to about 32,000! Well, you learn something new everyday..

Guess I'll be using long.

So your keypad entry has nothing to do with how many pictures you take. Just the time between them.

How do you want to stop the sequence. (I pressume you don't want it to go on forever).

No, I plan on just shutting the whole thing off to stop it. I don’t really need a stop button. That way I can take a million pictures if I really wanted to. And it simplifies things a lot. :smiley:

OK I've bookmarked this page and may have a look at it later if I get a chance. Unless some other kindly member gets to it before me.