12-18-2017 08:28 AM - edited 12-18-2017 08:34 AM
Hi all,
I know this question comes up regularly, but even with all the topics about it I cannot find the answer to my seemingly simple problem.
I'm trying to poll a trigger string ("#TRG\r") from a serial port, which arrives irregularly. When the trigger is received, the attached snippet should set a flag for another loop to respond to. In this snippet, the Visa Read always returns the infamous timeout error (0xBFFF0015) and I cannot find out why.
For testing I send the trigger string at shorter intervals than the timeout with a serial monitor tool. With this tool I have also verified that the termination char is sent and received correctly by the ports. No matter how I change the timeout, buffersize or bytes to read, it returns the timeout error. It does not read any data from the port.
The serial ports are from an EasySync H-9004-M usb-hub with four separate FTDI chips.
It must be a simple thing, but I've been breaking my head over it already for two days..
Solved! Go to Solution.
12-18-2017 09:17 AM
A couple things I see.
1. It is a mistake to put the error wire on a shift register. In the event you do get a single error, let's say a random timeout, that error will return to the beginning of the loop and normal error operation for that VISA Read tells it not to run when there is an incoming error. So a single error will essentially stop your code from working until you stop and restart.
2. You are comparing the incoming value to #TRG no #TRG/r The termination character is part of the incoming string so if you don't include that in the constant you are comparing to, the comparison will always be false.
12-18-2017 09:26 AM - edited 12-18-2017 09:29 AM
Isn't a trigger command *TRG, not #TRG?
That is if your device uses standard 488.2 commands
12-18-2017 09:39 AM
irPaul wrote:
I'm trying to poll a trigger string ("#TRG\r") from a serial port, which arrives irregularly.
This is actually one of the few times I say to use the Bytes At Port. Use the Bytes At Port to see if a message has started to come in. If a message has started, then read the entire message. The Bytes At Port should not be used to state how many bytes to read. See here and/or here for more details.
12-18-2017 09:59 AM - edited 12-18-2017 10:00 AM
Thanks for the quick reply all!
@RavensFan
1. Yes, I just found this out too. I saw an earlier topic where someone solved this by not wiring the error at all. Without any error wires, the VI is interrupted upon timeout. But using error tunnels, the VI continuous to work fine.
In general, should I avoid putting an error in a shift register?
2. I already figured, since I recall LabVIEW does leave the termination character in the string. This was just a quick-and-dirty test, I have changed it to a Match Pattern now.
@RTSLVU
My device is an Arduino, so I can program whatever I want. But good point, I will switch to the common standard.
@crossrulz
Also a very good remark. I was thinking about that, but in many similar topics it was strongly, strongly advised against using Bytes at Port in combination with termination chars. In the way you do it though, it makes sense to prevent the VI from continuously polling and taking unnecessary CPU resources.
12-18-2017 10:14 AM
Another tip: many times when I'm listening for a serial message asynchronously, with no idea if or when it might arrive, I simply treat the Timeout error as one of my expected cases to resolve. It happens a *lot*, and I simply deal with it.
Part of "dealing with it" includes RavensFan's advice not to retain errors in a shift register. Another subtle part of "dealing with it" is knowing that when the VISA Read times out, it *might* return a partial packet of bytes. Note: this tends to be fairly rare for most normal sized message packets, but it *can* and therefore eventually *will* happen. If so, you then need to get the rest of that packet before iterating again. A 2nd followup VISA Read with a minimal timeout should get them as long as you don't feed the error cluster into the 2nd VISA Read.
I just now saw the additional response from crossrulz. I didn't open his snippet, but assume he's got a Wait function in the other case. His method should prevent the partial message packet issue I talked about, and preventing is gonna be simpler than *handling*, so I'd recommend you go with that. I'm gonna remember that particular exception for the future too. I've listened so well to his (and others') admonitions about "Bytes at Port", that I simply avoided using it without thinking more carefully about where and how it *can* be helpful.
-Kevin P
12-18-2017 10:56 AM
Kevin_Price wrote:
I didn't open his snippet, but assume he's got a Wait function in the other case.
I think it was a 50ms wait in the other case. I state what it is in one of the links I gave previously.
Kevin_Price wrote:
I've listened so well to his (and others') admonitions about "Bytes at Port", that I simply avoided using it without thinking more carefully about where and how it *can* be helpful.
Intermittent transmitting instruments is the only time I find the Bytes At Port useful.
I really need to get those serial port nuggets written. Maybe my two little ones will give me some time over Christmas break...
10-18-2020 08:34 AM
I came to this old posting when having problems with timeout in VISA Read.vi when configured to use a termination character with the intention to always read full lines.
Issue is:
When VISA serial port is setup to use a termination character (for instance \n) you would expect that you always get a full line (/package) of data or a timeout. This is not the case however. The problem is that timeout timer in VISA read.vi is not restarted when a character is received, but when the VISA Read.vi is called.
The result is that there may come a timeout somewhere in the middle of a line (package) despite the data is in the process of flowing in!
Slow baud rates and short timeout aggravates this problem.
Of course you will know that the line is incomplete due to the timeout. The next message is likely to pass with proper termination, but the content will be missing the previous part which gave timeout - so, you will accept an illegal line if assuming that no timeout means a full line was received. Most of the time this will pass ok - but not guaranteed.
Below snippet of code deals with this.
The offending event (timeout in the middle of a line) is detected by::
1) String length >0
2) Error == VISA Timeout
In the event of 1) & 2) the VISA Read.vi is called again and the replies are concatenated.
To test it: Set the timeout shorter than the line length and it will still work reliably.
As is customary, set Max bytes to read larger than the longest line.
None of the replies here seamed to solve this problem so I decided to post my solution in the hope it is useful for other having similar issues.
10-18-2020 08:58 AM
@RavensFan wrote:
A couple things I see.
1. It is a mistake to put the error wire on a shift register. In the event you do get a single error, let's say a random timeout, that error will return to the beginning of the loop and normal error operation for that VISA Read tells it not to run when there is an incoming error. So a single error will essentially stop your code from working until you stop and restart.
2. You are comparing the incoming value to #TRG no #TRG/r The termination character is part of the incoming string so if you don't include that in the constant you are comparing to, the comparison will always be false.
I normally use a shift register on the error wire because I'm used to the old (old, old, old?) version of the QMH where general error handling was implemented at the beginning of the loop, not the end.
But if you implement general error handling at the end of the loop, there shouldn't be an error worth figuring out by the time you loop around to the beginning again, so the shift register does more harm than good.
10-18-2020 09:00 AM
I'm going to give a reply as there are better ways to fix this.
I'm guessing that this device sporadically sends data. It doesn't have a protocol where you would send a command to tell it to send data and then you can immediately do a VISA Read as it will send a reply back in a short period of time. If so, I would consider not using such a poorly designed device.
What you can do is use the Bytes at Port property node as this may be one of the 0.01% of the time where you should be using it.
Your "solution" isn't really a good solution when Crossrulz's message #4 handles the situation correctly without dealing with errors or tossing away incomplete messages.