Lvcore3 Exercisemanual English PDF
Lvcore3 Exercisemanual English PDF
LabVIEW Core 3
Exercises
Copyright
© 2004-2014 National Instruments. All rights reserved.
Under the copyright laws, this publication may not be reproduced or transmitted in any form, electronic or mechanical, including photocopying, recording, storing in an information retrieval system, or
translating, in whole or in part, without the prior written consent of National Instruments Corporation.
National Instruments respects the intellectual property of others, and we ask our users to do the same. NI software is protected by copyright and other intellectual property laws. Where NI software may
be used to reproduce software or other materials belonging to others, you may use NI software only to reproduce materials that you may reproduce in accordance with the terms of any applicable license
or other legal restriction.
Patents
For patents covering National Instruments products/technology, refer to the appropriate location: Help»Patents in your software, the patents.txt file on your media, or the National Instruments
Patent Notice at ni.com/patents.
Support
Worldwide Offices
Visit ni.com/niglobal to access the branch office websites, which provide up-to-date contact information, support phone numbers, email addresses, and current events.
To comment on National Instruments documentation, refer to the National Instruments website at ni.com/info and enter the Info Code feedback.
Contents
Student Guide
A. NI Certification........................................................................................................................................................................................vii
B. Course Description ..................................................................................................................................................................................viii
C. What You Need to Get Started ................................................................................................................................................................ix
D. Installing the Course Software ................................................................................................................................................................ix
E. Course Goal .............................................................................................................................................................................................ix
Lesson 1
Developing Successful Applications
Exercise 1-1 Review a Requirements Document............................................................................................................................1-3
Exercise 1-2 Review User Stories...................................................................................................................................................1-5
Lesson 2
Organizing the Project
Exercise 2-1 Create a Project Library .............................................................................................................................................2-3
Exercise 2-2 Resolve Project Conflicts...........................................................................................................................................2-7
Lesson 3
Creating an Application Architecture
Exercise 3-1 Create a Queued Message Handler ............................................................................................................................3-3
Exercise 3-2 Handshaking with Notifiers .......................................................................................................................................3-17
Lesson 4
Customizing the User Interface
Exercise 4-1 Create a User Interface Prototype ..............................................................................................................................4-3
Exercise 4-2 Create User Documentation.......................................................................................................................................4-17
Exercise 4-3 Initialize an Application from a File..........................................................................................................................4-25
Exercise 4-4 Improve Application Usability ..................................................................................................................................4-39
Lesson 5
Managing and Logging Errors
Exercise 5-1 Manage Errors............................................................................................................................................................5-3
Exercise 5-2 Log Errors ..................................................................................................................................................................5-17
Lesson 6
Creating Modular Code
Exercise 6-1 Implement and Test a Data Logging Module ............................................................................................................6-3
Exercise 6-2 Integrate and Test Modules from the Top-Down ......................................................................................................6-19
Exercise 6-3 Integrate and Test Modules from the Bottom-Up......................................................................................................6-35
Exercise 6-4 Implement Fuel Control Valve Functionality............................................................................................................6-53
Exercise 6-5 Integrate and Sandwich Test a Module......................................................................................................................6-63
Appendix A
Additional Information and Resources
Student Guide
Thank you for purchasing the LabVIEW Core 3 course kit. This course manual and the accompanying software are used in the three-day, hands-on LabVIEW Core 3
course.
You can apply the full purchase of this course kit toward the corresponding course registration fee if you register within 90 days of purchasing the kit. Visit
ni.com/training for online course schedules, syllabi, training centers, and class registration.
Note For course and exercise manual updates and corrections, refer to ni.com/info and enter the Info Code core3.
A. NI Certification
The LabVIEW Core 3 course is part of a series of courses designed to build your proficiency with LabVIEW and help you prepare for NI LabVIEW certification
exams. The following illustration shows the courses that are part of the LabVIEW training series. Refer to ni.com/training for more information about
NI Certification.
LabVIEW
LabVIEW LabVIEW LabVIEW Core 3
Getting Started Core 1 Core 2 Advanced
Architectures
LabVIEW
in LabVIEW
Connectivity
LabVIEW
Performance Managing
Software
Engineering
Object-Oriented
in LabVIEW
Design &
Programming
in LabVIEW
B. Course Description
LabVIEW Core 3 introduces you to structured practices to design, implement, document, and test LabVIEW applications. This course focuses on developing
hierarchical applications that are scalable, readable, and maintainable. The processes and techniques covered in this course help reduce development time and improve
application stability. By incorporating these design practices early in your development, you avoid unnecessary application redesign, increase VI reuse, and minimize
maintenance costs.
This course assumes that you have taken the LabVIEW Core 1 and LabVIEW Core 2 courses or have equivalent experience.
This course kit is designed to be completed in sequence. The course and exercise manuals are divided into lessons, described as follows.
• An introduction that describes the purpose of the lesson and what you will learn
• A summary quiz that tests and reinforces important concepts and skills taught in the lesson
• Some lessons include optional and challenge exercise sections or additional exercises to complete if time permits
Note The exercises in this course are cumulative and lead toward developing a final application at the end of the course. If you skip an exercise, use the
solution VI for that exercise, available in the <Solutions>\LabVIEW Core 3 directory, in later exercises.
C. What You Need to Get Started
Before you use this course manual, make sure you have the following items:
Directory Description
Exercises Folder containing VIs and other files used in the course
Solutions Folder containing completed course exercises
The installer places the Exercises and Solutions folders at the top level of the root directory. Exercise files are located in the <Exercises>\LabVIEW Core
3 directory.
Tip Folder names in angle brackets, such as <Exercises>, refer to folders in the root directory of your computer.
E. Course Goal
Given a requirements document for a LabVIEW development project, you will follow a software development process to design, implement, document and test the
key application features in a manner that satisfies requirements for readability, scalability, and maintainability.
Scenario
You are a member of a scrum team developing an application to control the startup process of a boiler. After meeting with the customer to discuss their needs and
researching common boiler operations and procedures, the team developed a requirements document. Review this document for completeness and accuracy, as it is
the foundation for the rest of the scrum development process, as shown in Figure 1-1.
Sprint Sprint
Review Retrospective
Meeting Meeting
Daily
Scrum
Meetings
No
Release Sprint
Concept Development Finished?
Planning Planning Ship
Sprint
Meeting Meeting Yes
Implementation
1. Review the Boiler Controller Requirements Document.docx located in the <Exercises>\LabVIEW Core 3\Release Planning directory
or in Appendix A, Boiler Controller Requirements of the LabVIEW Core 3 Course Manual, for the boiler startup controller to understand the software you create
in this course.
Note Many organizations use their own techniques to create a requirements document. If your organization is not using a format for a requirements
document, you can use this requirements document as a basis for other requirements documents.
2. As a group, work with the instructor and your classmates to identify at least one of the following requirements.
Non-functional requirement
Functional requirement
Scenario
After the scrum team completed the requirements document review, the product owner met with a customer representative to create a list of user stories. Each user
story informally describes an aspect of the application from the perspective of the end-users and what they need the application to do as part of their job.
The product owner returns to the scrum team with a list of user stories. This list of user stories serves as the product backlog for the development of this project. Each
development sprint focuses on implementing one or more user stories.
Sprint Sprint
Review Retrospective
Meeting Meeting
Daily
Scrum
Meetings
No
Release Sprint
Concept Development Finished?
Planning Planning Ship
Sprint
Meeting Meeting Yes
Implementation
1. As a class, review and discuss the list of user stories for the boiler startup controller found in the Boiler Controller User Stories.docx document in
the <Exercises>\LabVIEW Core 3\Release Planning directory, or in Appendix B, User Stories of the LabVIEW Core 3 Course Manual, to understand
of the needs of the end-user. You will base development sprints on these user stories.
Scenario
A member of your development team, with the help of a boiler expert, created a software model for the boiler that your application will control. To simplify
distribution of these files, and to control how this code is used, you must create a project library and set the access scope for each of the files your teammate developed.
Design
Create a LabVIEW project library (.lvlib) for the files your teammate developed and set the access scope for each file.
Note Do not open these files. They require code that you have not developed yet.
Implementation
1. Open LabVIEW.
4. Right-click the project library icon and select Add»File from the shortcut menu.
5. Navigate to the <Exercises>\LabVIEW Core 3\External\Boiler directory from the Select a File to Insert dialog box.
6. Select all the files in the Boiler directory and click the Add File button.
Note Click the Ignore All button in the dialog box that appears. LabVIEW is looking for controls that you create in future exercises.
7. Right-click the project library icon and select Save»Save As from the context menu.
8. Name the project library Boiler.lvlib and save it in the <Exercises>\LabVIEW Core 3\External\Boiler directory.
9. Click Save All when prompted to save the individual files. The project library window is shown in Figure 2-2.
10. Set the access scope for the files in the library.
Right-click the project library icon and select Properties from the shortcut menu to display the Project Library Properties dialog box.
Using the information in Table 2-1, click an item in the Contents tree to select the item and then click the proper radio button in the Access Scope area to
assign the proper scope.
Click the OK button to incorporate the changes into the project library and close the dialog box.
Scenario
Conflicts can arise within a LabVIEW project if top-level VIs call incorrect versions of nested code. Applications that are saved in multiple locations as a result of
archiving, backup, or division of work, can lead to the use of incorrect code and broken applications.
In this exercise, you examine a LabVIEW project that contains conflicts and use the tools in the Project Explorer to resolve the conflicts and manage the project.
Design
The project in this exercise contains the following conflicts:
• Two VIs within the project have the same name, Generate Signal.vi.
• A VI in the project calls a subVI outside the project, Log to File.vi, that has the same name as a VI within the project.
Implementation
Part I: Resolving Conflicts
1. Explore a LabVIEW project containing conflicts.
Expand Sine Wave, Square Wave, File IO, and Dependencies in the project tree, as shown in Figure 2-4.
Notice that LabVIEW has determined that various VIs have conflicts. A conflict is a potential cross-link that occurs when LabVIEW tries to load a VI that
has the same qualified name as an item already in the project. When there is a conflict, it is unclear which VI a calling VI should reference.
Tip The best way to determine if cross-linking exists is to view the full path to the item. Viewing file paths is often the first step in resolving cross-linking
conflicts. You can rename or move files as needed, but first you must determine which file is the correct file. Displaying the full path of an item helps you
determine the correct file.
Notice that the Generate Signal VI is actually two different VIs with the same name.
Conflicts might occur if you try to include VIs of the same name because only one VI of a given name can be in memory at a time. If you have a VI with a
specific name in memory and you attempt to load another VI that references a subVI of the same name, the VI links to the VI in memory.
Right-click Generate Signal.vi in the Sine Wave virtual folder and select Find»Callers from the shortcut menu.
In the project tree, LabVIEW highlights the Create and Save Signal VI because it calls the Generate Signal VI as a subVI.
Right-click Generate Signal.vi in the Square Wave virtual folder and select Find»Callers from the shortcut menu.
Even though this Generate Signal VI has no callers in the project, you note that the Generate Signal VI in the Square Wave directory performs a different
function than the Generate Signal VI in the Sine Wave directory. Therefore, renaming one or both files is an appropriate way to resolve the conflict.
In the Project Explorer window, right-click Generate Signal.vi in the Sine Wave folder, and select Rename.
Click Save when LabVIEW prompts you to save the changes made to the calling VI, Create and Save Signal.vi. LabVIEW updates the Create and
Save Signal VI to preserve the links to the subVI.
In the Square Wave folder, right-click Generate Signal.vi and select Rename.
Tip You also can rename files from the Files page view of the project.
Notice that there is copy of Log to File.vi in the File IO virtual folder and a copy of Log to File.vi in Dependencies, which indicates that a file
within the project calls the second copy. The file paths of these two VIs are different, as shown in the Paths section of the Project Explorer window.
Right-click each copy of Log to File.vi and select Find»Callers to determine which file, if any, within the project calls each copy.
Double-click Create and Save Signal.vi in the LabVIEW Project. The Resolve Load Conflict dialog box appears as shown in Figure 2-5 and prompts you
to select the subVI you want the caller to reference.
Click the Show Details button in the Load Summary Warning dialog box, which informs you that the Log to File subVI was loaded from a different
location.
Examine the information display in the Load and Save Warning List dialog box and click the Close button.
Review the items in the Project Explorer window. All conflicts in the project should now be resolved.
The Create and Save Signal VI has unlinked subVIs after resolving the conflicts.
To relink the subVIs, open the block diagram, right-click each subVI, and select Relink to SubVI from the shortcut menu.
Right-click the Sine Wave virtual folder in the project tree and select Convert to Auto-populating Folder from the shortcut menu.
Navigate to the <Exercises>\LabVIEW Core 3\Project Explorer Tools\Working Directory\Sine Wave directory and click Select
Folder. Notice in the project tree that the Sine Wave folder icon changes to indicate that the folder is now set to auto-populate.
Note In auto-populate mode, the contents of the project folder reflect the hierarchy of the specified folder on disk, as well as any changes that are made
outside the development environment.
Click the Windows Start button and select All Programs»Accessories»Notepad to launch Notepad.
In Notepad, select File»Save and save the file as Data File.txt in the <Exercises>\LabVIEW Core 3\Project Explorer Tools\
Working Directory\Sine Wave directory.
Close Notepad.
Notice that Data File.txt has been added to the Sine Wave auto-populating folder on the Items page of the Project Explorer window.
In the Find Project Items dialog box, enter sine in the textbox, as shown in Figure 2-6, and click Find.
Figure 2-6. Find Project Items Dialog Box
Select Sine Wave - Generate Signal.vi and click the Go To button. Sine Wave - Generate Signal.vi is now highlighted in the Project Explorer window.
Scenario
In the sprint planning meeting for this iteration, the product owner chose to implement two user stories that both apply to the overall system architecture:
• As the boiler operator, I want the application to be flexible enough that I can replace the boiler in my system or request that the application include additional
boiler features, so that these updates occur with a relatively quick turnaround and minimal down-time..
• As a boiler operator, I want the user interface to remain responsive while boiler operations are occurring, so that I can always shut down the boiler in the event
of an emergency.
The product owner asks you to lead the development effort for this sprint. After discussing each user story with the team, you identify the following development
tasks to implement the two user stories:
• Select the top-level architecture for the application, ensuring that the user needs for scalability, readability, maintainability, parallel processing, and user interface
responsiveness will be satisfied.
1. Review the code with the scrum team and implement code review feedback.
Note For this course assume you have had successful code reviews with no major feedback.
2. Test the code to ensure that you successfully satisfy the user stories and tasks for the sprint.
4. Test the executable to ensure that you can successfully deploy the code.
5. Ensure that the user stories have been implemented to the customer’s satisfaction.
Note For this course, assume that the customer is satisfied with the implementation of each user story.
Design
For the first task of this sprint, the team meets to brainstorm architecture ideas. One team member suggests using a state machine since there is a sequential flow to
the user actions. Someone else points out the need for parallelism and suggests the producer/consumer pattern. The product owner recognizes that the application may
need to generate messages from multiple processes so he suggests using the queued message handler template as a starting point. An overview of this template is
shown in Figure 3-1.
Message Queue
Message 1
Message 2
Message 3
1. Produce
Message Message 4
(Enqueue)
Message 5
3. Execute
Message Diagram based
on Message
2. Consume 4. (Optional)
Message Produce Message
(Dequeue) (Enqueue)
The Queued Message Handler (QMH) template facilitates multiple sections of code running in parallel and sending data between them. Each section of code
represents a task, such as acquiring data, and is designed similarly to a state machine. Because of this design, you can divide each task into states.
In addition to the Event Handling Loop (EHL) and the Message Handling Loop (MHL) you will need a third parallel process to handle user actions. This third process
also handles communication with the boiler, as shown in Figure 3-2.
Start
Open
References
UI Controller Boiler
Event Messages Message Messages Boiler Messages
Handler Loop Handler Loop Controller Boiler
Controller
Exit Notifier
Close
References
End
Implementation
Create a LabVIEW Project for the Application Using the Queued Message Handler Template
1. Open Boiler Controller.lvproj in the <Exercises>\LabVIEW Core 3\Course Project directory.
Note The <Exercises\LabVIEW Core 3> folder contains a project for use in this course. For future projects, LabVIEW can generate the starter files
for a queued message handler application. Select File»Create Project in LabVIEW to display the Create Project dialog box and select Queued Message
Handler in the Templates category.
Run the VI and click the Something, Something Else, and Stop buttons to see how the Display indicator updates.
Click the Something, Something Else, and Stop buttons and notice how the execution trace changes.
2. Right-click the Message Queues Out type def control select Open Type Def.
3. Modify All Message Queues.ctl as shown in Figure 3-3.
5. Modify the Create All Message Queues VI block diagram as shown in Figure 3-4.
sA
1 Obtain Message Queue and Enqueue Message—Duplicate the Obtain Message Queue VI and Enqueue Message VI to send a Initialize message to the MHL
and Boiler Controller queue refnums.
2 Merge Errors—Merges the errors from both queues.
In the Project Explorer window, create a virtual folder under My Computer named Boiler Controller.
In the virtual folder, create a new VI and save the VI to <Exercises>\LabVIEW Core 3\Course Project\Controller\Boiler
Controller.vi.
Create the Boiler Controller VI front panel as shown in Figure 3-5.
Figure 3-5. Boiler Controller VI Front Panel
1 Message Queues type def—Drag All Message Queues.ctl from the Project Explorer window.
2 Error In and Error Out—Place an Error In and Error Out cluster on the front panel.
1 Filter glyphs by keyword, computer, to find an appropriate glyph for the icon.
1 2
1 Format Into String—Wire a message into the format string input of the Format Into String function as shown.
2 Error Cluster From Error Code—Converts a code into an error cluster. Wire a constant 1 to the error code input.
3 Right-click the tunnel and select Use Default If Unwired from the shortcut menu to use the default value for the tunnel data type for all unwired tunnels.
2
3
10. Run the Main VI and verify that the Boiler Controller - Initialize dialog box launches.
11. Click the Do Something and Do Something Else buttons and verify that the Display status string updates appropriately.
12. Click the Stop button and verify that all loops exit successfully.
13. Use a global variable to update the display indicating that the VI has been stopped.
Move a copy of Boiler System Globals.vi from the <Exercises>\LabVIEW Core 3\External\Support VIs to
<Exercises>\LabVIEW Core 3\Course Project\support.
Add Boiler System Globals.vi to the Support VIs virtual folder in the Boiler Controller project.
Update the User Event case of the Event Handling Loop to use the VI Stopped global variable as shown in Figure 3-11.
Figure 3-11. Event Handling Loop User Event Case Using Global Variable
Note By using global variables from which you are only reading in this project, you reduce the number of strings used on the block diagram. This is an
advantage if you need to update a string that is used in multiple places because you need to update it in only one place.
1 2
1 Property Node—Click the Property terminal and select Application»Kind from the menu.
2 Case Structure—Wire the App.Kind terminal to the case selector of the Case structure. Right-click the Case structure and select Add Case for Every Value
from the shortcut menu.
3 Quit LabVIEW—Place a Quit LabVIEW function in the Run Time System case so that the application closes when you run it as an executable.
2. Save Main.vi.
a. Under the Build Specifications folder in the Project Explorer window, right-click Main Application and select Properties from the shortcut menu.
c. Change the Destination Directory to the following: <Exercises>\LabVIEW Core 3\Course Project\builds\Boiler Controller\Main
Application.
a. Right-click the Main Application build specification and select Build from the shortcut menu. LabVIEW creates a new build incorporating the changes
you made.
4. Click the Do Something and Do Something Else buttons and verify that the Display status string updates appropriately.
5. Click the Stop button and verify that the window closes.
Scenario
In the sprint planning meeting for this iteration, the product owner chose to implement two user stories that apply to the interaction of the boiler controller application
with the boiler:
• As a boiler operator, I want to ensure that when I shut down the system, the boiler controller does not suspend execution until the boiler finishes shutting down,
so that the boiler controller is always aware of the current state of the boiler.
• As a boiler operator, I want to test the functionality of the application by running it with code that simulates the behavior of a boiler, so that I can verify correct
operation before I implement the system.
After discussing each user story with the team, you have identified the following development tasks that must be completed to implement these user stories:
1. Obtain the notifiers that will handle handshaking among the Message Handling Loop of Main.vi, Boiler Controller.vi and the boiler to ensure that the
MHL does not turn off until Boiler Controller.vi shuts down, which does not happen until the boiler shuts down.
Design
You will create two VIs to handle obtaining and releasing the notifiers that you will use in this application:
• Create Notifiers.vi—Obtains two notifiers: one for handshaking between the MHL and Boiler Controller.vi and the other for handshaking
between Boiler Controller.vi and Boiler.vi. Bundle these notifiers into a type-defined cluster named Notifiers.ctl.
• Close Notifiers.vi—Releases the two handshaking notifiers to ensure that the memory for those references is deallocated.
A teammate will develop the code to send a command to the boiler and wait for it to be executed.
In Exercise 2-1, you created a project library that contains code that simulates the behavior of the boiler that the application will control. From this library, you add
Boiler.vi as a fourth parallel process for the application.
Figure 3-13. Communication Among Event Handler Loop, Message Handler Loop, Boiler Controller, and Boiler
Start
Open
References
UI Controller Boiler
Event Messages Message Messages Boiler Messages
Handler Loop Handler Loop Controller Boiler
Controller
Exit Notifier
Close
References
End
The integration of Boiler.vi requires the following additional changes to Main.vi:
• Add a message queue for the Boiler Loop. Boiler Controller.vi will use this queue to send instructions to Boiler.vi.
• Read configuration data for the boiler from Boiler Init.ini. To do this, you will create a subVI, Read Configuration Data.vi, that reads boiler
constants from the INI file.
Due to the amount of start up code that must occur before the parallel loops begin, the team decides to create a subVI, Boiler System Open.vi, that will handle
the following functionality:
Implementation
Create Notifiers for Handshaking
Obtain the notifiers that will handle handshaking among the Message Handling Loop of Main.vi, Boiler Controller.vi and the boiler to ensure that the MHL
does not shutdown until Boiler Controller.vi shuts down, which does not happen until the boiler shuts down.
In the Support VIs directory of the Boiler Controller Project Explorer window, create a virtual folder named Notifiers.
Create a new VI in the Notifiers folder and save it as Create Notifiers.vi in <Exercises>\LabVIEW Core 3\Course Project\support\
Notifiers.
Create an icon for the Notifiers type def control as shown in Figure 3-16.
Figure 3-16. Notifiers Type Def Icon
1 Filter glyphs by keyword, notifier, to find an appropriate glyph for the icon.
Move Notifiers.ctl into the Notifiers directory of the Project Explorer window.
2. Complete the front panel of the Create Notifiers VI as shown in Figure 3-17.
3. Create the an icon and connector pane for Create Notifiers.vi as shown in Figure 3-18.
1 Filter glyphs by keywords, create and notifier, to find appropriate glyphs for the icon.
Arrange the Boiler System Open front panel as shown in Figure 3-20.
1 Filter glyphs by keyword, initialize, to find an appropriate glyph for the icon.
6. Call the Boiler System Open VI from the Main VI instead of calling each function separately.
1 Boiler System Open VI—Replace Create User Event - Stop.vi and Create All Message Queues.vi with this VI.
Integrate Boiler.lvlib
This library contains Boiler.vi, the top-level VI responsible for simulating the behavior of the boiler, as well as the subVIs and type definitions required for
Boiler.vi to run. Boiler.vi will serve as a fourth parallel process in the application (Event Handling Loop, Message Handling Loop, Boiler
Controller.vi, and Boiler.vi).
1. Modify All Message Queues.ctl to include a Boiler queue as shown in Figure 3-23.
Add Controller to Boiler.vi to the Boiler Controller project in the Support VIs»Notifiers folder as shown in Figure 3-25.
Figure 3-25. Boiler Controller Project with Controller to Boiler Notifier
4. Add Boiler.lvlib to the project.
Move the contents of the <Exercises>\LabVIEW Core 3\External\Boiler directory to the <Exercises>\LabVIEW Core 3\Course
Project\Boiler directory.
5. Place an instance of Boiler.vi from the Boiler.lvlib on the block diagram of Main.vi and modify Main.vi as shown in Figure 3-27.
2
1
1 Wire the Message Queues, Notifiers, and Error cluster wires as shown.
2 Expand the Merge Errors node to accommodate another input.
Synchronize the Shutdown Operation
This operation is initiated through a button-click and results in stopping all four loops.
1. Modify the Stop Button: Value Change event to enqueue the Initiate Stop message as shown in Figure 3-28.
2. Create the Initiate Stop case of the Message Handling Loop as shown in Figure 3-29.
1 2
1 The Message Handling Loop sends a message to the Boiler Controller VI.
2 The Message Handling Loop waits for Boiler Controller VI to finish executing the message before proceeding.
3. Create the Wait on Boiler Exit case of the Message Handling Loop as shown in Figure 3-30.
Figure 3-30. Message Handling Loop Wait on Boiler Exit Case True
1 Unbundle the Controller Exit notifier and complete the wiring as shown.
4. Modify the Exit case of the Message Handling Loop as shown in Figure 3-31.
1 Delete the Enqueue Message.vi from this case because the Exit message is now being handled in the Wait on Boiler Exit case.
5. Update the Exit case of Boiler Controller.vi
Place a copy of the Notifiers.ctl type def control on the front panel of Boiler Controller.vi as shown in Figure 3-32
Figure 3-32. Boiler Controller Front Panel with Notifiers
6. Modify the Boiler Controller connector pane to include an input for notifiers as shown in Figure 3-33.
Figure 3-33. Boiler Controller Icon and Connector Pane with Notifiers Input
On the block diagram of Main.vi, wire the Notifiers output of Boiler System Open.vi to the Notifiers input of Boiler Controller.vi.
Boiler Controller.vi sends a message to Boiler.vi and waits for Boiler.vi to finish executing that message before proceeding.
Figure 3-34. Boiler Controller VI Exit Case
Release the Handshaking Notifiers when the Application Is Shutting Down
1. Close the notifiers that were allocated in Create Notifiers.vi.
Create a new VI and save it as Close Notifiers.vi in the <Exercises>\LabVIEW Core 3\Course Project\Support\Notifiers directory
and add it to the Support VIs»Notifiers directory of the Boiler Controller project.
Wire the error cluster wire directly through the Error case.
1 Filter glyphs by keyword, notifier, to find an appropriate glyph for the icon. Use the drawing tools to draw an X on the icon.
2. Modify Main.vi to wire Notifiers to Boiler Controller.vi and call Close Notifiers.vi at the end of execution as shown in Figure 3-38.
Run the VI and verify that the Boiler Controller - Initialize dialog box launches.
Click the Do Something and Do Something Else buttons and verify that the Display status string updates appropriately.
a. Right-click the Main Application build specification and select Build from the shortcut menu to build the executable with the changes from this lesson.
Verify that the Boiler Controller - Initialize dialog box launches and the Do Something and Do Something Else buttons update the Display status string
appropriately.
Scenario
In the sprint planning meeting for this iteration, the product owner chose to implement the following user story:
• As a boiler operator, I want to control the boiler start-up process from the user interface and observe the current state of the boiler, so that I can readily identify
if the boiler behaves correctly at each step.
After discussing this user story with the team, you have identified the following development tasks that must be completed:
1. Modify the front panel of Main.vi to include the anticipated controls and indicators.
3. Modify the data cluster type definition for the MHL to store values for each indicator and include references for all controls.
• Modify the Update Display case to update the values of the new indicators.
• Add a case to the MHL for each message from the EHL.
5. Update Boiler Controller VI to add a case for each message from the MHL.
Design
You need to modify the front panel of Main.vi to include the following controls and indicators:
You also need to update the Event Handling Loop and the Message Handling Loop to implement the following functionality.
• When you change the value of a control, it triggers an event in the EHL.
• The EHL case for that value change sends a message to the MHL.
• The MHL case for that message sends a message to the boiler controller.
• Eventually, the boiler controller will send messages to the boiler. For now, use a one-button dialog in the boiler controller case to indicate that the message was
received from the MHL.
Figure 4-1 illustrates the communication between the EHL, MHL, and boiler controller.
Figure 4-1. Communication Between the EHL, MHL, and Boiler Controller
Start
Open
References
UI Controller Boiler
Event Messages Message Messages Boiler Messages
Handler Loop Handler Loop Controller Boiler
Controller
Exit Notifier
Close
References
End
Implementation
1. Open Boiler Controller.lvproj from the <Exercises>\LabVIEW Core 3\Course Project directory.
1 Make sure that the label for these buttons match the labels in Table 4-1. Event cases use the label of Boolean controls, not the Boolean text, to identify a control.
2 Use the Process Stop Button to create the Emergency Stop button.
3 Set the representation for the Fuel Control Valve Slide to U32
4. Modify the Event Handling Loop to handle value change events for the controls and send messages to the Message Handling Loop.
Tip You can right-click the Event structure and select Duplicate Event Case to add new cases similar to cases already in the Event structure.
Figure 4-3. New and Updated Events for the Event Handling Loop
1 2
1 Control terminals—Move the terminals of the controls you created in step 3 into the appropriate event case.
2 Enqueue Message VI—Update the Message input to send the appropriate message for each control.
In Windows Explorer, copy the contents of the <Exercises>\LabVIEW Core 3\External\controls directory into the <Exercises>\LabVIEW
Core 3\Course Project\controls directory.
In the Project Explorer window, right-click the Type Definitions and select Add»File and then navigate to <Exercises>\LabVIEW Core 3\Course
Project\controls and select all the files to add to the project.
6. Modify the Initialize case of the Message Handling Loop as shown in Figure 4-4.
3
7 8
2 5 6 4
8. Modify the Update Display case of MHL to update the values of the new indicators, as shown in Figure 4-5.
2 4
5
1
1 Wire an MHL UI Data control to the Variant To Data function—Right-click the empty string constant and select Replace»Select a VI from the menu. Navigate
to the Course Project\controls directory and select MHL UI Data.ctl.
2 Unbundle By Name—Wire the data output of the Variant To Data function to the Unbundle By Name function. Expand the Unbundle By Name function to display
all six terminals.
3 Bundle By Name—Wire the Data Cluster wire to the input cluster terminal and wire the data output of the Variant To Data function to the MHL User Interface
Data terminal. This code bundles UI data from the Data Cluster wire with the MHL UI Data cluster. Because the boiler controller eventually calls the Update
Display case, this case needs to be able to read the message data and write it to the shift register.
4 Local Variable—Right-click the Fuel Control Valve control in the Fuel Control Valve event of the EHL and select Create»Local Variable from the shortcut menu.
Drag the Fuel Control Valve local variable to the Update Display case and wire it to the Unbundle By Name function.
5 Drag the terminals to the indicators you created in step 3 to the Update Display case and wire them to the Unbundle By Name function.
9. Update the Something case of the MHL Case structure to be the Reset case, as shown in Figure 4-6.
Figure 4-6. Modifying the Something Case to Create the Reset Case
1 Change the name of the Something case—Select the Something case and double-click the title to select it. Change the name of the case to Reset.
2 Delete the MHL Queue wire.
3 Enqueue message to the Boiler Controller—Wire the Controller Queue data to the Message Queue input of the Enqueue Message VI.
4 Change the constant wired to the Message input to Reset Lockout.
10. Duplicate the Reset case to create the Start Sequence, Pilot, Fuel Control Valve, and Shutdown cases as shown in Figures 4-7 through 4-10.
Note Make sure that the Case text matches the string value used in the EHL. Otherwise, the program enters the Default message case and produces an error.
11. Delete the Something Else and the Copy This Frame cases. The MHL Case structure should now have a total of 11 cases.
Figure 4-11. Cases that Handle Each Message from the MHL in Main VI
Note Make sure that the Case text matches the string value used in the MHL of Main VI.
Verify that the Boiler Controller - Initialize dialog box launches on start-up.
Click the Reset, Start, Light Pilot, and Stop Boiler buttons and verify that the boiler controller displays the appropriate dialog boxes.
Change the value of the Fuel Control Valve control verify that the boiler controller displays the appropriate dialog box.
Click the Emergency Stop button and verify that all VIs stop.
Right-click the Main Application build specification and select Build from the shortcut menu. LabVIEW creates a new build incorporating the changes you
made.
Click the Emergency Stop button and verify that all VIs stop and the application exits.
Scenario
After presenting the user interface prototype, the customer representative re-emphasized the desire for documentation in the user interface to improve usability. They
also made several cosmetic suggestions for the user interface. The product owner documented the user interface feedback for implementation in a future sprint
iteration.
As a result of the customer’s feedback, the product owner prioritized implementing the following user story:
• As a boiler operator, I want the system to include sufficient user documentation, so that new users can easily learn to operate the boiler controller.
After discussing this user story with the team, you identify the following development tasks that the team must complete.
Design
Include a detailed overview of the functionality of the application and instructions for how to use the Main VI.
Document each control so that the user understands the results of modifying each control. Document limitations or appropriate values for each control, if appropriate.
Document each indicator so that the user understands the information that the indicator conveys.
Using LabVIEW, generate HTML or RTF documents that include the VI, control, and indicator descriptions. You can manually edit the documents later, if necessary.
Link the VI Properties dialog box to this documentation.
Implementation
1. Modify the VI description for Main.vi to include a detailed overview of the VI functionality.
Delete the current description and enter information about the functionality of the application. Good documentation includes the following information.
– An overview of the VI
– Instructions on how to use the VI, such as how to start the boiler and how to shut down the system in case of emergency.
The boiler controller allows a user to start and shut down a boiler.
Use the Reset, Start, and Light Pilot controls to sequentially start the boiler.
Use the Fuel Control Valve to change the flow of fuel into the boiler.
To shut down the system or in the event of an emergency, use the Emergency Stop button to close the
application completely.
Click the OK button in the VI Properties dialog box when you finish documenting the VI.
2. Enter documentation for the Context Help window for each control and indicator on the Main VI front panel. Make sure the documentation includes functionality
and, if applicable, valid ranges and default values.
Right-click the control or indicator and select Description and Tip from the shortcut menu.
Create a description for each control and indicator. Figure 4-12 shows a few examples of control and indicator documentation.
Tip Refer to the requirements document for information about each control and indicator.
In the Project Explorer window, right-click Queued Message Handler Documentation.html under the Project Documentation folder and select Explore
from the shortcut menu.
Create a new folder, name it Queued Message Handler template and move all the files into the new folder.
Create a new folder, called Boiler Controller, in the <Exercises>\LabVIEW Core 3\Course Project\documentation.
In the Project Explorer window, select Queued Message Handler Documentation.html and the Documentation Images virtual folder and select Remove
from Project.
In the Select Folder to Connect dialog box, select documentation and click the Select Folder button.
Open Main.vi.
Modify the Help path to use a relative path to the file you created in step 5. by entering ..\Course Project\documentation\Boiler
Controller\Main.html in the Help path text box.
Click OK.
7. Rename the documentation virtual folder to Project Documentation to better describe the contents.
Right-click the documentation folder and select Stop Auto-populating. The name of an auto-populating folder must always match the name of the folder
on disk.
Verify that control and indicator descriptions appear in the Context Help window and LabVIEW displays tip strips the user hovers the cursor over controls
and indicators.
Verify that updated VI description appears in the Context Help window when you hover over the VI icon.
Click the Detailed Help link in the Context Help window for one of the controls or indicators and review the documentation from the HTML file.
Right-click the Main Application build specification and select Properties from the shortcut menu.
Click Source Files in the Category list.
Select Project Documentation»Boiler Controller in the Project Files tree and move this folder to the Always Included section, as shown in Figure 4-14.
Including this folder ensures that the HTML file and all images will be included in the build.
Figure 4-14. Including the Boiler Controller Documentation in the Build Specification
Right-click the Main Application build specification and select Build from the shortcut menu.
View the VI documentation by selecting Help»Help for this VI from the menu.
Click the Emergency Stop button and verify that all VIs stop and the application exits.
Scenario
In the sprint planning meeting for this iteration, the product owner chose to implement the following user story:
• As a boiler operator, I want to specify the configuration settings that the boiler controller uses, so that I can reuse the controller for boilers with different
configuration settings.
After discussing this user story with the team, you have decided to read the configuration settings from an INI file. The requirements document indicates that the Fuel
Control Valve should be limited to values between 10 and 75%. Since this may vary from boiler to boiler, those values should be read from a configuration file instead
of written as constants on the block diagram.
Your team identified the following development tasks that must be completed:
• Update MHL Data.ctl to contain the Fuel Control Valve limits that you want to read from the INI file.
• Create the INI file that contains configuration constants for the system.
• Create a VI that allows the user to specify the INI file, reads configuration constants from that file, and passes those values to the rest of the application.
Design
While it is possible to create the INI file manually, your team decides that would be a good idea to create a VI that programmatically creates the INI file. That way,
you can easily add more constants to the file or reuse the code to create INI files for other boilers that require different constant values.
Develop the INI file and the VI that reads it in a manner that allows for future expansion in case you want to scale it to read other constants for the MHL, the boiler
controller, or the boiler. To do this, you create a subVI that reads the boiler constants. If you eventually need to read constants for the other loops, you can create
separate subVIs to read the constants for each of those loops.
Implementation
1. Add configuration files to the project.
In Windows Explorer, copy the Configuration directory located in the <Exercises>\LabVIEW Core 3\External\Support VI directory and
paste it into the <Exercises>\LabVIEW Core 3\Course Project\support directory.
Create a virtual folder called Configuration in the Support VIs folder of the Boiler Controller project. Add only Write Configuration Settings
File.vi to the virtual folder.
Open the Write Configuration Settings File VI and verify the MHL default values are set to the values shown in Figure 4-15.
Figure 4-15. Write Configuration Settings File VI Front Panel
Run the Write Configuration Settings File VI and save the file as Boiler Init.ini in the <Exercises>\LabVIEW Core 3\Course Project
directory.
– Right-click My Computer in the Project Explorer window and select Add»File from the shortcut menu.
– Navigate to Boiler Init.ini and click the Add File button to add the file to the project.
3. Create a VI that allows the user to specify the INI file, read configuration constants from that file, and pass those values to the rest of the application.
Add a new VI to the project under the Support VIs»Configuration virtual folder and save the VI as Read UI Constants.vi.
Create the front panel and block diagram of the Read UI Constants VI as shown in Figures 4-16 through 4-19.
Figure 4-16. Read UI Constants VI Front Panel
1 Error In and Error Out—Place an Error In and Error Out control and indicator on the front panel. After you complete the block diagram, the front panel will contain
more items.
4
7
3
9
1 8
1 Case Structure—Place a Case structure on the diagram and wire the error in cluster to the case selector.
2 Read Key—This VI reads a value from the key in a MHL section of the configuration data. Select Double from the polymorphic selector.
3 Boiler System Globals variable—Drag Boiler System Globals.vi from the Project Explorer window and select MHL from the list. Right-click the global
variable and select Change To Read from the shortcut menu. Wire this global variable to the section input of each of the Read Key VIs.
4 Refnum—Right-click the refnum input of the Read Key VI and select Create»Control. Rename the refnum CFG File Refnum in and move the refnum outside
the Case structure. Re-wire the refnum if necessary.
5 Boiler System Globals variable—Change the global variables to read and select Fuel Control Valve Minimum and Fuel Control Valve Maximum from the
list. Wire these variables to the key input of the Read Key VI.
6 Refnum—Right-click the refnum out output of the Read Key VI and select Create»Indicator. Rename the refnum CFG File Refnum out and move the
refnum outside the Case structure. Re-wire the refnum if necessary.
7 MHL Configuration constant—Drag MHL Configuration.ctl from the Type Definitions folder in the Project Explorer window.
8 Bundle By Name—Wire the MHL Configuration constant to the input cluster input of the Bundle By Name function. Expand the function to display two terminals.
Wire the value output of each of the Read Key VIs to the Bundle By Name function.
9 MHL Configuration indicator—Right-click the output cluster output of the Bundle by Name function and select Create»Indicator. Rename the indicator MHL
Configuration and move it outside the Case structure. Wire the Bundle by Name function to the indicator.
Figure 4-18. Read UI Constants VI Block Diagram Error Case
1 MHL Configuration constant—Right-click the tunnel and select Create»Constant to create this constant.
1 Filter glyphs by keywords, file, get, and control to find appropriate glyphs for the icon.
Add a new VI to the project under the Support VIs»Configuration virtual folder and save the VI as Read Configuration Data.vi in the
<Exercises>\LabVIEW Core 3\Course Project\support\Configuration directory.
Create the front panel and block diagram of the Read Configuration Data VI as shown in Figures 4-20 through 4-23. The Read Configuration Data VI reads
the MHL configuration constants from the INI file and passes those values to the MHL.
1 Error In and Error Out—Place an Error In and Error Out control and indicator on the front panel. After you complete the block diagram, the front panel will contain
more items.
Figure 4-21. Read Configuration Data VI Block Diagram No Error Case
6 4 7
1 Case Structure—Place a Case structure on the diagram and wire the error in cluster to the case selector.
2 File Dialog—In the Configure File Dialog dialog box, place a checkmark in the Limit selection to single item checkbox and select the File and New or
existing radio buttons. View the Express VI as an icon to save room on the block diagram.
3 String constant—Create a constant for the pattern (all files) input of the File Dialog Express VI and enter *.ini.
4 Boiler System Globals variable—Drag Boiler System Globals.vi from the Project Explorer window and select Enter Filename from the list. Right-click the
global variable and select Change To Read from the shortcut menu. Wire this global variable to the prompt input of the File Dialog Express VI.
5 Boiler System Globals variable—Change the global variable to read and select Configuration Files from the list. Wire it to the pattern label input of the File
Dialog Express VI.
6 Application Directory—Wire to the start path input of the File Dialog Express VI. Application Directory returns the path to the directory containing the
application.
7 Read UI Constants—Drag this VI from the Support VIs»Configuration folder in Project Explorer window to the block diagram. You created this VI in step 3.
8 MHL Configuration indicator—Right-click the MHL Configuration output of the Read UI Constants VI and select Create»Indicator. Move the indicator outside
of the Case structure and wire Read UI Constants VI to the indicator.
Figure 4-22. Create Read Configuration Data VI Block Diagram Error Case
1 MHL Configuration constant—Right-click the tunnel and select Create»Constant to create this constant.
Figure 4-23. Read Configuration Data VI Connector Pane
1 Filter glyphs by keywords, new, and file to find appropriate glyphs for the icon.
Open Support VIs»Boiler System Open.vi from the Project Explorer window.
1 Read Configuration Data—Drag Read Configuration Data.vi from the Project Explorer window.
2 MHL Configuration indicator—Right-click the MHL Configuration output of the Read Configuration Data VI and select Create»Indicator.
5. Add a VI to initialize the user interface, set the range for the Fuel Control Valve, and build the MHL Data cluster to the project.
Navigate to <Exercises>\LabVIEW Core 3\External\Support VIs and copy Initialize Panel.vi to <Exercises>\
LabVIEW Core 3\Course Project\support.
Add Initialize Panel.vi to the Support VIs virtual folder in the Boiler Controller Project Explorer window.
6. Update the Main VI to read the configuration data and pass the data to the Initialize case of the MHL.
Wire the MHL Configuration output from the Boiler System Open VI to the MHL as shown in Figure 4-26.
Figure 4-26. Wiring the MHL Configuration Data to the MHL
Update the Initialize case of the MHL as shown in Figure 4-27.
Figure 4-27. Updated Initialize Case of the Main MHL
1 Initialize Panel—Drag the Initialize panel VI from the Project Explorer window. Wire the Initialize Panel VI as shown.
Verify previous functionality still works, such as the display of one-button dialog boxes when you click the Reset, Start, or Light Pilot buttons.
– The range of the Fuel Control Valve horizontal slider control is limited to values between 10 and 75.
Right-click the Main Application build specification and select Properties from the shortcut menu.
Select Boiler Init.ini in the Project Files tree and move this file to the Always Included section.
Right-click the Main Application build specification and select Build from the shortcut menu.
Note The starting directory to browse to the INI file has changed. The build now creates the Boiler Controller.ini. This file is NOT the INI file
that you created. Boiler Init.ini is inside the data folder.
Click the Emergency Stop button and verify that all VIs stop and the application exits.
Scenario
The product owner is finally ready to implement the user interface feedback that the customer representative provided after viewing the user interface prototype.
• The Fuel Control Valve control is not very intuitive. Either customize its appearance or replace it with a different type of numeric control.
• Create a custom run-time menu to stop the application or load the Help file.
Implementation
1. Update the Boiler VI so that it launches as a separate window.
Select File»VI Properties from the menu and select Window Appearance from the Category pull-down menu.
Uncheck the Same as VI name checkbox and enter Boiler in the Window title field.
Click the Customize button and update the Customize Window Appearance dialog box as shown in Figure 4-28.
Figure 4-28. Customize Window Appearance Dialog Box for Boiler VI
1 Note that the front panel displays when the Boiler VI is called and closes when the Boiler VI finishes executing.
2 The user does not have the ability to minimize or resize the Boiler VI window.
3 Select Default as the Window Behavior and remove the checkmark from the Allow user to close window checkbox.
Click OK to accept changes in the Customize Window Appearance and VI Properties dialog boxes.
2. Customize the run-time window appearance of Main VI so that it looks less like a LabVIEW dialog box.
Select File»VI Properties from the menu and select Window Appearance from the Category pull-down menu.
Uncheck the Same as VI name check box and enter Boiler Controller in the Window title field.
Run the Main VI to view the changes to the UI when executing as a top-level application window.
3. Create a custom run-time menu to stop the application and load the Help file.
In the Menu Editor dialog box, select Custom from the pull-down menu.
Select File»Save and save the custom menu as Main.rtm in the <Exercises>\LabVIEW Core 3\Course Project directory.
Close the menu editor.
Click Yes when prompted to change the run-time menu.
4. Modify the EHL to include an event case for menu selection.
In the EHL, right-click the Emergency Stop: Value Change event and select Duplicate Event Case from the shortcut menu.
Add a new event to the EHL Event structure as shown in Figure 4-30.
Figure 4-30. Menu Selection Event for the EHL
Right-click the Main Application build specification and select Build from the shortcut menu.
Verify that selecting File»Emergency Stop from the menu or pressing <Ctrl-Q> halt the application and close both windows.
Challenge
1. Reorganize the UI to more logically group controls as shown in Figure 4-33.
1
4
1 Group these controls together because you only use them after the boiler is running.
2 Center-align the text for each Boolean button.
3 Right-justify all indicators.
4 Emergency Stop in the bottom-right fits the general expectation for the Stop buttons to be in the bottom-right corner of the window.
Scenario
In the sprint planning meeting for this iteration, the product owner chose to implement the following user stories:
• As a boiler operator, I want the boiler controller to prevent the boiler from entering an unsafe state as a result of a critical error.
• As a boiler operator, I want the system to be robust enough that minor errors do not result in system shut down, so that the boiler only shuts down if the error
prevents safe operation.
Critical errors require shutting down the application because they cannot be otherwise managed. If they are not handled, critical errors may result in injury to personnel
or damage to equipment. They may also place the system into an unmanageable state.
Non-critical errors are more akin to inconveniences that should not prevent continued execution of the application.
After discussing these user stories with the team, you identified and classified the following errors:
Cancelling the Open File dialog when loading the INI file Non-critical
1. Modify Read Configuration Data.vi to handle cancellation of the Open File dialog.
3. Modify the Default case of the Message Handling Loop and Boiler Controller to handle typos when sending messages.
4. Modify the Message Handling Loop and Boiler Controller Loop to handle shutting down in the event of a critical error.
Design
The team decides on the following strategies for approaching each task:
1. Modify Read Configuration Data.vi to handle cancellation of the Open File dialog.
• Modify Read Configuration Data.vi to load a default INI file if the user cancels the Open File dialog.
• Modify Read UI Constants.vi to check that each key was properly read from the INI file.
• Use an error ring to generate a custom error to indicate that the INI file is not valid.
3. Modify the Default case of the Message Handling Loop and Boiler Controller to handle typos when sending messages.
• Use an error ring to generate a custom error to indicate that an invalid message was received by that loop.
4. Modify the Message Handling Loop and Boiler Controller Loop to handle shutting down in the event of a critical error.
• Create a separate Error case in the Message Handling Loop and Boiler Controller Loop.
• Modify Dequeue Message.vi to send you to the Error case instead of the Exit case in the event of an error.
• Critical errors should be passed as message data from the bottom up (Boiler»Boiler Controller»Message Handling Loop)
• The Error case of the Message Handling Loop sends you to the Initiate Stop case, as if you clicked Emergency Stop.
Figure 5-1. Errors Passed up to the Message Handling Loop, which then Stops All Loops
Critical
Error
Boiler “Error”
Boiler Controller
“Error”
MHL “Error”
MHL
“Initiate Stop”
Boiler MHL
Controller “Exit” “Wait on Boiler Exit”
No
Implementation
Non-Critical Errors
1. Modify Read Configuration Data.vi to handle cancellation of the Open File dialog.
Run Main.vi. Cancel the Open File dialog where you would normally select the INI file. Notice that the File Dialog express VI generates Error 43 to indicate
that the operation was cancelled. This error causes the application to exit. This is not a desirable behavior.
Modify Read Configuration Data.vi to load a default INI file if the user cancels the Open File dialog as shown in Figure 5-2.
Figure 5-2. Read Configuration Data VI Block Diagram Load Default INI File
3 1
Run Main.vi and cancel the Open File dialog. Notice that the code continues executing normally, using the default file.
Critical Errors
1. Modify Read UI Constants to handle selection of an invalid INI file.
Run Main.vi. Select any file other than the INI file that you created. Notice that the range of Fuel Control Valve updated to 0-1 instead of 10-75. This did
not generate an error, but the application cannot function without proper configuration of the Fuel Control Valve limits.
Modify Read UI Constants.vi as shown in Figure 5-3 to check that each key was properly read from the INI file.
Figure 5-3. Read UI Constants Using Error Ring
1 Error Ring—Generate a custom error to indicate that the INI file is not valid. This error shuts down the system.
Configure the Error ring with custom error code 5000 and the message Could not read UI constants from INI file.
2. Modify the Default case of the Message Handling Loop and Boiler Controller to handle typos when sending messages.
Modify the Reset event case of the Event Handling Loop to send the incorrect message, Resets, to the Message Handling Loop.
Figure 5-4. Event Handling Loop Reset: Value Change Case with Typo
Open the Default case of the Message Handling Loop. Notice that the code is already generating an error. Replace the Format into String and Error Cluster
From Error Code functions with an error ring, as shown in Figure 5-5. This method of generating an error allows greater flexibility in how you generate the
error.
Figure 5-5. Message Handling Loop Default Case with Error Ring
1 Error Ring—Configure the error ring with Custom Error Code 5003 and the message The invalid message string “%s” was received in the
Message Handling Loop.
3. Modify the Default case of the Boiler Controller.vi as shown in Figure 5-6.
1 Error ring—Configure the error ring with custom error code 5004 and the message The invalid message string “%s” was received in the
Boiler Controller Loop.
Run Main.vi. Click Reset. Notice that the application hangs because Dequeue Message.vi sends the Message Handling Loop directly into the Exit
case which causes the Message Handling Loop and Event Handling Loop stop, but no message is sent to the boiler controller to stop it and the boiler.
To halt the application, select the Boiler window and press <Ctrl -.>.
4. Modify the Message Handling Loop and Boiler Controller Loop to handle shutting down in the event of a critical error.
Create an Error case in the Message Handling Loop and Boiler Controller Loop.
Figure 5-7. Message Handling Loop Error Case
Figure 5-8. Boiler Controller Loop Error Case
5. Modify Dequeue Message.vi, as shown in Figure 5-9 to send you to the Error case instead of the Exit case in the event of an error.
Note You must close all open VIs and modify Dequeue Message.vi from the LabVIEW project. This VI is reentrant, so you must ensure that there is
only one copy in memory before you can edit it.
1 Update the comment to say that the output is an Error message instead of an Exit message
2 Update the Message to Stop the Handler to Error.
3 Error cluster constant
Critical errors should be passed as message data from the bottom up—Boiler»Boiler Controller»Message Handling Loop.
Note Boiler Controller Error sends a message to the Message Handling Loop Error. Errors in the boiler are passed up to the Boiler Controller in the
same way.
The Error cases should not wire the error cluster into the Enqueue Message. For the Boiler Controller, wire an error cluster constant to the shift register for
each loop to avoid an endless error cycle. (The desired effect for the error will happen by launching the shutdown process.)
The Error case of the Message Handling Loop sends you to the Initiate Stop case, as if you clicked Emergency Stop.
Verify that:
– Cancelling the Open File dialog does not stop the application.
– Cancelling the Open File dialog fails because the relative path to the default INI file is different for the EXE—in the data folder, instead of at the same
level.
3. Modify Read Configuration Data.vi, as shown in Figure 5-10, to use a different relative path for EXEs.
Update the Reset case of the Event Handling Loop to call Reset instead of Resets.
Scenario
In the sprint planning meeting for this iteration, the product owner chose to implement the following user story:
• As a boiler operator, I want information about critical errors to be logged to disk, so that I can identify and troubleshoot the cause of the error at a later date.
As it is currently implemented, critical errors cause the application to shut down without providing any additional information to the end-user.
To implement this user story, your team identifies the following tasks:
1. Create the error log file in the same directory as the main application.
2. When a critical error occurs, log the error code and source.
3. If you cannot write to the application directory, display the error information to the user.
4. After logging the error, close the error log file reference.
Design
The team decides on the following strategies for approaching each task:
1. Create the error log file in the same directory as the main application.
• The error log should only be created if a critical error actually occurs.
• Create the error file in the Error case of the Message Handling Loop.
2. When a critical error occurs, log the current time, error code and source.
• Pass the error cluster as Message Data when you send the Error message.
• Extract the error code and source from the error cluster.
• Create a subVI that writes the time, error code, and source to the error log file.
3. If you cannot write to the application directory, display the error information to the user.
• If the error log reference is invalid, then you cannot write to the file.
• Instead, launch a one-button dialog and display the information to the user.
4. After logging the error, close the error log file reference.
Implementation
1. Add a VI to write the time, error code, and source to the error log file.
Create a virtual folder called Logging in Support VIs folder the Boiler Controller Project Explorer window.
Navigate to <Exercises>\LabVIEW Core 3\External\Support VIs\Logging and copy Log Error.vi into the <Exercises>\
LabVIEW Core 3\Course Project\support\Logging directory.
Add Log Error.vi to the Logging virtual folder of the Boiler Controller Project Explorer window.
2. If you cannot write to the application directory, display the error information to the user.
Modify the error file in the Error case of the Message Handling Loop as shown in Figure 5-11.
Figure 5-11. Message Handling Loop Error Case
1 Create the error log file in the same directory as the main application.
2 After logging the error, close the error log file reference
3. When a critical error occurs, log the current time, error code and source.
Modify the Error case of Boiler Controller.vi, as shown in Figure 5-12. You use the custom errors 5001 and 5002 in future exercises.
Figure 5-12. Boiler Controller Error Case
1 Pass the error cluster as Message Data when you send the Error message.
Test the Application
1. Test the VI.
Run the VI. Verify the following:
– Specifying an invalid INI file stops the application and creates Error Log.txt.
– Error Log.txt contains time, error code, and error source information similar to Figure 5-13.
Modify the Reset event case of the Event Handling Loop to send a Resets message to the Message Handling Loop.
– Run the VI again.
– Clicking Reset halts the application with a critical error.
– Open Error Log.txt and view the new entry to the file.
– Close the file.
– Fix the Reset case to send a Reset message.
Verify the behavior when the application cannot write to the log file.
– Set Error Log.txt to read-only.
– Run the VI.
– Specify an invalid INI file. A dialog appears indicating the time, error code, and source.
– Set Error Log.txt to be writable.
2. Test the build specification.
Scenario
In the sprint planning meeting for this iteration, the product owner chose to implement the following user stories:
• As a boiler operator, I want the boiler controller to write status information when the boiler transitions between operating states, so that I can review the state
information at a later date if an error occurs.
• As a boiler operator, I want to click a button to reset the boiler to a known good state, so that the run interlock (safety control) on the boiler indicates that conditions
have been satisfied for the boiler to run safely.
• As a boiler operator, I want the user interface to let me modify only the controls that I am allowed to use at that stage of boiler operation so that I do not accidentally
execute any start-up steps out of sequence.
To implement these user stories, the team identifies the following tasks:
1. Create a code module, Create Status Log Header.vi, to write header information for the status log.
3. Develop code to test the functionality of Create Status Log Header.vi and Log Status.vi.
5. Implement functionality for the Reset button. Create a log entry when this operation completes.
6. Disable any controls that are not valid for the current state of the boiler.
Design
The team decides on the following strategies for approaching each task:
1. Create a code module, Create Status Log Header VI, to write header information for the status log. The Create Status Log Header VI must do the following:
• Write header information to the status log if the log file is empty. Otherwise, the VI passes the refnum through.
2. Create a code module, Log Status VI, to log status information to disk. The Log Status VI must format the data into a string and write that string to Status
Log.txt.
3. Develop code to verify the functionality of the Create Status Log Header VI and the Log Status VI by creating a VI that opens a file reference, calls the Create
Status Log Header VI, calls the Log Status VI, and then exits.
4. Create a log entry when the Boiler Controller VI completes initialization. The Initialize case of the Boiler Controller VI MHL must include the Create Status Log
Header VI and the Log Status VI.
5. Implement functionality for the Reset button to ensure that the boiler is in a safe state prior to starting it. To implement this functionality, the Boiler Controller
VI must do the following:
• Send a message to the MHL to update the status of the boiler controller.
6. Disable any controls that are not valid for the current state of the boiler by modifying the Update Display case of the MHL to include code that enables and disables
controls based on the current state of the system.
Figure 6-1. Implementing the Status Log and Reset Functionality
EHL
“Reset”
MHL
“Reset”
MHL
Status Log.txt
“Update Display”
Done
Implementation
Use Code Modules to Write Header Information to the Status Log and Log Status Information to Disk
1. In Windows Explorer, copy Create Status Log Header.vi and Log Status.vi from the <Exercises>\LabVIEW Core 3\External\
Support VIs\Logging directory and paste them into the <Exercises>\Course Project\support\Logging directory.
2. Add Create Status Log Header.vi, and Log Status.vi to the Logging virtual folder in the Boiler Controller Project Explorer window.
2. In the virtual folder, create a new VI and save the VI to <Exercises>\LabVIEW Core 3\Course Project\Test VIs\Test - Log Status.vi.
3. Create the Test - Log Status VI front panel and connector pane as shown in Figure 6-2.
Figure 6-2. Test - Log Status VI Front Panel and Connector Pane
1 String control—After entering values in the controls, select Edit»Make Current Values Default from the LabVIEW menu.
2 Filter glyphs by keywords, test and file, to find appropriate glyphs for the icon.
4. Create the Test - Log Status VI block diagram as shown in Figure 6-3.
3 4
5
5. Run the Test - Log Status VI and verify that the code modules work properly.
Navigate to the Status Log.txt that the Test - Log Status VI created.
Figure 6-4. Adding Logging to the Initialize Case of the Boiler Controller VI
2 1 3 5
1 2
1 Not A Number/Path/Refnum?—Makes sure the log file refnum is valid. The file refnum would be invalid only if the log file could not be created or opened.
2 Close File—Closes Status Log.txt.
3 Right-click the tunnel and select Linked Input Tunnel»Create & Wire Unwired Cases from the shortcut menu.
1 Unbundle By Name—Unbundle the MHL User Interface Data from the MHL Data wire.
2. Save Main VI.
3. Open the Boiler Controller VI and place an MHL UI Data constant between the While Loop and the Case structure as shown in Figure 6-7.
1 MHL UI Data constant—Drag MHL UI Data.ctl from the Project Explorer window.
4. Update the Reset Lockout case of the Boiler Controller VI as shown in Figure 6-8.
3 5
1 2 4 6
1 Variant to Data—Converts variant data from the Dequeue Message VI to a MHL UI Data type.
2 Controller to Boiler—Drag Controller to Boiler.vi from the Support VIs»Notifiers folder in the Project Explorer window. This VI sends a message to the
boiler to initiate the run interlock process.
3 Bundle By Name—Updates the MHL UI Data.
4 Boiler System Globals—Drag from the Project Explorer window and select the appropriate string. Right-click the global and select Change To Read.
5 Enqueue Message—Sends a message to the MHL to update the status of the boiler controller.
6 Log Status—Create a log entry when the reset lockout operation is complete.
Disable Controls Depending on the Current State of the Boiler
1. Add files that your teammates developed to the project. Your teammates developed the following two files:
• Set Enable State on Multiple Controls.vi—The VI enables and disables controls using an array of references to those controls.
• MHL Status.ctl—This enum is necessary to make decisions based on the current state of the boiler.
Copy Set Enable State on Multiple Controls.vi from <Exercises>\LabVIEW Core 3\External\Support VIs to
<Exercises>\LabVIEW Core 3\Course Project\support.
Add Set Enable State on Multiple Controls.vi to the Support VIs folder in the Project Explorer.
2. Open and modify the Initialize Panel VI to set the initial state of the boiler and disable all controls by default, as shown in Figure 6-9.
1 Expand the Bundle By Name function to display the MHL Status terminal. Right-click the terminal select Create»Constant from the shortcut menu. The MHL
Status sets the initial state of the boiler.
2 Build Array—Builds an array of all the UI control references from the Unbundle By Name function.
3 Set Enable State on Multiple Controls—Drag this VI from the Project Explorer window. Wire a False constant to the Enable? input to disable all controls.
1 Right-click the MHL Status terminal and select Create»Constant from the shortcut menu.
Copy Update Controls.vi from <Exercises>\LabVIEW Core 3\External\Support VIs to <Exercises>\LabVIEW Core 3\
Course Project\support.
Add Update Controls.vi to the Support VIs folder in the Project Explorer window, as shown in Figure 6-11.
Figure 6-11. Adding Update Controls VI to the Project
8. Modify the Update Display case of the MHL, as shown in Figure 6-12, to include code that enables and disables controls based on the current state of the system.
Figure 6-12. Enabling and Disabling Controls in the Update Display Case
1 2 3
1 Unbundle By Name—Right-click and choose Select Item»MHL References»All Elements from the menu.
2 Expand the Unbundle By Name function to display the MHL Status terminal.
3 Update Controls—Wire the MHL Status terminal to the Update Controls VI.
– All controls except for Reset and Emergency Stop are disabled.
– The Run Interlock indicator on the Boiler VI front panel is illuminated. The indicator illuminates because the Controller to Boiler VI sent a Run
Interlock message to the Boiler VI.
Click the Start button. The Boiler Controller - Pre-Purge dialog box still appears because you have not implemented any other functionality yet.
Open Status Log.txt and verify that the file contains two entries: Boiler Initialized and Boiler Ready.
Scenario
In the sprint planning meeting for this iteration, the product owner chose to implement the following user story:
• As a boiler operator, I want to click a button to execute the pre-purge process, which runs the primary fan for a pre-set period of time to purge gases from the
combustion chamber prior to lighting the pilot, so that the system does not explode.
To implement this user story, the team identifies the following tasks:
3. Integrate and test each code module with the Boiler Controller system.
Design
The team decides on the following strategies for approaching each task:
• Several of your teammates will work with an expert on this type of boiler to implement code modules to handle the bulk of the communication between the
boiler controller and the boiler.
• They will provide you with a project library that contains all of the code modules that you will need to test and integrate with the boiler controller.
• The team has decided to use top-down integration testing to identify any control or communication issues that may occur early on.
• Your role will be to create stub code that you will replace as you test and integrate the code modules.
EHL
“Start”
MHL
“Start Sequence”
Boiler Controller
“Pre-Purge”
Boiler MHL
Pre-Purge
“Primary Fan” ON “Update Display”
Status Log.txt
Wait
Status Log.txt
Done
Implementation
Create Code Modules to Execute the State Functionality
1. Your teammate provides you with a project library, Controller.lvlib.
Move this library and its files from <Exercises>\LabVIEW Core 3\External\Controller to <Exercises>\LabVIEW Core 3\
Course Project\Controller.
2. Add the project library to the top level of the Boiler Controller project.
4. Remove the empty Boiler Controller virtual folder from the project.
Integrate and Test Each Code Module with the Boiler Controller System
1. Modify the Start Sequence case of the MHL in Main.vi as shown in Figure 6-14.
1 Pass the MHL User Interface Data as the message data for the Pre-Purge message.
2. Create stub code for the Pre-Purge case of Boiler Controller.vi, as shown in Figure 6-15, to test the functionality.
1 Flat Sequence Structure—Add a three-frame sequence structure to the Pre-Purge case of the Boiler Controller VI.
Right-click the edge of the sequence structure and select Add Frame After to add a frame.
2 One Button Dialog function—Add a One Button Dialog function to each frame and wire the messages as shown.
Note The sequence structure frames are placeholders until you are ready to integrate each module. You delete these frames as you integrate each code
module into Boiler Controller.vi.
3. Run Main.vi.
Click the Start button. Each of the three dialog boxes launch in order. This shows that the top-level code is reaching the stub code that you created.
– Click OK.
– Click OK.
Open Status Log.txt and notice the new Start Pre-Purge entry.
6. Add the Controller Configuration type def to the Boiler Controller front panel as shown in Figure 6-17.
7. Modify the connector pane to include the Controller Configuration as shown in Figure 6-18.
3
1
1 Purge Time—Extract Purge Time from the Controller Configuration and wire it to the Wait VI.
2 Wait VI—This VI uses the Purge Time to determine how long to wait.
3 Wire unwired cases—Right-click the tunnel and select Linked Input Tunnel»Create & Wire Unwired Cases. Select the Controller Data tunnel on the left side
of the Case structure as the linked tunnel.
Verify the default values for the Write Configuration Settings File VI, as shown in Figure 6-20.
Figure 6-20. Write Configuration Settings File Default Values
Run the Write Configuration Settings File VI to overwrite Boiler Init.ini with the values you specified.
10. Modify Read Configuration Data.vi to read the Purge Time from the INI file.
Add Read Boiler Controller Constants.vi and Configuration Data.ctl to the Support VIs»Configuration folder in the Project
Explorer window.
Open Read Configuration Data.vi and modify it to call Read Boiler Controller Constants.vi, as shown in Figure 6-21.
Figure 6-21. Read Configuration Data VI Calling Read Boiler Controller Constants VI
1 Delete the MHL Configuration indicator on the front panel and replace it with the Configuration Data type def control and complete the block diagram as shown.
Modify the Read Configuration Data.vi connections to assign the Configuration Data indicator as shown in Figure 6-22.
Figure 6-22. Read Configuration Data VI Connections with Configuration Data
Modify Boiler System Open.vi to use the new output of Read Boiler Controller Constants.vi, as shown in Figure 6-23.
Figure 6-23. Boiler System Open VI
1 Replace the MHL Configuration type def on the front panel with the Configuration Data type def and complete the wiring as shown.
Modify the Boiler System Open.vi connections to assign the Configuration Data indicator as shown in Figure 6-24.
Figure 6-24. Boiler System Open VI Connections with Configuration Data Indicator
Modify Main.vi, as shown in Figure 6-25.
Figure 6-25. Main VI with MHL Configuration and Controller Configuration Passed to their Respective Loops
1 Unbundle MHL Configuration and Controller Configuration and pass them to their respective loops.
Run Main.vi.
When you click start, after the 2-second delay, the Primary Fan turns off and the Status displays Pre-Purge Complete.
Verify the behavior that you tested as you integrated each module.
Scenario
In the sprint planning meeting for this iteration, the product owner chose to implement the following user story:
• As a boiler operator, I want to click a button to start the flow of gas, ignite the pilot, prove the pilot flame, and start the boiler so that these steps always occur in
the proper order to ensure safe operation.
To implement this user story, the team identifies the following tasks:
2. Integrate and test each code module with the Boiler Controller system.
Design
The team decides to use bottom-up integration testing to test and integrate the code modules for the Light Pilot functionality. This method of testing allows you to
identify any module functional problems earlier in the test/integration process. However, it will take a bit longer to find out if the top-level application control methods
are appropriate for these modules.
The team decides on the following strategies for approaching each task:
• Boiler Controller.lvlib includes the modules that you will need to test for this functionality (Ignition.vi, Prove Pilot.vi, and Start
Boiler.vi).
• Teammates will develop test harnesses for Prove Pilot.vi and Start Boiler.vi.
• Test each module prior to integrating it with the rest of the system.
• Since all three pieces have been tested individually, it is now time to test how the interact with each other.
• You will integrate all three modules into the Ignition case of Boiler Controller.vi.
EHL
“Light Pilot”
MHL
“Pilot”
Boiler Controller
“Ignition”
Ignition
Boiler MHL
“Pilot” ON “Update Display”
Status Log.txt
Boiler “Set
Flame Level”
Status Log.txt
Status Log.txt
Done
Implementation
Create Code to Test Each Module
1. Move Test Harness.vit from <Exercises>\LabVIEW Core 3\External\Test VIs to <Exercises>\LabVIEW Core 3 Course
Project\Test VIs. Add it to the Test VIs virtual folder in the Project Explorer window of the Boiler Controller.
Note By opening the VI template file in Windows Explorer, LabVIEW forces you to save the template after you open it. Opening from the project, does
not force you to save. However, the file must be part of the project or the linking does not work.
– Save this VI as Test - Ignition.vi in the <Exercises>\LabVIEW Core 3\Course Project\Controller\Controller Tests
directory.
– Create a Test VIs virtual folder in the Controller.lvlib and add Test - Ignition.vi to this folder.
1 UI Data in control
Create a copy of the MHL Data indicator.
Right-click the copy and select Change to Control.
Rename the control.
5
4
Open Boiler.vi.
Note You must open Boiler.vi first, because that VI is configured to show its front panel when it runs and to close when it is finished and for this test,
you want to observe changes to the Boiler.vi front panel.
– The Pilot Gas Valve and Pilot LEDs turn on for both the Test - Ignition VI and Boiler VI.
– Save this VI as Test - Prove Pilot.vi in the <Exercises>\LabVIEW Core 3\Course Project\Controller\Controller Tests
directory.
– Modify the Test - Prove Pilot.vi as shown in Figure 6-30 and Figure 6-31
1 Numeric Control—Create the Flame Threshold control and set the representation to U32.
Figure 6-31. Test - Prove Pilot VI Block Diagram
2 3 4 5
Open Boiler.vi.
Observe the Pilot Flame Level on the Boiler.vi front panel increment from 0 to 50 in five seconds.
– Save this VI as Test - Start Boiler.vi in the <Exercises>\LabVIEW Core 3\Course Project\Controller\Controller Tests
directory.
Add the Test - Start Boiler.vi to the Test VIs virtual folder in Controller.lvlib.
Modify the VI as shown in Figure 6-32.
Figure 6-32. Test - Start Boiler VI Block Diagram
1
2 3
1 Create the UI Data in control similar to the one you created for the Test - Ignition.vi.
2 Expand the Unbundle by Name and select Handshake
3 Start Boiler VI
4 Create the Boiler Running case as shown and change the Boolean constant in the Default case to False.
Open Boiler.vi.
– The Fuel Control Valve indicator on the Test - Start Boiler VI and the Fuel Level (%) indicator on the Boiler VI both indicate a value of 10.
– The Forced Draft Fan LED turns on for both the test VI and Boiler.vi.
1. Open Boiler Controller.vi and modify the Ignition case, as shown in Figure 6-33.
2. Modify Read Configuration Data.vi to call Read Boiler Constants.vi as shown in Figure 6-34.
1 Add Read Boiler Constants.vi from the <Exercises>\LabVIEW Core 3\Course Project\Support\Configuration directory to the
Support VIs»Configuration directory in the Project Explorer window.
Modify Main.vi, as shown in Figure 6-35 to extract Boiler Configuration and pass it to Boiler.vi.
Figure 6-35. Main VI Passing Boiler Configuration to Boiler VI
3. Modify the Pilot case of the Message Handling Loop in Main.vi to pass MHL User Interface Data as the message data for the Ignition message to the Boiler
Controller as shown in Figure 6-36.
Figure 6-36. Main VI Pilot Case Passing MHL User Interface Data
Run the VI. Verify that all previously-implemented functionality still works.
– Status = Pilot On
– Pilot Gas Valve and Pilot LEDs turn on for both the test Main.vi and Boiler.vi.
When the Pilot Flame Level reaches 30%, observe the following changes.
– Fuel Control Valve on Main.vi and Fuel Level (%) on Boiler.vi both = 10.
– Forced Draft Fan LED turns on for both Main.vi and Boiler.vi.
– Pilot On
– Pilot Proved
Scenario
The product owner gathered feedback from the customer representative and a boiler expert after the previous sprint. The boiler expert pointed out that when the boiler
enters the Boiler Running state, the pilot fuel valve should be closed, turning off the pilot light. The customer pointed out that the Simulate Failure button should be
enabled and monitored once the boiler is running and there should be a status log entry when the boiler starts running. This entry should record the fuel control valve
level when the boiler starts running.
In the sprint planning meeting for this iteration, the product owner chose to implement the above feedback and the following user story:
• As a boiler operator, I want to adjust the rate at which fuel enters the boiler furnace, so that I can adjust the temperature of the boiler and the fuel level is always
within safe levels.
To implement the user feedback and this user story, the team identifies the following tasks:
1. Create a new state in the boiler controller to handle the steps involved in running the boiler.
2. When the user updates the fuel control valve level, send the new value to the boiler.
Design
The team decides on the following strategies for approaching each task:
1. Create a new state in the boiler controller to handle the steps of running the boiler.
• The pieces to implement this functionality already exist. The Run Boiler case, which executes immediately after the Ignition case, just needs to call the
functionality.
2. When the user updates the fuel control valve level, send the new value to the boiler.
• Use the handshaking notifier to send the fuel control valve value to the boiler.
EHL “Fuel
Control Valve”
MHL “Fuel
Control Valve”
Boiler Controller
Boiler
“Update Fuel
“Fuel Level”
Control Valve”
Done
Implementation
Create a New State in the Boiler Controller VI to Implement Boiler Running States
Note Because the Run Boiler VI directly implements the new functionality and each piece is relatively small, you test the functionality when the case is
finished.
2. Create a new case after the Ignition case and name it Run Boiler.
3. Modify the case as shown in Figure 6-38.
1 2
3 4 5 6
1 Variant to Data—Converts variant data from the Dequeue Message VI to a MHL UI Data type.
2 Bundle By Name—Sets the Pilot Gas Valve and Pilot indicators to off, indicating that the pilot gas valve is closed and the pilot light is off.
3 Controller to Boiler—This VI sends a message to the boiler to turn off the gas and pilot light.
4 Enqueue Message—The first instance sends a message to the Boiler.vi and the second sends a message to the MHL to update the status of Boiler Controller.vi.
5 Unbundle By Name—Extracts the Status and Fuel Control Valve values.
6 Number To Decimal String—Converts the fuel control valve data to a string so the Log Status VI can log the information.
4. Modify the Ignition case to call the Run Boiler case as shown in Figure 6-39.
Figure 6-39. Updating the Ignition Case to Call the Run Boiler Case
1 Enqueue Message—Sends the Run Boiler message to the Boiler Controller queue.
When the pilot flame reaches the flame threshold level, the Pilot Gas Valve and Pilot LEDs turn off and the Simulate Failure button is enabled on the
Boiler VI.
Clicking the Simulate Failure button displays the Boiler Controller - Shutdown dialog box. Simulating failure results in a boiler shutdown, in the same
way as clicking Stop Boiler button.
Open Status Log.txt and verify that the file contains the entry: Boiler Running.
1 2
1 Variant to Data—Wire a Numeric constant of 0 to the type input of the Variant to Data function.
2 Controller to Boiler—This VI sends a message to the boiler about the fuel level.
Figure 6-41. Updating the Fuel Control Valve Event in the EHL of the Main VI
4. Modify the Fuel Control Valve case of the MHL as shown in Figure 6-42.
Figure 6-42. Modifying the Fuel Control Valve Case of the MHL
1 2
1 Variant to Data—Wire a Numeric constant of 0 to the type input of the Variant to Data function. Right-click the constant and select Representation»U32 from
the shortcut menu. U32 is the same representation as the Fuel Control Valve numeric control.
2 Enqueue Message—This VI sends the value of the fuel control valve to the boiler controller.
When the pilot flame reaches the flame threshold level, the Fuel Control Valve control is active and the value is 10.
Changing the value of the Fuel Control Valve control updates to the Fuel Level (%) indicator on the Boiler VI.
Scenario
In the sprint planning meeting for this iteration, the product owner chose to implement the following user story:
• As a boiler operator, when the boiler is running, I want to click a button to shut down the boiler without exiting the system, so that the system always follows the
boiler shutdown procedure and the boiler safely shuts down.
To implement this user story, the team identifies the following tasks:
2. Integrate and test each code module with the Boiler Controller system.
Design
The team decides on the following strategies for approaching each task:
• Two code modules implement this functionality: Shutdown Controller.vi and Purge Complete.vi. You already tested and used Purge
Complete.vi when you implemented the Start button functionality. You need only test Shutdown Controller.vi in this sprint.
• Use sandwich testing to test the Shutdown Controller module. Sandwich testing requires a bit more overhead, but it provides all of the benefits of top-down
testing (the ability to test the top-level control early in the process) and bottom-up testing (the ability to ensure module functionality early).
• Sandwich testing, like bottom-up testing, requires that you develop a test VI for the Shutdown Controller module.
• Sandwich testing also requires that you create stub code in the calling VI to ensure that the top-level control works properly.
2. Integrate and test the Shutdown Controller VI and Purge Complete VI code modules with the Boiler Controller system.
• You modify the Shutdown case of the Boiler Controller VI to integrate this code.
Implementation
Test Each Code Module Needed
1. Create stub code for the Shutdown case of the Boiler Controller VI.
Modify the Shutdown case with a Flat Sequence Structure as shown in Figure 6-43.
Figure 6-43. Stub Code in the Shutdown Case
Note You delete these frames as you integrate each code module (Shutdown Controller VI and Purge Complete VI) into the Boiler Controller VI. These
frames serve as placeholders until you are ready to integrate each module.
Verify that when you click the Stop Boiler button, the two dialogs boxes launch in order. This ensures that the top-level code, Main VI, is reaching the
stub code.
In the Project Explorer window, open Boiler Controller»Controller.lvlib»Test VIs»Test - Prove Pilot.vi.
Add Test - Shutdown Controller.vi to Controller.lvlib by dragging the VI to the Test VIs folder in the Project Explorer window as shown in Figure 6-44.
Figure 6-44. Project with Test - Shutdown Controller VI
3. Update the front panel of the Test - Shutdown Controller VI as shown in Figure 6-45.
1 Numeric control—Right-click the numeric control and select Representation»U32 from the shortcut menu.
4. Update the block diagram of the Test - Shutdown Controller VI as shown in Figure 6-46.
3 2
1 Prove Pilot—Re-wire the connections to the Prove Pilot VI. The Shutdown Controller VI requires that the Pilot Flame Level (%) on the boiler be a non-zero value.
The Prove Pilot VI sets this value.
2 Shutdown Controller—Wire the Purge Time control terminal to the Shutdown Controller VI.
3 Expand the Unbundle By Name function and wire the Handshake terminal to the Handshake Notifier in input of the Shutdown Controller VI.
4 Create the Purge case as shown and change Boolean constant in the Default case to False.
Open the Boiler VI so you can observe changes to the front panel when you run the test. You must open the Boiler VI before running the test because it is
configured to appear when run and close when finished running.
Control Value
Flame Threshold 40
Purge Time 2
– On the Boiler VI front panel, the Pilot Flame Level (%) increments from 0 to 40 in 4 seconds (100 ms per increment).
– On the Test - Shutdown Controller VI, the MHL Status indicator changes to Shutdown.
– On the Boiler VI front panel, the Pilot Flame Level (%) decrements from 40 to 0 in 2 seconds (50 ms per increment).
Integrate and Test the Shutdown Controller VI and Purge Complete VI into the Boiler Controller System
1. Integrate the Shutdown Controller VI into the application.
Modify the Shutdown case of the Boiler Controller VI to include the Shutdown Controller VI as shown in Figure 6-47.
Figure 6-47. Adding the Shutdown Controller VI to the Shutdown Case
1 2
Modify the Shutdown case of the Main VI to pass MHL User Interface Data as the message data for the Shutdown message as shown in Figure 6-48.
Figure 6-48. Modifying the Main VI Shutdown Case to Use MHL UI Data
Run the Main VI and verify that previous functionality still works.
Click the Stop Boiler button or the Simulate Failure button and verify the following:
– Fuel Control Valve, Stop Boiler, and Simulate Failure buttons are disabled.
– On the Boiler VI front panel, the Pilot Flame Level (%) indicator decrements to 0 in about 2 seconds.
– The Boiler Controller - Purge Complete.vi dialog box appears. Click OK.
Open Status Log.txt and note the Start Shutdown Purge entry.
3. Integrate the Purge Complete VI into the application.
Note You do not need to test this VI at the module level because you tested and integrated it during Exercise 6-2 when integrating the Start functionality.
Modify the Shutdown case of the Boiler Controller VI to include the Purge Complete VI as shown in Figure 6-49.
Figure 6-49. Adding the Purge Complete VI to the Shutdown Case
Run Main.vi.
– Notice that after the purge cycle finishes, the primary fan turns off, Reset is enabled, and Status indicates Lockout. You can now begin the entire boiler
startup cycle again.
Open Status Log.txt and note the new Shutdown Purge Complete entry.
You also can visit the Worldwide Offices section of ni.com/niglobal to access the branch office Web sites, which provide up-to-date contact information, support
phone numbers, email addresses, and current events.