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.

VeriStand

cancel
Showing results for 
Search instead for 
Did you mean: 

RT FIFO read can't get data from input channel

 

I'm trying to create a serial communication custom device for VeriStand, but have problems reading input data from VeriStand input channel via RT FIFO Read, and writing output data to VeriStand output channel via RT FIFO Write.
The attached file is the RT driver. Any suggestion will be very much appreciated.

 

0 Kudos
Message 1 of 8
(7,375 Views)

Have you tried printing debug strings to the console window to see where the problem is?  If not, I recommend this VI to print to the console.  The console viewer is built into the Workspace Tools menu.

 

For starters, I would print the following:

 

  • Error Source string after the initialization code and before the Timed Loop.
  • Size of the input and output channel reference arrays.
  • String output from VISA read and Flatten to String.
  • Error Source string after the Merge Errors node inside the TL.
  • TL Iteration terminal.
I suggest you use the Backslash Code \r when using debug strings.  This code will return the cursor to the beginning of the line so the screen doesn't have to scroll.  Scrolling the screen requires some work from the target, and can affect the timing of the engine.

 

 

Is it possible for your device to return more serial data than you have room for in the output channel FIFO?

 

Steve K

0 Kudos
Message 2 of 8
(7,366 Views)

Thank you for the debug VI. I will try that.

 

Using only RT FIFO Read/Write without VISA Write/Read or vice versa works fine. So I think the problem happens during the data conversion from RT FIFO Read to VISA Write, and from VISA Read to RT FIFO Write. But the data conversion looks fine to me.

 

By the way, "Unflatten From String" used between "VISA Read" and "Replace Array Subset" seems not working. "String To Byte Array" works instead.

 

0 Kudos
Message 3 of 8
(7,362 Views)

One thing to keep in mind is that the default behavior of the Flatten to String primitive is to prepend the length of the array to the string.  This adds an additional 4 bytes of data to the beginning of the string, which could cause unexpected behavior if you aren't expecting the data in this format.  Similarly, the default behavior for the unflatten primitive is to expect the first 4 bytes of the string to contain the array size.  If the data is not in that format, you're going to get unexpected results.

 

You may want to wire a False constant to the input on both of these functions.

0 Kudos
Message 4 of 8
(7,356 Views)

Thank you, Devin.

 

Prepending the length of array size is one issue. But I have problem displaying the right data. I can use "Byte Array To String" instead of "Flatten To String" for data conversion, but it only takes 1 byte.

Any suggestion which VI to use for the data conversion between RT FIFO Read output and VISA Write input?

 

Two additional questions about VS.

The RT FIFO Read input is 1-D array of real number, which is from the input channels in VS. But what if the input value is string? What will it be stored in the FIFO?

It looks like WorkSpace only display numerical values. Is it possible to display strings?

 

Thanks,

0 Kudos
Message 5 of 8
(7,341 Views)

Hi MileP,

 

First, to answer your additional questions: all VeriStand channels are scalar numeric values stored as the double data type.  Strings and arrays are at this time not supported as channel types.  There are ways to get around this (ex. instead of having a single channel which is a numeric array, use multiple channels to represent the array), but typically each channel in VeriStand is used to represent a single value expressed in some engineering unit.

 

I looked at your VI, and I'm not really sure what you're trying to accomplish.  Are you attempting to make a generic serial custom device, or something specific to a specific serial instrument?  The problem with serial communication (as well as other protocols like TCP, UDP, etc...) is there is no stardard defining how a message or command should look or be formatted.  This makes it extremely difficult to write a generic serial custom device that would work with any serial instrument, since you would need to devise a way to handle any arbitrary set of string commands.

 

What it looks like you're trying to do in your VI is have a certain number of input channels in VeriStand represent a string command.  For example, if you wanted to send the command "Test", you would need to have 4 input channels set to the corresponding decimal values for each letter (ie. [84,101, 115, 116]).  If this is the case, you would take the array of doubles, convert it to an array of U8s (use the "To Unisigned Byte Integer" on the numeric palette), then either flatten it to string or use "Byte Array to String".  If the input is an array of U8s instead of an array of doubles, both should yield the same result, although I'd say it would be more proper to use "Byte Array to String".

 

The problem with the above approach is that it's not scalable or easy to work with.  What happens when you want to be able to handle multiple different messages being sent at different rates?  How do you manage all of the many many channels in System Explorer?  There are a lot of questions, and the implementation quickly becomes very complex.

 

However, if you know ahead of time what messages you will want your custom device to send over VISA, the problem quickly becomes a lot more manageable.  Suppose your device has three commands "POWERON", "POWEROFF", and "TAKEREADING".  You could create an input channel for each of these commands in your custom device (and one output channel to store the result of the reading).  When one of those channels is True (a value of 1), send that command over VISA, otherwise don't send anything.  When the "TAKEREADING" command was sent, you would also do a VISA read and convert the resulting response to the appropriate units (such as a voltage) and store it in the output channel.

 

Another implementation would be to have a single input channel in you custom device, with 0 = do nothing, 1 = POWERON, 2 = POWEROFF, 3 = TAKEREADING.

 

Or, if there is already an existing instrument driver available for your device on http://www.ni.com/idnet/, you could simply wrap up the VIs of the driver in your custom device and not have to worry about sending the low-level serial commands.

 

There are a lot of different approaches that you can take when dealing with serial devices, but trying to map raw channel values to characters that form a serial string is not an approach that I would recommend.

 

As a side note, I'm not sure what you mean by "but it only takes 1 byte".  "Byte "Array To String" should take an array of any size of U8s and convert it to a string.

 

Regards,

0 Kudos
Message 6 of 8
(7,321 Views)

Adding on to Devin's post,

 

Ideally you would create a custom device that grabs the serial data, parses and scales it, and then presents that data into channels as engineering units (EU). Passing the raw data through channels isn't usually a good idea.

 

Where are you going to parse the raw data then?

Stephen B
0 Kudos
Message 7 of 8
(7,319 Views)

Thank you, Devin and Stephen.

 

The purpose of creating the custom device is to get the serial data, decode it and present it in VS output channels; collect the data from VS intput channels, encode it and send to serial port.

 

We have our own communication protocol and I plan to write a sub-vi to do the encode/decode part. I just started the project, and tried to set up the serial communication first, then do the data encoding/decoding part. So this testing custom device uses one input channel in VS to send the ASCII value of a letter (I thought I could use one input channel to send a string - this is why I said "Byte Array To String" only takes 1 byte), converts the value to string, and write to serial port. VISA Read then reads the value and outputs string, the string is convereted to value again and sent to output channel of VS.

 

What you explained is very helpful. I will have to think about it and come back if having more questions.

0 Kudos
Message 8 of 8
(7,308 Views)