08-13-2009 07:23 AM
Hi,
We are using NI-DAQmx PCI 4461 card and Measurement Studio Version 4.5
We have voltage signal as an input and want to get correct magnitude values from it. We are using the following lines to get the magnitudes but seems that the magnitude calculated is not correct:
Task myTask = DaqSystem.Local.LoadTask("MyVoltageTask");
myTask.Control(TaskAction.Verify);
AnalogSingleChannelReader dataReader = new AnalogSingleChannelReader(myTask.Stream);
// Get voltage values
double[] voltageData = dataReader.ReadMultiSample(100);
int dataSize = voltageData.Length;
double[] objMagnitudes = new double[dataSize];
ComplexDouble[] fftValue = new ComplexDouble[dataSize];
fftValue = Transforms.RealFft(dataToAnalyze);
// Get the magnitudes of FFT array..
objMagnitudes = ComplexDouble.GetMagnitudes(fftValue);
We have generated 100 random voltage values and calculated the magnitudes from them using the above logic (attached the results herewith). Can you please analyze the result we get and let us know whether the magnitude values we calculated are correct or not?
Bipul Dobhal
08-14-2009 11:02 AM
Hello Dobhal,
I did not find the results file attached. Send it across. Also, why dont you try giving an array of 100 (known) values as input to your logic which you had posted above? This way we can compare the results obtained from your current program with an FFT analysis tool built on another platform or ADE and validate your results.
Looking forward to seeing your test results and little more information on your application! 🙂
08-15-2009 03:35 AM
08-17-2009 01:18 AM
Hi Bipul,
The FFT magnitude array you're getting is correct. I have calcuated the FFT for both the arrays (random values and known values) using LabVIEW (vi: "FFT VI") and am attaching the code below. I'm reading values from the Excel file you have attached and computing the FFT.
I'm attaching my code below for your reference. Please have a look at it.
Regards,
Vaibhav Vashisht.
08-18-2009 04:37 AM
Thanks for your response.
Actually the problem we are facing is too complicated. Let me explain the whole problem in brief.
We have an existing application (running on production) built in “Power Builder & C++” where we are using NI 4551 card. And now we have re-engineered the same application in .Net where we are using NI 4461 card. To test the new application we have configured both applications is such a way that both can run in parallel. But magnitude values calculated from both application are differed a lot.
The logic implemented to get magnitude values in existing application (C++ code) is as follows: ViSession dsa_session;ViInt32 ipchannel= 16, measurement_length;double mag[101]; ViReal32 x0, dx, measurement[101];ViInt32 Real_Or_Complex = 0;ViStatus new_measurement = 0; while ( new_measurement < 1 ){NIDSA_check_new_measurement ( dsa_session, &new_measurement);Sleep(13);Application->ProcessMessages();} NIDSA_get_measurement_length (dsa_session, ipchannel, 2, &measurement_length, &Real_Or_Complex);NIDSA_read_measurement (dsa_session, ipchannel, 0,measurement_length, 2, 0, 1,0, &x0, &dx, measurement); for (int i=0; i<= 101 ; i ++){mag[i] = x0 + i * dx;
}
The logic implemented in new application (.Net) is already published in my previous posts.
So now please go through the logic of both applications and suggest us the correct logic/changes so that we can get the same results as of existing application.
Bipul Dobhal
08-18-2009 04:44 AM
Thanks for your response.
Actually the problem we are facing is too complicated. Let me explain the whole problem in brief.
We have an existing application (running on production) built in “Power Builder & C++” where we are using NI 4551 card. And now we have re-engineered the same application in .Net where we are using NI 4461 card. To test the new application we have configured both applications is such a way that both can run in parallel. But magnitude values calculated from both application are differed a lot.
The logic implemented to get magnitude values in existing application (C++ code) is as follows:
ViSession dsa_session;
ViInt32 ipchannel= 16, measurement_length;
double mag[101];
ViReal32 x0, dx, measurement[101];
ViInt32 Real_Or_Complex = 0;
ViStatus new_measurement = 0;
while ( new_measurement < 1 )
{
NIDSA_check_new_measurement ( dsa_session, &new_measurement);
Sleep(13);
Application->ProcessMessages();
}
NIDSA_get_measurement_length ( dsa_session,ipchannel, 2,&measurement_length,&Real_Or_Complex);
NIDSA_read_measurement (dsa_session, ipchannel, 0,measurement_length, 2, 0, 1,0, &x0, &dx, measurement);
for (int i=0; i<= 101 ; i ++)
{
mag[i] = x0 + i * dx;
}
The logic implemented in new application (.Net) is already published in my previous posts.
So now please go through the logic of both applications and suggest us the correct logic/changes so that we can get the same results as of existing application.
Bipul Dobhal
08-18-2009 05:18 AM
Hi Bipul,
The .NET application, as I verified, is functioning accurately. If the magnitude values that you obtain from your C++ code are very different, then probably you should check if you're actually making the same measurement in the two cases. In the .NET code, you're measuring the magnitude of the complex FFT. What exactly are you measuring in the C code below? Please confirm this.
Also, it would once again be helpful if you could send an Excel sheet like before containing the results of both the codes, side by side (if you're trying to make the same measurement in the two cases indeed).
Regards,
Vaibhav Vashisht.
08-18-2009 06:42 AM
Hi Vaibhav,
We don’t know which kind of measurement has been calculated in C++ code. Actually this code was developed about 3-4 years before by some other developers and we know don’t know much about the exactly the type of measurement they are calculating. I already provided the lines of C++ code by which they are calculating magnitude values. Following are the main lines by which they are getting measurement in C++ code using NIDSA library functions:
NIDSA_check_new_measurement (dsa_session, &new_measurement);
NIDSA_get_measurement_length (dsa_session, ipchannel, 2, &measurement_length, &Real_Or_Complex);
NIDSA_read_measurement (dsa_session, ipchannel, 0,measurement_length, 2, 0, 1,0, &x0, &dx, measurement);
Can you please check the above code lines to know the type of measurement? All functions used here are from NIDSA library and only you guys can let us know about the exact description of these functions.
In addition to this; in both applications, the voltage values are used to calculated the magnitude and frequency. The voltage values in both application never stored in the database so can’t provide you the same. Please check the attached excel sheet where we kept the frequency and magnitude values calculated by both applications.
Regards,
Bipul Dobhal
08-18-2009 06:53 AM
08-19-2009 11:00 PM
Hi Bipul,
I recommend that you go through Chapter 3 of this Manual to understand the use of the functions you have listed. It has been explained rather in detail and I believe this should solve your issue.
If understanding the function of the code you write is what concerns you, then probably you could do what I did: input the same data to a LabVIEW VI and see what kind of measurement (or which measurement VI) gives you the result you aim to get 🙂
Regards,
Vaibhav.