Example Program Drafts

Showing results for 
Search instead for 
Did you mean: 

Sequencer Example: A User-configurable State Machine

by Member HandyAndy ‎11-08-2012 11:24 AM - edited ‎01-30-2017 10:23 AM

Sometimes, we want to let users configure different states of a program, adjusting timing on a sequence of outputs.  This is an example of how that might be done.

This project is about CLD difficulty, and is one example of how you might let a user configure a sequence of outputs during runtime.

This code might be used in a factory or manufacturing line.  Here, the user will specify the settings for a number of on/off valves, and one variable valve.  They can be settable to the nearest 10 ms (plus or minus operating system jitter, of course).  Exposing these as an array lets the user create an arbitrary length vector of these sequence steps. each with user-configurable timing. 

Here is the front panel while in the Idle state, where the user can edit the sequence:

Front panel.png

And once the user pushes Run, here is the front panel as it runs, with its status being shown on the screen:


To accomplish this, I started with the basic State Machine template.  There are states for program initialization, letting the user edit the sequence, initializing the sequence, running the sequence, ending the sequence, and stopping the program:

system states.png

Once we are running the sequence, we traverse the array of steps, and make use of a functional global variable to keep track of timing:

timing FGV.png

Once the timing on one state has expired, we pass on to the next.  Upon completing the sequence, we return to the idle state.

The VI uses a couple of DAQ VI's.  I set up simulated instruments at the time since I had none of my own at my desk.

Active Participant J.Harv
Active Participant

Is there a potential problem with using the tick count?  What happens if the tick count rolls over in the middle? 

From what I can tell, your current time would be much less than your saved time and elapsed would always be zero and time elapsed would be false until you got up to where it rolled over (2 months or so from the time of the mistake). 

I'm implementing something like this now and was trying to avoid the tick count for this reason, what do you think?  Granted the chances of this happening are slim, it could still cause quite a problem in a released system if it happened.


Member HandyAndy

When the tick count rolls around its data type, it actually is not a problem.  Try experimenting with the math with a subtract VI and a couple of controls.  As long as both inputs and the outputs are all of the same datatype, you still get the true difference of what would be the elapsed time.  It has to do with the operation being confomant to the datatype.

For a simple example, consider using a U8 count, which is valid from 0 to 254:

If you were at 250, and then you checked a handful of counts later and it was at 5, the computation would be (5 - 250).  But, the answer comes out to be 11, since the answer lies outside of the datatype range and wraps as well. 

The only time you might run into problems is if you had a step that lasted longer than a the count period of 2 months and some change.  Rolling over twice is very bad.  But once is ok.

Active Participant J.Harv
Active Participant

Ah!  I understand. I didn't consider the data type, makes complete sense now. Neat.  

I ended up implementing the same thing but with a Get Data/Time in Seconds in place of the Tick Count.  I suppose they are roughly the same thing ....except if I have a time interval longer than a few months (my intervals are seconds though) I'm set! 

Thanks for the quick reply!

Member HandyAndy

That's the difference - the Tick Count will give you (roughly) millisecond resolution, as opposed to second resolution.  I had in mind an application that was looking to get around 200ms for most operations.  For sequence states that have step sizes with a whole number of seconds, what you have will work great! 

No problem!