LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Paused timer not resuming properly

Solved!
Go to solution

The application I'm working on involves three timers that trigger each other in sequence. There are three buttons the user can use to interact with them: start, pause, and stop. If you don't pause it at all, they flow between each other without any issue. However, if you pause, it doesn't seem to resume at the same point in the timer's schedule. Typically this results in running a shorter cycle than intended. I need pressing pause to not change the total time the timers are active, so this is a significant problem.

 

I'd rather not post code because of IP restrictions, but I can explain my implementation a bit. There is a global variable "isPaused" that starts as zero and is set by the pause and start callbacks. In the start callback, if isPaused is 1, it resumes by re-enables the active timer. If isPaused is 0, it treats it like it's starting the program from the beginning: setting timer intervals, determining the timer sequence, and setting up outputs. Each timer has a callback that determines what the next timer is in the sequence and sets that to be the active timer.

 

It might've just been my implementation, but I've tried two things without luck. First, I tried having the timers on a 0.001s interval and only transition when a static timeElapsed variable exceeds a global interval variable. That led to sequence problems, though it still seems like a sound idea to me. Second, I tried forcing a tick on pause and resume and using global booleans to have the active timer reset its time remaining instead of move on. I haven't been able to get forced ticks working without screwing up the timer interval though.

 

Does anyone have any ideas or know a standard way of doing this?

0 Kudos
Message 1 of 5
(1,607 Views)

Hello csulliva, I don't understand what you mean by "three timers that trigger each other in sequence" and "Each timer has a callback that determines what the next timer is in the sequence and sets that to be the active timer" a bit later.

A timer is by itself an asynchronous object that fires with its own pace, the concept of "active timer" is meaningless to me, so if you can explain a bit more what you are doing it will be better; I'm afraid a piece of code or some pseudo-code will be necessary to clarify your design.

 



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 2 of 5
(1,583 Views)

Hi,

 

Sorry my explanation was unclear. Each timer controls a voltage to be supplied as the main program output. When the first timer is on, the first voltage is supplied. Once it finishes, it switches to the second voltage, sets its own ATTR_ENABLED to 0, and sets the timer for the second voltage to ATTR_ENABLED=1. Once that one finishes, it either goes back to the first voltage or to the third voltage, depending on criteria that I believe is irrelevant to this problem, but I could go into if it would be helpful. There is only ever one timer with ATTR_ENABLED=1 at a time, hence the term "active timer." 

 

I've attached a .txt with pseudocode.

 

Thanks for the help.

0 Kudos
Message 3 of 5
(1,577 Views)
Solution
Accepted by topic author csulliva

Interesting approach.

 

I never tried such a paradigm: in similar situations I normally use a state machine inside a single timer that fires every second or less depending on the process to be handled; something along this line:

 

switch (step) {
  case 1:
    if (time elapsed) {
      stop voltage 1
      start voltage 2
      step++
    }
    break;
  case 2:
    if (time elapsed) {
      stop voltage 2
      if (execute step 3) {
        set voltage 3
        step = 3
      }
      else {
        set voltage 1
        step = 1
      }
      break;
    }
  case 3:
    if (time elapsed) {
      stop voltage 3
      set voltage 1
      step = 1
    }
    break;
}

 

 

This state machine can be populated with some other tasks you need to be performed and can be stopped in every moment by pausing a single timer every time.

Or you could use a toggle button for pausing, reading it inside the machine and operating accordingly if pressed: this does not stop the timer which can be useful if inside it you are performing some surveillance of the environment that needs to be always active.

 



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
Message 4 of 5
(1,559 Views)

This seems like a much cleaner solution and I plan on adopting it. Thanks for the help.

0 Kudos
Message 5 of 5
(1,542 Views)