From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Weird VCP COM behavior w/ CP210x Silicon Labs hardware

Solved!
Go to solution

I am using a conductivity meter (cond 3310) from WTW, which has a CP2102 VCP (virtual COM port) adapter chip inside it. Once running, the meter spits out a reading automatically every second, and my VI reads those values in. Everything was going fine at first, then I noticed it was not reading "live" data. In other words, when I change conditions (e.g., 0 vs 800 uS conductivity), I see the meter face change within 1-2 second, and if I use TeraTerm, it also switches back and forth. But under Labview it gets "stuck" reading the same data forever.

 

I can "fix" things If I close my VI and re-open it (i.e., it will correctly start reading the latest data from the meter), however it won't follow any subsequent changes in the readings. But if I simply stop the VI and restart it, it won't "fix" itself (regardless of whether I "Abort" it from the LV Icon, or hit my 'STOP" button which closes the COM port).

BTW, another weird quirk is that if I hit "STOP" and close the port, the very next time I run it I receive an "overrun" error in the VISA Read function. Any subsequent running of the VI doesn't get an overrun. But just aborting the VI and restarting doesn't create an overrun.

 

In the attached VI, I selected some indicators to display default data that I typically see, for anyone's possible benefit (because you don't have my hardware to play with), but the values obviously depend on the particular conductivity (and temperature) values that the meter is reading.

 

It seems well confined to Labview. I.e., I can run over and over, quickly close the port and watch the port with Teraterm, and it pretty much immediately follows the meter's display when conditions change, then switch back to my VI and see it reading stale data again.

 

Any thoughts folks?

0 Kudos
Message 1 of 7
(2,625 Views)
Solution
Accepted by topic author paul_bridges

It looks like you have a complicated packet of data coming in, but it is keyed around the use of the linefeed character as a termination.  Rather than having all of those embedded loops to look for the termination character, take advantage of it!

 

Read a large number of bytes.  The VISA Read will automatically terminate once it sees the linefeed.  Now instead of a complicated loop structure, you have a single VISA Read.  To get rid of the 5 next lines, just do a VISA Read in the For Loop with a large number of characters.

 

I think a major problem with your code (besides the use of the stacked sequence structure), is that your final VISA Read has an uninitialized shift register on the loop that it is in.  That means the read string you are operating on is always growing longer.  Thus the analysis you are doing is always working on the same stale data at the beginning of the string.  Again, if you get rid of that loop and just read a lot of bytes, let's say 100, you should always see fresh data.

Message 2 of 7
(2,590 Views)

You're exactly right, I don't know how I missed the uninitialized shift register. Like water to a fish, or something like that.

Thank you very much! It works as expected now.

 

I have communicated with dozens of device types over recent years using VCP's, and that "auto-termination" behavior has annoyed me sometimes so as a habit, I choose to not have Labview "help me" under the hood, in order that I can see explicitly what's going on. But I think you're right once you accept that behavior, it does work consistently and can make life easier. 

 

Thanks again.

 

 

0 Kudos
Message 3 of 7
(2,577 Views)

Don't think of it as having LabVIEW "Help" you.

 

Think of it as you telling LabVIEW and VISA to do exactly what you want it to do.  Which is give me everything in the buffer up to the termination character.  Bytes at Port is the wrong thing to use 99% of the time.  If you don't take advantage of the termination character when it is there and are using Bytes at Port, you are micromanaging the serial port.  Now THAT's annoying!

 

Where you should not use and the termination character and should disable it is whenever you are dealing with binary data.  Where a byte of 10 (linefeed) or 13 (carriage return) is considered a normal part of the data stream and you don't want it to cut your message off early.  In those cases, you need other methods to determine where messages start and end.  Commonly some header bytes as indicators for a message start, and some bytes that say "X" number of bytes will follow in this message.

0 Kudos
Message 4 of 7
(2,572 Views)

I think it's the fact that the behavior feels hidden (inside the Read function) that bothered me a bit, particularly if your reading is done far from where you Initialize, compared to text-based languages. For example in other languages there is a "read" vs. a "ReadLine", or "ReadString" vs. "ReadStringUntil", so the name makes the behavior clear. 

 

But I still agree that once you embrace your approach, it's a more elegant solution than what I was doing. 

0 Kudos
Message 5 of 7
(2,556 Views)

@paul_bridges wrote:

I think it's the fact that the behavior feels hidden (inside the Read function) that bothered me a bit, particularly if your reading is done far from where you Initialize, compared to text-based languages. For example in other languages there is a "read" vs. a "ReadLine", or "ReadString" vs. "ReadStringUntil", so the name makes the behavior clear. 

 

But I still agree that once you embrace your approach, it's a more elegant solution than what I was doing. 


I never thought of it that way before.  I can see your point about perhaps doing different kinds of reads and that the initialization can be separated programmatically so far from the actual Read.  Perhaps there is something in the underlying VISA driver that requires it to be determined earlier on.  Actually, you can enable and disable the termination character whenever you want after the Serial Configure by using the property node, but I've never had a reason to change it mid-program for any device I've communicated with.

0 Kudos
Message 6 of 7
(2,547 Views)

Actually C doesn't really have a readln() function in the standard library. What you mention looks very much like Pascal/Modula. 🙂

 

LabVIEW being originally written in C, later in C++, borrowed a lot of programming concepts from the C world, unless they were dictated by the Macintosh platform on which it was originally released. Just look at the String formatting and scanning functions for another very C library inspired feature, although they did add some extra formatting options that are not present in the C standard library and dropped a few rather obscure ANSI C options that I have never come across in any C code in the wild.

Rolf Kalbermatter
My Blog
0 Kudos
Message 7 of 7
(2,536 Views)