<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Culverson Software-Custom DAQ Software labVIEW &#187; Beginners</title>
	<atom:link href="http://culverson.com/category/beginners/feed/" rel="self" type="application/rss+xml" />
	<link>http://culverson.com</link>
	<description>Custom Labview Data Acquisition Software Maine</description>
	<lastBuildDate>Thu, 20 May 2010 20:02:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Writing Non-Fragile Code</title>
		<link>http://culverson.com/writing-non-fragile-code/</link>
		<comments>http://culverson.com/writing-non-fragile-code/#comments</comments>
		<pubDate>Wed, 14 Oct 2009 20:48:59 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[Easier Programming]]></category>
		<category><![CDATA[LabVIEW]]></category>

		<guid isPermaLink="false">http://culverson.com/?p=254</guid>
		<description><![CDATA[Oooops&#8230;. who broke it?
&#8220;Fragile&#8221; code is code that breaks in one place because of changes you make in some other place. It&#8217;s most aggravating when you&#8217;re due to ship a new version tomorrow and you need to make one last tweak at 11:30 PM, or your client is looking over your shoulder and this little [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><strong><em>Oooops&#8230;. who broke it?</em></strong></p>
<p>&#8220;Fragile&#8221; code is code that breaks in one place because of changes you make in some other place. It&#8217;s most aggravating when you&#8217;re due to ship a new version tomorrow and you need to make one last tweak at 11:30 PM, or your client is looking over your shoulder and this little &#8220;harmless&#8221; change shows up as a smoldering heap during the demo.</p>
<p>In this case, &#8220;break&#8221; doesn&#8217;t ONLY mean &#8220;broken arrow&#8221; , or uncompilable code (at least you can chase those down easily enough). Here, &#8220;break&#8221; also means &#8220;operates incorrectly&#8221; or &#8220;completely wrecks itself like it never did before&#8221; or somewhere in between.</p>
<p>These sorts of breaks come from unrecognized dependencies, and they&#8217;re all too easy to make: the header size has been 3 for months and months now, so when you add a new function that needs it, it&#8217;s easy to stick in a constant 3 and be done with it.</p>
<p>DON&#8217;T DO IT.</p>
<p><span id="more-254"></span>If you&#8217;re an old-hand bit-banging cycle counter like me, it&#8217;s easy to think of saving a few cycles and adding up the bytes in this cluster, and using a constant of 53 when you need the size of it.</p>
<p>DON&#8217;T DO IT.</p>
<p>The problem is, or course, then when (not <em>if</em>, but <em>when</em>) these things change, then you will have to track down ALL the instances where you use this number and change them.  Not a good plan.  The compiler won&#8217;t complain &#8211; the code is still valid.  But reading thee bytes when you should be reading four will not get you where you want to go.</p>
<p>One tip to solving this is to reduce the number of places that you use such numbers. Focus such procedures into a single VI if you can. But the real key to solving this is to recognize these things when you originate them.</p>
<p><strong>Example #1</strong></p>
<p>Here we need to receive a packet header, consisting of a cluster of a U8 enum command and a U16 integer.  It&#8217;s easy enough to count up to three bytes, and it would be easy to plop down a 3 constant.  However, it is safer to use a constant of the header&#8217;s typedef and calculate its size in code.  This might go against your instincts (it does mine), but in fact the extra time taken (to flatten into string and get string length) is trivial (<a href="http://culverson.com/what-time-is-it/" target="_blank">measure it yourself</a> if you have doubts). On top of a TCP READ operation, this burden is truly insignificant.</p>
<p>And the benefit is that when the integer needs to become an U32 or the command must become a U16, here&#8217;s one less thing YOU have to worry about.  Since the constant here is a TYPEDEF, and since you&#8217;re calculating the size every time, then it will keep on working.</p>
<p><img class="alignnone size-full wp-image-256" title="Fragile1" src="http://culverson.com/site09/wp-content/uploads/2009/10/Fragile1.PNG" alt="Fragile1" width="234" height="158" /></p>
<p><strong>Example #2</strong></p>
<p><strong><span style="font-weight: normal;">This example is similar &#8211; sending a packet header plus a payload thru a connection. Even if your payload is always the same size, it&#8217;s better to calculate it than to use a constant.  With any luck at all, the STRING LENGTH operation will get the same answer every time. and if you do change it at some point, then this code won&#8217;t break.</span></strong></p>
<div><img class="alignnone size-full wp-image-258" title="Fragile2" src="http://culverson.com/site09/wp-content/uploads/2009/10/Fragile2.PNG" alt="Fragile2" width="344" height="140" /></div>
<div><strong>Example #3</strong></div>
<div>Here&#8217;s another use.  When you have an ENUM, it might be useful to loop over every value. But how do you know how many values to use?  You could count them and plop down a constant. That&#8217;s no good, because it leaves you vulnerable.  You know the first value has a numeric equivalent of 0, you could add a value called &#8220;Last&#8221;, but that&#8217;s ugly if the enum is a control onscreen somewhere.</div>
<div>My answer is to cast a large U16 (or whatever data type the ENUM is) into that type (and then possibly back to an integer if needed).</div>
<div>Here, the FOLDER is an enum listing the various folders my program can refer to. I don&#8217;t know how many there are, maybe 25-30 (in this case, ignorance really is bliss), because I don&#8217;t care.</div>
<div>This code is responsible for creating them all (with exceptions) at startup time.</div>
<div>First we start with a large U16.  I picked U16 to match the representation of the enum itself; that&#8217;s necessary for proper casting results.</div>
<div>Then we typecast it to the folder type.  Presumably, 9999 is more than the number of entries in the ENUM, so the typecasting process can&#8217;t let a literal cast stand, as it would be an illegal value.  So what comes out is the last possible value.</div>
<div>Inside the loop, we convert the &#8220;i&#8221; variable to a U16 to match the representation of the enum itself.</div>
<div>Then we typecast that value into the folder type.</div>
<div>The result is a variable that cycles from first ENUM value to the last ENUM value, and does something with each value, all without knowing how many there are!</div>
<div>If we add a new folder type to the ENUM (it is a typedef), then this code does not need changing.</div>
<div><img class="alignnone size-full wp-image-259" title="Fragile3" src="http://culverson.com/site09/wp-content/uploads/2009/10/Fragile3.PNG" alt="Fragile3" width="351" height="183" /></div>
<div>I hope that this thought will help you create code that is more robust.  Your clients will love you for it.</div>
<div>Enjoy.</div>
]]></content:encoded>
			<wfw:commentRss>http://culverson.com/writing-non-fragile-code/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Watch your step</title>
		<link>http://culverson.com/watch-your-step/</link>
		<comments>http://culverson.com/watch-your-step/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 12:42:45 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[Easier Programming]]></category>
		<category><![CDATA[LabVIEW]]></category>

		<guid isPermaLink="false">http://culverson.com/?p=203</guid>
		<description><![CDATA[But who&#8217;s watching the watchers?
Some development environments have a concept called &#8220;watching&#8221;, where you choose a variable to watch and you see a continuous display of that variable in some window.  This is very useful during debugging, as you can step through your program and find out where this variable is being changed.
LabVIEW has no [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><em><strong>But who&#8217;s watching the watchers?</strong></em></p>
<p>Some development environments have a concept called &#8220;watching&#8221;, where you choose a variable to watch and you see a continuous display of that variable in some window.  This is very useful during debugging, as you can step through your program and find out where this variable is being changed.</p>
<p>LabVIEW has no such built-in feature, but it doesn&#8217;t really need one.  You can construct your own watch windows, have them run independently of your main code and accomplish the same thing.</p>
<p>Simply make a new VI with a WHILE loop and a STOP button.  Add a WAIT for 200 mSec (or something) inside it (so you don&#8217;t hog the CPU).  Each time thru the loop, grab your watch variable, process it, and display it.</p>
<p>The &#8220;processing&#8221; can be unbundling a single item from a complicated cluster, or picking an element out of an array, or anything you need to display the item in question.  Perhaps you need to call a VI to get it. Perhaps you need to query an I/O port, or a TCP instrument. Whatever you need to do to watch your troublesome variable.</p>
<p>SUGGESTION:  When you&#8217;re done with it, save it in a folder called &#8220;Miscellaneous Stuff&#8221; or something, so you can get at it easy next time.  There will be a next time.</p>
]]></content:encoded>
			<wfw:commentRss>http://culverson.com/watch-your-step/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Next Step in TCP-IP</title>
		<link>http://culverson.com/the-next-step-in-tcpip/</link>
		<comments>http://culverson.com/the-next-step-in-tcpip/#comments</comments>
		<pubDate>Sat, 12 Sep 2009 21:37:56 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[LabVIEW]]></category>
		<category><![CDATA[TCP]]></category>

		<guid isPermaLink="false">http://culverson.com/?p=198</guid>
		<description><![CDATA[Several conversations at once
A question came up on the LabVIEW forum the other day about multiple connections, and how hard it was to have two connections transmitting at two different rates.  This surprised me a bit, because I have been doing just that for quite a few years.  The allegation was made also that TCP [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center; "><strong><em>Several conversations at once</em></strong></p>
<p>A question came up on the LabVIEW forum the other day about multiple connections, and how hard it was to have two connections transmitting at two different rates.  This surprised me a bit, because I have been doing just that for quite a few years.  The allegation was made also that TCP requires a minimum packet size of 32 bytes. That is also a surprise since I have been doing things contrary to that &#8220;rule&#8221; for quite a few years.</p>
<p>So, in an attempt to clarify things above and beyond the <a href="http://culverson.com/beginners-guide-to-tcpip/" target="_blank">Beginner&#8217;s Guide to TCP/IP</a>, I present this example with a CLIENT and a SERVER.</p>
<p>The SERVER should be run first and listens for four connections on four consecutive ports. It has four data generators, running at different rates.  When data is available, it transmits it over the connection  if there is one, or listens for one if there&#8217;s not.</p>
<p>The SERVER uses a re-entrant VI so that the same code can be executing in four instances at one time.  The four instances are given four different intervals. The WAITs do not conflict because of this reentrancy.</p>
<p>The CLIENT initiates four connections to these same ports, and waits for data in four loops.  I did not use reentrant VIs here, because of the connection to the charts.  Although you could pass a reference to the chart to four reentrant subVIs, I chose not to, thinking that the speed would be better with the direct approach.</p>
<p>Given that this is based on the mSec Timer in LabVIEW, I wouldn&#8217;t vouch for it&#8217;s accuracy as you approach 1000 Hz. But the basic techniques are sound and will work beyond that frequency.</p>
<p><a href="http://culverson.com/site09/wp-content/uploads/MultiConnect.llb.zip">Click here</a> for a downloadable example of four-channel client server communications.</p>
]]></content:encoded>
			<wfw:commentRss>http://culverson.com/the-next-step-in-tcpip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Speed of En Masse Operations</title>
		<link>http://culverson.com/speed-of-en-masse-operations/</link>
		<comments>http://culverson.com/speed-of-en-masse-operations/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 18:04:03 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[LabVIEW]]></category>
		<category><![CDATA[Timing]]></category>

		<guid isPermaLink="false">http://culverson.com/?p=193</guid>
		<description><![CDATA[Zip-zap-zowee and swoosh!
Just in case you thought I was kidding in the article on en masse operations, I decided to offer some proof of the speed advantages they can give you.
I used the Timing Template vi to measure the time it takes to multiply an array of DBLs by two, both with a loop, and [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center; "><strong>Zip-zap-zowee and swoosh!</strong></p>
<p>Just in case you thought I was kidding in the article on <a href="http://culverson.com/operations-en-masse/" target="_blank">en masse</a> operations, I decided to offer some proof of the speed advantages they can give you.</p>
<p>I used the <a href="http://culverson.com/what-time-is-it/" target="_blank">Timing Template</a> vi to measure the time it takes to multiply an array of DBLs by two, both with a loop, and without.  I set up the timing VI to create an array of 1000 random numbers, and then time the multiply operation.</p>
<p>First, the loop method, where you auto-index every value out of the array, multiply it, and auto-index it back in:</p>
<p><img class="alignnone size-full wp-image-194" title="viaLoop" src="http://culverson.com/site09/wp-content/uploads/2009/09/viaLoop.PNG" alt="viaLoop" width="450" height="564" /></p>
<p>As you can see, this took 7.47 uSec per loop.  Not all that shabby.  But just removing the loop lets the <em>en masse</em> operation do it:</p>
<p><img class="alignnone size-full wp-image-195" title="EnMasse" src="http://culverson.com/site09/wp-content/uploads/2009/09/EnMasse.PNG" alt="EnMasse" width="461" height="570" /></p>
<p>Holy Speed Demon, Batman!  That&#8217;s 0.77 uSec or about ONE TENTH the time!</p>
<p>Now, I&#8217;m not guaranteeing that all such operations will save you that much time, but if you have a chance to use them, then you should!</p>
<p>It&#8217;s easier on you and easier on the hardware!</p>
]]></content:encoded>
			<wfw:commentRss>http://culverson.com/speed-of-en-masse-operations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Operations en Masse</title>
		<link>http://culverson.com/operations-en-masse/</link>
		<comments>http://culverson.com/operations-en-masse/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 14:06:47 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[Data Handling]]></category>
		<category><![CDATA[Easier Programming]]></category>
		<category><![CDATA[LabVIEW]]></category>

		<guid isPermaLink="false">http://jimdugan.com/culverson/?p=56</guid>
		<description><![CDATA[The things that I used to do…
En masse is a French term meaning “as a whole” or “all together”; treating a group of something as a single unit.   LabVIEW has the ability to treat arrays this way, which can greatly reduce your workload. If you come to LabVIEW from a text-based language, it’s easy [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><strong><em>The things that I used to do…</em></strong></p>
<p style="text-align: left;"><em>En masse</em> is a French term meaning “as a whole” or “all together”; treating a group of something as a single unit.   LabVIEW has the ability to treat arrays this way, which can greatly reduce your workload. If you come to LabVIEW from a text-based language, it’s easy to miss the capabilities that are right at your fingertips.</p>
<p style="text-align: left;">For example, if you need to scale a series of readings into percent of the total (a procedure called normalizing),  then you tend to think:</p>
<p>I need to find the total:</p>
<ul>
<li>I need to start with a zero sum     <em>sum = 0.0;</em></li>
<li>I need to loop over every element  <em>for (int i = 0; i &lt; nElements; i++)</em></li>
<li>I need to add this element to the sum   <em>sum += array[i]</em></li>
</ul>
<p style="text-align: left;">Now I need to divide each entry by the total, to get the fraction of the total:</p>
<ul>
<li><em>for (int i = 0; i &lt; nElements; i++)</em></li>
<li><em>array[i] /= sum;</em></li>
</ul>
<p>Now I need to multiply by 100 to get percentages:</p>
<ul>
<li><em>for (int i = 0; i &lt; nElements; i++)</em></li>
<li><em>array[i] *= 100.0;</em></li>
</ul>
<p>That’s all well and good, and you could translate that literally into LabVIEW and it will get you the answer you want to see.  But that’s not the LabVIEW way of thinking.</p>
<p>What newcomers often fail to realize is that most primitive numeric functions (the ones with yellowish icons) will accept an array of numbers directly. This goes for basic arithmetic (add,subtract, multiply, divide), comparisons (greater than, less than, MAX/MIN), and many other operations.  It will happily multiply an array of numbers by a single scaler number, to produce an array of numbers.</p>
<p>This has great power to reduce the work that you do as the programmer. Consider the literal translation of the above code:</p>
<p><a href="http://culverson.com/site09/wp-content/uploads/2009/08/EnMasse-11.png"><img class="aligncenter size-full wp-image-166" title="EnMasse-11" src="http://culverson.com/site09/wp-content/uploads/2009/08/EnMasse-11.png" alt="EnMasse-11" width="498" height="141" /></a></p>
<p>If that’s as good as it gets then why should I go with LabVIEW?</p>
<p>Well, it does get better.  There is a function in the numeric palette called ADD ARRAY ELEMENTS.  If we replace the entire first loop with this function, then we get to this:</p>
<p><a href="http://culverson.com/site09/wp-content/uploads/2009/08/EnMasse-21.png"><img class="aligncenter size-full wp-image-167" title="EnMasse-21" src="http://culverson.com/site09/wp-content/uploads/2009/08/EnMasse-21.png" alt="EnMasse-21" width="476" height="145" /></a></p>
<p>Now for the <em>en masse</em> parts: You can replace the entire second loop with a single operation as well:</p>
<p><a href="http://culverson.com/site09/wp-content/uploads/2009/08/EnMasse-31.png"><img class="aligncenter size-full wp-image-168" title="EnMasse-31" src="http://culverson.com/site09/wp-content/uploads/2009/08/EnMasse-31.png" alt="EnMasse-31" width="475" height="144" /></a></p>
<p>Any guesses what we can do with the third loop?    Yes, that’s right:</p>
<p><a href="http://culverson.com/site09/wp-content/uploads/2009/08/EnMasse-41.png"><img class="aligncenter size-full wp-image-169" title="EnMasse-41" src="http://culverson.com/site09/wp-content/uploads/2009/08/EnMasse-41.png" alt="EnMasse-41" width="474" height="122" /></a></p>
<p>Now you have SO much more room to add comments about what you’re doing!</p>
<p>Now THIS is what makes you more productive in LabVIEW than in C; your chances for error are far less when you let the <em>en masse </em>operators handle the details, and you don’t even have to think about the details.</p>
<p>But be aware of what’s going on, however; there is no magic here.  Under the hood there is still a loop somewhere.  It’s now hidden somewhat; it’s not as obvious, but the work is still being done.  Don’t let the simplicity obscure the real processing that’s going on.</p>
<p>Here is an example of the normalizing function in use, from the real LabVIEW example examples\general\graphs\charts.llb\Draw Stacked Graph.vi (in LabVIEW 8.6. anyway).</p>
<p><a href="http://culverson.com/site09/wp-content/uploads/2009/08/EnMasse-5.PNG"><img class="aligncenter size-full wp-image-170" title="EnMasse-5" src="http://culverson.com/site09/wp-content/uploads/2009/08/EnMasse-5.PNG" alt="EnMasse-5" width="194" height="203" /></a></p>
<p>This amounts to the same as our last part above.  In the example, the array given contains five elements and this is executed only once, so efficiency is not a concern.</p>
<p>But consider if the array was 10,000 elements. Don’t forget that the first operation is doing 10,000 divide operations, and the second is doing 10,000 multiplications.  Can you improve things?</p>
<p>Well, certainly! What you have to realize is that, by the associative property of numbers, (X / sum) * 100 is equal to (100 / sum) * X.  You also have to realize that 100 / sum, in this context, is a constant, and therefore needs to be calculated only once.  In effect, you are dividing by sum and multiplying by 100, but you are doing it 10,000 times!</p>
<p>With any luck at all, you get the same answer every time, so you only need to do it once:</p>
<p><a href="http://culverson.com/site09/wp-content/uploads/2009/08/EnMasse-6.png"><img class="aligncenter size-full wp-image-172" title="EnMasse-6" src="http://culverson.com/site09/wp-content/uploads/2009/08/EnMasse-6.png" alt="EnMasse-6" width="443" height="119" /></a></p>
<p>THIS is why we use LabVIEW!</p>
<p><strong>NOTE</strong>:  <em>En masse </em>is my term for this feature, it is not an official LabVIEW term.</p>
]]></content:encoded>
			<wfw:commentRss>http://culverson.com/operations-en-masse/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>About Type Definitions</title>
		<link>http://culverson.com/about-type-definitions/</link>
		<comments>http://culverson.com/about-type-definitions/#comments</comments>
		<pubDate>Fri, 05 Jun 2009 15:35:28 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[Easier Programming]]></category>
		<category><![CDATA[LabVIEW]]></category>

		<guid isPermaLink="false">http://jimdugan.com/culverson/?p=68</guid>
		<description><![CDATA[The types, they are a-changin’
LabVIEW beginners often either don’t know about type definitions, or don’t appreciate their value. This article will attempt to explain their use and how they can save you boatloads of time and effort.
Suppose you have a cluster of items that’s very handy to your project. For the sake of discussion, we’ll [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><em><strong>The types, they are a-changin’</strong></em></p>
<p>LabVIEW beginners often either don’t know about type definitions, or don’t appreciate their value. This article will attempt to explain their use and how they can save you boatloads of time and effort.</p>
<p>Suppose you have a cluster of items that’s very handy to your project. For the sake of discussion, we’ll call it a <em>channel</em>, and assume this is a data acquisition project. A channel might have these items:</p>
<ul>
<li>Channel Name</li>
<li>Active switch</li>
<li>Scale factor</li>
<li>Units</li>
</ul>
<p>So, suppose you have an array of these to match the channels on your MIO DAQ board.</p>
<p>You might develop a series of VIs that deal with <em>channel</em>s:</p>
<ul>
<li>You need an editor, so the user can rename them, select which ones to use, and scale them;</li>
<li>You need a VI that takes an array of <em>channel</em>s, and configures the hardware;</li>
<li>You need to print the setup, so a VI takes an array of <em>channel</em>s and formats a page for printing;</li>
<li>You need to export the data to a spreadsheet, so another VI takes the array of <em>channel</em>s and produces a spreadsheet.</li>
</ul>
<p>and so on. You’ve defined the cluster and all these subVIs and it all works.</p>
<p>Now, though, you realize that you need to add another item to the <em>channel</em>, namely OFFSET. You have a new 4-20mA transducer which produces a 1-5V signal when you use the right resistor. So, instead of the single SCALE FACTOR (which assumes 0.0EU at 0.0 Volts), you implement the standard linear equation Y = mX + b, where X is the measured voltage, m is the SCALE FACTOR (slope), b is the OFFSET, and Y is the resulting Engineering Units (EU). How do you go about it?</p>
<p>The brute force way to go about it is to open up every instance of the cluster you used, and add an OFFSET term to the cluster. OUCH! In the example, you have 4-8 instances; that’s painful enough, but imagine if you had 50!</p>
<p>A slightly (<em>slightly</em>) more civilized way is to add the OFFSET term to one cluster somewhere, then copy the cluster, and paste it over all the old instances.</p>
<p>One of the good things about LabVIEW is that you can follow all the broken RUN arrows and figure out the places you missed. But is this really what computers are for? After all, LabVIEW knows all these things are broken, it knows WHY they are broken, but it’s YOU that has to chase them all down. So, do this a few dozen times and you might start wishing for a better way.</p>
<h3>A Better Way</h3>
<p>Enter the TYPEDEF, short for Type Definition. A Typedef is a “master” control. To use it, you ask for a new custom control (File | New | Custom Control). Here’s where you define the cluster you want for a channel. The first time you would use the four items mentioned initially. You then set the control menu to STRICT TYPEDEF, and SAVE the file with a name like CHANNEL.ctl. Now, every time you want to use it, you use the SELECT A CONTROL option on the panel palette and choose that file. What you get is a cluster that looks just like the one you made originally. Place one on your VI for exporting, another on the VI for printing, etc., etc. You can copy and paste them just like anything else.</p>
<p>So far, there’s nothing different. Where the value come in is when you need to change it. You may notice that you can’t change the cluster on your export VI. Drag something on top of it, and the something just sits there, on top. It doesn’t get put “into” the cluster. If yuo really do want to change it, you open the CTL file. You can do this thru the FILE menu, or notice that every instance has an OPEN TYPE DEF entry in the pop-up menu now.</p>
<p>If you open the CTL file, you can add the OFFSET term there, and SAVE it. When you do, EVERY INSTANCE of that control/indicator updates to follow! Open any of your VIs that used it, and it will have the OFFSET term in it! You’ve just changed 4-8 (or 40-80) controls in one whack. This is convenient for this example, but on a larger program, it is absolutely essential.</p>
<p>Another use for them is in ENUMs. Suppose you have an ENUM for units, with the options “PSI, kPA, mmHG, InH2O”. You can create that, and copy and paste it wherever you need it, but if you have to add something to the list, you’re in the same boat as the cluster, above. The answer is the same, make it a TYPEDEF, and use the TYPEDEF wherever you need to. Then when it’s changing time, all the instances update at once.</p>
]]></content:encoded>
			<wfw:commentRss>http://culverson.com/about-type-definitions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Terminator</title>
		<link>http://culverson.com/the-terminator/</link>
		<comments>http://culverson.com/the-terminator/#comments</comments>
		<pubDate>Sat, 25 Apr 2009 15:38:50 +0000</pubDate>
		<dc:creator>Steve</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[LabVIEW]]></category>
		<category><![CDATA[User Interface]]></category>

		<guid isPermaLink="false">http://jimdugan.com/culverson/?p=73</guid>
		<description><![CDATA[Make sure that quitting time is followed by happy hour.
Generally, you don’t do anything special in a LabVIEW program to quit; when it runs out of things to do, it terminates. (Quite clever, that). Your program has a loop waiting on the user to do something: when the QUIT button is clicked, the loop stops. [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><em><strong>Make sure that quitting time is followed by happy hour.</strong></em></p>
<p style="text-indent: 1em;">Generally, you don’t do anything special in a LabVIEW program to quit; when it runs out of things to do, it terminates. (Quite clever, that). Your program has a loop waiting on the user to do something: when the QUIT button is clicked, the loop stops. If that is the last thing in your VI, then the VI terminates, and it’s left on the screen for you. Usually, that’s what you want; you quit because you’re ready to add the next feature, or because you decided that the purple font on the pink background was too gaudy, or because you need to find out why the temperature shows -1.33e+44 degrees.</p>
<p style="text-indent: 1em;">But if you compile your program into an executable, the same thing happens (the main window hangs around), but that’s usually NOT what you want here.  The user pressed the QUIT button – why doesn’t it quit?  Most programs make their windows disappear when the user quits, and yours doesn’t do that.   <span style="text-decoration: underline;">You</span> might understand that it really did quit and the window’s just hanging around waiting for you to close it, but unless you enjoy the tech support calls that result, you should consider doing something about it.</p>
<p style="text-indent: 1em;"><span id="more-14"> </span></p>
<p style="text-indent: 1em;">To get that window to close in an executable, you have to QUIT LABVIEW.  Find that function on the APPLICATION CONTROL palette and put it where it will execute when everything in your program is safely shut down.</p>
<p style="text-indent: 1em;">The trouble is, it will ALSO quit LabVIEW when you’re in the development system.  That’s nice in the executable, as all your windows go away just like they’re supposed to. But in the development system, you don’t want to quit developing; you want to stop your program from running.</p>
<p style="text-indent: 1em;">One easy way to satisfy both requirements is to use the <a title="Root Folder" href="http://culverson.com/where-am-i/" target="_blank">ROOT FOLDER</a> vi.  It has an output called NOT IN LIBRARY which connects to the QUIT? input on the QUIT LABVIEW function.  If you’re already using that VI to ascertain your root folder, then just remember the initial value of NOT IN LIBRARY.  Or call it again at quitting time; it’s small and fast.</p>
<p style="text-indent: 1em;">That way, you close up the windows in an executable, but leave it ready in the development environment, and you don’t have to set conditionals, or remember to set a boolean flag in your code.  It works without change in either situation.</p>
]]></content:encoded>
			<wfw:commentRss>http://culverson.com/the-terminator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Beginner&#039;s Guide to TCP-IP</title>
		<link>http://culverson.com/beginners-guide-to-tcpip/</link>
		<comments>http://culverson.com/beginners-guide-to-tcpip/#comments</comments>
		<pubDate>Thu, 02 Apr 2009 15:56:38 +0000</pubDate>
		<dc:creator>Jim</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[LabVIEW]]></category>
		<category><![CDATA[TCP]]></category>

		<guid isPermaLink="false">http://jimdugan.com/culverson/?p=84</guid>
		<description><![CDATA[Talk amongst yourselves.
I guess this Internet thing is here to stay, huh? It can be daunting at first, what with looking at the complexities of a web page and the realization that banks use it to launch nuclear missiles and the military can conduct a million two-dollar transactions in a day (or something like that…:-). [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><strong><em>Talk amongst yourselves.</em></strong></p>
<p>I guess this Internet thing is here to stay, huh? It can be daunting at first, what with looking at the complexities of a web page and the realization that banks use it to launch nuclear missiles and the military can conduct a million two-dollar transactions in a day (or something like that…:-). If you grew up with RS-232 and GPIB as the ways for one box to talk to another, it might seem seriously complicated, what with clients and servers and HTTP and proxies and routers and ports and …</p>
<p>It’s not.</p>
<p>It’s not even close.</p>
<p>The truth is, it’s a whole lot simpler than either of those technologies, at least from a software point of view. And a whole lot more versatile, as well. There’s one analogy that brought it home for me:</p>
<p style="text-align: center;"><strong>TCP communications is just like using a telephone.</strong></p>
<p>This is true in a lot of ways:</p>
<ul>
<li>To make a TCP connection, you have to open a connection to a given IP address (dial a phone number).</li>
<li>To answer a connection, you have to be listening for one (have your ringer turned on),</li>
<li>Once the connection is established, the roles of client and server are established by convention, not by any property of the connection. Either end can send at any time (you can call the office of the U.S. President, but who is the client and who is the server is debatable).</li>
<li>A port is the final destination-specifying part of an address (like an extension).</li>
<li>Figuring out what you’re going to say and how you’re going to say it takes a whole lot more thought than establishing the connection itself.</li>
</ul>
<h3>How to Use TCP in Your Programs</h3>
<p>First, decide how it is to be used. By convention, the “client” is the piece that initiates the call and requests information, and the “server” is the piece that answers the call and dispenses information. Note that this is a general guideline, not a rule: the connection works both ways. How does that relate to your situation? Which piece is going to initiate the call? Which piece will answer? Do you have control of both ends of the connection? If you don’t, you have to play by the rules already established by the other end (if you want to dial up a web server, you can; but what you get back is not under your control).</p>
<p>Next, establish how you’re going to obtain the server’s IP number for the client. If you have a local area network (LAN), you can just fix the address (192.168.xxx.xxx) and store a constant somewhere, or offer it as a user-configurable field. If your project is large-enough scale, you can register a domain name, and the DNS service will connect the name (www.culverson.com) to your IP number. That’s only useful if it’s supposed to be a publicly-available service though. For most small scale projects, make it a user-configurable field and be done with it.</p>
<p>You need to know several VIs, all in the PROTOCOLS: TCP palette:</p>
<ul>
<li>TCP Open Connection</li>
<li>TCP Close Connection</li>
<li>TCP Write</li>
<li>TCP Read</li>
<li>TCP Create Listener</li>
<li>TCP Wait on Listener</li>
</ul>
<p>For the client side, it’s extremely easy:</p>
<ol>
<li>Call TCP OPEN CONNECTION with the IP Number you want to connect to, the PORT number you want to connect to, and a suitable timeout. “Suitable” requires a bit of thought: if you’re dialing across the room on a clean network, 100 mSec might be adequate, but if you’re dialing across the world, then 10000 mSec might be more appropriate.</li>
<li>Call TCP WRITE, as appropriate. For TCP WRITE, you have to provide the CONNECTION ID (obtained from TCP OPEN CONNECTION ), and a string to send. It doesn’t have to be ASCII, you can flatten anything into a string and send it. That is especially useful for sending binary data.</li>
<li>Call TCP READ, as appropriate. For TCP READ, you have to provide the CONNECTION ID (obtained from TCP OPEN CONNECTION ), a MODE (more about that later), and a NUMBER OF BYTES TO READ (more about that later).</li>
<li>When you’re done, call TCP CLOSE CONNECTION.</li>
</ol>
<p>For the server side, it’s only a tad more complicated:</p>
<ol>
<li> Call TCP CREATE LISTENER.  This gives you a LISTENER ID.</li>
<li>In a WHILE loop, call TCP WAIT ON LISTENER, using the LISTENER ID you just got. Usually you use a timeout of -1 (never). You’ll get out of it later. This suspends the loop until a connection comes in; for that reason you have this in a separate loop from your main code.</li>
<li>When a connection comes in, the WAIT ON LISTENER function returns to you without an error. You want to check the error code – when it returns WITH an error, you want to terminate your loop.</li>
<li>If you have no error, then the CONNECTION ID out of WAIT ON LISTENER is valid. Call TCP READ and TCP WRITE, as appropriate.</li>
<li>When you’re done with this connection, call TCP CLOSE CONNECTION on the CONNECTION ID, and repeat the loop, to wait on another connection to come in.</li>
<li>When you’re ready to quit the program, or at least quit listening, call TCP CLOSE CONNECTION, but use the LISTENER ID as an input for that. That will cause WAIT ON LISTENER to terminate with an error, and your loop to stop.</li>
</ol>
<p>For the MODE parameter to TCP READ, there are four choices, as detailed in the HELP for that function. I almost always use BUFFERED, so that I get either nothing, or the amount of bytes I requested. When talking to an instrument that sends Carriage Returns / Line Feeds, I will use CRLF mode, so that I get things a line at a time. I have never used the other two modes. I also usually use a timeout value of zero, so that it returns immediately, with either a whole message to deal with, or a timeout error. In any case, I have better things to do that wait around for the message to come in.</p>
<p>So, how many bytes do you request? Good question. There are two methods in common use, each appropriate to some circumstances. The first is to design a protocol that uses a fixed length. If all messages can be sent in 13 bytes, then use 13 as a message length, and you’re done. Anything that is shorter can be padded up to 13 bytes, and it’s OK. For other situations, that is not adequate. In one project I’ve done, some messages can be a single byte, others can be several thousand. It would be very wasteful to pad every message up to 4000 bytes, so a better scheme is needed. The answer is to send a fixed-size header, and then a variable-sized data portion. The header includes a number specifying the length of the data portion. So each receive operation must actually read twice; once to read a header, and once to read the payload. LabVIEW documentation suggests that it is better(faster) to combine the header and payload and do a single TCP WRITE than to do two separate TCP WRITEs for the header and payload. That means the OS handles it as one transmission, not two, which makes sense.</p>
<p>So, for my case, I designed a HEADER typedef (you are using typedefs, aren’t you?), consisting of two fields: a COMMAND field (1 byte) and a PAYLOAD SIZE field, a two byte integer (U16).</p>
<p>The COMMAND field contains an enumerated typedef, defining what type of message this is. The SIZE field specifies the payload to follow.</p>
<p>The receiving end can therefore use a common procedure to receive messages. First you read 3 bytes from the connection, and unflatten it into a header. Then you use the PACKET SIZE field of that header to determine how much more to read for the payload.</p>
<p>That’s all there is to it! Well, except for that pesky bit about what to say. You still need to decide what the protocol is going to be. That’s just another way of defining who’s going to say what when. Does the server answer with a “Hello”, or does the server expect the client to ask the question first? If you control both ends, it’s entirely up to you.</p>
<p>Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://culverson.com/beginners-guide-to-tcpip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
