Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Downsampling Graph Data

Device: NI PCI-6259

Measurement Studio, C#, WPF, dotNet4.0

 


Acquiring samples on 16 Channels with 32 KHz sampling rate and writing them to disk as .TDMS is fine, no notable performace hit.

But as soon as I bind the data to the WPF NI:Graph the performance gets intollerable.

 

1. Is there an built-in option for downsampling the Graph data ? TDMS must have the complete data set though

2. Whats the ratio for the Task setting Rate and Samples per Second, if I set the latter to low the DAQ may crash, i.e. how can I calculate the samplesPerSecond for Rate X with Y Channels ?

3.

 

 

0 Kudos
Message 1 of 5
(7,345 Views)

3. I want the the scale for the X axis to be Time in seconds. 

I configure the axis in XAML as integer based with a certain range, but as soon as I start the Acquisition, it getts overwritten with the SamplesPerChannel value

0 Kudos
Message 2 of 5
(7,296 Views)

Hey,

 

I have no knowledge of this function being built-in. 

Together with your point 3 I would suggest not to bind the data but to manage the display yourself.

 

As for your second point, I don't understand it yet I think. Please attatch a screenshot of your configuration, 

and describe what hardware you are using in what mode.

 

Kind regards, 

Rome

0 Kudos
Message 3 of 5
(6,973 Views)

Hi RomBe,

 

disregard my 2nd question.

 

My approach goes like this:

Instead of feeding the Graph with data every time the DAQ has something new aquired (I still save the complete data as TDMS), I have a background thread that wakes every 200ms where a copy of the current DaqTaskComponent.Data array gets saved in an identical data structure(downsampledData), which is bound to the Graph.

The displayed value is always ZERO, but according to the debugger it isnt. 

Binding the original DaqTaskComponent.Data is working correctly (but awefully slow)

Comparison DownsampleData<>TaskData

 

XAML

<ni:Graph x:Name="_graph"  RenderMode="Raster" Margin="20,0,22,20" SuppressScaleLayout="True" Background="LightGray"  Canvas.Left="418" Canvas.Top="121" Width="401" Height="287" DataSource="{Binding}" UseLayoutRounding="False" >
                <ni:Graph.Plots>
                    <ni:Plot Label="plot1" Name="plot1"/>
                </ni:Graph.Plots>
                <ni:Graph.Axes>
                    <ni:AxisInt32  x:Name="xScale"  Orientation="Horizontal" Label="Time [ms]" LabelOrientation="Natural" Range="0,1000"  />
                    <ni:AxisDouble x:Name="yScale" Orientation="Vertical" Adjuster="None" Visibility="Visible" Range="-10, 10" Label="Amplitude [V]" MinorDivisions="{x:Null}" MajorGridLines="{x:Null}"/>
                </ni:Graph.Axes>
            </ni:Graph>

 

Code: Working standard variante (DaqTaskComponent.Data)

      public event PropertyChangedEventHandler PropertyChanged;

          private void OnPropertyChanged(String info)
          {
              PropertyChangedEventHandler handler = PropertyChanged;
              if (handler != null)
              {
                handler(this, new PropertyChangedEventArgs(info));
              }
          }
         public AnalogWaveform<double>[] FillGraph 
        {
            get { return taskComponent.data; }
            set
            {
                if (value != taskComponent.data)
                {
                    value = taskComponent.data;
                    OnPropertyChanged("FillGraph");
                }
            }
        }
 void buttonDAQ_StartClick(object sender, RoutedEventArgs e)
        {
                taskComponent.StartRead();
                _graph.DataSource = FillGraph;
        }

Code: (downsampled.Data), Graph displays just 0

        AnalogWaveform<double>[]  downsampledData;
        downsampledData = new AnalogWaveform<double>[DAQ_CHANNELS];
        for (int i = 0; i < DAQ_CHANNELS; i++)
        {
          downsampledData[i] = new AnalogWaveform<double>(DaqConfig.samplesPerChannel);
        }
        private void PlotGraph()
        {
            for (int i = 0; i < DAQ_CHANNELS; i++)
            {
                downsampledData[i] = taskComponent.data[i];
             }
            Thread.Sleep(250);
        }
public AnalogWaveform<double>[] FillGraph // 
        {
            get { return downsampledData; }
            set
            {
                if (value != downsampledData)
                {
                    value = downsampledData;
                    OnPropertyChanged("FillGraph");
                }
            }
        }

 void buttonDAQ_StartClick(object sender, RoutedEventArgs e)
        {
                taskComponent.StartRead();
                _graph.DataSource = FillGraph;

                Thread.tTimer = new Thread(PlotGraph);
                Thread.tTimer.Start();
            }

 

I cut some minor stuff to the code so it doesnt compile correctly, if need to look something else up, I attached the project. (sorry about the mess, but its just a test project )

0 Kudos
Message 4 of 5
(6,803 Views)

I missed the while condition in the thread tTimer.

 

But this version is also exremely slow (task manager says 50-60%, feels more like 100% cpu consumption just for the graph)

 

 

0 Kudos
Message 5 of 5
(6,795 Views)