Time lapse controller, swapping delays for timed functions

Hi all, I have been working on a time lapse controller for my DSLR for a couple of weeks. I have got it working OK and I have just added motor control for using a slider using a modded servo. The code is very messy and with lots of spaces here and there but I find it helps me navigate while I'm working on stuff.

I use delays for the intervals so obviously I am jamming up the processor which id rather not so I can do other things.

I have been pondering for the last couple of days over how to change the delays for timed functions but no success yet. I just cant think how it would be done, I need to toggle a pin, wait for time x, then toggle another pin, wait for time y, then turn toggle both pins at the same time, then toggle another pin high, wait for time z, then toggle it again - without re-writing a lot of my code

any help would be good :slight_smile:

edit.. code seems to big to post, although i didn't think it was that big!

Do you want the short answer (catch me a fish) or the long answer (teach me how to catch fish)?

or the long answer (teach me how to catch fish)?

No, no. That should be "teach me to sit in a boat and drink beer all day and try to catch fish"

haha, well... Is there an intermediate option? :stuck_out_tongue:

I'd like to learn how to do it, but I'm new to programming as a whole and it has taken a long time to get the (mess) of code working that I have written.

I just cant picture how it could be structured, I was thinking you would set a variable to 0 then set to millis() and examine it each time through the loop, but the structure that I have currently got I don't think it could work?

thanks all

Is there an intermediate option?

No. You can either use delay() and suffer the consequences, or you can completely restructure your code to not use delay().

A state machine is what you want, with millis() calls to determine if it is time to change states.

OK thanks for the advice.

Will this method work... I don't for a minute expect it to be the 'proper' way of doing it. I'm at work so won't be able to test anything until later this evening

I expect it will just stay in the while loop until the time has elapsed?

Thanks again

(the rest of the code is the same)

//Trigger focus
        timer1 = millis();
        digitalWrite(focusPin, HIGH);

      while (millis() - timer1 > focusDelay)
      {
        //hold focus button down and do nothing else for x seconds
      }

      
      //Trigger shutter
      timer1 = millis();
      digitalWrite(shutterPin, HIGH);
      digitalWrite(shutterLED, HIGH);
      
      while (millis() - timer1 > (expose * 1000))
      {
        // Hold open shutter for x seconds
      }
  

      digitalWrite(shutterPin, LOW);
      digitalWrite(shutterLED, LOW);
      digitalWrite(focusPin, LOW);

cant get it to work :frowning: It seems to enter the while loop, but does not execute its contents, and also does not exit the loop at all

what am I doing wrong here guys?

//Trigger focus
      unsigned long timer1 = millis();
      lcd.clear();
      digitalWrite(focusPin, HIGH);

      while (millis() - timer1 < focusDelay)
      {
        //hold focus button down and stay in this loop until focusDelay has been reached
        lcd.setCursor(0,1);
        lcd.print("test");
      }
      lcd.clear();

dtokez:
cant get it to work :frowning: It seems to enter the while loop, but does not execute its contents, and also does not exit the loop at all

Unless the laws of physics have been repealed, that isn't possible.

That code will execute the loop zero or more times and then execute the code that follows. It has to either execute the body of the loop or leave the loop and execute the subsequent code.

What you've done there is just a hand-coded replacement for delay() that does the same thing - it blocks your sketch until the required time has passed. This in no way solves your problem.

Sorry I had the focusDelay to short to notice the while loop passing. It’s working now and doing what I wanted, probably the entirely wrong way to do things but I’ll continue to work on it!

Now it prints a countdown until the loop passes to the LCD which is what I was hoping to achieve

//Trigger focus
      unsigned long timer1 = millis();
      lcd.clear();
      digitalWrite(focusPin, HIGH);
      
      int countdown = 0;

      while (millis() - timer1 < focusDelay)
      {
        //hold focus button down and do nothing else for x seconds
        lcd.setCursor(0,1);
        lcd.print("test");
        
        countdown = focusDelay - (millis() - timer1);
        lcd.setCursor(1,0);
        lcd.print(countdown / 1000);
        lcd.print("s        ");

Hello,
I'm not a programmer and totaly new to arduino, can somebody please point me to a site or eventually right here maybe, if I not ask to much, where I can get a copy of source code for time lapse? I have a DC motor that must be controlled and of course the camera. I can give more details if needed but I won't dare to ask more... Please help me, thank you in advance!

Is this software compatible?

When it comes to switching things on and off you don't have too many options. You can turn it on and then delay but that has the problems the OP is finding out. It can't do anything else while waiting for delay. Another option is to use an interval timer. When you turn the device on get the time in millis, then just keep checking that the run duration hasn't been exceeded. basically if (millis() - onTime > runDuration) turn it off. You would probably want to use a similar scheme for when to turn it on next. Lastly, you can schedule on and off times, check against the current time and take appropriate action. To be effective this scheme needs a properly set clock.

I think what you are looking for is a 'simple scheduler', search for it in the forum. The simplest one is to put all the events you want in one loop. For every pass you check if the time is reached for the next event. See the 'blink without delay' example. Expand the example with several events, each with its own timer (previousmillis1, previousmillis2, etc.), if you need.

That's the level of complexity I manage myself so far, but you can do a lot with this. Only make sure one loop never takes longer than the minimum time base you have. It seems your events are hundreds of ms? Then you should be fine.

Expand the example with several events, each with its own timer (previousmillis1, previousmillis2, etc.), if you need.

Each with its own time, not timer. Timers are something completely different.