Creating a timer longer than a few seconds

I have a timer set up now which is programmed to activate in seconds, what is the best way to extend the time to hours?
Thanks.

You could alway multiply by 3600 :sweat_smile:? Depending on what you’re trying to do, you may, or may not want to get some millis() math involved. Could you describe what it is that you’re trying to do? The more info, the better. Code would also be great :wink:

You helped me awhile back with a simple off delay in the tinker app, it delays in seconds now but i would like to be able to extend time to about an hour then have it turn off.

if(command.startsWith("D")){
    pinMode(pinNumber, OUTPUT);
    //this checks if it's pin D7, then toggles
    //it off after 2 seconds.
    if (pinNumber == 7){
        digitalWrite(pinNumber, value);
        delay(2000);
        digitalWrite(pinNumber, LOW);
    }
    else
    //The above was the only thing that was added ^

(For other readers, the thing I helped with a while ago was this http://community.spark.io/t/solved-how-to-add-a-timer-in-the-tinker-ios-app/9443/)

Back to the question; What I said above is still true, you could create an hour long delay by doing delay(3600000) Although it would work, it wouldn’t exactly be an elegant solution, and I would definitely not recommend it! To make it a bit nicer we should use some millis() tricks like I mentioned above. I’d recommend you check out this Arduino tutorial, since they’re doing pretty much the same thing: http://arduino.cc/en/Tutorial/BlinkWithoutDelay
Take a look at it, try to come up with something, and let us know if you need any further assistance :smile:!

1 Like

In this case you should take the off-part out of the Spark.function() into loop() - similar to @Moors7 suggestion.

But if you want to “keep” the status for a day or so, you’d have to take into account that your Core might go offline or even restart. So some means to store the current state and desired off-times beyond restarts might be required.

As for the timing you could also look into @bko 's TimeAlarms lib.

3 Likes

You could also use the standard time library for this, see http://docs.spark.io/firmware/#libraries-time

Check out the ElapsedMillis library

It makes it real easy to handle timers without having to use delay.

1 Like

Thanks for the suggestions, i am looking to make this as simple as possible. Looks like some heavy duty reading is in my future. I pledged to the new Blynk app and I hope it will make it as easy as it sounds, then later I can put more time into learning why something is coded the way it is.

1 Like

Just so I’ve said it, the Spark is for hardware development, it’s no plug&play magically-do-everything-you-want consumer device. It’s meant to be programmed. There are inherent boundaries to how ‘simple as possible’ you can make something. Even with Blynk you’re probably going to have to write some code.

The current ‘problem’ can be made as simple or difficult as you like. There are however some things to consider, which can make it increasingly more difficult.

  • “as simple as possible”: multiply the time in second by 3600 to get hours. Done. it really doesn’t get more simple than that.
    But like @ScruffR mentioned, if your connection drops, or the Core reboots within that time, it’ll turn the pin off prematurely. Also, if you use delay(), the code is blocking, and you can’t do anything else.
  • “bit less simple as possible 1.0”: multiply the time in seconds by 3600, but instead od using delay(), use some millis() math. You’ll have to move the time checking and turning off part into the loop().
    This way, the code is no longer blocking, and can do other things in the mean time. If it were to reset in the mean time though, you’d face the same problem as before were it’ll turn of early, since the time is also reset, and the power goes low.
  • “bit less simple as possible 2.0”: use the elapsedMillis library as mentioned by @Carsten4207. This basically does the same thing, while making sure you don’t have to use any nasty math skills to calulate times. You will however have to learn how to work with libraries, which may, or may not, be “less simple”.
  • “even less simple 1.0”: get the current time, and the time it needs to delay to it, and have it check that. Something like:“button pressed at 12:00, delay by 2 hours, so turn off at 12:00 + 2:00 = 14:00”. So now you have a turn-off time to which you can compare. There’s a built in library for time-related things, to which @TheHawk1337 linked in his post.
    This way, the code is no longer blocking, and can do other things in the mean time. If it were to reset in the mean time though, you’d face the same problem as before were it turns off early, since the time is also reset, and the power goes low.
  • “even less simple 2.0”: this is were things get interesting. To make sure the turn-off time persists even after a reset, you’ll need to save that time to persistent memory. You’re probably going to have to use something like this: http://docs.spark.io/firmware/#other-functions-eeprom
    So, you’d be doing the same thing as with “even less simple 1.0”, but now you’re also storing the turn-off values in memory, and retrieving them at boot. If the Core resets within the delay time, it’ll get the values from memory, and will still be able to work. Mind the fact that you’ll have to erase those values when the turn-off is triggered to prevent future problems.
  • “not quite as simple”: Use the timeAlarms library as mentioned by @ScruffR. This allows you to set times as which certain actions have to be triggered. I’m not entirely sure these persist when rebooted, so you’d have to look into that. You’d also have to deal with using a library, but that shouldn’t neccesarily be a problem, if you’re willing.

You see, all of the above solutions are simple, depending on the terminology used to classify them. “simple as possible” is a relative term, and should be applied with caution. There are often many ways in which certain goals can be achieved, with the ‘simplest’ one not always being the best one. The problem lies not in the difficulty of a solution, but in the willingness to tackle it.
The simplest of solutions would be to ditch the Spark, hit a switch, sit there for two hours with a stopwatch, and hit the switch again. Seeing as that’s rather uncomfortable, I think it’s worthwhile putting in the small effort required to get this up and running. It’s not that difficult as it seems (and that’s coming from someone who only recently started to code, with the Spark being my first controller).

3 Likes

And just to stress what @Moors7 has already written, but might have gone lost while reading the rest :wink:
Even if you got the persistence stuff sorted (as in “even less simple 2.0” and “not quite as simple”) you need to make sure, that your ON state stays ON and OFF stays OFF even if and while the Core has gone offline/powerless/bonkers/… :wink:

2 Likes

To persist regardless of whether or not the Core is running you could make use of a (JK) Flip-Flop, if I’m not mistaken?

1 Like