I have a VI in labview that takes an array from a .NET and playback it with DAQmx, one value every millisecond.
I have to make the same thing with Veristand 2011, programmatically.
As far as I understood, it looks like I can do this in 2 different ways:
1) Write some file that the stimulus profile editor can read, and open it with the stimulus profile editor API
2) Make a custom device and use an input for the array
Am I missing something? I'm kind of a noob with Vstand.
Solved! Go to Solution.
There is a shipping example that does almost exactly what you want, and would be a good starting point for reference. It doesn't even require writing any stimulus profiles or real-time sequences, because a real-time sequence ships with VeriStand that is designed for such playback purposes, and this example uses that one directly.
Check out: <LabVIEW>\examples\NI VeriStand\API\Execution API\Sequences\Play Waveforms\Waveform Player Example.vi.
The only difference is that this example is based on the waveform datatype, which has a dt and t0 parameter in addition to the array of y-values. But it's a trivial modification to make.
I have two more questions:
1) What do I have to do if I want to loop the waveform?
2) If I want to playback more channels, all I have to do is add more "Create play waveform sequence call" to the "waveform player example" and connect them with the "Open stimulus profile session", right?
1. You will probably want to create your own real-time sequence that has a parameter that allows looping a set number of times.
The built-in PlayWaveform real-time sequence does not have this capability. You can open up the PlayWaveform sequence to see what it does and make a copy that is modified to allow looping. You can open this sequence simply by double clicking it in the Sequences palette in the Stimulus Profile Editor. It can be found under Real-Time Sequence Library >> Standard >> Waveforms. This sequence might be more complicated than you need, especially because it supports interpolation. If you don't require interpolation and just want to play back points at a specific interval (1ms), then it will be much easier to write a sequence from scratch that does this.
Below is an example that should do what you want. It is pretty basic. It has an outer For Loop set to run for the number of times you want to loop the waveform. Inside that For Loop is a For Each Loop that iterates over the elements of the array to play back. All it does is copy the current array value onto the output variable, and then call the Wait function passing in the period to wait for.
It shouldn't be too hard to modify the Waveform Player Example VI to call this VI instead of the built-in PlayWaveform. Make sure to make copies first rather than editing the example files directly!
2. Yes, you are absolutely correct! To play multiple waveforms, just create multiple sequence calls and pass them into the Open Stimulus Profile Session VI. When you start the session, all the sequences will start simultaneously, supposing they're configured to run on the same RT Target.
What rate is your target specified to run at in your system definition where this sequence is running? How are you verifying the final dt at which the waveform is playing back?
100 Hz ... that was the problem. Now that I'm running it at 7KHz the timing is right.
Isn't there a way to use DAQmx hardware clock for the timing instead of the real time OS? I'm using a lot of CPU using "wait".
If I try to playback an array of more than 65536 element, i get the following error:
Error 1172 occurred at Error calling method NationalInstruments.VeriStand.ClientAPI.IStimulusProfileSession.Deploy, (System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
Inner Exception: System.ServiceModel.CommunicationException: There was an error while trying to serialize parameter http://www.NationalInstruments.com/VeriStand/1.0:session_data. The InnerException message was 'Maximum number of items that can be serialized or deserialized in an object graph is '65536'. Change the object graph or increase the MaxItemsInObjectGraph quota. '. Please see InnerException for more details.
Inner Exception: System.Runtime.Serialization.SerializationException: Maximum number of items that can be ...
Because the xml serializer is called by a ni .net, I don't know how to set a higher MaxItemsInObjectGraph.
I can reproduce this issue you are seeing. I filed CAR 352792 for further investigation regarding it. You will not be able to set the MaxItemsInObjectGraph, since those options are hard-coded in the VeriStand Execution API.
I can think of one workaround. I tested it out on my machine and it worked fine. The problem is that you are trying to assign a large array to your sequence parameter, and this data cannot be successfully sent to the VeriStand Gateway through the execution API. Instead what you can do is programmatically script a wrapper sequence to call your waveform playback sequence, where this wrapper sequence contains the data to playback as a Local Variable, instead of a parameter. Then you call this generated wrapper sequence instead of your desired sequence. You won't actually be passing the large array value in as a parameter, since its data will be hard-coded into the wrapper sequence, so you'll avoid this issue entirely.
Attached is an example version of the Waveform Player Example VI that should help you out. Specifically I created a template sequence called PlayWaveformWrapper.nivsseq that calls PlayWaveform and has the array local variable already in it. Then at run-time when I want to generate a sequence with a specific array value to play back, all I need to do is open this template with the SequenceDefinitionAPI, programmatically update the value of the array local variable, and save the template to a temporary location. Finally, after I am done running this sequence, I should delete it on disk to clean things up.
Hope this helps and thanks for bringing the issue to our attention.