Author Topic: Signal processing - getting exact frequency from short ADC sample  (Read 9448 times)

0 Members and 1 Guest are viewing this topic.

Offline MasterT

  • Frequent Contributor
  • **
  • Posts: 791
  • Country: ca
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #25 on: December 14, 2019, 11:51:55 pm »
Correlation with a sine wave is a Goertzel algorithm. The solution is to synthesize 10-50 sets of coefficients for Goetzel tunned at 10 000 +-  N x 0.1 Hz, than run a math with input data array. Last step is to find a maximum. Theoretically, there is no limits to frequency calculation, since steps could be any value, 0.1 or 0.0001 Hz. Everything would depends on SNR ratio. Here is a quick test,

889798-0
Data 12-bits, polluted with noise 16 - 64- 256 LSB. With higher noise level peak is drifted to the right, last value -256 is off for 0.2 Hz
Code:
« Last Edit: December 15, 2019, 12:03:41 am by MasterT »
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 27203
  • Country: nl
    • NCT Developments
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #26 on: December 14, 2019, 11:57:59 pm »
That doesn't sound like a good approach because you need to do a lot of math and the result is still a guess. Goertzel is basically a single bin FFT. If you need to achieve a high resolution then you need many very narrow bins to try.

The easiest and least processing intensive solution by far is to create a frequency meter in software using interpolated data.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline Marco

  • Super Contributor
  • ***
  • Posts: 6746
  • Country: nl
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #27 on: December 15, 2019, 08:39:30 am »
Very simple algorithms using the FFT bins near the max bin seem to get so close to the error bound that anything more complex than that seems superfluous.

https://www.researchgate.net/publication/3316697_Fast_nearly_ML_estimation_of_the_parameters_of_real_or_complex_single_tones_or_resolved_multiple_tones

Following the citations there are autocorrelation methods which are faster.

PS. actually if I wanted something faster I'd consider doing single sample delay autocorrelation to get a good estimate, then do DFT for 3 or 5 components and do the DFT based estimation. That way you can skip the full 256 point FFT ... but is a 256 point FFT really going to be a problem?
« Last Edit: December 15, 2019, 04:19:14 pm by Marco »
 

Offline mark03

  • Frequent Contributor
  • **
  • Posts: 720
  • Country: us
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #28 on: December 15, 2019, 05:56:27 pm »
I'm seeing an awful lot of ad-hoc and intuition-based methods being proposed here, largely based on the FFT.  While this may be useful for understanding the problem, I feel like I should repeat the point I made earlier:  The best chance for success will probably come from "subspace" methods using the singular value decomposition, specifically the MUSIC and ESPRIT type algorithms.  These are able to leverage a priori knowledge about the signal (the number of sinusoids) and can achieve significantly better resolution than FFT-based methods.
 
The following users thanked this post: daqq

Offline Marco

  • Super Contributor
  • ***
  • Posts: 6746
  • Country: nl
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #29 on: December 15, 2019, 06:14:05 pm »
They are ridiculously over complex for a single sinusoid. The 5 bin discrete fourier based method in the paper is within 0.6 dB of optimal ... as I said, something much more complex doesn't make a whole lot of sense.
 

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 2145
  • Country: fi
  • Embedded SW/HW.
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #30 on: December 15, 2019, 06:42:10 pm »
Made some bogus data, with an amplitude of +/- 75% at 10,000.0 Hz and 10,000.1 Hz. You can draw your own conclusions:
<snip>

If you look at the samples from hamster_nz's original post, you should get the idea how difficult this will be with such short data even without any noise involved.
 

Offline ogden

  • Super Contributor
  • ***
  • Posts: 3731
  • Country: lv
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #31 on: December 15, 2019, 09:44:52 pm »
You can't accurately know amplitude until you accurately know frequency.
:palm:
 

Online Kleinstein

  • Super Contributor
  • ***
  • Posts: 14365
  • Country: de
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #32 on: December 15, 2019, 10:00:00 pm »
For pulsed acoustic data, I would assume there would be quite some idle time after the 2 ms pulse, just to wait for echos to decay. So the overall data rate would not be that high, maybe getting data for 1% of the time.  Depending on the µC / CPU used there could be enough time to do the full least squares fit and thus get very close to the best possible (at least in case of additive white noise) result.  A general nonlinear least square fit takes quite some time. However specialized to estimating DC offset, amplitude, phase and frequency the computations are not that bad anymore. In the right form (as cos and sine part) only the frequency is a nonlinear parameter so the iterations can be quite effective (exact for the amplitudes and DC offset).
 
The following users thanked this post: daqq

Offline Marco

  • Super Contributor
  • ***
  • Posts: 6746
  • Country: nl
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #33 on: December 15, 2019, 10:17:55 pm »
:palm:

What? Do you want to calculate it from variance? AFAICS that will have more noise than an ideal estimate from a discrete Fourier transform at the exact frequency ... and there's not a lot of room for less than ideal estimates.

You don't even really need the renormalization, but the phase based approaches using single sample lag autocorrelation need a lot of hacks to make it work well regardless. In fact to get close to the error bound they tend to only work for frequencies near zero. So it's usually a two step process, first do a bad estimate, mix down to near DC, then try again. A lot more code than Macleod's discrete Fourier domain approach (assuming you use someone else's Fourier transform code).
« Last Edit: December 15, 2019, 10:22:33 pm by Marco »
 

Offline mark03

  • Frequent Contributor
  • **
  • Posts: 720
  • Country: us
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #34 on: December 15, 2019, 10:40:58 pm »
They are ridiculously over complex for a single sinusoid. The 5 bin discrete fourier based method in the paper is within 0.6 dB of optimal ... as I said, something much more complex doesn't make a whole lot of sense.
Well, this is not my area of expertise, but I am skeptical.  Macleod casts the problem as finding "the parameters (frequency, amplitude, and phase)" which would seem to rule out many techniques at the outset.  Here we only care about accurate frequency estimation.  Also, Macleod's only mention of the subspace methods in the paper is to dismiss them as computationally expensive.  Finally, I know that these methods are used in other settings with only one tone, e.g. NMR.  In fact, I run a proton-precession magnetometer (not my design) which uses the so-called "filter diagonalization method" for accurately estimating the frequency of the decaying precession signal.  I'm quite sure it would not work with a simple FFT + interpolator approach.
 

Offline ogden

  • Super Contributor
  • ***
  • Posts: 3731
  • Country: lv
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #35 on: December 15, 2019, 11:50:37 pm »
:palm:
What? Do you want to calculate it from variance? AFAICS that will have more noise than an ideal estimate from a discrete Fourier transform at the exact frequency ... and there's not a lot of room for less than ideal estimates.
I just wanted to point out that you are wrong with your blanket statement. To measure signal amplitude you do not need to "accurately know signal frequency" as you say. You can measure amplitude w/o even knowing frequency. Think white noise for instance. All you want to know is "frequency band", ensure that period of lowest frequency component (of interest) is shorter than time window of measurement of amplitude.

BTW method I did propose is widely used and comes from power industry where mains frequency drift shall be detected as soon as possible and accumulating enough periods for other methods (correlation/fft/zerocrossings/e.t.c.) is not an option.

[edit] BTW upsampling, then reciprocal frequency calculation for full sine periods (zero crossings) is derivative. Put a little thought into it and you will see.
« Last Edit: December 15, 2019, 11:57:55 pm by ogden »
 

Offline Etesla

  • Regular Contributor
  • *
  • Posts: 150
  • Country: us
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #36 on: December 15, 2019, 11:57:24 pm »
Maybe something more practical.

Apply a bandpass DSP filter (to get rid of as much out of band noise as you can).

Interpolate zero crossing between samples.

Period is 2*(LastZeroCrossTime-FirstZeroCrossTime) /(NumberOfZeroCrossings-1)

Frequency is 1/period.

That was my first thought as well assuming the signal your measuring is guaranteed to cross zero x times per cycle
 

Offline coppice

  • Super Contributor
  • ***
  • Posts: 8797
  • Country: gb
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #37 on: December 15, 2019, 11:59:10 pm »
:palm:
What? Do you want to calculate it from variance? AFAICS that will have more noise than an ideal estimate from a discrete Fourier transform at the exact frequency ... and there's not a lot of room for less than ideal estimates.
I just wanted to point out that you are wrong with your blanket statement. To measure signal amplitude you do not need to "accurately know signal frequency" as you say. You can measure amplitude w/o even knowing frequency. Think white noise for instance. All you want to know is "frequency band", ensure that period of lowest frequency component (of interest) is shorter than time window of measurement of amplitude.

BTW method I did propose is widely used and comes from power industry where mains frequency drift shall be detected as soon as possible and accumulating enough periods for other methods (correlation/fft/zerocrossings/e.t.c.) is not an option.
I suspect he meant that you need the frequency of the signal of interest before you can calculate its amplitude, rather than the total signal amplitude with noise, harmonics, etc. However, he's wrong on that too.

Calculating mains power frequency is easy. With glitch suppression you can use zero crossings of the voltage waveform. The current waveform can be so distorted that you get extra zero crossings, but if the voltage waveform is that distorted something is badly wrong.
 

Offline ogden

  • Super Contributor
  • ***
  • Posts: 3731
  • Country: lv
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #38 on: December 16, 2019, 12:05:22 am »
Calculating mains power frequency is easy.
Actually math is same for all sine waveforms no matter they are mains power or other kind of "signals".
 

Offline coppice

  • Super Contributor
  • ***
  • Posts: 8797
  • Country: gb
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #39 on: December 16, 2019, 12:07:01 am »
Calculating mains power frequency is easy.
Actually math is same for all sine waveforms no matter they are mains power or other kind of "signals".
Perhaps you should have read what I wrote.
 

Offline ogden

  • Super Contributor
  • ***
  • Posts: 3731
  • Country: lv
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #40 on: December 16, 2019, 12:11:09 am »
Calculating mains power frequency is easy.
Actually math is same for all sine waveforms no matter they are mains power or other kind of "signals".
Perhaps you should have read what I wrote.
Perhaps you shall explain what you mean by saying so.
 

Offline coppice

  • Super Contributor
  • ***
  • Posts: 8797
  • Country: gb
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #41 on: December 16, 2019, 12:21:26 am »
Calculating mains power frequency is easy.
Actually math is same for all sine waveforms no matter they are mains power or other kind of "signals".
Perhaps you should have read what I wrote.
Perhaps you shall explain what you mean by saying so.
Let me expand on what I said. If you just use zero crossings on the voltage waveform to estimate the mains frequency you will have problems when people use certain equipment, like arc welders. You can apply a glitch suppression algorithm to clean up the fast transitions caused by equipment like that, which can have a huge amplitude, and very fast edges. Then, applying a zero crossing detector is a robust mechanism for measuring the mains frequency. The voltage waveform might have 30% to 40% THD under some conditions, but you just don't see extra zeros crossing in real world conditions. Try that with the current waveform, and you will have trouble. The current waveform is frequently so distorted it does show zero crossings at one of the harmonic frequencies. So, if you specifically need to extract the frequency from the current waveform you will need to use other techniques.
 
The following users thanked this post: ogden

Offline Berni

  • Super Contributor
  • ***
  • Posts: 4997
  • Country: si
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #42 on: December 16, 2019, 06:42:36 am »
Let me expand on what I said. If you just use zero crossings on the voltage waveform to estimate the mains frequency you will have problems when people use certain equipment, like arc welders. You can apply a glitch suppression algorithm to clean up the fast transitions caused by equipment like that, which can have a huge amplitude, and very fast edges. Then, applying a zero crossing detector is a robust mechanism for measuring the mains frequency. The voltage waveform might have 30% to 40% THD under some conditions, but you just don't see extra zeros crossing in real world conditions. Try that with the current waveform, and you will have trouble. The current waveform is frequently so distorted it does show zero crossings at one of the harmonic frequencies. So, if you specifically need to extract the frequency from the current waveform you will need to use other techniques.

Easy way to solve that is to run the signal trough a bandpass FIR/IIR filter to remove signals out of the band of interest, leaving you with just the sine wave you want.

But still i think OP is looking at the problem from the wrong direction. If you use a quadrature mixer to convert the 100.1KHz signal down to a pair of 100Hz signals things get a lot easier (Its essentially a software defined radio at this point). Not only is this computationally cheap to do, but unlike his method of taking 1 second long 1MSPS recordings of the signal and processing them later, this downconversion method can also operate continuously on a signal, giving you a result on every sample rather than just one sample per second.

Another advantage to mixer downconversion is that the sample rates can be quickly reduced. The only thing that runs at the full 1 MSPS is the mixer it self (This involves two multiply operations against a sine table and a sum to advance the table) after that the signal is low bandwith (100Hz) so you can use averaging (or a proper FIR downsampler if you like to be fancy) to drop the samplerate to something like 1KHz for all the rest of the processing, this downsampling step also filters out any out of band noise.

At this point there are two 90 degree out of phase 100Hz sinewaves coming out of this. This allows you to convert them to polar form from just looking at one sample. The polar magnitude being the sine wave size and the phase being distance to doppler target. You can then unroll phase between any two samples and get the distance the doppler target has moved between those two points in time, divide that by time to get the average speed within that chosen window of time (Note this window can be placed anywhere along the stream of data)

If your radar/sonar is picking up multiple doppler targets then this step is a bit more complicated because there will be multiple sinewaves in this downconverted signal. Here you might use complex input FFT to seperate them out, pick out the targets, then inverse FFT them back into a time domain signal to process same as before. This creates a sort of tracking bandpass filter for each target. This part is computationally heavy but thanks to the prior work this only needs to run at a sample rate of 1KHz so actually does not need a lot of processing power.
« Last Edit: December 16, 2019, 06:45:31 am by Berni »
 
The following users thanked this post: daqq

Offline daqqTopic starter

  • Super Contributor
  • ***
  • Posts: 2302
  • Country: sk
    • My site
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #43 on: December 16, 2019, 07:56:14 am »
Wow. Thanks guys for the amazing replies, I'm still reading through them in detail.

I'll try simulating the signal in Octave (open source matlab equivalent) and play around with it some more based on everyones advice.

Quote
The simplest way would be to interpolate (upsample) the signal so you get to the required resolution and then determine the frequency by looking at the zero crossings. Jitter and noise will be your biggest enemy though but if you can average the frequency of several cycles you should be able to filter out the noise. Using a narrow filter to make sure you only get the relevant frequencies of the signal will help to reduce noise. Basically a frequency meter in software.
That's an interesting approach. I'll try that, though I'm not sure how to apply the filter to the 'edges' of the sample window.
Quote
Centroid timing and transition midpoint timing time to digital converters use curve fitting to make a more precise measurement of a waveform with known characteristics.  If your signal is bandwidth limited, then sin(x)/x interpolation will also allow this.
It is bandwidth limited, yeah.

I'll have to study upon the whole interpolation math.

Quote
A general nonlinear least square fit takes quite some time. However specialized to estimating DC offset, amplitude, phase and frequency the computations are not that bad anymore.
At the moment there's no real limit on the processing power, it's just in the guessing and estimating stage, whether or not it's possible at all.

Berni: Thanks for the mixer idea, I've been thinking about it, but with such a small time frame, the more I downconvert (mix it with a high frequency getting the frequency difference), the less 'full sines' I get? Basically, if my window 2ms (200 samples) and I downconvert from 10kHz to, say, 100Hz, then, during the 2ms I don't even get one full sine.

Thanks again everyone, I'll play around with it more during the week.
Believe it or not, pointy haired people do exist!
+++Divide By Cucumber Error. Please Reinstall Universe And Reboot +++
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #44 on: December 16, 2019, 08:02:45 am »
Not sure if you are aware of the Hilbert Transform? https://en.wikipedia.org/wiki/Hilbert_transform

With it you can take an 'real' signal, and convert it into an I+Q signal.

What might be interesting about it is that you don't need to apply it to each point.

You can cut the dataset in to two halves (points 0-99 and points 100-199), then convert ONLY points 50 and 150 into I+Q (based on, then look at the phase difference between them - and see how much the phase has changed over the 100 samples. This isn't a bad as it seems, as if you are to run a FIR or IIR filter over your data to remove noise, you will end up truncating your data (for a FIR filter) or have to wait for the IIR filter to settle down.

One of the interesting properties (well at least to me) of the Hilbert Transform is that you can incorporate a bandpass filter at the same time, so that might be a win too.

Doing this means you don't have to worry about 'zero crossings' or anything like that - you get to pick the points you want to look at the phase of, rather than waiting for zero crossings where you know the phase is one of two values.

It also hints (at least to me), that if I had the choice of 2ms of data or 8ms of data at 1/4th the sample rate, I would take the 8ms of data as any phase difference will be 4x as great, and it is far less work to bandpass filter the frequencies of interest.

PS. If interested, you could convince me to code up a demo...
« Last Edit: December 16, 2019, 08:05:53 am by hamster_nz »
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline Berni

  • Super Contributor
  • ***
  • Posts: 4997
  • Country: si
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #45 on: December 16, 2019, 08:49:21 am »
Berni: Thanks for the mixer idea, I've been thinking about it, but with such a small time frame, the more I downconvert (mix it with a high frequency getting the frequency difference), the less 'full sines' I get? Basically, if my window 2ms (200 samples) and I downconvert from 10kHz to, say, 100Hz, then, during the 2ms I don't even get one full sine.

Thanks again everyone, I'll play around with it more during the week.

The point of using downconversion is to turn the real signal into a complex I/Q quadrature signal, the reduction in frequency is just a side effect that can be later used to help reduce the required processing power. It is perfectly possible to go the other way and upconvert against 1GHz to turn 100.1KHz into 1000100.1 KHz if you want more frequency.

The advantage of having the signal in I/Q form is that you determine the phase by looking at only 1 sample, just converting that complex I/Q number from rectangular form to polar form (This is just calculating the sides of a right angle triangle, so just needs elementary school level math). Since phase and frequency are related via time means that you only need 2 samples from the ADC to be able to determine the frequency to any precision past 0.0001Hz. In practice however more points are needed to get to sub 1Hz precision due to the ADC not being perfect (number of bits, noise, nonlinearity etc...). There is no need to see single a zero crossing in the signal, since you know the phase in every point means you can determine the frequency pretty accurately by seeing just 1/4 of one sine wave period. This is because a sinewave will move forwards by 90 degrees in phase after 1/4 period, and there is only one unique frequency that will move its phase by 90 degrees in the given time frame of the ADC capture.

So if your ADC is decent and input signal is stable you can likely use this "downmixing and polar connversion" to determine the frequency down to 0.1Hz precision from looking at only 5ms of your 1MSPS ADC data.

Another advantage is that if you skip averaging after downconversion you keep 1MSPS trough the signal chain. So with only a few dozen multiply and accumulate operations per sample (after some optimizations) you stream data trough the process in a pipelined way to get 1 000 000 frequency readings per second as the output, each accurate to 0.1Hz (Or even more accurate if you use a larger phase integration window).

Best of all doing this required no advanced math at all. All you have to do is multiply each sample with a sine function, then do a bit of trigonometry to find the phase angle and you are done. But the process is a bit easier to understand if you have a good idea of how complex numbers work.
 

Online Kleinstein

  • Super Contributor
  • ***
  • Posts: 14365
  • Country: de
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #46 on: December 16, 2019, 09:35:34 am »
The Hilbert transform / down-conversion is a viable option if computational speed is critical. I would still use averaging before calculating the phase. In C code the  ATAN2 function needed here is one of the really slow ones. With noisy data one could also get effects of noise leaving the linear range. So it makes sense to do averaging / down sampling before in the complex domain.

The least squares fit gives the limit how good it can get (if the noise is white). The fitting result to the 12 Bit simulated data showed that sufficient resolution would be possible. I just realized the uncertainty number was in absolute numbers so the error bar is more like 1-1.5 ppm. So to get 0.1 Hz resolution (10 ppm) the noise could be higher by about a factor of 8. So the data would need to be good to about 9 Bits to reach the aimed for 0.1 Hz resolution.

From my experience (though with considerably longer data sets and additional amplitude decay as another parameter) the Hilbert transform is slightly more sensitive to noise and may need another 2-6 dB better signals. How much depends on the exact implementation (e.g. choice of the windows for the transformation). Speed wise the Hilbert transformation is faster by maybe a factor of 10 - with the rather short data set the ATAN2 function may reduce that advantage and have the noise disadvantage a little higher as relatively short windows have to be used.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #47 on: December 16, 2019, 09:52:59 am »
I couldn't resist - here's using the Hilbert Transform to detect the phase change over 100 samples and extrapolating that to 100,000 samples. The input is a file containing 200 samples.

Note that any signal that is a harmonic of the sample rate divided by 100 could be used... so with a sample rate of 100kS/s the signal you are analyzing could be 50kHz, 33.3kHz, 25KHz, 20kHz.. whatever. All that matters is that after 100 samples there is nominally zero phase offset. (oh, and you will need to change the magic fudge factor in the kernel if you are looking for a different frequency).

Assumes that the input data has already been bandpass filtered to just around the frequencies of interest.

Code: [Select]
/************************************************************
 * poc.c : A really bad Proof of concept
 *
 * Can you extract tiny frequency changes from small datasets
 * using the Hilbert Transform? Yes, it seems you can.
 *
 * Expects a single command arg that is a list of 200 samples
 * Processes it assuming the sample rate is 100kS/s, and
 * measures the crawl in phase over 100 samples. This is then
 * used to extrapolate to the change of phase after 100,000 samples.
 *
 * This isn't supposed to be the most correct code, just a hack
 * to see if it works.
 ************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

double data_r[200];
double data_i[200];
double kernel[99];

static void build_kernel(void) {
   int i;

   for(i = -49; i < 50; i++) {
     if((i&1)==1) {
        // I pulled the scaling factor out of my data
        kernel[i+49] = 1.0/i/3345*2047;
     }
   }
}

static void hilbert(double *data, double *result) {
   double r = 0;
   int i;
   // Apply the kernel
   for(i = -49; i < 50; i++) {
      r += data[i]*kernel[i+49];
   }
   *result = r;
}

int main(int argc, char *argv[]) {
   int i;
   FILE *f;

   build_kernel();

   if(2 != argc) {
      fprintf(stderr,"Only supply data file name\n");
      exit(0);
   }

   f = fopen(argv[1],"rb");
   if(NULL == f) {
      fprintf(stderr,"Unable to open file\n");
      exit(0);
   }

   for(i = 0; i < 200; i++) {
     if(1 != fscanf(f,"%lf",data_r+i)) {
        fprintf(stderr,"Error reading data\n");
        exit(0);
     }
     data_i[i] = 0.0;
   }
   fprintf(stderr, "Data read\n");

   // Just calculate the transform at two places
   hilbert(data_r+49, data_i+49);
   hilbert(data_r+149, data_i+149);

   double phase49,phase149,change;

   phase49 = atan2(data_r[49],data_i[49]);
   phase149 = atan2(data_r[149],data_i[149]);
   change = (phase149-phase49)/100;

   /* change' needs to be wrapped into +/- PI, but I haven't done it */

   printf("Angle at sample 49 is  %10.6f\n",phase49);
   printf("Angle at sample 149 is %10.6f\n",phase149);

   printf("Change in cycles after 100,000 samples %10.6f\n", change*100000/(2*M_PI));
   return 0;
}


Here's the output when the data is 0.1 Hz faster:
Code: [Select]
Data read
Angle at sample 49 is   -0.657761
Angle at sample 149 is  -0.658373
Change in cycles after 100,000 samples  -0.097432

And 0.1 Hz slower

Code: [Select]
Data read
Angle at sample 49 is   -0.657381
Angle at sample 149 is  -0.656791
Change in cycles after 100,000 samples   0.093872

Here's the hack I was using to generate test data

Code: [Select]
#include <stdio.h>
#include <math.h>
#define SAMPLE_RATE (100000.0)
#define FREQUENCY   (9990.0)
#define SCALE       (2047)
int main(int argc, char *argv[]) {
   int i;
   for(i = 0; i < 200; i++) {
      double d = sin(i/(SAMPLE_RATE/FREQUENCY)*2*M_PI)*SCALE;
      printf("%i\n",(int)(d));
   }
   return 0;
}
« Last Edit: December 16, 2019, 10:03:04 am by hamster_nz »
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 
The following users thanked this post: mycroft

Offline ogden

  • Super Contributor
  • ***
  • Posts: 3731
  • Country: lv
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #48 on: December 17, 2019, 02:31:21 pm »
But still i think OP is looking at the problem from the wrong direction. If you use a quadrature mixer to convert the 100.1KHz signal down to a pair of 100Hz signals things get a lot easier (Its essentially a software defined radio at this point). Not only is this computationally cheap to do, but unlike his method of taking 1 second long 1MSPS recordings of the signal and processing them later, this downconversion method can also operate continuously on a signal, giving you a result on every sample rather than just one sample per second.
I am afraid that you drive OP into wrong direction as well. Estimating precise frequency of downmixed 100Hz do not seem to be simpler than just counting zero crossings of "carrier".
 

Offline Marco

  • Super Contributor
  • ***
  • Posts: 6746
  • Country: nl
Re: Signal processing - getting exact frequency from short ADC sample
« Reply #49 on: December 17, 2019, 03:03:04 pm »
He isn't suggesting just downmixing it, he's suggesting downmixing it by sines in quadrature.

I think after low pass filtering, the phase of the quadrature results treated as a complex vector will give you the frequency shift (side effect of the PM/FM equivalence).
« Last Edit: December 17, 2019, 03:08:33 pm by Marco »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf