High-Speed Digitizers

cancel
Showing results for 
Search instead for 
Did you mean: 

unable to display waveform / multiple recording

Dear all,

It would be very nice if you could answer some questions to help me with my first steps with High-Speed Digitizers and NI-Scope.

Situation:

We bought the NI PCI-5122 High-Speed Digitizer to substitute our Tektronix Digital Scope (TDS 3032), which we are currently using for data acquisition via GPIB in our system. We want to operate the digitizer with NI-Scope 2.6 under LabVIEW 6.1 and/or 7.1.
To get familiar with NI-Scope I had a look at the examples and wrote a simplified program (please see attached “simple_acquisition.vi”) which is based on the “niScope EX Measurement Library.vi”.


Questions:

1. If I apply a sinusoidal-function (30Hz, amplitude: 0.8V) to CH0 and run the Scope Soft Front panel (edge trigger), I have no problem to see the function (please see attached screen-shot “Scope Soft Front Panel.doc”).
Now, I run the “simple_acquisition.vi” and, I am unable to see the sinusoidal-function on the waveform graph. What am I doing wrong?

2. Is the waveform data scaled (the 1-D array), I am acquireing with the “NI Scope INITIATE.vi and NI Scope FETCH WDT.vi”?

3. How do I realize SINGLE Sequence operation mode with the digitizer, like we are doing currently with our Tektronix Scope (using an external TTL trigger at 40 Hz)?

4. Do I realize averaging by substituting the while-loop with a for-loop and set the iterations to 100 (for an average of 100)?

5. How can I create positioning sliders like those in the Scope Soft Front Panel?

6. How do I acquire e.g. 100 waveforms subsequently (using an external TTL trigger signal) and than transferring the 100 waveforms as 1-D arrays, one by one, out of the digitizer’s 32 MB onboard memory?
In parallel, when the 100 1-D waveform arrays are transferred from the digitizer, I want to feed these 1-D arrays, one by one, through my data-analysis routine to do a fit for each of the 100 waveforms. The fit-results should than be displayed in an 1-D array for further statistical processing.

I know that I have to do this in a loop-structure. Can somebody give me some suggestions?


Thank you very much for all your help!

Kind regards,

beam
0 Kudos
Message 1 of 16
(9,746 Views)
0 Kudos
Message 2 of 16
(9,736 Views)
Fortunately, you are doing almost nothing wrong. Your basic problem is that your acquisition rate is too high. If you look at the SFP front panel, notice that the acquisition rate is 200kS/s. Your VI is set to 20MS/s. In addition, the SFP is acquiring 2000 points, while you are acquiring 1000. Taken together, the SFP has an acquisition time of 10ms, you have an acquisition time of 5µs. What you are seeing is a tiny section of your waveform - looks like a line. Reset your acquisition rate and number of points and you will be fine.

If you want to acquire a single waveform, do a single initiate/fetch cycle instead of doing it in a loop. The data will stay in the digitizer until you initiate another acquisition or the computer is turned off.

Do you really need to average? If you set your gain correctly, the noise levels on the 5122 are pretty good. Assuming you do, you are correct that you want a FOR loop. Just take the data, divide by your number of averages and add to an array in a shift register that will be your output. See scope_SimpleAverage.vi below (LV7.1). WARNING - this sort of simple averaging will tend to smear your waveform by a time amount equal to your acquisition period. So, if you take a point every 10µs, your data will be smeared that much. This is because the trigger position is indeterminate relative to the sample clock of the digitizer. The actual trigger point is more or less randomly distributed in the cycle period before the data point right after your reference position. To fix this, use the reference position data and the resample algorithms built into LabVIEW (I believe you will need LabVIEW 7.0+ and something over the base version). This topic is a bit more advanced that I want to get into in this reply. You can check the LabVIEW examples for more info.

The slider on the Y axis of the SFP is simply changing the graph scales programmatically using the graph property node. This has the effect of moving the waveform up and down on the display. The X slider is a bit more complex. It changes the reference position of the acquisition while also changing the scale on the graph. This ensures that the data will fill the graph at the next acquisition.

You can acquire 100 waveforms at once by using multi-record acquisitions. Check the NI-SCOPE examples for how to do this. You fetch these from the digitizer the same way you fetch any other waveform, except now you must specify the record number. Use a FOR loop and wire the index into the record number to make it easy.

Good luck and keep on wiring...
Message 3 of 16
(9,728 Views)
Dear DFGray,

thank you very much for your help and all the usefull comments! After changing the acquisition rate and record length, I can see the function on the waveform graph. Also recording a single waveform works beautifully.

Maybe you could clarify the following:

1. I checked the NI scope examples, but it is still not clear to me how to realize the X- and Y-axis sliders with the property node. In the end, I would like to have the choice of punching the numbers into something like "vertical position ", "offset" and "reference position" or moving a slider instead (like you can do in the SFP). THE BASIC THINGS I NEED TO ACCOMPLISH ARE:

a) If I change the referece position (x-axis), I want to see the scale of the x-axis moving (like in the SFP), so that the zero at the x-axis scale is always marking my reference position. How can I do this?
If your reference position is 50, how can you make sure that the zero of the x-scale is in the middle of the waveform graph x-axis scale?

b) For the y-axis I want simply to be able to change the y-position of the waveform (like in the SFP). Additionally, I tried to change the "vertical offset", but the waveform did not change its vertical position, why?

In general, I want to position my waveform on the waveform graph for data acquisition like you would do it with the "vertical pos." and "horizontal pos." knobs on a scope.

Comment: I do not like to use the "niScope Auto Setup VI". I prefer the basic "Configure Vertical" and "Configure Horizontal" VI's were I have more control over what I am doing.


2. How do I display a horizontal cursor on the waveform graph to display my trigger level position (like it is done at the SFP)?

3. How can you set your gain?

Sorry, if these questions are very basic and simple, but these are my first steps with NI-Scope and High-Speed Digitizers.


Kind regards,

beam
0 Kudos
Message 4 of 16
(9,718 Views)
Most of your questions are answered by using the graph property nodes. To create a graph property node, pop-up on the graph and select Create->Property Node. The node will show up on your block diagram. LabVIEW allows you to have multiple axes per graph direction (the SFP uses two apiece on the X and Y axes). To modify an axis, you have to select it, then modify it. So, to change the range on an X-axis, select Active X Scale as the property node and wire in the index of the axis you want to modify (typically 0, if you have only one). Then drag the property node to create a couple more property spaces. Select X Scale->Range->Minimum and X Scale->Range->Maximum to programmatically change the scale ranges. You can use other properties to change virtually all aspects of the graph. Now to specifically answer your questions. First, turn autoscaling off on all the axes of your graph.

NOTE: Axes and cursors cannot be created at run-time. You have to create as many as you will want before you run your VI. Details below.

1a) Any time you change the acquisition rate, reference position, or number of points acquired, calculate what the graph range should be and change the graph X-axis values as mentioned above. I will give you some tips on how to make this maintainable below.

1b) To change the Y position, simply change the range of the graph (not the acquisition) programmatically based on input from your slider/control. This will "move" your data on the screen without changing its actual value. Changing the vertical offset of the acquisition changes where the center of the scopes acquisition range occurs. The data is still the same, so the scope returns the same data, as it should. If you change the vertical offset enough, you can clip your data. Vertical offset is used to allow a high resolution acquisition of data on a large level without having to use AC coupling.

2) Cursors control is similar to axes control - it can be done through the graph property node. First, you need to create a cursor. Pop-up on the graph and select Visible Items->Cursor Legend. This gives you the interactive cursor UI. Create a cursor by clicking on anything in the top line. You can now hide this legend by selecting Visible Items->Cursor Legend again. Change the position of the cursor using a graph property node (it can be the same one as before or a different one). Set Active Cursor, then Cursor->Cursor Position. Set the X value to zero and the Y value to your trigger level. Update any time you change your trigger level. You can control other properties (e.g. Visible, Color) programmatically as well.

3) To set the gain, change the range on both the NI-SCOPE acquistion and the Y-Axis of the graph.

If this is your first major LabVIEW program, you may want to check out the attached presentation on how to write a maintainable application in LabVIEW. In your case, you will want to have two parallel loops - one for UI interactions containing an event handler and task manager, and another for acquisition. If you want the scope to act like an analog scope and not timeout if there is no trigger, iniitiate your acquisition, then poll for acquisition status. When the acquisition has completed, acquire the data with zero timeout.

Good luck. This has been a once over very quickly, so repost if you run into difficulties.
Message 5 of 16
(9,702 Views)
Dear DFGray,

Thanks for all your help. When I followed your instructions I ran into the following problems:

x-axis and trigger level:

1. In both files “frontpanel_3.vi” and “frontpanel_4.vi” I was able to modify the min./max. values of the x-scale range. When I changed the min. value to –10ms, I could only see the waveform in the range from 0-10ms. I tried to play with the record length, sample rate and reference position% but I could not fix it. What could be the problem? What is the best way to realize the additional function Time/Div like in the SFP?

2. The 0-position at the x-axis is still not moving with the change of the reference position%. Only the cursor (trigger level) is shifting. How can I additionally shift the 0 of the x-axis with the reference position% (I tried to wire the Cursor.PosX at the property node to the reference position% but it did not work)? In the SFP the cursor (trigger level) is always at the reference position.

3. If I lock the cursor (trigger level) to the waveform, using the cursor legend, the cursor is fluctuation with the waveform fluctuations. How can I minimize these fluctuations, which I do not see in the SFP?


y-axis and Volts/Div:

4. In the file “frontpanel_3.vi” I was able to change the y-position of the waveform by changing the min. value and max. value of the x-scale range (e.g. -400mV/300mV). Changing the “vertical range” control had no effect and did not change the Y-axis scale.

I tried to correct this as shown in “frontpanel_4.vi”. Then, changing ‘vertical range” is now similar to the change of Volts/Div in the SFP, but I was unable to maintain the change of the y-position like in “frontpanel_3.vi”. How can I combine these two things? Additionally, I tried to implement the Volts/Div function using a third property node with the Y.scale.increment but the program did not like it. Is there a good way to implement the Volts/Div function?

5. I think at least the vertical offset is working fine?



Thank you very much for all your help! I apologize for all these questions!

Kind regards,

beam
0 Kudos
Message 6 of 16
(9,696 Views)
0 Kudos
Message 7 of 16
(9,386 Views)
1,2. You almost have it. Most of your problems are due to a graph configuration issue - the graph is ignoring your waveform timestamp. To fix this problem, pop-up on the graph and select Ignore Timestamp. This will deselect this option, but it will also reformat your X axis. You now need to pop-up on the graph X-axis, select Formatting... and reset to what you would like. This is a personal preference, but I tend to like SI notation with 6 significant digits and hide trailing zeros.

But you are still not finished. The reason the graph ignores timestamps by default is that timestamps are, by default, the absolute time in seconds from January 1, 1904 12:00 midnight GMT. This doesn't do you a whole lot of good. You want to know what the time from your reference position is. This is a relative timestamp. On your fetch VI, create a constant on the timestamp type input and set it to relative. At this point, things should work the way you expect them to.

You can set the time/div by using the Increment property of the graph scale (XScale->Range->Increment). Make sure you set it after setting the max and min values. LabVIEW has “intelligence” which resets the increment value for you based on the size of your labels and how much screen space you have when you set the max and min values or resize the graph. If you don't get what you expect, this may be the reason.

3. If you lock the cursor to the waveform, it will always rest on a point in the waveform. Since the point positions move every time you get a new waveform, this results in jitter. The SFP does not lock the cursor to the waveform and sets it like you have currently done. That way it is stable. Note that the reference position will usually NOT have a point on it.

4,5. You almost have the Y-axis, as well. I am not really sure why what you have done is not working. It appears to be OK. However, try doing it just a bit different. Don't use the YScale.Offset on the waveform graph property. Instead, add the offset to the values you set for the min and max. You may also try wiring the min value to YScale.Start in addition to min. You should be able to implement V/div using Increment. That is how the SFP does it. Be aware, however, that if you use standard scope increments, the vertical range will not line up well with the physical vertical ranges of the device. The SFP gets around this problem by using an IVI feature of NI-SCOPE. If you ask for a range that is not a valid value for the device, it gives you the next highest range which is. To get the graph to look like a scope, you will need to pick max, min, and inc values which are consistent with each other.

As a freebie, I have attached some code to generate the standard scope 1, 2, 5 sequences for you (LV6.0, I think).
Message 8 of 16
(9,688 Views)
Dear DFGray,

thank you very much for all your help and the attached code examples!

I could not find the "timestamp type input" at the NIScope FetchWDT VI. I am running LabVIEW 7.1 with NIScope 2.6.

Can it be that you are using a higher NIScope version which has this additional feature at the NIScope FetchWDT VI?


Kind regards,

beam
0 Kudos
Message 9 of 16
(9,348 Views)
My apologies. I am using NI-SCOPE 2.7 and that feature was introduced in 2.7. You can get the same effect with older versions of NI-SCOPE by unbundling relativeInitialX from the wfm info output of the fetch VI and replacing t0 in your waveform with it. That is what the SCOPE SFP does. Use the Build Waveform primitive from the Waveform palette to do this. The attached VI should make this a bit more clear (LV 7.1).
Message 10 of 16
(9,325 Views)