Who needs design anyway. LabVIEW makes it easy for us to throw a few indicators on the front panel and use the lasso to squish our code down to acceptable proportions . |
NO NO NO NO NO NO NO NO NO NO NO NO!
This is like embarking on a journey armed with unclear directions, no map or compass, and a vague idea of your destination.
We don't suggest you go down this road, since death and pestilence will be your traveling companions.
The first thing to do is to trawl the available information for candidate components. OO texts tell you to do a noun-verb parse. Nouns can be used to define a component or a component attribute, and verbs are generally actions that are applied to components. English is a very imprecise language full of innuendo and subtle meaning. So, the point we are aiming for is to get an understanding of the test system and for this understanding to be reflected in the model. |
Noun Parse of Requirements Specification | |
Noun | Noun |
Widget | Analog Output port |
Widgetometer | Visual Inspection |
Test system | Calibration |
Test specification | Test position |
Display (Widgetometer) | Active test position |
Output Port (Widgetometer) | Customer test specification |
RS232 Communications | Part number |
Standard Widget | Data |
Test ports | Printout |
Reading | UUT |
Communication port |
Noun Parse of Target Specification | |
Noun | Noun |
Main Display | Part number |
Central Display Area | Time of Test |
Control Buttons | Issue |
Dialog | Software Version |
Units Under Test | An Out |
Test Type | Serial Out |
Unit Details | Display Out |
Serial Ports | File |
Test Report | Directory Structure |
User Name | |
Date of Test | |
Serial Number |
There are a few hidden components that most systems will need. For example, for this ATE there is no mention of the display and how it should look. A phone call confirms that the customer would like to see the test status and unit details on a screen.
We can also have a look at the hardware design to swipe a few ready-made components. For example, there is a digital multimeter (DMM) for taking the measurements, a Switching System for making the connections, and a PSU (power supply unit) for providing power. Now you can try to disregard repeats and obvious components that are outside the system.
So, let's go through our list and collate what we have identified into a smaller set of nouns, deleting those that we don't need:
Nouns | |
---|---|
Widget | |
Widgetometer | Discardis not meaningful for ATE |
Test system | |
Test specification | Discardnot part of system |
Display (Widgetometer) | Put in Hardware |
Output Port(Widgetometer) | |
RS232 Communications | |
Standard Widget | |
Test ports | |
Reading | |
Communication port | |
Analog Output port | |
Visual Inspection | |
Calibration | |
Test position | |
Active test position | Discardreplace with Test Position |
Customer test specification | Discardnot part of system |
Part number | |
Data | |
Printout | |
UUT | |
Main Display | Replace with Display |
Central Display Area | Replace with Display |
Control Buttons | Replace with Display |
Dialog | Replace with Display |
Units Under Test | |
Test Type | |
Unit Details | |
Serial Ports | |
Test Report | |
User Name | |
Date of Test | |
Serial Number | |
Part number | |
Time of Test | |
Issue | Discard relates to documentation |
Software Version | |
An Out | Discardsame as Analog Output Port |
Serial Out | Discardsame as RS232 |
Display Out | Discardsame as Widgetometer display |
File | |
Directory Structure |
From our table we can see that some nouns have been discarded, but others have been replaced with (we think) a more meaningful descriptionDisplay.
Customer test specification and test specification are obviously referring to the same thing, so drop customer test specification because the system will not care who owns the specs .
There's also an argument that test position and active test position are similar enough to be ignored. Active could be an attribute of test position perhaps.
All right, our next job is to group the nouns under a heading.
Data | Hardware | Test System | Report | Display |
---|---|---|---|---|
Test Report | Widget | Visual Inspection | Printout | Display |
User Name | Output Port | Calibration | Control Buttons | |
(Widgetometer) | ||||
Date of Test | RS232 Communications | Test position | Dialog | |
Serial Number | Standard Widget | Part number | ||
Part number | Test ports | UUT | ||
Time of Test | Reading | Units Under Test | ||
File | Communication port | Test Type | ||
Directory Structure | Analog Output port | Unit Details | ||
Software Version | Test position | Serial Ports | ||
Widgetometer display |
We have grouped each of our nouns under a heading that collectively describes it. This should be our starting point for the highest level components. More than one design can solve a problem, and you could have dissected the nouns differently and still come up with a decent design. For our example though, we have decided that our table headings now represent the main components in our system.
Putting it all together we will have a display that is populated by readings taken from the test system component. This test system will consist of a hardware component that will model all the states of the hardware. The hardware component will be responsible for talking to the serial communications, the DMM, and the visual inspection system. The results will be stored by a data component and printed by the report component. The component interaction diagram will look like Figure 9.2.
Now at the top level we can define the actions for each component.
This component describes the abstract things that the display will be required to do.
Reset Display
Show Test Position
Update Test Position
Update Status Area
This will be a state machine that will run through each test for each unit, checking pass-fail criteria and distributing the results data. So as well as the individual tests there will be states that model initialization, storing data, checking status, error states, and printing reports .
Any individual action for the hardware is modeled by this component. This is at the highest level of abstraction.
Initialize
Measure UUT Channel 1 An Out
Measure UUT Channel 2 An Out
Read UUT Channel 1 Serial
Read UUT Channel 2 Serial
Read UUT Data Serial (this is Serial Number, Part Number, etc.)
Get UUT Channel 1 Display
Get UUT Channel 2 Display
Any output to any printer is handled by this component. At this stage there is only one report required.
Initialize
Print Report
All test data is held here. This component has the responsibility for loading test limits and settings as well as storing and archiving the test results.
Command | Attribute |
---|---|
Initialize | Measure Error % |
Load Test Settings and Limits | Read Error % |
Store Test Results | Display Error % |
Get Limit | Measured Value 1 (An out) |
Set Result | Measured Value 2 (An out) |
Read Value 1 (Serial) | |
Read Value 2 (Serial) | |
Read Value 1 (Display) | |
Read Value 2 (Display) |
This component handles anything to do with the configuration data. The attributes will be set during development.
Load All
Save All
Load
Save
Get
Set
This component sets up the configuration data and anything else that needs initializing.
At this stage the top-level components are doing very broad, abstract operations. The language of the commands is very specific to the test system. The components that these top-level components employ will become more and more specialized the farther down the program hierarchy they are.
Okay, this is a bit contrived, and since design is a gray area there will be other ways of doing it. Practice has shown us that using these techniques does throw up similar designs again and again. Patterns are a way of taking advantage of these prefabricated designs.
System design should ideally be a collaborative effort between the developer and the customer. Lucky us, we're armed with our design patterns, which will allow us to ask very specific questions. The responses to these questions can be directly applied to the components in the pattern. |
There are two design patterns that we can employ here. If it looks as though the system is going to have a lot of individual displays, then we suggest starting off with the Menu Tree Pattern. If any of the displays are complex and require information from subVIs to be passed and displayed, we suggest using the UI Controller>>Message Queue Pattern for each.
This system doesn't require a large number of displays and therefore doesn't merit a menu-submenu system, but the complexity of the data to be displayed on the main UI does warrant the use of the UI Controller>>Message Queue Pattern.
First, let's reach a consensus about what the general UI operation is going to be.
A meeting is called with the main protagonists attending :
|
There has been a lot of information floating about, so Derek now writes the following on his sketch.
Initialize>>Set Up Display>>Run>>Finish
These are fairly repeatable from system to system. The other common state for the system could be a general error state where the program goes if it all goes horribly wrong.
Action | Description |
---|---|
No Action | Just ignore |
Disable Position | Disables the selected position |
Enable Position | Enables the selected position |
Position Visible | Makes the selected position visible |
Position Invisible | Makes the selected position invisible |
Update Position Data | Updates the data for the selected position |
Update Instruction Display | Sends text to the Instruction display |
Set to Tests Not Started | Sets the display to the not started state |
The beauty of separating the actions like this is that you can design the basics of the system and implement them for the prototype without getting bogged down in detail. You know that the User Interface will react to the commands even though the actual contents of the Unit Data areas have not been established yet.
Position Number (1 . . . 5)
This is a useful technique for simplifying the interface. Derek could have described the system fully by having lots of UI actions. For example, he could have had Disable Position 1, Disable Position 2, . . . Disable Position X. There is a potential problem in that the customer could come back and say that for cost purposes he or she wants to test 10 units. While not a showstopper, it could become cumbersome to have to write in all the commands for each unit.
Test Not Started>>Enter Data>>Testing>>Tests Complete
There will also be a Test Executive defined as part of the Testing State. We'll come back to this when we have the Test Specification of the Widgetometer.
We now have an idea of the User Interface, so let's tackle the hardware.
Back to the meeting.
(Derek reads through his notes.)
|
UnderRange
Read Unit Status
Read Unit Serial Number
Read Unit Part Number
Read Unit Software Version
Read Chan1 Reading
Read Chan2 Reading
Get Chan1 An Out
Get Chan2 An Out
Get Chan1 Display Reading
Get Chan2 Display Reading
OverRange
The Hardware component actions are now defined and there is a list of jobs that need doing. Using the Control >>Drive>> Read Pattern we can break down the components further (although this is not necessary for the purpose of the meeting).
Unit Number (1 . . . 5)
Some customers haven't thought that deeply about what they want. It is also often the case that they don't fully understand what they want until they get it. This happens frequently, so we recommend the use of a prototype to demonstrate the User Interface interactions.
In LabVIEW, building a prototype is not necessarily expensive, and if you use patterns you can use the prototype as the basis for your main program. The idea of a prototype is to emulate the look and feel of how you envision the program working. Therefore, the User Interface should be functional to the extent that buttons can be pressed and data displayed. There shouldn't be any connections to the hardware at this stage. You shouldn't spend much more than one to two days putting the prototype together.
Another small bit of advice given to us by an ISO9000 auditor is "always feed them something," by this we mean deliberately leave something out or leave an obvious gap. In the auditor 's case it was a ploy used by those being audited to distract. In our case we can use it to generate customer involvement, or to get customer "buy in" and start the conversion. We have found that people begin to accept the design more readily if they feel that they have contributed to it in some way. We should try to animate each step in the programremember it is a demonstrator for the customer.
From the requirements document it was established that there would be five test positions. This was the limit of what could be displayed completely on the screen, without having to resort to summary screens. A Strict Type Def. cluster was created that held all the data for each unit under test. Copies of this cluster were distributed around the screen and titled Position 1Position 5. Using a Strict Type Def. cluster will allow you to make changes to all of the clusters at the same time. The central area was allocated for instructions and test details and is just a plain string. Finally, the [Exit] button was left as is and [Button2] was renamed [Start Test].
Before we go on to actually emulating the running of the test, let's look at what basic actions we require from the User Interface.
User Interface Basic Actions
Each position cluster will need to be updated, enabled, disabled, and made visible or invisible.
For every [Start Test] button there should be a [Stop Test] button.
The [Exit] button should be disabled during a test.
[Button3] should be made invisible, since there is no apparent use for it yet.
Following are the User Interface Actions that came with the pattern:
Action | Description |
---|---|
Underrange | Throws or passes error |
Clear Queue | Clears the queue of display actions |
Get Display | Gets the next display item off the queue |
Enable Button 1 | as action |
Disable Button 1 | as action |
Enable Button 2 | as action |
Disable Button 2 | as action |
Button 2 Visible | as action |
Button 2 Invisible | as action |
Enable Button 3 | as action |
Disable Button 3 | as action |
Overrange | as Underrange |
Button 1 is the [Exit] button for our User Interface and the action should be updated to reflect this. Button 2 is the Start/Stop Test Button and, as well as renaming the button, we need further action to change the button text. Button 3 needs the visible-invisible actions.
We need to list new actions for the position clustersthese will be update, enable, disable, visible, and invisible. We should leave the UnderRange, OverRange, Get Display, and Clear Queue actions alone since they are always used.
The new User Interface Actions will need to be put into the Display Command.ctl and the Display Setting.ctl. Just open , edit, and save each control.
Display Command.ctl | Display Setting.ctl |
---|---|
Underrange Error | No Display |
Clear Queue | Enable Exit Button |
Get Display | Disable Exit Button |
Enable Exit Button | Enable Start Stop Button |
Disable Exit Button | Disable Start Stop Button |
Enable Start Stop Button | Update Start Stop Button Label |
Disable Start Stop Button | Enable Button 3 |
Update Start Stop Button Label | Disable Button 3 |
Enable Button 3 | Button 3 Visible |
Disable Button 3 | Button 3 Invisible |
Button 3 Visible | Enable Position |
Button 3 Invisible | Disable Position |
Enable Position | Position Visible |
Disable Position | Position Invisible |
Position Visible | Update Position |
Position Invisible | Update Inst Screen |
Update Position | |
Update Inst Screen | |
Overrange |
Create a Strict Type Def. enumerated control that models the test position, and its values should be:
Underrange, Unit 1, Unit 2, Unit 3, Unit 4, Unit 5, Overrange
Save it as Test Position.ctl and use it everywhere.
The UI queue component will have the Test Position.ctl as both input and output, and it will also pass it as part of the message queue. The adjustments to the UI queue component are relatively straightforward.
Open the UI Queue.vi.
Select the Test Position control using the "Select a Control . . ." button on the Control Palette.
Drop it into the Input box and copy it to the Output box.
Change the Test Position.ctl in the output box to an indicator.
Copy and Paste the Test Position control into one of the Local Store Clusters. This is a Strict Type Def. and will need to be opened and the Test Position control pasted into it.
Wire the input and output connector terminals.
Finally, wire the input and output controls onto the block diagram.
The result should be something like Figure 9.4.
The cluster constants seen in the diagram in Figure 9.5 are instances of the Strict Type Def Queue Items.ctl, and any changes to it are reflected in changes to the diagram.
Figure 9.6 shows the UI controller component that acts as a wrapper for the UI queue component. Once again we'll need to add the Test Position.ctl as both input and output and wire them to the connector. If you open up the diagram, you'll notice that the source has changed to reflect the new values for the instances of Display Setting.ctl and Display Command.ctl. Spooky!
The Test Position.ctl will need wiring into and out of the case structure and connecting to the UI queue component where required. In this case it is only required as an output from the Get Display>>More Items?=True case. See Figure 9.7 for the wiring diagrams.
Now we need to add the new cases to correspond to the elements in Display Command.ctl. This is a simple matter of selecting a suitable case and right-clicking and selecting Duplicate Case from the pop-up menu as shown in Figure 9.8.
The new case will automatically take on the name of the next element in Display Command.ctl, which in this case is "Enable Position." This case needs to be aware of the test position, so it will need Test Position wiring into the UI queue component. See Figure 9.9 for wiring of additional cases.
Finally, we need to make each action work! Look at the Control Display While Loop on the Widgetometer Test System block diagram in Figure 9.10. Right-click on the case structure and select Add Case for Every Value. Now you have a set of pigeonholes awaiting their actions. All of these actions are simple attribute settings, except for Update Position, and we'll tackle that later.
Here's the code for the Control Display While Loop as shown in Figure 9.10.
Figure 9.11 shows examples of the cases filled out. You will need a case for every action.
Now if you load a Test Stub VI called UI Display Stub.vi, and run the Widgetometer User Interface, you will be able to test the changes that have been made. The UI Display Stub.vi simply places messages on the message queue, and these are actioned by the User Interface. Now we are ready to give the prototype some life.
On starting, the program will settle into its first state: Test Not Started. When the start button is pressed, the Enter Data state is activated. After successfully entering data, the Testing state is started and the sequence of tests are run through. When the tests are done, the Tests Complete state is entered and any posttest actions finished.
A flexible approach is to produce a simple component that drives the program executive states. Figure 9.12 demonstrates how.
This component stores the required program executive state locally, by the "Set Test State" command, and returns it once on a "Get Test State" command. All we need to do now is have a loop checking the Test State and acting when it changes, and we have ourselves a nice, flexible program executive. We'll add the loop to the Widgetometer User Interface VI and put in some functionality, or the "Enter Data State." A simple Enter Data dialog box was created, and if you notice the Monitor Control Buttons loop on the diagram in Figure 9.13, you'll be able to see that when button 2 [Start Stop Test] is pressed, the Test State is set to Enter Data. When the Program Executive loop next iterates, it will retrieve that state and action it.
Inside the Enter Data dialog will be the code that decides what step to go to when the dialog exits. If it exits on a Cancel the next state should be to return to Test Not Started. If the dialog exits successfully then the next state would be Testing. In a similar fashion to decoupling the User Interface actions from the front panel, we've now decoupled the Program Executive actions. We now have the freedom to control the way the Test Sequence runs from nearly anywhere in the software hierarchy.
Top |