LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

sequential serial reads within a loop

Greetings,

 

Here's where I highlight my lack of serial comm experience and waning LV skills.  Each second I'm trying to... get a block of data from my instrument (send .11 command)... get a second (different) block of data from the same instrument (send .13 command)... get two channels from a USB-6001... append date/time... space-delimit all of that and write as a single line to a text file:

[data from .11 command][data from .13 command][-6001 data][time stamp]

 

I'm getting the correct data from the instrument, but it's being written as two separate lines in the file, and each line includes the -6001 data & time stamp:

[data from .11 command][-6001 data][time stamp]

[data from .13 command][-6001 data][time stamp]

[data from .11 command][-6001 data][time stamp]

[data from .13 command][-6001 data][time stamp]

... etc.

 

I've tried writing the code as shown, I've tried nested loops, I've tried arrays... all have the same outcome as shown below.  Am I missing some serial control steps?  The instrument uses the default COM params (9600,  8, none, 1, none) & term char (\n) used by VISA config node.

 

(The "Calibration 1..." file is a sub-VI.)

 

LV15.0f2

 

Thanks!

 

-Heyla
Download All
0 Kudos
Message 1 of 12
(4,487 Views)

What does the data look like in "concatenated string" before it gets written to file?

 

Nothing about what you say is in the file matches how you are building the string.  Something doesn't add up.  It looks like the Clean White Space should be doing its job inside the subVI.  Your output shows two timestamps, one for each piece of data, but your string functions only include the timestamp once.

 

A couple tips:

Index Array is resizable.  Don't copy it.  Just drag the bottom border of the first one down.  You'll automatically get indices 0 and 1 without having to wire up any constants.

You should open the file before the loop and close it outside the loop.  You did that correctly for the serial communication.  You should to it for the file.

You can use a single Format Date/Time String with both the date and time in the Format code so you can eliminate the extra nodes and inputs to the Concatenate.  Better yet,  Just use Format into String and set it for all the formatting functions and you can eliminate. 4 functions, all the extra input characters, a lot of wiring, as well as the concatenate.

0 Kudos
Message 2 of 12
(4,468 Views)

@RavensFan said...

"Nothing about what you say is in the file matches how you are building the string.  Something doesn't add up."

 

EXACTLY!  Smiley Very Happy Unless my skills are worse than I thought, I've wired it how I *want* it to show up in the file.  But having said that, it behaves like it's going through the loop one time for the .11 command write/read, then a second time for the .13 command write/read.

 

I've attached a partial output file so you can see what is being logged.  The fields are as follows:

".11 thru !92 = inst output, followed by two -6001 outputs, followed by date & time"

".13 thru !98 = inst output, followed by two -6001 outputs, followed by date & time"

 

Ideally, the .11 output/.13 output/-6001 outputs/date&time would be on a single line, with single date & time entries on the end.

 

In one of my previous code iterations, I had an indicator after each write/read node.  While running, the indicators were random.  Sometimes the .11 data would show up in the "other" indicator and vice versa.  Sometimes the .11 and .13 data would alternate in one indicator or the other.  Regardless of what construct i use, I can't seem to get all of the info to write (or even display) onto a single line.

-Heyla
0 Kudos
Message 3 of 12
(4,458 Views)

Are you using a project to organize this? It almost seems like you're not actually using the VISAReadWrite.vi that you think you are. With Trim Whitespace there, you shouldn't get the extra carriage returns.

 

Also, your log file includes the text " .11 [timestamp]"..." .13 [timestamp]".... Nowhere in either VI is the text ".11" and ".13" logged to the file, so SOMETHING is putting it in there. See if you can find what is doing that.

 

Also, like RavensFan said, expand Index Array instead of copying it, and I'd suggest using the function "Write Delimited Spreadsheet" to handle your delimiter work. Build all of your data into a string array and feed that to Write Delimited Spreadsheet with Append set to True, and it'll be a LOT easier to read and debug. You are already opening and closing the file reference each time you use it anyway, so it will clean up your block diagram a lot at zero performance cost.

0 Kudos
Message 4 of 12
(4,452 Views)

@BertMcMahan:

The ".11[timestamp]..." and ".13[timestamp] is coming from the instrument.  It regurgitates the command, adds its own timestamp, and appends the requested data.  I'm merely adding my own (local) time stamp so I know when the data was collected.

 

Thank you and @RavensFan for the tips and suggestions.  I will rework the code, try again, and share the results tomorrow.

 

 

-Heyla
0 Kudos
Message 5 of 12
(4,447 Views)

Ah, that makes sense. Is it putting a carriage return in the data by any chance? If it's got a carriage return in the data but not at either end, that would screw up your formatting. Trim Whitespace will only get the stuff at the ends of the string. Just a thought.

 

By the way- this is an *excellent* place to break your project into a subVI. Create a subVI that just does the file logging with string inputs. You can then debug your code by writing known strings to the inputs, and if that subVI runs well, then you *know* your logging works. We can't debug your code properly as we don't have instruments we can talk to- but if you just had a subVI that accepted data as inputs that wrote to a file, all of us could run it on our machines to make sure that works.

 

This way you can separate your data acquisition from your file writing... and you may even be able to use that subVI in another project one day 🙂

0 Kudos
Message 6 of 12
(4,445 Views)

@Heyla wrote:

@RavensFan said...

"Nothing about what you say is in the file matches how you are building the string.  Something doesn't add up."

 

EXACTLY!  Smiley Very Happy Unless my skills are worse than I thought, I've wired it how I *want* it to show up in the file.  But having said that, it behaves like it's going through the loop one time for the .11 command write/read, then a second time for the .13 command write/read.

 

I've attached a partial output file so you can see what is being logged.  The fields are as follows:

".11 thru !92 = inst output, followed by two -6001 outputs, followed by date & time"

".13 thru !98 = inst output, followed by two -6001 outputs, followed by date & time"

 


I think your data file looks even worse than what you first posted with even more timestamps in there.

You should follow my other advice and look at what is in the concatenated string indicator to see if what is in that string matches what is in the file.

 

As Bert says, something is putting more data in those commands than you think it is.  Look at NI-SPY (or is it now NI I/O trace) to see at the driver level for VISA what the data comms look like.

 

0 Kudos
Message 7 of 12
(4,428 Views)

Greetings,

 

I modified the code, hopefully per your collective suggestions, and it's attached.  I also removed the write/read subVIs and inserted blocks from the menu to address Bert's concern that my subVI might not be doing what I think it is.  While I'm still getting the same unwanted output (two separate data lines instead of one large concatenated line), I stumbled onto a second (maybe related?) issue.  I ran the code for an extended period and discovered that after a few minutes, the .13 data starts dropping out.  I get a few lines of .11 data, a single .13 line of data, then a few more lines of .11 data, instead of alternating one at a time.  

 

I have since tapped into the COM port and am viewing the inst INPUT (commands from LV to inst) using Tera Term, and it is indeed what the logged data show... the .13 command is going out once for every 3-5 times that the .11 command goes out (they are not alternating).  It works as intended (the commands alternate) for several minutes, then the .13 command starts dropping out.

 

I hooked up NI-SPY and I'm occasionally getting an error on the .13 read (0xBFFF006C).  A 10-sec spy dump is attached.  I hadn't seen the error while running, is it because my error line is not connected via shift registers on the while loop?

 

Just a reminder that the intended output would be (all on a single line):

.11 time data ack .13 time data ack DAQch1 DAQch2 time

... but what I'm seeing is:

.11 time data ack DAQch1 DAQch2 time

.13 time data ack DAQch1 DAQch2 time

... on two separate lines.  Again noting that if I let the code run for a few minutes, then I get multiple .11 data lines interspersed with the occasional .13 data line.

 

Thanks again for your collective input!

-Heyla
Download All
0 Kudos
Message 8 of 12
(4,398 Views)

You're getting buffer overflows on your Read's. Up the number of bytes read from 100 to something higher, then get back to us.

 

This is starting to look like an issue with the serial data protocol. Unless you're 100% certain that your device ALWAYS responds with EXACTLY 100 bytes of data, you're going to have issues with buffers that'll show up after running it for a while.

 

I'd recommend using termchars for this application if your device supports them. If not, I'd use a Wait... then a "Bytes at Port" to read ALL of the data in the nodes.

 

My theory: you're getting multiple responses with newline characters in the *middle* of your buffer reads, throwing newlines into your output.

0 Kudos
Message 9 of 12
(4,385 Views)

There are definitely newline characters coming in.

 

The buffer overruns seem to have already started by the time your capture began.  What I see in the capture:

 

First read:

Ask for 100, get 19.  Ends at the linefeed character (ends with CR/LF  0D 0A) as expected since the VISA Configure is set for termination character enabled and for Linefeed.  Data is ASCII and I believe is what you were describing in the original post.

Capture1

 

Second read:

Ask for 100, get   59.  Ends at linefeed character.  Is the second .11 request, but has a lot more stuff in it like the timestamp which you didn't mention in the first message.

Capture2 

 

Third read:

Similar to second with a .11 request, again with timestamp.

Capture3

 

Fourth read.

Like first with a .13 response.  But has 39 characters in response.

Capture4

 

Later reads:

Similar with .;11 responses and .13 responses. 

 

 

So it seems like there is extra data in there.  And I find it odd that you got two .11 responses in a row.  And that a .13 response was shorter the first time than the next time.  We still don't know if when you get a VISA read, if you are grabbing all the bytes in the buffer, or the message was longer with a LF in the middle of it effectively breaking it into 2 reads,  that you don't get until later with the next request then read, continually reading stale data until the buffer overruns.

 

I think there are a couple things you should do.

1.  Your request string is .11\r, a carriage return.  It is odd to end a command with a carriage return when the response comes back ending in a line feed (actually CR/LF).  Should your write command be .11\n.   ??

2.  You use a 1000 millisecond wait until next in your loop.  You really should use a regular Wait.  The wait until next could cause you to miss loop periods if a given iteration takes longer than a second.

3.  Perhaps get rid of the wait and let the DAQ timing control your loop speed.  Set your DAQ to be continuous samples with a 1 Hz rate acquiring 1 sample.  It will control your loop iteration time.  Better yet, use real DAQmx functions instead of the DAQ Assistant.

4.  Simplify your program to do a single call without a loop.  Disable the termination character, do a single write such as .11\r, wait 2 seconds, then do a single read of 1000 bytes.  Let the program end.  i.e. no while loop.  This should give you everything that is being returned.  Then repeat the process for the .13\r command.

 

I don't think you've ever told us what instrument you are talking to.  Is it a commercial instrument or something someone programmed on their own.  What does the manual say about the communication protocol?  So far what you've told us it should be doing just doesn't match what is actually happening.

 

Step 4 above should help figure out what makes up the full response to a give command.  The buffer overrun, the extra .11 responses in a row, all make me think you are getting a longer message with line feeds in the middle and the number of VISA Reads isn't enough to empty the buffer before it eventually overruns.


Oh.  And the original problem is more about the extra line feeds showing up in the text file.  I still don't see why that is happening. as your Clean text should be stripping them off the end.  But in your new VI , you got rid of the indicator after you concatenate everything together.  That is what I told you to look at see why there would  be extra line breaks in the middle of what is getting written to the file.

 

Actually, something just occurred to me.  You are obviously getting errors for the overrun.  Most LabVIEW functions will not execute on an incoming error.  So if you get an overrun error on your first VISA Write/Read, the subsequent one won't execute.  But then again, neither would the file open or write since they are all connected to the same error line.  So I don't know how anything gets written to the file, but it could explain why there are incomplete messages.  Put some error indicators on all those error wires.

 

That means you really need to go and solve the VISA communication problems.  If you fix them, then perhaps the file write problems disappear.

Download All
Message 10 of 12
(4,379 Views)