LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

How to plot out-of-phase data on a stripchart?

I apologize to anyone who actually reads this. Hope you have some aspirin.  

 

I'm trying to continuously plot the derivate of input data. The function "Difference()" appears to be made for calculating the derivative of an array of data. But using Difference() with continuous data is a serious headache.

 

My data is obtained 100 samples at a time. The data is stored in a 100 element array. In addition to the 100 element array, Difference() requires an initial and a final value, or 102 points in all. The requirement of a "final" value is the problem. It means you can't calculate the derivative immediately.

 

To calculate the derivative of the current 100 sample points you have to wait for the next 100 samples to get the "final" data point that Difference() requires. The first element of the next 100 samples is the "final" value required to calculate the derivative of the current 100 samples. This requires two 100 element arrays. One to hold the current 100 samples and another for the next 100 samples.

 

The chaining of 100 sample arrays works ok until you try to plot the data. I'm trying to plot raw data on one stripchart and the derivative of the raw data on another stripchart just below it. This works fine until the raw data chart fills up and starts scrolling. Since the derivative chart is 100 samples behind the raw data chart it doesn't scroll at the same time. So the charts become out of phase with each other.

 

The problem gets worse when Difference() is used again to calculate the second derivative and plot it on a third chart.  The charts get even further out of phase. More arrays are required to hold previously obtained data for the calculations. It gets really messy.

 

So my first question is, is there a way to sychronize charts so that they scroll at the same time?

 

My second question is, why does Difference even require a "final" value? Seems unnecessary to me. You only need two points to calculate a slope. But Difference() requires at least three, one actual data point and one initial and one final point.

 

I think I'm going to write my own Difference function and eliminate the need for a final value. If it works it will sure be a lot easier to use.

Maybe I'll find out from experience why Difference() calculates the derivative the way it does.

 

 

 

 

0 Kudos
Message 1 of 5
(3,868 Views)

The reason for initial and final condition is evident if you look at the formula used in calculations:  

Y(i) = [X(i+1) - X(i-1)] / 2dt

this permits to obtain an output  array with the exact dimension as the input one and to perform calculation od ferivative in place reusing the arrays. (A brute solution could be to pass x(0) as initial condition and x(n-1) as final condition.)

 

 

 

Just to save me some headaches Smiley Wink , I would consider if this approach can be a workaround for your problem:

 

 

First program iteration:

Plot 99 points or add a dummy extra point at the beginning or the end of the measures array

Calculate derivative on the 99 points array or calculate on the 100 elements dummy array using the 100th measure as the final condition

Subsequent iterations

Build a supplementary 100 measures array using the 100th from preceding iteration and 99 points acquired in actual iteration

Derivative calculated as above on the 100 elements array

 

Message Edited by Roberto Bozzolo on 09-25-2009 09:42 AM


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 2 of 5
(3,857 Views)

well, that's the way a derivative works: you need 2 points to compute one difference, so the difference is always 1 sample smaller than the data. (ok, the required final value seems strange, but anyway...)

 

you may overcome this problem by giving 0 as the initial value and the last point of your 100 samples as the final value, and the 99 other samples as data. for the second set of 100 samples, give the last sample of your previous set as the initial data and the last sample of this second st as the final one, etc... this way, you don't need to wait for the next set of 100 samples to get the derivative and the charts will be in sync.

 

(we have the same problem when computing the derivative of an image: we need a border one pixel wide which value greatly influences the result. often, we compute the derivative on an image which is 2 pixels smaller in each direction: the result does not have the same size as the original image but its value is far more correct and this avoids having an artifact on the border of the image)

 

(huho, it seems that, as always, Roberto was faster and clearer than me)

Message Edited by dummy_decoy on 09-25-2009 02:54 AM
0 Kudos
Message 3 of 5
(3,854 Views)

Thanks for your help Roberto.

 

I was aware of the formula used by the "Difference()" function. But what's wrong with the following? It eliminates the problematic "final" condition.

 

Y(i) = [X(i) - X(i-1)] /dt

 

Below is my "derivative()" function. It appears to produce the same result as "Difference()", at least the results look the same on a plot.

 

Maybe mathematical purists won't like my approach but I'm just an engineer. Close enough is good enough. This is a whole lot easier and cleaner to use than Difference(). It eliminates the need for additional arrays for temporary storage which is hard to develop and support.  It's also also error prone.

 

 
int derivative( double *data, int numRead, double dt, double initialCondition, double *dataDot)
{
 

    // initialCondition is the last element of the previous array of data.  
    

     int i;

    dataDot[0] = (data[0] - initialCondition)/dt;
    
    for (i=1; i < numRead; i++) {
    
        dataDot[i] = (data[i] - data[i-1])/dt;
    }
    
    return 0;

}

 

Surely this method doesn't produce much more heartburn for purists than using the last data array element as the "final" condition.

 

I hope someone who understands the consequences of this method will inform me of inaccuracies that result from it.

 

 

0 Kudos
Message 4 of 5
(3,843 Views)

Decoy,

 

Seems like you and Roberto agree that using the first 99 elements as the data array and the 100th element as the final/initial condition is the way to go. Maybe you're right. I'll give it a try.

 

thanks

0 Kudos
Message 5 of 5
(3,841 Views)