Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

Multiple serial data stream inputs

Solved!
Go to solution

I am trying to display the outputs from two different RS-232 instruments that are operating asynchronously with no handshaking.  Each meter (one a weight scale and the other a DVM) are updating at different rates.  I would like to sample them every 100mS and display the values at that time.  The problem appears to be that when I use the attached vi the DVM is putting more data in the buffer than the scale. When the while loop pulls data out of the buffer it is stale and the two data streams are way out of sync at that point.

 

I have tried using the VISA flush buffer but have not been able to get it to work.

 

 

What I need to do is basically -

 

When timer triggers the while loop, go get the most recent data from each instrument, and display the data.  I do not need anything that has been transmitted prior to that time.

 

Download All
0 Kudos
Message 1 of 15
(4,985 Views)

You could use the VISA Bytes at Serial Port to read all of the data and then parse out only the data you need.

bytes at port.PNG


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 2 of 15
(4,978 Views)

OK, I added VISA Bytes at Serial Port and can see the data coming in.  This number just continues to increment up and never resets to zero.

 

 

I could use a bit more help here on parsing out the data and getting the most recent data at the sample interval.

 

 

0 Kudos
Message 3 of 15
(4,965 Views)

1. When you use termination characters, you do not use Bytes at Port. Set the Bytes to Read to a value larger than the expected number of characters in a message.  The Read will terminate when the line feed character occurs in the data stream.

 

2. It appears that the remote devices are sending continuously.  You also indicate that they are sending at different rates.  This is the type of application for which the Producer/Consumer (Data) Design Pattern is intended. Because the rates are different, you will probably need two producer loops, one for each device.

 

3. When you have implemented suggestions 1 and 2 then you will have all the data coming into the consumer in nice, clean, one message per iteration per instrument, blocks.  The consumer loop will need to dequeue all of the available information so the queues do not increase in length over time. You can then decide to discard old messages if you wish.

 

Lynn

0 Kudos
Message 4 of 15
(4,959 Views)

Looks like that will do the job.  Thanks to all that looked and helped!!!!

 

vi attached (work in progress)

0 Kudos
Message 5 of 15
(4,949 Views)

You are making progress.  There are a few more things you should consider.

 

1. You Enqueue data in both the Voltmeter and Scale loops. However, you have no way to tell which data is from which source.

2. You Dequeue the data in the Data Retrieval loop but do not do anything with it!

3. You Dequeue and Get Queue Status in parallel.  You do not know whether the Elements in Queue indicator shows the number before or after the Dequeue.

4. It is not clear why you need a 2D array to write to the file, but you have come up with a quite unusual way to do it. If you really need it, just replace all the Dynamic Data Type nodes with a single element Build Array.  See the lower Build Array in this image.

 

Build Array.png

 

5. I am not sure the timeout on the Equeue Elements functions do what you want.  After the queue fills up, then the waits will start happening while the Enqueues wait for the Dequeue to remove an element.  You have no way of knowing which Enqueue loop will win and which will continue to wait.  They may not even take turns.

6. You do not need the local variables. Use the Dequeued data.

7. Do you really want to do 50 file writes per second?  Accumulate the data in a shift register until you have a larger block and then write that block.

 

Solutions:

For 1 use two queues (voltmeter and scale).

For 2 and 6 wire the dequeued data to the build array.

For 3 use dataflow in the error and queue refnum wires to assure that the Get Queue Status runs after the Dequeue.

For 5 I am not propsing a solution because I am not sure what timing you want.

 

Lynn

0 Kudos
Message 6 of 15
(4,943 Views)

I beleve that I understand most of your suggestions, however, I am struggling with what I need to do to implement the Enqueue > Dequeue processes in order to keep things syncronized. 

 

1) I have setup two seperate Enqueues for Scale and Voltmeter an assume that I would have a seperate "Obtain Queue" for each.  Is this correct?

 

2) I have wired the "Obtain Queue"to for each of them to its corresponding Dequeue.  Is this correct?

 

3) Do you know of an example of a Enqueue/Dequeqe sequence that you can point me to?

 

vi attached.

 

Phil

0 Kudos
Message 7 of 15
(4,935 Views)

Phil,

 

1. Yes.  You need a separate Obtain Queue for each queue.  You also need to give them unique names or not name them at all.  Calling each of them "Data" results in the same queue being used for all three signals.

2. The wiring is correct.

3. I do not have an exmple at the moment.

 

4. You do not need the sequence structure.  Dataflow causes things to happen in the same order.

5. Why do you repeatedly configure the serial ports? Use an event structure with a Set Serial Ports 2: Value Changed event and only configure once when the button is pressed.  If you do need to configure repeatedly, you should have a Wait in that loop so that it does not try to run as fast as possible, hogging CPU resources.

6. You probably do not need to limit the size of the queues.  The default (-1, unlimited size) shold be OK.

 

In your original post you said that the instruments update at different rates. The VIs you have posted are all reading the ports at the same intervals.  Will you be losing data? You are not using the Read error out information. If multiple messages pile up in the buffer, Read will throw an error to tell you about it, but you will not get the message.

 

Here is your VI, cleaned up a bit so that it fits on one screen and with separately named queues.

 

Lynn

 

0 Kudos
Message 8 of 15
(4,927 Views)

Thanks for the updateed vi.

 

 

It is starting to become a lot more understandable.  As you can tell, I am prettuy rusty on this as it has been almost 10 years since I last used LabVIEW but I now have a number of projects backed up and thought that it is time to dive back in.

 

You are correct in that the data is coming into the Queues aysyncronously and indeed the Queues are becoming filled very quickly.  I ultimatly will only want to get the most recent data at an interval of about 1 sample per second.  The sacle outputs about 20 samples per second and the voltmeter is sampling about 10 samples per second.

 

 

What do I need to do to discard the "stale" data and only write the most recent data at the point the the "Time Between Iterations (mS)" triggers the while loops?

 

 

thanks,

Phil

 

 

0 Kudos
Message 9 of 15
(4,925 Views)

Phil,

 

It gets a little more complicated to keep the queues from filling up, but not too much.  What you want to do is to read each queue fairly quickly and keep reading it until it is empty.  Keep only the last data read. When the 1 second intervals are done (use Elapsed Time Express.vi), save those last points fro each queue.

 

To do this you may need dequeue loops for each queue or Flush Queue with Return Elements? True rather than Dequeue.

 

Lynn

0 Kudos
Message 10 of 15
(4,923 Views)