LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Looking for suggestions on program structure

Hi,

I hope this hasn't been covered before, but I'm new to this board. I am in the process of reworking a diagnostics program and am wondering if someone might have a general idea of the optimal structure. The program works like this:

LabView interfaces with target hardware that is continuously spitting out diagnostic data on a RS-485 port. Occasionally, the user may click a button the on the Labview front panel that sends data back to the target HW, expecting a response. The data communications are a packet format with a header, length, command, and associated data.

My question is this: Would it be faster to have one VI read ALL of the packet, including the data and pass that to another VI for display, or would it be faster to just have the network VI read the header, length, and command, and send that to another VI that reads the data as it comes in. Remember, everything is RS-485 running at only 115kBPS so it's fairly slow. How long would it take to pass 16 32-bit numbers from one VI to another? Is that an insignificant amount of time?

Thanks,

Jason
0 Kudos
Message 1 of 14
(3,693 Views)
How long would it take to pass 16 32-bit numbers from one VI to another? Is that an insignificant amount of time?


Yes, don't worry about that amount of data. Structure it any way you like, but I wouldn't base any decisions on that argument-passing time.



I would have one thread (while loop) reading and displaying the data, while another loop waits for the button press (or a QUIT button press, whatever other UI you need).

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

Message 2 of 14
(3,664 Views)
Thanks, I am structuring the program like that. Actually, I have three things going on:

1. Data is being continuously streamed into the LabView application via a network protocol:
[Header, Length, Command, Data]
2. That data has to be either:
a. Routed to the scope displays (dependent upon the command)
b. Routed to other command handlers (dependent upon the command)
3. Button presses occur, which generally induce transmission of a command out of the VISA serial port

My plan is to structure this three loops:
1. Network packet handler producer loop - sends data to the consumer loop
2. Consumer loop - handles incoming packets, including streaming data
3. Button press loop - sends data back on the VISA output

Does this seem reasonable? Or would it make more sense to have the network handler handle both Tx and Rx events?

Thanks,

Jason
0 Kudos
Message 3 of 14
(3,633 Views)
Well, I can't say it's wrong, but I don't know why you have a receiver loop and a "consumer" loop. If the "consumer" only consumes data from the receiver, then I don't see why they shouldn't be in the same loop.

And if your XMIT is only in reply to receiving something, then it makes sense to have it in the same VI. Something like:

If Packet Received
Case Packet.Command of
New Data: Display New Data (Packet.Data)
New Status: Display New Status (Packet.Status)
Need Info: Transmit Reply (My Current Info).
Shutdown: CloseConnection (myConnectionID).

etc...

The button and VISA stuff would be in a separate loop.
Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 4 of 14
(3,624 Views)
I guess the reason I put them in two loops is because I just finished the LabView Intermediate I class 🙂 But seriously, the reason I did this was because receiving data from the network and stripping out the command and associated data seemed to be something that would ideally warrant its own loop and queue structure. Although this is running on a PC, I am mainly trying to optimize for speed. The network connection is RS-485, so it is relatively slow. In the produce loop, I have one case statement for each of the network packet pieces - header, length, command, and data. Only when it is complete, do I enqueue the command and data as a cluster and send it to the consumer loop. This might give a speed boost because the producer loop can be processing data while the consumer loop is, for example, waiting for the next command after a length byte.

I guess this gives rise to an additional question: If I am waiting on a VISA read and there's nothing there, will the loop give up and let another loop run?

I did have this all in one loop before, but it got a bit complicated. Also, since we wish to use this on multiple programs, we want the ability to easily modify the consumer loop, something I supposed you could do the other way, but this way is it "separate".

Does this make sense? Sorry if not, I'm pretty new to LabView programming. I'm used to C programming and thinking object-oriented is a bit different for me.

Thanks much for the help,

Jason
0 Kudos
Message 5 of 14
(3,624 Views)
I didn't realize your "network" was not TCP, but I don't think it matters.

My general rule for this is that if the XMIT is only in response to a RECEIVE then they belong together. In that case you could not transmit anything without receiving something first.

If I am waiting on a VISA read and there's nothing there, will the loop give up and let another loop run?


From the HELP docs: The operation returns only when the transfer terminates.


Well, "give up" is not the right term, but it will sleep the thread it's in. That means that other WHILE loops in the same VI or other VIs will continue to run.


If you want to use the "consumer" in other programs, then by all means make it a separate loop. Use a queue to pass from one to the other.

Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

0 Kudos
Message 6 of 14
(3,618 Views)
>My general rule for this is that if the XMIT is only in response to a RECEIVE then they belong >together. In that case you could not transmit anything without receiving something first.

In this case, the XMIT is in response to a button press. Maybe I haven't done a very good job of describing the system. The way it works is this:

There's streaming data constantly coming in from the target hardware on the RS-485 bus (VISA). This is in the format if a network packet with [header, length, command, and (multiple channels of)data] as I previously described. Interspersed with the STREAM command are other commands which have to be handled differently, such as the GET_GAIN command. It's sort of a command/response thing with the exception that STREAM does not require a command. The GET_GAIN would be generated by a button press, and in fact, would trigger up to 6 consecutive GET_GAIN commands. (Each would have to wait for a response before sending the next - another design issue).

I did this so continuously display data on the scopes and minimize interruption.


>>If I am waiting on a VISA read and there's nothing there, will the loop give up and let another >>loop run?
>Well, "give up" is not the right term, but it will sleep the thread it's in. That means that other >WHILE loops in the same VI or other VIs will continue to run.

Yes, you're right and that is what I wanted - to have it sleep while waiting, so we can process the data in other loops.

>If you want to use the "consumer" in other programs, then by all means make it a separate loop. Use >a queue to pass from one to the other

A queue seems to work fine. Thanks for the responses, this is my first program.

Jason
0 Kudos
Message 7 of 14
(3,613 Views)
Hi,

One quick question - how can I do a quick lookup? I wish to have a function that takes a hex string, such as A0, A1, A2, etc. and returns a unique index for an enumerated data type - and I want to be able to specify the text, not the numeric index. C code would probably be a case statement. I am assuming LabView can do this with some sort of searching through a Nx2 table for a value, then using the index to return the value in the second column, like this:

A0 TEST
A1 GET_PARM
A2 SET_PARM

So, if you input hex "A1", it finds it at index 2 then returns "GET_PARM". Any ideas? Can I do this with one array?

Thanks,

Jason
0 Kudos
Message 8 of 14
(3,588 Views)
I'm not 100% what you're asking, but here's an answer - maybe it fits your question.
You have an enum, say:
TEST | GET_PARM | SET_PARM

By the way, do the world a favor and DON'T use the underscores. They're not needed in LabVIEW.

You have an enum, say:
TEST | GET PARAM | SET PARAM | WHATEVER

You have a text string that corresponds, say:

"A0" | "A1" | "A2" | "E3"

then I would use a CASE statement to translate:

Case InputString of
"A0": OutputValue := TEST;
"A1": OutputValue := GET PARAM;
"A2": OutputValue := SET PARAM;
"E3": OutputValue := WHATEVER;
end;

No array needed. No muss, no fuss. Wire the string to the selector and set the cases to what you wish to detect.
Steve Bird
Culverson Software - Elegant software that is a pleasure to use.
Culverson.com


LinkedIn

Blog for (mostly LabVIEW) programmers: Tips And Tricks

Message 9 of 14
(3,577 Views)
That sounds great! How do I do that - a formula node?

Jason
0 Kudos
Message 10 of 14
(3,570 Views)