LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

reentrant serial port access problems

I have a variable number of devices connected to the serial ports (actually USB virtual serial ports). The serial ports are polled to see if a device is present. Those with a device present are presented to the user. A reentrant subvi is dynamically loaded to provide a GUI for each device the user wants to use.

I have tried several methods but "RunVI" with "wait until done"=false provides the correct operation. But this is then messy since I have to also use FP.open and CtrlVal.Set to preload the com port and some title text to the rentrant vi. (serial port initialisation and closing is done inside the reentrant VI)

Qustion 1) is there a better way to do this?

Question 2) "terminal standalone.vi" runs correctly when launched as a vi but when run as above the read VISA vi stops working after the first newline character received - (there are no errors) it hasn't crashed the vi since there is still interaction with the front panel - just no serial coms after the first line!

Should I be able to initialise VISA / write VISA / Bytes at port / Read VISA in a reentrant vi?

0 Kudos
Message 1 of 11
(3,482 Views)
I have also found that with the above reentrant subvi that the property "KeyFocus"=True has no effect - this works fine if I deselect reentrant operation. Any ideas what is going on? Are there properties / functions that I need to avoid when using reentrant subVIs?
0 Kudos
Message 2 of 11
(3,466 Views)
You didn't show much code there.  Why don't you attach terminal standalone.VI?Smiley Wink  Where do you tell each copy of the VI which serial port to use?
Message 3 of 11
(3,439 Views)

Here is the terminal program Smiley Happy . What I want to do is load the VISA, title and history length to the settings cluster then run and then return to the launch program without waiting for the terminal subVI to finish running. I would then launch several more terminals for the other devices (different ports).

If I want to "launch and leave running" the terminal I think that I'm forced to use the "RunVI" method but this means I don't have access to the connector pane. Therfore I open the VI reference using option "8" to prepare for reentrant operation then show the front panel ("FP.open" method) and then load the settings with the "Ctrl Val Set" method first.

Is there a better way to do this?

Any ideas why I get the unexpected behaviour mentioned in my original post?

0 Kudos
Message 4 of 11
(3,424 Views)

It looks like you have a race condition going on.  You are using several local variables for the Monitor indicator.  You are using it in 3 places:  as part of your write operation, with the results of your read operation, and stripping out a new line character, in addition to clearing it at the begininng of the VI.  If monitor is intended to show the results of your read operation, why are you using it as a part of your write operation?

 

Where the race condition comes into play is with the local variables.  There is no dataflow order between when the monitor indicator is read and written to in the VISA read case structure vs. when it is read and written to in the lower part of the loop.  The read and writes could happen and any time relative to each other and cause the various parts of the code to step all over each other in trying to update the monitor string.

 

1.  The use of the monitor string as a part of your VISA write operation makes no sense to me.

2.  Use a shift register to store the monitor string between iterations and wire between the various case structures.  Only use an indicator in the loop.  The use of the local variable before the loop to clear the string is okay.

Message 5 of 11
(3,399 Views)

The write case takes the command surrounds it by "*" and appends to the monitor control at the same time writes the command to the serial. (so you know what you've typed - it actually makes it very easy to use and looks good!)

The read case reads any available characters from the serial and writes them to the monitor control.

The third case strips out excess lines from the monitor control i.e. only keeps the visible lines of the monitor plus "history" lines available using the scroll bars.

 

I've removed the locals and replaced with shift registers. Its now much more elegant code and the gremlins have gone.

I assume when the subVI is made reentrant what could work by luck before (the order of read / writes to locals) isn't necessarily compiled the same way.

 

Thanks for your helpSmiley Very Happy

0 Kudos
Message 6 of 11
(3,389 Views)

That looks better.  I'm glad it is working now.

 

I do believe that changing it to reentrant could have an effect.  Since the reentrancy setting has a direct effect on execution, I do believe it can affect how LabVIEW will compile it for execution.

Message 7 of 11
(3,385 Views)

Smiley Mad Oh no... unfortunately the main problem is still there. If you launch the terminal subVI with the RunVI method and WaitUntilDone=False then the serial dies without an error (VISA ref OK, no Error and subVI interaction still works)

if you change to WaitUntilDone=True or launch from pressing play then everything is OK.

The same happens if it is reentrant or not - so that was a red herring. AutoDisposeRef has no effect on this problem.

So is it possible to launch a subVI using VISA to access serial by using the RunVI method with WaitUntilDone=False?

0 Kudos
Message 8 of 11
(3,380 Views)

Your reentrant VIs all share the same path, so I'd use a "This VI" reference instead of a "This VI's Path" path constant, which will open a reference to a reentrant VI (which may or may not even do anything to your current instance).  Also, I'd switch to an event driven structure for reentrancy, like the attached.  The error indicator is just to see if anything happens before you get into your loop, because nothing will happen in it until you quit out of it (the errors will skip most of the important steps).

 

edit - there's also a race condition in my first Send Command event (and in your sequence) where the local variable could blank Command before it has a chance to be read, so I replaced it with a Value property node and wired it in after the Visa Write.

Message Edited by JeffOverton on 09-09-2008 04:25 PM
Message 9 of 11
(3,344 Views)

There was no race condition in my version since the "command" control is outside the first case statement.

You are correct the event structure makes for better code and the "This VI" reference is neater (I haven't seen that before do you need to "close reference" after use?)

Rather than have a "send command" button in previous designs I have looked for a "key down" event ="return key" to trigger the send command - more natural for the user.

I have used a modified version of your code called by some test code and it seems to work! but I don't see what is fundamentally different - any ideas?

0 Kudos
Message 10 of 11
(3,339 Views)