07-14-2009 02:02 AM
07-15-2009 09:52 AM - edited 07-15-2009 09:55 AM
To fully answer this question, there is a lot of info missing.
Is the frequency of the source constant?
Is the sampling rate of the ADC equal to or greater than 2 times the frequency of the source (Nyquist limit)?
How well to you need to know the exact frequency / period of the source?
If you just want to get a crude estimate of the period, you can walk through the data until you find a local maxima. Store the location of that maxima, then repeat. Once you have two adjacent maxima, the period is the number of data points between the two maxima divided by the sampling rate. Something similar to this should work
float *data_array, period, sampling_rate;
int l_maxima_1 = 0.0, l_maxima_2 = 0.0;
for (i=0; i < num_data_pts - 1; i++)
{
if (data_array[i] < data_array[i + 1])
continue;
if (l_maxima_1 == 0.0)
{
l_maxima_1 = data_array[i];
continue;
}
l_maxima_2 = data_array[i];
i = num_data_pts; // done exit for loop
}
period = (l_maxima_2 - l_maxima_1) / sampling_rate;
This code assumes that the function contains positive values. If not sure if there are any positive values do a median calculation first and set the l_maxima and their test condition to the median value. The algorithm here assumes the function is very smooth and that any noise is small relative to each sampling step.
If you need a better estimation of frequency / period use a FFT based approach. Be aware that the FFT of a square wave (at 50% duty cycle) will return the fundamental frequency plus all of the odd harmonics. The abundance ratio of these harmonics will change as the duty cycle changes. I really don't know what the FFT of a triangle wave gives you.
As for duty cycle, I guess I understand duty cycle in terms of a square wave (two state process)but not so much in terms of a triangle or sine wave. For duty cycle of the square wave, use a similar code to above but measure rising edge (first time value is above threshold) and falling edge (first time value falls below threshold).