Quantcast
Channel: LabWindows/CVI topics
Viewing all articles
Browse latest Browse all 5340

Bode Plot - issue with phase

$
0
0

I previously had an implementation issue while trying to produce Bode plots for hardware my team has designed. I have now successfully been able to produce the expected data, with one issue. Some of the phase data points are the reciprocal of what is expected. I will explain the process used...

 

The hardware I am connecting to allows me to inject signals on channels, as well as stream these channels to my PC application for analysis. The function I am trying to replicate is a frequency sweep, as follows:

- commanding the hardware to override a channel (the stimulus) with a sine wave of given frequency, f

- stream the stimulus channel as well as its response channel for a given number of cycles, P

- perform analysis ("transfer function") on both stimulus and response channels' streamed data

- log the frequency (f) with the corresponding calculated magnitude and phase for use to produce a Bode Plot

- increase frequency (f) and repeat steps

 

This code sample is the "analysis" performed:

 

int i, MaxMagIdx, DontCareIdx;

double *TimeInMag,
*DontCareArr, TransferReal, TransferImg, TransferMag, TransferPhase, DontCare, AdjFreq; NIComplexNumber *TimeSweepIn, *TimeSweepOut, *FFTSweepIn, *FFTSweepOut; TimeSweepIn = malloc(gSweepCountMax * sizeof(NIComplexNumber)); TimeSweepOut = malloc(gSweepCountMax * sizeof(NIComplexNumber)); FFTSweepIn = malloc(gSweepCountMax * sizeof(NIComplexNumber)); FFTSweepOut = malloc(gSweepCountMax * sizeof(NIComplexNumber)); TimeInMag = malloc(gSweepCountMax * sizeof(double)); DontCareArr = malloc(gSweepCountMax * sizeof(double)); int InputSigIndex; unsigned char OverrideMsg[L_ADC_OVERRIDE_RQ] = {0}; for (i=0;i<gSweepCountMax;i++) { TimeSweepIn[i].real = gSweepInArr[i]; TimeSweepOut[i].real = gSweepOutArr[i]; TimeSweepIn[i].imaginary = 0.0; TimeSweepOut[i].imaginary = 0.0; } CxFFTEx (TimeSweepIn, gSweepCountMax, gSweepCountMax, NULL, FALSE, FFTSweepIn); CxFFTEx (TimeSweepOut, gSweepCountMax, gSweepCountMax, NULL, FALSE, FFTSweepOut); for (i=0;i<gSweepCountMax;i++) { ToPolar (FFTSweepIn[i].real, FFTSweepIn[i].imaginary, &TimeInMag[i], &DontCareArr[i]); } MaxMin1D (TimeInMag, gSweepCountMax, &DontCare, &MaxMagIdx, &DontCare, &DontCareIdx); CxDiv (FFTSweepOut[MaxMagIdx].real, FFTSweepOut[MaxMagIdx].imaginary, FFTSweepIn[MaxMagIdx].real, FFTSweepIn[MaxMagIdx].imaginary,&TransferReal, &TransferImg); ToPolar (TransferReal, TransferImg, &TransferMag, &TransferPhase); TransferMag = 20 * log10 (TransferMag); TransferPhase = RadToDeg (TransferPhase); AdjFreq = (double)((unsigned long)(gSweepFreq*0x200000000/(double)50000000)) * 50000000/(double)0x200000000; fprintf(Logfile_Handle, "%lf\t%lf\t%lf\n", AdjFreq, TransferMag, TransferPhase); free(TimeSweepIn); free(TimeSweepOut); free(FFTSweepIn); free(FFTSweepOut); free(TimeInMag); free(DontCareArr);

 

It works nearly perfectly. The issue is that the calculated phase will sometimes be positive when it should be negative, and vice versa.

 

Here is a plot of the data produced:

 

bad bode.png 

 

This is what is expected:

 

good bode.png

 

Here are both overlayed:

 

both bode.png

 

The expected plot was produced by cheating the log file. I went in and all I did was change the incorrect points to/from negative values. I want to eliminate this step. As you can see, if the incorrect data is mirrored on the zero-line, it would be what we expect. This "expected" data matches what my co-worker's analyzer hardware (Venable device) produces when used on our device.

 

 

We believe that the issue is not with the complex math performed, but an issue in the FFT function, or the selection of the index to use on the array of data.


Viewing all articles
Browse latest Browse all 5340

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>