06-16-2006 08:15 AM
06-19-2006 07:38 AM
06-19-2006 11:02 AM
Hi James,
Thanks for quickly responding. Yes, I want to Self-Calibrate once (or maybe a few times) during my program start. I have actually called
DAQmxErrChk2( DAQmxSelfCal("Dev1") );
after running
taskHandle = hAItask;
in the above program but it did nothing except update the DAQmxGetSelfCalLastDateAndTime() date and time.
I am new to programming NI boards (this is my first) so I dont know the "National Instruments way" of calibrating. (My program was originally written to use the Axon Instruments 1322A board and it self calibrated in the program during startup if needed.)
I dont even know if I have to calibrate the 6221 board while in MAX, or if I can calibrate the board by calling DAQmxSelfCal("Dev1") in my program at startup if the board has not yet been self calibrated. I would definately prefer the second way because it would be much simpler for my users. I would like to use MAX only to get the "Dev1" device name, if possible.
I am actually measuring picoamps from a single channel patch clamp amplifier (a neurophysiological amplifier), so I guess its a transducer that MAX does not have a type for. But if I could just get the board accurately calibrated in volts at the board input I would be completely satisfied.
But so far, I can't even get the SaveChannelCalibrationInfo.c demo program working, and I think the problem could be in using my taskHandle created earlier in my above program
taskHandle = hAItask; // THIS I'VE MODIFIED - IS THIS WHERE THE PROBLEM IS ?????
rather than this commented out DAQmxLoadTask() code to get the task from MAX
//DAQmxErrChk2( DAQmxLoadTask(taskName,&taskHandle)); // Used to get task from MAX
Then the code later fails in
DAQmxErrChk2( DAQmxGetAIChanCalHasValidCalInfo(taskHandle, chanName, &hasValidCalInfo)); // ERROR IS HERE
because hasValidCalInfo returns 0 or NO. Remember I have tried putting in DAQmxSelfCal("Dev1") after running taskHandle=hAItask, and that did not make the above code work.
I'll worry about how to use the coeffients after I get DAQmxGetAIChanCalHasValidCalInfo() to work. But I do want to use the previous SELF (NOT EXTERNAL) calibrations constants saved to the EEPROM used to scale up my data?
Hope to hear from you soon.
Cheers, Bill
06-19-2006 11:57 AM
06-20-2006 07:17 AM
Hi Tom,
Thanks for your response, it clears up a lot of it. I wont bother with DAQmxGetAIChanCalHasValidCalInfo().
However I don't think I can use DAQmxGetAIDevScalingCoeff(). I want to convert unscaled, uncalibrated binary values to UNSCALED, CALIBRATED binary values (not SCALED, calibrated voltages), in part, so that I can save them to a binary disk file. My understanding is that DAQmxGetAIDevScalingCoeff() converts unscaled, uncalibrated binary values to SCALED, calibrated voltages.
What function should I use?
I tried DAQmxGetAIChanCalPolyForwardCoeff(), but when using this code,
DAQmxErrChk( numCoeffVals = DAQmxGetAIChanCalPolyForwardCoeff(taskHandle,chanName,NULL,0));
DAQmxGetAIChanCalPolyForwardCoeff() returned numCoeffVals = 0, indicating that it was NOT WORKING.
In contrast, using this code,
DAQmxErrChk( numCoeffVals = DAQmxGetAIDevScalingCoeff(taskHandle,chanName,NULL,0));
I could get DAQmxGetAIDevScalingCoeff() to return numCoeffVals = 4, suggesting that at least it works even though it is not the right function.
Cheers, Bill
06-20-2006 03:40 PM
Hi Bill-
There is no way to return scaled binary values with NI-DAQmx. The best method if you're performing high speed logging would be to get the DAQmxGetAIDevScalingCoeff(), log them to file and then log the raw data as it is returned by DAQmxReadBinary... Then when you need to read the file back you should just apply the calibration and scaling via the 3rd order polynomial coefficiencts you saved previously.
Hopefully this helps-
06-21-2006 10:57 AM
Hi,
what exactly do you mean by unscaled, uncalibrated? I think you're referring to the fact that, if your device supports software calibration (M-series boards), NI-DAQmx does not calibrate unscaled samples.
Your device uses software calibration to adjust the software scaling of signals read from and produced by your device. Using calibration pulse width modulated (PWM) sources with a reference voltage, your device measures and calculates scaling constants for analog input and analog output. The scaling constants are stored in nonvolatile memory (EEPROM) on your device. NI recommends that you self-calibrate your device just before a measurement session but after your computer and the device have been powered on and warmed up for at least 15 minutes. You should allow this same warm-up time before performing any calibration of your system. Frequent calibration produces the most stable and repeatable measurement performance. The device is not harmed in any way if you recalibrate it often.
For the M-series board, the acquired raw data will be uncalibrated. However, the calibration information and the scaling information is combined by the driver and available though the AI.DeviceScalingCoeff property of a DAQmx Channel Property Node. This property is selected by clicking Properties » Analog Input » General Properties » Advanced » Device Scaling Coefficients. The data returned by this property is an array. Each element of the array is a polynomial coefficient. This polynomial can be applied to the raw data to get the scaled data. (and calibrated)
Therefore, if you want the unscaled calibrated values, you'll need to use the scaling coefficients to convert the data to a real number, which is then calibrated, and then put the values back to an integer appropriate for the resolution of the board. You might aswell read it fully scaled and calibrated, and then convert it back, since then the driver level is performing the scaling application efficiently.
Otherwise, as Tom says, dealing with the DeviceScalingCoefficients will give you the data you ultimately need to get to the real workd values, just dealing with the raw uncalibrated data you'd have to store. (i.e. the DeviceScalingCoefficients include the calibration).
Thanks
Sacha Emery
National Instruments (UK)
06-21-2006 11:09 AM
Hi Tom and Sacha,
I essentially got the Analog Input calibrated essentially using this code to convert from unscaled, uncalibrated binary values to scaled, calibrated voltages, and then to calibrated, unscaled binary values
DAQmxErrChk( DAQmxGetAIDevScalingCoeff(hAItask, "Dev1/ai1", ai0CoeffVals, 4) ); NUM_COEFF_VALS) ); /
UnCalBinVal = AIbuffer_RepSweep[sn];
// I assume the polynomial is of the form Coeff_0 + Coeff_1*x + Coeff_2*x^2 + Coeff_3*x^3 ....
dCalVoltVal = Mseries_AD0_CoeffVals[0]
+ (Mseries_AD0_CoeffVals[1] * UnCalBinVal)
+ (Mseries_AD0_CoeffVals[2] * (UnCalBinVal^2) )
+ (Mseries_AD0_CoeffVals[3] * (UnCalBinVal^3) );
CalBinVal = ((dCalVoltVal / 10.0) * 32767);
dg[DGnum].arraydata.ADaryCh[AD0].ADarray[uLinArraySmplNum+lsn] = CalBinVal;
06-21-2006 11:40 AM
Hi Tom and Sacha,
(SORRY ABOUT THE ABOVE GIBBERISH MESSAGE, I PUSHED THE WRONG (SUBMIT) BUTTON BY MISTAKE!)
Thanks for your help. I essentially have the Analog Input calibrated using the code below to convert from unscaled, uncalibrated binary values to scaled, calibrated voltages, and then to calibrated, unscaled binary values, as Sacha suggested.
// get the coefficients
float64 ai0CoeffVals[4];
DAQmxErrChk( DAQmxGetAIDevScalingCoeff(hAItask, "Dev1/ai1", ai0CoeffVals, 4) ); // 4 = NUM_COEFF_VALS
// get the uncalibrated binary value
UnCalBinVal = AIbuffer[ii];
// get the calibrated, scaled voltage
dCalVoltVal = ai0CoeffVals[0] + (ai0CoeffVals[1] * UnCalBinVal) + (ai0CoeffVals[2] * (UnCalBinVal^2) ) + (ai0CoeffVals[3] * (UnCalBinVal^3) );
// then convert the voltage back to a CALIBRATED binary value (10.0 is 1/2 the p-to-p voltage). This is a bit of a kludge to be worked on later but should be only off by 1 LSB
CalBinVal = ((dCalVoltVal / 10.0) * 32767);
For a 5.0 voltage output pulse, my calibrated scaled graph reads 5.068 and a 4-digit multmeter reads 5.065 or within 0.05% which seems OK for the Analog Input calibration. To speed it up I may put the calculations in a TABLE to read from.
I ONLY HAVE ONE MAJOR PROBLEM LEFT: The analog output voltage is about 5.065 rather than 5.000 or about 1.31% too high. This could be a problem internal to my program, but I dont think so.
I therefore have a final question: Do I have to software calibrate the binary values used for Analog Output with DAQmxWriteBinaryI16(), or are they calibrated by DAQmxSelfCal("Dev1")?
Thanks for your help.
Cheers, Bill
06-21-2006 05:03 PM