Loading files
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Windows-1252">
<title>Queued Message Handler</title>
<style>
<!--
/***************************************************/
/* MINIMAL STYLES */
/* The following section defines styles that every HTML Help project should need. */
/* Specifies White Background color */
body {background-color:#FFFFFF; font-family:Verdana, sans-serif; font-size:8pt; color: #000000;}
/* The default style of P is red to alert you that you need to apply a style class, such as Body. */
P { margin-top:6.00pt; margin-bottom:6.00pt;}
BR { font-size:4.00pt; }
/* Use H1 for all topic headings. */
H1 { margin-top:3.00pt; margin-bottom:3.00pt; font-size:150%; font-weight:bold; }
/* Use H2 for second-level headings. */
H2 { margin-top:9.00pt; margin-bottom:3.00pt; font-size:125%; font-weight:bold; }
/* Use H3 for third-level headings. */
H3 { margin-top:6.00pt; margin-bottom:3.00pt; font-size:100%; font-weight:bold; }
/* Use H4 for fourth-level headings. */
H4 { margin-top:6.00pt; margin-bottom:3.00pt; font-size:100%; font-weight:bold; }
/* H5 and H6 have the same definition as H4 because you should not need this level of heading in one topic. If you need to use H5 or H6, consider breaking up your topic into more than one topic. */
H5 { margin-top:6.00pt; margin-bottom:3.00pt; font-size:100%; font-weight:bold; }
H6 { margin-top:6.00pt; margin-bottom:3.00pt; font-size:100%; font-weight:bold; }
/* Use the Body style class for normal paragraphs. */
P.Body { }
/* Use the Anchor style class for graphic references on a line by themselves. */
P.Anchor { font-size:125%; }
/* Use the Indent style classes to indent a paragraph. If you need to indent text below a list item, use <br><br> to start the new paragraph within the same set of <li></li> tags. If you need to indent a list within another list, nest the indented list within the first list's set of <ol></ol> or <ul></ul> tags. */
P.Indent1 { margin-left:12.00pt; margin-bottom:3.00pt; }
P.Indent2 { margin-left:24.00pt; margin-bottom:3.00pt; }
P.Indent3 { margin-left:36.00pt; margin-bottom:3.00pt; }
P.Indent4 { margin-left:48.00pt; margin-bottom:3.00pt; }
P.Indent5 { margin-left:60.00pt; margin-bottom:3.00pt; }
/* Use the LI style for all list items. */
LI { margin-top:3.00pt; margin-bottom:3.00pt; }
/* Use the OL style for numbered lists. You do not have to type the number for each list item in a numbered list. */
OL { margin-left:22.00pt; margin-top:3.00pt; margin-bottom:3.00pt; text-indent:0pt; list-style-type: decimal; }
/* Use the OL style for numbered lists. Nested lists will use the bullet types according to the nesting scheme below */
ol ol {list-style-type:lower-alpha}
ol ol ol {list-style-type:decimal}
ol ol ol ol {list-style-type:lower-alpha}
ol ol ol ol ol {list-style-type:decimal}
ol ol ol ol ol ol {list-style-type:lower-alpha}
ol ol ol ol ol ol ol {list-style-type:decimal}
ol ol ol ol ol ol ol ol {list-style-type:lower-alpha}
/* Use the EquationNum style class for numbered lists of equations. You do not have to type the number for each list item in a numbered list. */
OL.EquationNum { margin-left:36.00pt; text-indent:0pt; list-style-type: decimal; }
/* Use the List-abc style class for lettered lists. You do not have to type the letter for each list item in a lettered list. */
OL.List-abc { margin-left:22.00pt; text-indent:0pt; list-style-type:lower-alpha; }
/* Use the UL style for bulleted lists. You do not have to type the bullet for each list item in a bulleted list. */
UL { margin-left:22.00pt; text-indent:0pt; margin-top:3.00pt; margin-bottom:3.00pt; list-style-type: disc; }
/* Use the UL style for bulleted lists. Nested lists will use the bullet types according to the nesting scheme below. */
ul ul {list-style-image: none;list-style-type: circle}
ul ul ul {list-style-image:none;list-style-type:disc}
ul ul ul ul {list-style-image: none;list-style-type: circle}
ul ul ul ul ul {list-style-image:none;list-style-type:disc}
ul ul ul ul ul ul {list-style-image: none;list-style-type: circle}
ul ul ul ul ul ul ul {list-style-image:none;list-style-type:disc}
ul ul ul ul ul ul ul ul ul{list-style-image: none;list-style-type: circle}
/* Use the List-Box style class for bulleted lists with boxes instead of bullets. You do not have to type the box for each list item in a box list. */
UL.List-Box { list-style-image: none;list-style-type: square}
Table { font-size:100%; }
/* Use the Borderless style class for tables that do not need borders, such as for 2-column or 3-column lists with no headings. */
Table.Borderless { border:none; }
/* Use the Bordered style class for tables that need borders. */
Table.Bordered { border-width: 1pt; border-style: solid; border-color: #000000; border-collapse: collapse; }
/* Use the TD style for table cells in Borderless or Borderless-Wide tables. */
TD { vertical-align:top; padding:3px; }
/* Use the Bordered style class for table headings and cells in Bordered or Bordered-Wide tables. */
.Bordered { border-width: 1pt; border-style: solid; border-color: #000000; }
/* Use the Icon style class for table cells that contain note, caution, warning, or tip icons, or LabVIEW datatype terminals. */
TD.Icon { width:40px; }
/* Use the TH style for table heading cells in Borderless or Borderless-Wide tables. */
TH { font-weight:bold; padding:3px; }
/* Use the Left-Align style class for table headings and cells that you want to left align instead of center align. */
.Left-Align { text-align:left; }
/***************************************************/
/* CHARACTER FORMATS */
/* The following section defines character formats that every HTML Help project should need. */
/* CHARACTER FORMATS Updated to conform with the CSE HTML Validator Pro */
/* The following section defines character formats that every HTML Help project should need. */
/* Use the Dark-Red format for warnings or cautions. */
.Dark-Red { color: #800000 }
/* Use the Monospace format for code or syntax examples. */
.Monospace { font-family: Courier New; font-size: 100%; }
/* Use the Monospace-Bold format for messages and responses that the computer automatically prints to the screen. */
.Monospace-Bold { font-family: Courier New; font-weight: bold; font-size: 100%; }
/* Use the Monospace-Italic format to denote text that is a placeholder for a word or value that the user must supply. */
.Monospace-Italic { font-family: Courier New; font-style: italic; font-size: 100%; }
/* small class */
.smallFont { font-size:87.5%; }
/* Bold class */
.Bold { font-weight: bold; }
/* Italic class */
.Italic { font-style: italic; }
/* Use the Platform format to denote a specific platform. */
.Platform { color: #0000FF; font-weight: bold; }
/* Use the Symbol format for characters not in the Verdana character set. Use this format sparingly. When possible, you should use the correct ASCII code for the symbol or use a graphic to recreate the symbol. */
.Symbol { font-family: Symbol; }
/* Use the Red-text format to call attention to text that needs information added or edited by techcomm */
.Red-text {color: #FF0000;}
/* Use the Green-Underline format for the green defintion in the conventions topic */
.Green-Underline {color: #007700; text-decoration : underline;}
/* Use the glossButton format for the glossary buttons used in the glossary topic */
.glossButton { font-size:12px; color:black; }
/* Use for text sections and hyphenated words that should not break at line wraps */
.nobreak{white-space:nowrap}
/* Use for template instructions. */
.instructions{color:red; font-style:italic}
/*Use for words and text sections that do not need to be localized */
.DNL { }
/* The following styles define the color of links. */
a:link { color: #007700 }
a:visited { color: #7F007F }
a:link:hover { color: #FF0000 }
a:link:active { color: #FF0000 }
/***************************************************
** Forms */
form { margin-top:0pt; margin-bottom:3pt; color:black; }
select { font-size:100%; color:black; }
/*******************************************************
** Margins **
** Use these styles for block-level elements inside tables cells or list items where you do not want extra padding at the top or bottom of a cell. */
.noTopMargin { margin-top:0pt;}
.noBottomMargin { margin-bottom:0pt;}
/***************************************************
** CODE STYLES **
** The following section defines styles that you need to format entire sections of code or syntax examples. If you have just a few words you need to format as a code or syntax example, use the Monospace character format. */
P.Code { margin-top:3.00pt; margin-bottom:0.00pt; font-family:Courier New; }
P.Code1 { margin-left:12.00pt; margin-top:3.00pt; margin-bottom:0.00pt; font-family:Courier New; }
P.Code2 { margin-left:24.00pt; margin-top:3.00pt; margin-bottom:0.00pt; font-family:Courier New; }
P.Code3 { margin-left:36.00pt; margin-top:3.00pt; margin-bottom:0.00pt; font-family:Courier New; }
-->
</style>
<script type="text/javascript"> // define hyperlinks and function for launching a URL in a browser
var L_case_structure = "http://digital.ni.com/express.nsf/bycode/ex746b2013";
var L_while_loops = "http://digital.ni.com/express.nsf/bycode/ext9fg2013";
var L_shift_registers = "http://digital.ni.com/express.nsf/bycode/exar5k2013";
var L_enums = "http://digital.ni.com/express.nsf/bycode/ex3zj72013";
var L_typedefs = "http://digital.ni.com/express.nsf/bycode/exicsz2013";
var L_event_structures = "http://digital.ni.com/express.nsf/bycode/exfjrp2013";
var L_value_change_events = "http://digital.ni.com/express.nsf/bycode/exb2cb2013";
var L_error_handling = "http://digital.ni.com/express.nsf/bycode/exfbp32013";
var L_clusters = "http://digital.ni.com/express.nsf/bycode/exwemq2013";
var L_control_refnums = "http://digital.ni.com/express.nsf/bycode/exend62013";
var L_parallel = "http://digital.ni.com/express.nsf/bycode/exxaf62013";
var L_PC = "http://digital.ni.com/express.nsf/bycode/exbfny";
var L_state_machines = "http://digital.ni.com/express.nsf/bycode/ex85gn";
var L_user_events = "http://digital.ni.com/express.nsf/bycode/ex9s6m2013";
var L_queues = "http://digital.ni.com/express.nsf/bycode/extwnb";
var L_trademarks = "http://digital.ni.com/express.nsf/bycode/rdtrad";
var L_patents = "http://digital.ni.com/express.nsf/bycode/rdlv17";
var L_walkthrough = "http://digital.ni.com/express.nsf/bycode/DW_QMH";
function WWW(url)
{
var urlWindow;
urlWindow = window.open(url, "New", "directories=yes,location=yes,menubar=yes,resizable=yes,scrollbars=yes,status=yes,toolbar=yes");
}
</script>
</HEAD>
<body>
<h1>Queued Message Handler</h1>
<p class="Body">LabVIEW 2013</p>
<p class="Body">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.</p>
<p class="Body">The QMH template is a version of the Producer/Consumer design pattern, where the user interface (producer) produces messages and the tasks (consumers) consume them. However, in the QMH template, you also can produce messages from a consumer loop.</p>
<p class="Body">This template includes one producer loop and one consumer loop. You can <a href="#add_task">add consumer loops</a> as needed.</p>
<h2>Example</h2>
<p class="Body">Refer to the Continuous Measurement and Logging sample project, available from the <strong>Create Project</strong> dialog box, for an example of adapting this template to a measurement application.</p>
<h2>Developer Walkthrough</h2>
<p class="Body">Refer to <a href="javascript:WWW(L_walkthrough)">ni.com</a> for a developer walkthrough of this template.</p>
<h2>System Requirements</h2>
<p class="body">LabVIEW Base, Full, or Professional Development System</p>
<h2>Use Cases</h2>
<p class="Body">The QMH template is useful for applications where multiple tasks occur in parallel, often at different rates. For example, consider an application that continuously acquires, logs, and displays two signals: an RS-232 signal and an analog signal. These signals occur at different rates, so the application must have two loops that run in parallel. In addition, each loop is divided into the following states:</p>
<ul>
<li>Initialize the data acquisition hardware</li>
<li>Acquire data</li>
<li>Log the acquired data to disk</li>
<li>Display the acquired data in a waveform chart</li>
<li>Set the hardware to a safe state</li>
<li>Stop the data acquisition and shut down the hardware</li>
</ul>
<p class="Body">The application requires a responsive user interface; that is, users should be able to click buttons even while the application is executing another command. Therefore, the application requires a third parallel loop that continuously monitors the front panel for events, such as the following commands:</p>
<ul>
<li>Start RS-232 acquisition</li>
<li>Stop RS-232 acquisition</li>
<li>Enable RS-232 logging</li>
<li>Disable RS-232 logging</li>
<li>Start analog data acquisition</li>
<li>Stop analog data acquisition</li>
<li>Enable analog data logging</li>
<li>Disable analog data logging</li>
</ul>
<p class="Body">The QMH template provides a starting point for writing this kind of application.</p>
<h2>Overview</h2>
<img src="loc_queued_message_handler.gif">
<p class="Body">This template repeatedly executes the following steps:</p>
<ol>
<li>A user interacts with the front panel, causing the Event structure in the Event Handling Loop (EHL) to produce a message. LabVIEW stores the message in a queue.</li>
<li>The Message Handling Loop (MHL) reads a message from the message queue, removing the message.</li>
<li>The message is a string that matches one of the subdiagrams of the Case structure in the MHL. Therefore, reading the message causes the corresponding subdiagram of the Case structure to execute. This subdiagram is called a <em>message diagram</em> because it corresponds to a message.</li>
<li>Optionally, the message diagram produces another message, storing it in the message queue.</li>
</ol>
<p class="Body">Notes:</p>
<ul>
<li>The EHL is the producer loop. The MHL is the consumer loop. These loops run in parallel and are connected by the message queue, which facilitates communication between the loops.</li>
<li>The message queue is a LabVIEW queue that stores messages for consumption. Because the EHL sends messages to this queue and not directly to the MHL, the EHL can produce messages while the MHL is not consuming them. Each message queue belongs to a single MHL.</li>
<li>Every iteration of the MHL reads the oldest message in the message queue and then executes the corresponding message diagram. Although the MHL primarily consumes messages, it also can produce them.</li>
<li>Each loop handles errors using a loop-specific error handler subVI. If the QMH encounters an error in the MHL, LabVIEW displays an error message.</li>
<li>Your application can have multiple MHLs. Each MHL corresponds to a task the application performs, such as acquiring or logging data.</li>
<li>Notice the <strong>UI Data</strong> cluster in the above diagram. This cluster is data that each message diagram in an MHL can access and modify. In this template, the cluster is defined as a typedef, UI Data.ctl. Each typedef belongs to a single MHL.</li>
</ul>
<h2>Running This Template</h2>
<ol>
<li>In the <strong>Project Explorer</strong> window, open and run Main.vi.</li>
<li>Click the front panel controls and watch the <strong>Display</strong> indicator display messages.</li>
</ol>
<h2>Modifying this Template</h2>
<h3>Determining Your Needs</h3>
<p class="Body">The following table summarizes the design decisions you must make when modifying this template:</p>
<table class="Bordered">
<tr class="Bordered">
<th class="Bordered">Design Decision</th>
<th class="Bordered">Example</th>
<th class="Bordered">Detailed Information</th>
</tr>
<tr class="Bordered">
<td class="Bordered">You need to determine how many MHLs to add. Each MHL defines a task that executes in parallel with other tasks.</td>
<td class="Bordered">You have an application that acquires data and, in parallel, logs this data to disk.<br><br>This application consists of two tasks: data acquisition and data logging. Therefore, you need two Message Handling Loops.
</td>
<td class="Bordered"><a href="#add_task">Creating a Message Handling Loop</a></td>
</tr>
<tr class="Bordered">
<td class="Bordered">For each MHL, you need to determine what message diagrams to add.<br><br>A message diagram is a subdiagram of the Case structure in an MHL. Each subdiagram corresponds to a state the task can be in; therefore, to determine the message diagrams to add, separate each task into states.
</td>
<td class="Bordered">You want to separate the data acquisition task into three states: Initialize, Acquire Data, and Exit. Therefore, create these message diagrams in the MHL that acquires data.<br><br>You want to separate the data logging task into three states: Initialize, Log, and Close. Therefore, create these message diagrams in the MHL that logs data.
</td>
<td class="Bordered"><a href="#add_diagram">Creating a Message Diagram</a></td>
</tr>
<tr class="Bordered">
<td class="Bordered">You must determine what data the message diagrams of an MHL need.</td>
<td class="Bordered">Each message diagram of the data acquisition MHL needs access to a hardware reference. The Initialize message diagram needs to open this reference, the Acquire Data diagram uses this reference to acquire data, and the Exit message diagram closes the reference.</td>
<td class="Bordered"><a href="#change_ui_data">Defining Data that a Message Handling Loop Needs</a></td></tr>
<tr class="Bordered">
<td class="Bordered">You need to determine when to execute each message diagram. A message diagram executes after its MHL receives the appropriate message. Therefore, you need to determine when to send each message to the MHL. You can send a message from a front panel control or from a message diagram.</td>
<td class="Bordered">You want to add a button that sends the Initialize message to the data acquisition MHL.<br><br>You then want the Initialize message diagram to send the Acquire Data message to the same MHL.
</td>
<td class="Bordered"><a href="#add_control">Adding a Control that Sends a Message to a Message Handling Loop</a> or <a href="#send_message">Sending a Message to a Message Handling Loop</a>, depending on whether you want a control to send the message.</td></tr>
<tr class="Bordered">
<td class="Bordered">You need to determine if you want the Exit message to stop each MHL. The Dequeue Message VI uses this message because it is able to shut down an MHL.</td>
<td class="Bordered">You want each MHL to shut down when it receives the Stop message instead of the Exit message.</td>
<td class="Bordered"><a href="#change_stop_msg">Changing the Message that Stops a Message Handling Loop</a></td></tr>
<tr class="Bordered">
<td class="Bordered">You need to determine if you want to ignore any specific errors within the EHL or the MHL.</td>
<td class="Bordered">When reading messages from the message queue, you want to ignore network timeout errors.</td>
<td class="Bordered"><a href="#ignore_errors">Ignoring Errors in the Event Handling Loop and Message Handling Loop</a></td></tr>
</table>
<a name="add_task"></a><h3>Creating a Message Handling Loop</h3>
<p class="Body">A Message Handling Loop (MHL) represents a task the application can perform, such as acquiring data or logging data, in parallel with other tasks. Each MHL can be divided into sub-tasks that correspond to states. MHLs consist of the following components:</p>
<ul>
<li>A message queue</li>
<li>A While Loop that reads messages from the message queue</li>
<li>A Case structure that contains a subdiagram, also known as a message diagram, for each possible message that can be read, where each message corresponds to a state of the task</li>
<li>(Optional) Data that each message diagram of the MHL can access</li>
</ul>
<p class="Body">Complete the following steps to add an MHL:</p>
<ol>
<li>This template contains a typedef that defines the cluster that holds the refnums for all message queues. By default, this typedef has space for only one queue. Complete the following steps to add a second queue to this typedef:
<ol>
<li>In the <strong>Project Explorer</strong> window, open Message Queue.lvlib:Create All Message Queues.vi.</li>
<li>Right-click the <strong>All Message Queues</strong> constant and open the typedef:<br><br><img src="loc_open_msg_queue_typedef.png"><br><br>LabVIEW launches the <strong>Control Editor</strong> window.</li>
<li>Expand the border of the <strong>Message Queues</strong> cluster.</li>
<li>Duplicate the <strong>UI</strong> queue refnum in the cluster.</li>
<li>Name the new queue refnum. For example: <br><br><img src="loc_new_task_typedef.png"></li>
<li>Select <strong>File»Apply Changes</strong> and close the <strong>Control Editor</strong> window. The <strong>Message Queues</strong> typedef now contains an additional message queue.</li>
</ol>
</li>
<li>Modify Create All Message Queues.vi to execute the following steps:
<ul>
<li>Obtain the message queue reference</li>
<li>Bundle this queue into the <strong>Message Queues out</strong> cluster</li>
<li>(Optional) Send an initial message to the new MHL</li>
</ul>
<br>The following screenshot shows an example of code that accomplishes the above steps:<br><br><img src="loc_create_two_queues.png">
</li>
<li>(Optional) If the MHL needs access to data, create a typedef that represents this data.</li>
<li>In Main.vi, create the Message Handling Loop that represents the task:<br><br><img src="loc_new_task_loop.png">
<br><br>Notes:
<ol>
<li>Recall that in step 2, you bundled the <strong>New Task</strong> queue refnum into the <strong>Message Queues out</strong> cluster. The code above shows where this cluster is unbundled and how the wire branch for the <strong>New Task</strong> queue goes to the <strong>New Task</strong> MHL.</li>
<li>Recall that in step 2, you had the option to send an initial message to the message queue. The code in step 2 shows the initial message <span id="Monospace">Initialize</span>. The code above shows the message diagram (Initialize) that executes when this message is received.</li>
<li>Recall that in step 4, you had the option to create a typedef. The code above shows how you wire this typedef, <strong>New Task Data</strong>, so the MHL can use it.</li>
<li>If you want the new task to send messages to the <strong>UI</strong> queue, branch the wire for the UI queue refnum into the <strong>New Task</strong> loop.</li>
<li>The code above shows the FALSE constant wired to the conditional terminal of the While Loop. In each MHL, only one message diagram should be able to stop the MHL. This design prevents accidental and partial shutdowns by guaranteeing the following conditions:
<ul>
<li>Shutdown code runs only right before the MHL shuts down.</li>
<li>Shutdown code always runs to completion.</li>
</ul>
</li>
<li>To keep the block diagram of Main.vi compact and readable, you can encapsulate each MHL into a subVI. To further organize the project, you can put each subVI, any supporting VIs, and its data typedef into a project library. Refer to the Continuous Measurement and Logging sample project, available from the <strong>Create Project</strong> dialog box, for an example of this design.</li>
<li>The MHL shown above does not need access to the Stop Event wire. The MHL in the template uses this wire to execute the Fire User Event - Stop VI, which shuts down the Event Handling Loop. No other MHL needs to do this.</li>
</ol>
</li>
<li><a href="#add_diagram">Add message diagrams</a> to the Case structure in the MHL. To minimize errors and unexpected behavior, ensure each MHL has the following message diagrams:
<ol>
<li>A message diagram that initializes the task; for example, this diagram could connect to a hardware device, open files for data logging, and so on.</li>
<li>A message diagram that <a href="#handle_unrecognized">handles unrecognized messages</a>.</li>
<li>A message diagram that, when executed, releases the message queue and stops the loop. For example: <br><br><img src="loc_stop_task.png"><br><br>By default, the message that triggers this message diagram is <span id="Monospace">Exit</span>, but you can <a href="#change_stop_msg">change this</a>.</li>
<li>(Optional) If the application requires that the MHL stop performing its task but stay active (to potentially restart the task), create a message diagram that uses the Flush Queue function to remove any pending messages.<br><br>For example, in a continuous measurement application, you may have <strong>Start Measurement</strong> and <strong>Stop Measurement</strong> buttons. Clicking <strong>Start Measurement</strong> initiates the MHL, which continues execution by sending itself the same message continually. In this application, clicking <strong>Stop Measurement</strong> should not only stop the measurement but also flush the message queue without stopping the MHL. If you do not flush the message queue, clicking <strong>Stop Measurement</strong> will have no effect. The message queue contains more messages to continue the measurement, and each of these messages causes another message of its kind to be produced.</li>
</ol>
</li>
<li>Add code to the EHL that instructs the new MHL to stop in the event of an error or when the application stops; that is, execute the message diagram you created in step 5c. Add this code to the Event Structure and Error case shown in the following figure:<br><br><img src="loc_stop_new_mhl.png"></li>
<li><a href="#send_message">Send messages to the MHL</a>.</li>
</ol>
<a name="add_diagram"></a><h3>Creating a Message Diagram</h3>
<p class="Body">A message diagram is the subdiagram of a Case structure, located in a Message Handling Loop, that handles a particular message. It is similar to a state in a state machine.</p>
<p class="Body">A message diagram is a subdiagram of a Case structure that is labeled with a string. It executes when the MHL receives a message that matches this label.</p>
<p class="Body">Complete the following steps to create a message diagram:</p>
<ol>
<li>In the MHL that represents the task, add a subdiagram to the Case structure.
<table class="Borderless"><tr><td class="Icon"><img src="noloc_tip.png"></td><td><strong>Tip</strong> If you are adding a message diagram to the MHL included in the template, you can automatically include the data and error wires in the new message diagram by duplicating the ---Copy This Frame--- case.</td></tr></table>
</li>
<li>In the case selector label, enter the text of the message that will trigger this message diagram to execute. For example, the following message diagram executes when LabVIEW reads <span id="Monospace">New Message</span> from the message queue:<br><br><img src="loc_new_message_diagram.png"></li>
<li>Add code that executes upon receiving this message. As you do this, pay attention to the following guidelines:
<ul>
<li>To access and modify task data, use the Unbundle By Name and Bundle By Name functions:<br><br><img src="loc_access_task_data.png"></li>
<li>To ensure that you track all errors, use the Merge Errors function to merge errors coming from all nodes in the subdiagram.</li>
<li>To access message data, wire the <strong>Message Data</strong> input tunnel to a Variant to Data function:<br><br><img src="loc_convert_variant.png"></li>
<li>To send a message to a message queue, use the Enqueue Message VI.</li>
</ul>
</li>
<li>To execute the message diagram, <a href="#send_message">send a message</a> to the MHL. The message you send must match the label of the message diagram that you entered in step 2.</li>
</ol>
<a name="change_ui_data"></a><h3>Defining Data that a Message Handling Loop Needs</h3>
<p class="Body">In the template, <strong>UI Data.ctl</strong> is the typdef that defines the cluster of data that the MHL can access:</p>
<img src="loc_ui_data.png">
<p class="Body">Modify this typedef according the needs of your application. For example, if more than one message diagram in an MHL needs to modify the same Boolean control, add a Boolean control to this typdef.</p>
<p class="Body">If you have more than one MHL, create a typedef for each one. This design prevents errors by ensuring one MHL cannot access the data of another.</p>
<a name="add_control"></a><h3>Adding a Control that Sends a Message to a Message Handling Loop</h3>
<ol>
<li>Add a control to the front panel.</li>
<li>(Optional) If you want a message diagram to programmatically modify this control, <a href="#bundle_control">bundle the control refnum</a> into the typedef for that MHL.</li>
<li>Add an Event case to the Event structure in the Event Handling Loop.</li>
<li>Configure the event to trigger when the value of this new button changes:<br><br><img src="loc_value_change_event.png"></li>
<li>Click <strong>OK</strong>. LabVIEW creates an event case in the Event structure.</li>
<li>Associate the terminal with the event by dragging the block diagram terminal for the new control inside this event case.</li>
<li>Add code to this event case that <a href="#send_message">sends a message to an MHL</a>.</li>
</ol>
<a name="send_message"></a><h3>Sending a Message to a Message Handling Loop</h3>
<p class="Body">Messages are strings that instruct an MHL to execute one of its message diagrams. Messages are produced by the EHL and are stored in the message queue. Every iteration of the MHL reads the oldest message in the message queue and executes the corresponding message diagram.</p>
<p class="Body">Complete the following steps to send a message to an MHL:</p>
<ol>
<li>Decide what part of the application will send the message and which MHL will receive the message. You can send messages from the EHL or from a message diagram.</li>
<li>Decide what message diagram will execute when the MHL receives this message. Ensure the message diagram exists and has the same name as the message you want to send. If the message diagram does not exist, <a href="#add_diagram">create it</a>.</li>
<li>In Main.vi, access the wire that represents the message queue of the receiving MHL. You access this wire by unbundling it from the <strong>Message Queues out</strong> cluster that is returned from the Create All Message Queues VI. Main.vi already contains the following code that unbundles the UI queue refnum:
<br><br><img src="loc_message_queue_wire.png">
<br><br>Expand this Unbundle by Name function to access the wires of message queues for all MHLs.</li>
<li>In the part of the application that will send the message, create the following code:<br><br><img src="loc_enqueue_generic_message.png"><br><br>In the code above, <span id="Monospace">Message</span> is the text that matches the message diagram you identified in step 2, and the message queue refnum is the wire you identified in step 3.
<table class="Borderless"><tr><td class="Icon"><img src="noloc_note.png"></td><td><strong>Note</strong> Access the Enqueue Message VI from the <strong>Project Explorer</strong> window of the template or by using Quick Drop.</td></tr></table>
</li>
<li>(Optional) To specify that this message supersedes others already in the queue, wire TRUE to the <strong>Priority Message?</strong> input of the Enqueue Message VI:<br><br><img src="loc_enqueue_priority_message.png"><br><br>High-priority messages are typically reserved for emergency stop situations. These messages are placed at the front of the message queue, guaranteeing that the receiving MHL will consume that message next.</li>
<li>(Optional) To send data with the message, wire a value to the <strong>Message Data</strong> input of the Enqueue Message VI. This terminal can accept any data type. For example, the following code sends a double-precision floating-point number along with the message:<br><br><img src="loc_enqueue_message_with_data.png"><br><br>LabVIEW displays a coercion dot on the input terminal because the data type of this terminal is variant.</li>
</ol>
<a name="change_stop_msg"></a><h3>Changing the Message that Stops a Message Handling Loop</h3>
<p class="Body">Messages are strings, meaning you can create or change a message without modifying a typedef. However, this template defines one message: the <span id="Monospace">Exit</span> message is defined in Message Queue.lvlib:Dequeue Message.vi:</p>
<img src="loc_exit_message.png">
<p class="Body">If you want your MHLs to shut down on a message other than <span id="Monospace">Exit</span>, change the message in this VI.</p>
<a name="handle_unrecognized"></a><h3>Handling Unrecognized Messages</h3>
<p class="Body">Ensure all Case structures in an MHL have a <strong>Default</strong> message diagram. The code in this message diagram executes when the MHL reads a message that does not have a corresponding message diagram. Having a <strong>Default</strong> message diagram is important because messages are strings that you enter while programming, not values you select from an enum.</p>
<a name="ignore_errors"></a><h3>Ignoring Errors in the Event Handling Loop and Message Handling Loop</h3>
<p class="Body">You can specify a list of errors to ignore for both the EHL and MHL using their respective error handler subVIs by completing the following procedures:</p>
<ol>
<li>In the <strong>Project Explorer</strong> window, open Error Handler - Event Handling Loop.vi or Error Handler - Message Handling Loop.vi, depending on where you want LabVIEW to ignore the errors, and display the block diagram.</li>
<li>Find the array constant labeled <strong>Ignore Errors (Static List)</strong>:<br><br><img src="loc_qmh_ignore_errors.png"></li>
</ol>
<p class="Body">To ignore errors in the EHL or MHL, add error codes to the array. Specify one error code per array element. The errors to ignore depend on your application. For example, if you are reading the queue over a network, you might want to ignore timeout errors.</p>
<p class="Body">You also can specify ignore errors dynamically at runtime by wiring an array control to the <strong>Ignore Errors (Runtime)</strong> input of the error handler subVI. Specify one error code per array element.</p>
<p class="Body">LabVIEW treats all errors that you do not specify as ignore errors as regular errors. LabVIEW sends regular errors as Error messages to the MHL where you can define how the application handles them.</p>
<a name="bundle_control"></a><h3>Enabling a Message Handling Loop to Programmatically Modify Controls and Indicators</h3>
<p class="Body">To enable an MHL to modify a control programmatically, create a refnum for the control and bundle it into the typedef that stores data for that MHL. The following procedure uses UI Data.ctl as an example.</p>
<ol>
<li>Create the control refnum and move it into the Initialize subdiagram of the MHL.</li>
<li>Open UI Data.ctl and add space for the refnum to the cluster.</li>
<li>In the Initialize subdiagram, expand this new terminal on the Bundle by Name function and wire the control refnum to it:<br><br><img src="loc_bundle_new_button_ref.png"></li>
</ol>
<p class="Body">The refnum for this control now is available to any message diagram that has access to UI Data.ctl. For example, the following code shows the Disable Button message diagram, which uses the control refnum to disable and gray out the front panel button:</p>
<img src="loc_disable_new_button.png">
<h2>LabVIEW Features and Concepts Used</h2>
<ul>
<li><a href="javascript:WWW(L_case_structure)">Case structures</a></li>
<li><a href="javascript:WWW(L_clusters)">Clusters</a></li>
<li><a href="javascript:WWW(L_control_refnums)">Control refnums</a></li>
<li><a href="javascript:WWW(L_enums)">Enums</a></li>
<li><a href="javascript:WWW(L_error_handling)">Error clusters</a></li>
<li><a href="javascript:WWW(L_event_structures)">Event structures</a></li>
<li><a href="javascript:WWW(L_parallel)">Parallelism</a></li>
<li><a href="javascript:WWW(L_PC)">Producer/Consumer design pattern</a></li>
<li><a href="javascript:WWW(L_queues)">Queues</a></li>
<li><a href="javascript:WWW(L_shift_registers)">Shift registers</a></li>
<li><a href="javascript:WWW(L_state_machines)">State machines</a></li>
<li><a href="javascript:WWW(L_typedefs)">Typedefs</a></li>
<li><a href="javascript:WWW(L_value_change_events)">Value change events</a></li>
<li><a href="javascript:WWW(L_user_events)">User events</a></li>
<li><a href="javascript:WWW(L_while_loops)">While Loops</a></li>
</ul>
<h2>Developer Walkthrough</h2>
<p class="Body">Refer to <a href="http://www.ni.com">ni.com</a> for a developer walkthrough of how to use and customize this sample project.</p>
<hr>
<h2>Important Information</h2>
<!--Copyright-->
<p class="Body"><strong>Copyright</strong></p>
<p class="Body">© 2013 National Instruments. All rights reserved.</p>
<p class="Body">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.</p>
<p class="Body">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.</p>
<p class="Body"><strong>End-User License Agreements and Third-Party Legal Notices</strong></p>
<p class="Body">You can find end-user license agreements (EULAs) and third-party legal notices in the following locations:</p>
<ul>
<li>Notices are located in the <span class="Monospace"><National Instruments>\_Legal Information</span> and <span class="Monospace"><National Instruments></span> directories.</li>
<li>EULAs are located in the <span class="Monospace"><National Instruments>\Shared\MDF\Legal\license</span> directory.</li>
<li>Review <span class="Monospace"><National Instruments>\_Legal Information.txt</span> for information on including legal information in installers built with NI products.</li>
</ul>
<!--Trademarks-->
<p class="Body"><strong>Trademarks</strong></p>
<p class="Body"><span class="DNL">LabVIEW</span>, <span class="DNL">National Instruments</span>, <span class="DNL">NI</span>, <span class="DNL">ni.com</span>, the <span class="DNL">National Instruments</span> corporate logo, and the Eagle logo are trademarks of <span class="DNL">National Instruments Corporation</span>. Refer to the <em><span class="DNL">Trademark Information</span></em> at <span class="Monospace">ni.com/trademarks</span> for other <a href="javascript:WWW(L_trademarks)"><span class="DNL">National Instruments</span> trademarks</a>.</p>
<p class="Body">Other product and company names mentioned herein are trademarks or trade names of their respective companies.</p>
<!--Patents-->
<p class="Body"><strong>Patents</strong></p>
<p class="Body">For patents covering the National Instruments products/technology, refer to the appropriate location: <strong>Help»Patents</strong> in your software, the <span class="Monospace">patents.txt</span> file on your media, or the <a href="javascript:WWW(L_patents)">National Instruments Patent Notice</a> at <span class="Monospace">ni.com/patents</span>.</p>
</body>
</html>a8fd7f682This file is pinned to the selected release. Download the original to open it in your design tool.