05-18-2009 05:14 PM
Min inDAQmxCreateAIThrmstrChanIex
Last night I got through a tedious issue getting my program (Delphi, I know, not supported by NI) to make thermistor measurements. I kept getting a "feature not supported" type error. It turned out the problem was the value of Min I was specifying when setting up the thermistor channel. I had been setting this to -80°C since that is what my termistor could manage, but when I set this to 0°C my rogram finally started working. The NI documentation didn't say anything about limits to this value. Anyway, a little more trial and error and it looks like -32°C is the lowest temperature you can use here.
Divide-by-Zero in DAQmxReadAnalogF64
This error popped up as soon as I got past the above error, and it was a devil to track down. It was intermittant and it dsiplayed all of the characteristics of having overwritten memory, such as when you store more data in an array that it was dimensioed for. And when it occurred the program would freeze up on the next niDAQmx fnction call. This seemed to strengthen my hypothesis that some part of the driver was being corrupted. I scowered my program for the possibilities that I had done this, but found nothing. It's a smallish test program. More testing and I found that slight changes to other parts of the program caused the problem almost went away. Another change, and it would happen all of the time. Another change, intermittant gain. Again, these changes were being made in areas not realated to this operation, which was convincing me even more that the driver was being corrupted by itself. One thing I did notice when the program was more or less working was that it would occurr reliably after I did some voltage inputs (DAQmxCreateAIVoltageChan). So I searched here (search = divide-by-zero DAQmxReadAnalogF64) and found two posts, one mine from last night mentioning my first encounter with this problem, and the other a few years old that held the clue to the solution. The solution? Turn off the divide-by-zero error detection. ??? Mask it??? Googling the code I found a post saying that this is indeed the way to solve this problem and that is is used in Delphi apps that use QuickTime or COM. Anyway, it all seems to be working now, except that I don't actually have my thermistor circuit hooked up yet so I haven't confirmed that I'm getting thecorrect temperature.
My final code:
function niExecuteAnalogIn(
TaskInt:niTaskInt;
var Values: array of double;
var Count:LongInt):longint;
var CW: Word;
begin
niResult:='DAQmxStartTask';
Result:=DAQmxStartTask(TaskInt); // Start the task
if Result<>0 then Exit;
niResult:='DAQmxReadAnalogF64'; // Execute the task
// DAQmxReadAnalogF64(
// taskHandle:Longint;
// numSampsPerChan:Longint;
// timeout:Double;
// fillMode:DAQmxFillMode;
// var readArray:Double;
// arraySizeInSamps:Longint;
// var sampsPerChanRead:Longint;
// reserved:boolean):Longint; stdcall;
CW := Get8087CW;
try
Set8087CW($133f); // Disable FPU Exceptions
Result:=DAQmxReadAnalogF64(
TaskInt, // Task handle
1, // Timeout in seconds
1, // Samples per channel to read
DAQmx_Val_GroupByScanNumber, // Fill mode
Values[0], // Value read
Length(Values), // Array size in samples
Count, // Number of samples actually read
false); // Reserved
if Result<>0 then Exit;
Set8087CW(CW); //restore
except
end;
// Stop the task, normal way
niResult:='DAQmxStopTask';
Result := DAQmxStopTask(taskint);
end;
I hope this helps someone.
P.S. This forum could use [code][/code] tags.
P.P.S. Delphi support, please.