LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

dynamic string array

I need to make a dynamic string array.

Deeper explanation:

I am trying to use a FOR loop to send a series of commands to an 8-channel device.  Each channel requires 7 (actually, 1/2 need only 5, the other 1/2 need 7) strings to set them up and the entire sequence needs to be performed 8 times.  I started a test .vi by simply using a constant array of type sting.  I can sequentially pick each string and program my device perfectly.  Now I'd like to do things like add the channel # somewhere in the mix, use variable values based on other controls in my .vi to set the parameters of the channel.

EXAMPLE:
The user sets certain values that determine delays and width for an 8-channel DDG (Digital Delay Generator, to some, a pulse generator).  These values then need to be loaded into the DDG.  The Strings will look something like this:

:PULSE1:STATE 1
:PULSE1:WIDTH 0.009 000           *NOTE:Spaces behind decimal are for better viewability only
:PULSE1:DELAY 0.000 000
:PULSE1:SYNC T0
:PULSE1:CMODE DUTY
:PULSE1:PCOUNTER 1
:PULSE1:BCOUNTER 1

:PULSE2:STATE 1
:PULSE2:WIDTH 0.000 300
:PULSE2:DELAY 0.008 700
:PULSE2:SYNC T0
:PULSE2:CMODE NORMAL


So widith and delay params change, the pulse# changes, and whether it's on certain channels decides if the mode is duty or normal and duty comes with the subsequent params pcount and bcount.

help?

PS - I am going to move the state, sync, and cmode to a common, initialize loop run only at program start, but I still need to use width, delay, and (variably) pcount and bcount.

PPS - I am trying to edit post to diable smilies.  Commands should read:"colon, P (or D)" not :P, 😄

PPPS - Success, at least for me.  I disabled smilies in my settings, I don't know if that means my posts won't show smilies or if just what I am looking at won't show smilies, any responders let me know how it's showing for you.

Message Edited by Radiance_Jon on 07-16-2007 01:48 PM

Message Edited by Radiance_Jon on 07-16-2007 01:52 PM

0 Kudos
Message 1 of 20
(4,547 Views)
I at least see a bunch of smilies and the icon with the smily sticking its tongue out. I'll try not to take it personally. Smiley Wink

It seems to me that you should look at the "Format Into String" function. This will allow you to create your string based on any number of parameters. You can even, if you wanted to, have it create the entire list of commands at once with the proper format string. For example, your "PULSE1: STATE 1" command would have a format string of "PULSE%d: STATE %d".

Message Edited by smercurio_fc on 07-16-2007 02:07 PM

Message 2 of 20
(4,507 Views)
smercurio_fc:

Thanks, I had thought about taking this approach.  I chose not to (right or wrong, I do not know, I am not a Comp Sci/Engr, just a lowly EE) use this method because I'm sending so many command string (4*5 + 4*7) and the only thing common to them all is ":PULSE".  HEre's how I have sort-of solved the problem thus far.




I am about to tackle the issue of choosing which channel is duty cycle and which is normal
0 Kudos
Message 3 of 20
(4,489 Views)
Well, in the left frame you seem to be sending 10 commands as some sort of setup. In the right frame it's a bit hard to tell since the screenshot is so big everything is fuzzy. But, it seems that you're sending 3 commands 6 times each, each time changing the number after "PULSE". The stuff you're doing in the right frame with the string is more easily accomplished (and more straightforward) using the "Format Into String" function.

A couple of other points:
  • You can use auto-indexing rather than setting the value of "N" for the loop in the left frame and the outer loop in the right frame.
  • You are not handling the errors properly. You are passing the errors between the VISA Write and Read functions but you're not doing anything with them. If an error occurs during any iteration of the loop the error gets lost. You should be using a shift register to pass the error around. Doing this you can connect the two sections of code with the error out from one loop to the error in of the other loop and eliminate the sequence structure.
  • You seem to have two VISA resource name controls, yet your original post implied you only had one device.
  • I don't see where the width or delay is set.
Message 4 of 20
(4,481 Views)
smercurio:

You are being extremely helpful, I appreciate your feedback.  I guess at this point you can tell how little of a programmer I actually am. 

I don't care to handle the errors at this point in time.  I decided to not worry about them since this is for an R&D project.  It MAY someday become and end-user program, but IF and when that time comes I will handle errors.  At this time I will be the primary operator of this program and all the equipment hooked up to it (well, not actually, but my PM and I will be working side-by-side and his left the ball in my court for most of this stuff to keep his realm of responsisbility a little quieter).  I realize this is a big no-no in the software world, but the nature of R&D is often to concern oneself with time deadlines and ignore convention or style if it is not absolutely necessary.

I have NO idea what auto-indexing is.... sorry, I'll likely go look that up when I am done typing this.

I will be setting width and delay elsewhere.  What I have set so far are merely one-time initialization params for the device.  I will only need to do all these once at startup.  But good eye... you are clearly paying close attention to my original question, so thanks again for the very thorough help you are providing.

Yes I do have to VISA resource name controls, and as you have noted I am only using one device.  I tend to program in modules and then copy-paste things over when I know the general idea works.  I failed to clean this detail up.

You mentioned I do not need the sequence structure, but you mentioned it in relation to the error handling.  Are they somehow related as I have them implemented at this time?  I am only using the sequence structure b/c I was stepping through the code and I got a little aggravated at how NI seemed to handle the loops in those two frames concurrently - it made debugging a little more time consuming and frustrating.  I don't know if this is necessary or a good or bad idea, just my solution for purposes of debugging.

Thanks again for all your help!
0 Kudos
Message 5 of 20
(4,472 Views)
Well, in my experience I have found that dealing with errors early on is the best course of action as it leads to less headaches down the road...Smiley Wink

Auto-indexing is one of the more powerful features of LabVIEW. If you're familiar with text-based languages it's equivalent to the "foreach" statement. Basically it allows you to wire an array into a for-loop and the size of the array tells LabVIEW how many times the loop needs to execute. Inside the loop LabVIEW peels of each element of the array in order for each iteration of the loop. Looks like this:


My comment regarding not needing the sequence frame was related to using the error cluster since that wire would allow you enforce data dependency like so:


Note that the VISA resource wire does the same thing.

"I got a little aggravated at how NI seemed to handle the loops in those two frames concurrently".  That's because LabVIEW is a data-flow language, and not a sequenced language like C or VB. In fact, that's one of the things that makes LabVIEW so powerful.

Message Edited by smercurio_fc on 07-16-2007 04:48 PM

Download All
Message 6 of 20
(4,467 Views)
Oh, I also didn't understand why the "Format into string" function would be more appropriate here.  If I used that wouldn't I have to have three different implementations of it, one for each "line" in the string array I already have?  And even then some of the other paramaters are not the same every time.  Here is a list of all the strings I need made:

Note: I have put spaces after all colons to avoid smilies.  the only spaces that should be present are b/t the last sub-system and the parameter.

: PULSE1: STATE 1
: PULSE1: SYNC T0
: PULSE1: CMODE NORMAL

: PULSE2: STATE 1
: PULSE2: SYNC T0
: PULSE2: CMODE DCYCLE
: PULSE2: WCOUNTER 0
: PULSE2: PCOUNTER 1
: PULSE2: BCOUNTER 1

: PULSE3: STATE 1
: PULSE3: SYNC T0
: PULSE3: CMODE NORMAL

: PULSE4: STATE 1
: PULSE4: SYNC T0
: PULSE4: CMODE NORMAL

: PULSE5: STATE 1
: PULSE5: SYNC T0
: PULSE5: CMODE NORMAL

: PULSE6: STATE 1
: PULSE6: SYNC T0
: PULSE6: CMODE NORMAL
: PULSE6: WCOUNTER 0
: PULSE6: PCOUNTER 1
: PULSE6: BCOUNTER 1

: PULSE7: STATE 1
: PULSE7: SYNC T0
: PULSE7: CMODE NORMAL
: PULSE7: OUTPUT: MODE TTL
: PULSE7: WCOUNTER 1
: PULSE7: PCOUNTER 1
: PULSE7: BCOUNTER 1

: PULSE8: STATE 1
: PULSE8: SYNC T0
: PULSE8: CMODE NORMAL
: PULSE8: OUTPUT: MODE TTL
: PULSE8: WCOUNTER 1
: PULSE8: PCOUNTER 1
: PULSE8: BCOUNTER 1

So I need to set WCOUNTER to 1 on 7 & 8, and set DCOUNTER to 0 on 2 & 6, I need params for PCOUNTER, & BCOUNTER on 2 & 6-8, I need CMODES set to NORMAL for 1 & 3-5 and to DCYCLE for 2 & 6-8, and finally, I need to set channels 7 & 8 to TTL (all others are already optical and change is not permitted in the DDG).  That's a mouthful!  These are all givens and will never change.  I guess I should have just hard coded them all!  Man, I am retarded!  The following params will vary based on user input:

: PULSE1: WIDTH [VARIABLE]
: PULSE1: DELAY [VARIABLE]

: PULSE2: WIDTH [VARIABLE]
: PULSE2: DELAY [VARIABLE]

: PULSE3: WIDTH [VARIABLE]
: PULSE3: DELAY [VARIABLE]

: PULSE4: WIDTH [VARIABLE]
: PULSE4: DELAY [VARIABLE]

: PULSE5: WIDTH [VARIABLE]
: PULSE5: DELAY [VARIABLE]

: PULSE6: WIDTH [VARIABLE]
: PULSE6: DELAY [VARIABLE]

: PULSE7: WIDTH [VARIABLE]
: PULSE7: DELAY [VARIABLE]

: PULSE8: WIDTH [VARIABLE]
: PULSE8: DELAY [VARIABLE]

0 Kudos
Message 7 of 20
(4,461 Views)

@smercurio_fc wrote:
Well, in my experience I have found that dealing with errors early on is the best course of action as it leads to less headaches down the road...Smiley Wink

Auto-indexing is one of the more powerful features of LabVIEW. If you're familiar with text-based languages it's equivalent to the "foreach" statement. Basically it allows you to wire an array into a for-loop and the size of the array tells LabVIEW how many times the loop needs to execute. Inside the loop LabVIEW peels of each element of the array in order for each iteration of the loop. Looks like this:


My comment regarding not needing the sequence frame was related to using the error cluster since that wire would allow you enforce data dependency like so:


Note that the VISA resource wire does the same thing.

"I got a little aggravated at how NI seemed to handle the loops in those two frames concurrently".  That's because LabVIEW is a data-flow language, and not a sequenced language like C or VB. In fact, that's one of the things that makes LabVIEW so powerful.

Message Edited by smercurio_fc on 07-16-2007 04:48 PM





MAN!  I KNEW that!!!!  GGRRRRR!!!  That makes sense.  Actually that's WHY I connected the error lines in the first place was to aide in flow control.  OH!!!  Still getting used to LabVIEW. 

But I still have a question related to flow control.  Check out the pic below.  LabVIEW runs everything in a seemingly random order... well at least where it STARTS each chain of data.  It obviously starts with the static constants or the earliest data in each chain, but I can't figure out how in the world it's deciding WHICH chain to start first.  It kind of seems to go with the lower right and work it's way to top-left, but it doesn't exactly do that either.  I dunno if it's worth you answering this concern or not, but if you got one for me I'd be much obliged. 

I should take a LabVIEW class!  Yeah right, as if they'd let me... R&D means I won't need it tomorrow ;( which stinks cause I'm liking LabVIEW the more I learn it.  (I was not fond of it in the beginning, but that was my stubborness). 

thanks again so much for all your help!!!!




Also, I am using all those strings to make my display appear as I want it to... I wonder if there is another way?  I am aware of system labels, but I like the look of the recessed, grayed control boxes better.






Message Edited by Radiance_Jon on 07-16-2007 05:06 PM

0 Kudos
Message 8 of 20
(4,459 Views)
PS - where in the heck are error in and error out?!?!  I can't find them in the functions palette
0 Kudos
Message 9 of 20
(4,456 Views)
It may seem random, but it's not. It's all based on dataflow, which means that a function will execute as soon as data for it is available. Take this simple example:

In the top example, the left Add function will execute first since its input terminal have the required data from the "x" and "y" inputs. The right Add function cannot execute until the left one is done since one of its inputs requires data that is generated by the left Add function.

In the bottom example both Add functions can execute at any time since for both their input terminals have the required data with no dependency between them. As for which one LabVIEW chooses to execute, it doesn't really matter.

You can head over the NI Developer Zone Learning Center. There are tutorial available there, as well as on external sites. Links for them can be found in the Learning Center. Also, there's a tutorial that comes with LabVIEW.

Message Edited by smercurio_fc on 07-16-2007 05:47 PM

Message 10 of 20
(4,448 Views)