Monday, March 9, 2009

A More Universal Approach to Wait Cases

By: Dave Graybeal – Project Engineer, CLD




INTRODUCTION

The purpose of this particular blog is to help show an example of something that the WTI Clarkston Office has developed to help decrease the number of cases in our code and help speed up the application development process(even if only slightly increased). In this Blog I will be talking about the Typical Wait Case found in many applications and how we have replaced those wait cases with a single more Universal Wait Case in their place. These examples are shown using a Queued Master Slave State Machine with a String Queue. Other Types of Queues (Variants, Enums, etc.) could also be used but may require some additional code not shown in the Figures below.


TYPICAL WAIT CASE

The picture below (Figure 1) shows a common wait case. The key elements found in a wait case are the loop rate control (which controls the processor usage during free spin), the start time (typically set in the case that sent the application to this wait), the wait time (commonly found as a hard coded constant like shown in the picture) and the case decision (with the current wait case wired to the false condition and the destination case hard coded and wired to the true condition). Many times in an application you may find the need for different destinations and/or different amounts of wait time. Using wait cases in this way create the need to have multiple cases in a single application that all provide the similar functionality. This in turn makes the code harder to follow and makes for a longer case list (which may already be long enough)

See larger Image


Figure 1


MAIN CLUSTER SETUP

The picture below (Figure 2) shows an example of how the WTI Clarkston Office uses a single Cluster Shift Register to carry around our data. We also break down the cluster into the subcategories; Application Control, Application Timing, Application Data, and Static Inputs). The items relevant to this Blog are the items shown underneath the Application Timing Category. If you are already using a single cluster shift register then you would need to add a cluster within it that contains the following:
1. String – “Next Case”
2. U32 – “Start Time (ms)”
3. U32 – “Wait Time (ms)”
4. U32 – “Loop Rate (ms)”
Each of these items satisfies one of the key elements described in the Typical Wait Case section.

See larger Image


Figure 2


UNIVERSAL WAIT CASE

This case shown below (Figure 3) shows the Universal Wait Case. Each item required by the key elements is pulled from the MAIN CLUSTER and acted upon accordingly. The code is very similar to that found in the Typical Wait Case, except that the Hard Coded Components are replaced with controllable items found within the cluster instead. This allows for this single Wait Case to be used for multiple desired waits throughout the same application. In turn this makes the flow a little easier to follow and reduces the number of cases found in the application.

See larger Image


Figure 3


CALLING THE UNIVERSAL WAIT CASE

To use the Universal Wait Case simply wire the Desired values into the Bundle Cluster Node(as shown below in Figure 4) and Enqueue “Wait” into the Queue. As a note, to save some more space where loop rate is not as important to have programmatic control over you can simply use a default value for the “Loop Rate (ms)” control in the creation of the Shift Register and simply don’t wire a new value into it.

See larger Image


Figure 4


SUMMARY

As simple of a change as this is, it has certainly proved to be value added to me and my colleagues. In the end I believe it saves time recoding the wait case multiple times (even if it only means a time saving of duplicating a previously created wait case and changing the hard coded values), and promotes re-usable code. I hope that this blog post has been helpful to everyone.

Expect more on our Queued Master Slave State Machine Template to come in the future.

2 comments:

  1. One problem with this is that you're using a queued state machine, but you're not passing the state arguments with the state command. This means that you have potential for a coding bug - if someone enqueues two wait states before the first state has a chance to execute, the first wait state will lose the values you set for it and use the ones from the second wait state.

    I'm assuming this isn't likely to happen with the way you use your state machines, but it is technically possible.

    P.S. It's called a "blog post". The entire collection of posts is the blog.

    P.P.S. I would expect a CLA to be able to capitalize LabVIEW correctly (the "about me" section).

    ReplyDelete
  2. Thanks for visiting our blog, we appreciate your comments. Obviously your comments on the state machine our valid; our developers are very familiar with this architecture and typically will not make that mistake. To your second point, we appreciate the correction to our blogging terminology. As far as the LabVIEW spelling, I got it right 2 out of three times :). Sometimes I get lazy with my typing I should have caught this, I do know better.

    ReplyDelete