https://www.youtube.com/watch?v=83TpYkJQTyU&feature=youtu.beFeedback is welcome on a project, I'm having fun with.
Frequency range: 1k - 6.8M
DDS synthesizer AD9833
Accuracy of the phase measurement better than:
0.01 degree for frequencies < 100k.
0.3 < 1M
TBD > 6.8M
Modest results at high frequencies due to limited GBW of the MCP6S91.(Needs to be replaced. PGA feature is not active at the moment, both channels in buffer G=1 mode.)
Arduino adc sampling rate set 1 MSPS, 12-bits, 2 channels at 500 ksps. Sampling above 250 kHz is done in "undersampling" mode, aliasing number goes up to 28(!) at 6.8M. FFT size is 2048, 244 Hz/bin.
22-09-2018
///// Updates, after some debates we have on two pages...
Project is inspired by AD5933 IC, to create something even better and lower cost.
Objective of this project - network analyzer - is to measure magnitude and phase.
What next is not completely defined yet, using precise phase data impedance could be calculated, capacitance, inductance, phase and gain of the OPA or any other amplifiers could be traced with one click on a knob.
Arduino DUE as a base platform was chosen, because it's cheap and well supported on the software side.
Primary goal is accuracy of this two parameters: magnitude and phase.
To get 0.01 degree or better, w/o paying to much for gold plated IC, extremely overpriced high speed ADC, etc.
What I have is 12-bits adc, that is actually 9.6 (ENOB at 1 MSPS). So, SNR is less than 60 dB, not accounting for buffer amps, interference and all noise from digital circuits around.
60dB is Very low to reach the goal. To increase SNR ( and to calculate a magnitude & phase, of course) FFT-2048 was selected.
And here is the magic, fft provides 30 dB improvement in SNR, bringing it's up to 90 dB. That is about the same that someone could get out of expensive 16-bits ADC.
If I make fft size bigger, sacrificing speed, even better SNR ratio could be reached, and consequently, more accurate measurement results for magnitude & phase.
Logic diagram (crystalized on page 2): Phase Error - > SNR - > Bandwidth - > FFT
Now more software tricks...
I'd underline, highest priority is for phase accuracy.
Phase is easily calculated out of the fft results:
double get_Phase(int *fr, int n_bin)
{
int real = fr[n_bin];
int imag = fr[FFT_SIZE -n_bin];
double Phase = RAD_CONV *atan2((double)imag, (double)real);
return Phase;
}
Because there is a ratio: imag/real (arctang ( sin /cosine)), the most accurate results
is when ratio is close to 1. I don't think it has to be proofed.
There are couple steps implemented in software to keep an error smalest
To minimize phase noise:
1. DDS frequencies is always set to exact FFT bin, so it's corrected
+- 122 Hz up or down to nearest fft bin.
2. DDS synthesizer is preset to phase zero each time new freq. value loaded,
hold in reset mode, and start simultaneously with arduino adc sampling.
It's helpful at lower frequencies <1 MHz.
Since ADC is running at its own clock derived from arduino DUE prescaller
settings, that different from on-board DDS module's 25 MHz crystal,
phase jitter still exist. AD9833 is also not very stable on this matter:
LATENCY PERIOD
A latency period is associated with each asynchronous write
operation in the AD9833. If a selected frequency or phase
register is loaded with a new word, there is a delay of seven
or eight MCLK cycles before the analog output changes. The
delay can be seven or eight cycles, depending on the position
of the MCLK rising edge when the data is loaded into the
destination register.
3. I'm thinking to add some quality factor, when phase data close to 0 or close to 90
- results should be discarded and measurements repeated at this point.
I attached a "working copy" of the software. Be careful, there are many debug messages, and may be some harsh comments, don't take it personally.
King of the dsp engine - fft library - was posted here, message #4
https://www.eevblog.com/forum/microcontrollers/fft-processing-using-ucpu/ Though, any other will make no difference, DSP pack for cortex-3 for example (not tested).