Pages: [1]   Go Down
Author Topic: How to use Timer to exit LoopA,then run LoopB?  (Read 621 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, I am very new to Arduino, my question is:
How to use Timer to do this:  Run LoopA 10sec. then Run LoopB 2sec., then LoopA 10sec. LoopB 2sec., repeatly. Could somebody write some code for me? Thanks in advance.

????
void LoopA()
????
void LoopB()
Logged

Offline Offline
Full Member
***
Karma: 4
Posts: 187
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

EDIT: Wrong Answer tomorrow i post right one now i am late

Code:
void loop(){
while (millis() < 10000) {
LoopA();
}
while (millis() < 2000) {
LoopB();
}
}

Are you looking for this
« Last Edit: November 28, 2012, 06:59:17 am by Cybernetician » Logged

From Idea To Invention

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

http://gammon.com.au/blink
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48556
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@Cybernetician
What is going to happen after the Arduino has been running for 10 seconds in your code?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes that one only works the first iteration. I haven't compiled this code to test (to the Arduino C++ variant have do...while... loops?).
Code:
long quitTime;
void loop () {
    quitTime = millis () + 10000;
    do {
        // Do stuff
    } while (millis () < quitTime);

    quitTime = millis () + 2000;
    do {
        // Do other stuff
    } while (millis() < quitTime);
}

Remember that it won't interrupt the execution and jump out of a loop, so to make it work you can't have too much code (execution time wise "much") in there.
Say that in the second step you have code which takes 1.5 second to run. Then it will exit the loop 3 seconds after it started.
But if you have code that only takes 10 ms to run, well you may overshoot with a few ms but that is probably okay.
Logged

Offline Offline
Full Member
***
Karma: 4
Posts: 187
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
@Cybernetician
What is going to happen after the Arduino has been running for 10 seconds in your code?

Code:
void loop(){
while (millis() < 10000) {
LoopA();
}
while (millis() < 2000) {
LoopB();
}
}

Ooops. what a big mistake

tomorrow i post right one now i am late

Logged

From Idea To Invention

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48556
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
    quitTime = millis () + 10000;
Adding unsigned longs is not a good idea in robust code.

Code:
    do {
        // Do stuff
    } while (millis () - startTime < diddleTime);
is guaranteed to work. Though I suspect that a do/while is NOT the construct you want to use. While probably is. Look up the differences.
Logged

Saskatchewan
Offline Offline
Sr. Member
****
Karma: 19
Posts: 363
When the going gets weird, the weird turn pro. - Hunter S. Thompson
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'd go with something like this. I put it in a loop() function for clarity.

Code:
constant unsigned long firstLoopLength = 10000;
constant unsigned long secondLoopLength = 5000;

void loop(){
        // loop A
unsigned long loopStartTime = millis();
while (millis() - firstLoopLength > loopStartTime){
// do loop A stuff
}

        // loop B
loopStartTime = millis();
while (millis() - secondLoopLength > loopStartTime){
// do loop B stuff
}
}
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48556
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
while (millis() - firstLoopLength > loopStartTime){
would, in my humble opinion, be better as
Code:
while (millis() - loopStartTime < firstLoopLength)
        {
Since that more naturally reflects how one would describe the while clause in English.

Logged

Saskatchewan
Offline Offline
Sr. Member
****
Karma: 19
Posts: 363
When the going gets weird, the weird turn pro. - Hunter S. Thompson
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I value your opinion and I can see what you are saying. It makes sense.

Thanks.
Logged

Offline Offline
Full Member
***
Karma: 4
Posts: 187
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

PaulS says:
Quote
@Cybernetician
What is going to happen after the Arduino has been running for 10 seconds in your code?
Aqualize Says:
Quote
Yes that one only works the first iteration. I haven't compiled this code to test (to the Arduino C++ variant have do...while... loops?).

Code:
long quitTime;
void loop () {
    quitTime = millis () + 10000;
    do {
        // Do stuff
    } while (millis () < quitTime);

    quitTime = millis () + 2000;
    do {
        // Do other stuff
    } while (millis() < quitTime);
}
Remember that it won't interrupt the execution and jump out of a loop, so to make it work you can't have too much code (execution time wise "much") in there.
Say that in the second step you have code which takes 1.5 second to run. Then it will exit the loop 3 seconds after it started.
But if you have code that only takes 10 ms to run, well you may overshoot with a few ms but that is probably okay.

Quote

Quote
@Cybernetician
What is going to happen after the Arduino has been running for 10 seconds in your code?

Code:
void loop(){
while (millis() < 10000) {
LoopA();
}
while (millis() < 2000) {
LoopB();
}
}

Ooops. what a big mistake

tomorrow i post right one now i am late

thanks PaulS.

Need to minus time of loopA, loopB, and other statements execution time for near to perfect result.

Code:
#include "Timer.h"

Timer t;

bool lpA = true;
bool lpB = false;
int loopAEvent;
int loopBEvent;

void setup()
{
  Serial.begin(9600);
  loopAEvent = t.every(10000, loopBFlag);
}

void loop()
{
  t.update();
  if(lpA==true)
  {
    Serial.println("LOOPA");
  }
  if(lpB==true)
  {
    Serial.println("LOOPB");
  }
}

void loopBFlag()
{
  t.stop(loopAEvent);
  lpA=false;
  lpB=true;
  loopBEvent = t.every(2000, loopAFlag);
}
void loopAFlag()
{
  t.stop(loopBEvent);
  lpA=true;
  lpB=false;
  loopAEvent = t.every(10000, loopBFlag);
}
Logged

From Idea To Invention

Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
    quitTime = millis () + 10000;
Adding unsigned longs is not a good idea in robust code.

Code:
    do {
        // Do stuff
    } while (millis () - startTime < diddleTime);
is guaranteed to work. Though I suspect that a do/while is NOT the construct you want to use. While probably is. Look up the differences.
I had to think about it but I understand the part about adding unsigned longs. In the corrected version millis() - startTime will never result in a wrap around because startTime can not be larger than millis() result. Except after those 50 days when result of millis() wraps around. But that is more esoteric, if the machine isn't expected to stay on for such long time.

But the part about while instead of do/while?
The difference I know is that do/while will execute at least once. My thinking was that it will save one loop condition check in this particular application, if setting the startTime (or as I had written, the quitTime) just before the loop and we want to interrupt after several seconds it till definitely don't have time to become false for that first iteration (using interrupts and having a lot of heavy code in the interrupt could cause this if the interrupts occurs exactly after the variable assignment). Also the code could be / probably would be written that the second loop expects to run after the first one, not that one time the first loop will be skipped.
Because of this reasons I thought that having the loop condition check after the first run was the most economical and effective one.
Am I wrong in my intention why to use do/while or is it some other side effect that I'm unaware of?
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48556
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Am I wrong in my intention why to use do/while or is it some other side effect that I'm unaware of?
As long as you understand the distinction, use the one that is appropriate for your situation. Personally, I've never used do/while. The time required to check the condition, even when you KNOW that the condition will be true, one extra time is only a couple hundred nanoseconds.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

There are times when using do...while is highly appropriate. For example, if the thing you are testing is set up inside the loop.

On the other hand, if the thing being tested can happen zero times (eg. while (we_have_apples) eat_an_apple(); ) then you should use while on its own.
Logged

Pages: [1]   Go Up
Jump to: