Go Down

Topic: Opinions wanted (Read 688 times) previous topic - next topic

Jassper

When it comes to timing, which method is better - or does it matter. (edit) I should mention that this is within the void loop of the program.
Method 1:
Code: [Select]

if(currTime - lastCycle >= CycleInterval)
   {
   digitalWrite(Pin1,HIGH);
   }
 
// Is it time to stop?
 if(currTime - lastCycle >= CycleInterval + CycleTime)
   {
   digitalWrite(Pin1,LOW);
   lastCycle = currTime;
   }


Method 2:
Code: [Select]

if(currTime - lastCycle >= CycleInterval)
     {
     Somefunction(CycelTime);
     lastCycle = currTime + CycelTime;
     }

void Somefunction(int time)
{
   digitalWrite(Pin1,HIGH);
   delay(time);
   digitalWrite(Pin1,LOW);
}


The only thing I can an issue with is that the void loop part of the program doesn't run with Method 2 during that delay(time). So I guess it boils down to how important that part is.

Your thoughts...


jraskell

Method 3:  State Machine.

Method 4:  Hardware Timer (only if necessary for adequate accuracy).

Nick Gammon


The only thing I can an issue with is that the void loop part of the program doesn't run with Method 2 during that delay(time). So I guess it boils down to how important that part is.


I'm not sure what you mean by that.

Method 1 will "creep" - let's say whatever else you are doing means your test comes at a couple of milliseconds after your CycleInterval elapses, then by starting back at currTime again, you start at the new (late) time.

Method 2 will be more consistent, by adding your cycle time to the original time (rather than the current time) it shouldn't creep. But you have the potential problem that if the cycle time is short, that even after you add it, you still haven't caught up. But with reasonable figures, probably method 2 is going to be more exact - assuming that this is what you call "better".
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Jassper

#3
Oct 19, 2011, 03:11 am Last Edit: Oct 19, 2011, 03:36 am by Jassper Reason: 1


The only thing I can an issue with is that the void loop part of the program doesn't run with Method 2 during that delay(time). So I guess it boils down to how important that part is.


I'm not sure what you mean by that.



I mean that during the delay(time) the loop pauses until the delay is done and the function returns. So if there are other timed functions they will fall behind, or possibly miss a beat. depending on how long the delay time is.


EDIT
Think I this is what I'm looking for as there are several things that need attending to inside the loop.
http://arduino.cc/en/Tutorial/BlinkWithoutDelay
So in this case using the delay inside the function call wouldn't be optimal





Nick Gammon

And check out this thread:

http://arduino.cc/forum/index.php/topic,74861.0.html
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Jassper


And check out this thread:

http://arduino.cc/forum/index.php/topic,74861.0.html


Thanks for the link, that helps. It's a bit complicated to me because I need to set one pin high for 5 sec every 5 min all the time  and another high for 1 sec every min only when condition A is true.

frank26080115

I usually just use a flag that's set by a timer overflow ISR, then in the loop, execute an if statement with the condition on that flag, and then clear that flag.
Freelance engineer, consultant, contractor. Graduated from UW in 2013.

Jassper


I usually just use a flag that's set by a timer overflow ISR, then in the loop, execute an if statement with the condition on that flag, and then clear that flag.


I was going to ask what would be the pitfalls of doing something like that,
Code: [Select]

void loop()
{

a++;
if(a > 5000)// aprox 5 second
   //start somthinge
if(a > 6000)
  {
  // one second later stop something
  a=0;
  }
}




jraskell

The only pitfall is that it utilizes one of the hardware timers, which you only have a limited supply of (though it's possible to utilize a single timer for multiple uses with careful coding).

The blink without delay method may be perfectly suitable if your timing doesn't need to be highly accurate, and since you're talking about pulses on the order of seconds, I think that is likely. (fyi, what I'm considering highly accurate here is on the order of single digit millisecond or sub-millisecond accuracy).  I would still utilize a simple state-machine to handle the firing of the pulse though.

Jassper


The only pitfall is that it utilizes one of the hardware timers, which you only have a limited supply of (though it's possible to utilize a single timer for multiple uses with careful coding).


How many hardware timers are there on the ATmega328, do you know? I would need maybe 5 different timers.

Is this what you mean by State-Machine
http://www.state-machine.com/arduino/index.php
Not sure I understand what a state machine is.



jraskell


How many hardware timers are there on the ATmega328, do you know? I would need maybe 5 different timers.


The Atmega 168/328 has two 8 bit timers and one 16 bit timer.

As I said though, it's possible to use a single timer for multiple purposes, even to provide timing for 5 separate signals.



Is this what you mean by State-Machine
http://www.state-machine.com/arduino/index.php
Not sure I understand what a state machine is.


Well, Yes and No.  For your purposes, you don't need nearly so complex an implementation.  Googling state machine tutorial should provide some useful links, this looks like a potentially good start (I just skimmed through it myself): http://www.generation5.org/content/2003/FSM_Tutorial.asp

You'd be looking at a very simple state machine, with two states and two events.  The states being Signal On, and Signal Off, and the events being Turn On, and Turn Off.

I would start with an implementation utilizing the Blink Without Delay method of timing, and only look at switching to a timer based implementation if you aren't getting the accuracy you need.



Jassper

Great information - thanks XD

Go Up