LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

fast communication using visa / serial

Hi,

 

I've been using labview for years and have communicated to lots of equipment using visa, gpib, serial, tcp/ip.  I just would use basic methods to communicate at just average speeds. 

 

Normally I would just set up a visa connection set the timeout to 0.2 seconds and just send a write command to ask for data, put a 0.1 second delay and then use a read command that would read 1024 bytes.  It would read all the data on the buffer and then timeout and I'd get the data somewhat fast.

 

But now I'm wanting to communicate as fast as possible with a serial piece of equipment using visa. I've read that you're supposed to read back how many bytes are on the serial port and then just read in taht many bytes, then I don't have to wait for the timeout.  I'm still trying this and getting some errors.

 

Basically, can anyone point me to some really good examples, tutorials or something to teach me about how to do the fastes type of communication with serial/visa?

 

thanks,

-Jesse

0 Kudos
Message 1 of 25
(8,100 Views)

One of the ways to improve serial com throughput is to use handshaking and/ or termination characters.  Essentially you want to go from "exchanging bytes" to "exchanging packets of data" or messages.

 

start by defining the message with some way of breaking up messages. Commonly this is done by appending a 0x0A (eom) to let the recieving device know that the package is done.

 

VISA ser inst class can be set to read until a termination character is recieved vastly speeding the data exchange


"Should be" isn't "Is" -Jay
0 Kudos
Message 2 of 25
(8,086 Views)

I shall assume that you've looked at the LabVIEW examples (help > find examples), because the basic serial write and read.vi in there is a pretty good starting point. If you have multiple reads and want to keep the VISA connection open it starts getting more complicated, but if you put the property node into the advanced serial write and read.vi you should start getting close.

 

A better description of the errors might help (errors in the error cluster or just in the returned data?).

0 Kudos
Message 3 of 25
(8,078 Views)

going with the idea that "the most efficient form of recycling is reuse" I now present a cut-n-paste from this thread.

 


The following images show how I handled a similar (???) situation. THis code monitors a serial port to which is attached a 3-axis anemomter that gives me three values that record the air speed as vector of (U,V,W). Depending on the model it may have a 30 degree offset in the UV plane or could be mounted upside down (inverted).

 

When the time comes to check the port the following code is invokde.

 

Parse_Packet.png

 

after reading all of the bytes waitng at the serial port (Visa Property nodes >>> bytes at port tells me the count) the new data is passed to a sub-VI (see below) that determines if we have a complete frame of data coming from the widget. If so the packet is parsed for the data using "Scan from String" (Note: Packet also contains anemometer name that I used to make sure users did not connect wrong widget to port). The thrre values of the vector are then passed to another sub-VI where the values are adjusted and packed into an array of waveforms that can be plotted on a chart or pltted to a 3D garph to illustrate the wind direction and magnitude.

 

Images of the two mentioned sub-VIs follow

 

Find_Frame.png

 

FInd Frame

This sub-VI uses a shift register to accumulate the data from the serial port into complete packet that start and end as we expect by seraching for the "Terminator". Whn a complete packet is found the packet is returned andthe caller flagged that a packet was found. If there are extra bytes left over, they get strored in the SR for use in the next packet.

 

Build_Waveform_array.png

 

 

THis sub-VI does the adjusts and then builds an array of waveforms that can be plotted on a chart. I like the "waveform" (WF) data type because it lets me control the time stamp (see above) so that when the data gets plotted, it is ploted at the correct time (since serial is seldom periodic). WF data types also allow assign attributes to the data. One attribute I use is the name so that the charts will automatically pcik-up the name for the plot legend from the data and it will automatically adapt when another set of data is presented to the chart ( but now I digress)..

 

So that is how I typically handle serial. I hope it gives you some ideas to work with.

 

Ben

 


Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 4 of 25
(8,071 Views)

Jeff, 

 

I have also read a little bit about setting the termination character and turning on the ability to end the read command when it sees the termination character.   It was only a small paragraph saying this could be done.  Is there somewhere that shows examples and explains exactly how this should work?

 

For the past 3 hours I've been trying to use the "bytes at port" method and haven't really gotten any success.  I'd rather use the termination character method if possible.

 

thanks everyone for the help.

0 Kudos
Message 5 of 25
(8,058 Views)

Check out the Advanced Serial Write and Read in examples, it shows it all. It's part of the options via the VISA Serial Configure Port.vi

 

As to how it should work, you need to look at the very basic information for how serial communications work - you need to understand the communications protocol, usually you're looking for line feeds. But, if your termination character is more complicated, then it gets a little more complicated, and Bens post should get you closer from the quick look I gave it.

0 Kudos
Message 6 of 25
(8,051 Views)

Ben,

 

I think my situation is a little different than your example.  It sounds like your device is constantly sending data?  So you are always checking the serial port for new data?

 

My situation is that I have to send a command to the serial port, then wait for the data to come back.  Usually I just send the command, wait a solid amount of time so the equipment can respond, then do a visa read, and let the timeout value cancel the read.

 

I also tried using the "Bytes at port" inside of a while loop until it returns a value greater than 0, then use another "bytes at port" and a visa read in a while loop.  But these would not work at all unless I put delays inside the loops to slow them down, which then just makes my program as slow as it was before.  I'm sure I'm still doing something wrong though.

 

thanks,

0 Kudos
Message 7 of 25
(8,049 Views)

Yes the devies is in spew mode. Those are generally the hardest protocols to handle since you seldon start up with a good packet.

 

If you use a "zero" wired to "wait ms" function, it will release the CPU for other threads if they are executable.

 

You could also try using the advanced function under VISA to configure and wait for a VISA event when a charater shows up. The code constrct would be similar to the above the difference bing do you wait for an event or check for the bytes.

 

 

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 8 of 25
(8,036 Views)

Kathryn,

 

I'm checking into that advanced serial write and read examples.  I'm going to go back and try to figure out what this device's termination character is.  I use a serial port sniffer to find out how this thing communicates.

Even if I get the read portion to work,  is there still a chance that my write commands might be taking to long?  If I dont specifiy a termination character for my writes, does that create slowness to my equipment?

 

thanks,

0 Kudos
Message 9 of 25
(8,033 Views)

I have written lots of stuff which are a command/response type of communication where I have no idea how much data is coming back. The approach I use is to have a read of 1 byte with some reasonable timeout value (5, 10 or 60 seconds depending on your application) so I don't wait forever. Once I read a single character I go into a loop which reads small blocks of data and I use a much smaller timeout (something in the range of .05 to .5 second. again depending on your application). I continue to read data until I get a timeout. the assumption is that once the sender starts sending the data I should see a steady stream of data with no breaks in it. The small timeout allows me to respond fairly quickly to the end of data. Using a longer timeout will introduce delay for all of your communications. If I am doing serial communications I may put some intelligence in the determination of the delay by taking the BAUD rate into consideration and programmatically calculate a reasonable timeout.

 

You can specify a timeout for the write but I would set this according to the BAUD rate being used. Determine how much data you need to send and calculate the absolute minimum time required to send the data. Add some slop to allow for potential delays due to flow control and use this as the timeout. If you are sending a large block of data and have a small timeout you may not be allowing enough time for all the data to be transmitted.



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
Message 10 of 25
(8,024 Views)