clade / PyDAQmx

Interface to National Instrument NIDAQmx driver
Other
133 stars 55 forks source link

Using PyDAQmx to read analog input with different Voltage Levels #21

Closed vslm698 closed 9 years ago

vslm698 commented 9 years ago

Hello PyDAQmx experts, I am using PyDAQmx to read analog input with different voltage levels and meet some problem. I need to measure two channels (A and B) analog input voltage at the same time with PyDAQmx. The range of Channel A's input is (-0.1, 0.1). While Channel B is (-5.0, 5.0). We found the value from channel A is not accurate. BTW, the voltage channels set as below, is there someone meet the same issue? Thanks!

DAQmxCreateAIVoltageChan(taskHandle,"Dev1/ai16","",DAQmx_Val_Cfg_Default,-0.1,0.1,DAQmx_Val_Volts,NULL) DAQmxCreateAIVoltageChan(taskHandle,"Dev1/ai24","",DAQmx_Val_Cfg_Default,-5.0,5.0,DAQmx_Val_Volts,NULL)

frejanordsiek commented 9 years ago

This issue is most likely electronic. It is something common to all multi-channel measurements, but made worse when using different input ranges on the channels. Most of the NI DAQ's have only a single ADC that they have to multiplex between all the channels, since that is the cheapest way to do things (they do have ones that read from each channel simultaneously but those are very expensive and probably not what you have).

The analog input of the DAQ has a certain capacitance (I forget what it is). Lets start with it connected to channel B and the voltage on the capacitor (which is what is read) has reached equilibrium (the voltage the sensor is producing). When the DAQ changes to channel A, the ADC and amplifiers are still at the voltage of channel B. The voltage on the ADC and amplifiers then start to charge or discharge to match channel A's source, but how long that takes depends on the source's output impedence (how much current it can drive). If you read channel A before then, you are measuring a mix of the source's current voltage and the voltage from channel B along with anything introduced by changing the amplification (voltage range). For any output impedences of your sources for A and B, there is an acquisition frequency that is high enough that you run into this problem. It sounds like you have reached it.

There are a few solutions.

One is to acquire at a slower rate to allow more time for the ADC and amplifiers to reach the voltages of the sources.

The other is to reduce the output impedences of your sources (increase how much current they can drive). If you are not using an instrumentation amplifier (or a plain old OP-Amp if you don't need high precision) on your sources, this is a good time to start using one. If you are using an instrumentation amplifier but still have the problem, then the instrumentation amplifier is not able to output enough current. That can be fixed by using a different instrumentation amplifier (say an INA114 or AD620) or by adding a unity gain OP-Amp follower. A lot of instrumentation amplifiers have a special pin to read the output of a follower so that they can adjust their output to retain the accuracy of the instrumentation amplifier as opposed to being limited by the accuracy of the OP-Amp (the AD524 and AD624 are good examples of amplifiers that do this, but you should note they are expensive at $20-60). The other reason to use an instrumentation amplifier is because, depending on your circuit, the DAQ itself when it switches channels, will drive current into the electronics due to its mismatch and cause problems. An instrumentation amplifier isolates that. Similarly, this current from the DAQ can destabilize some instrumentation amplifiers. Using a OP-Amp follower helps, but occasionally you need to add some electronics between the instrumentation amplifier and the ADC in the DAQ. You put a small resistor (say 10-50 Ohm) between the instrumtation amplifier (or follower OP-Amp) and the DAQ channel input, and then put a capacitor between the DAQ channel input and ground (1 pF to 1 muF depending on your circumstances). The resistor prevents large currents going to and from the instrumentation amplifier keeping it from destabilizing and the capacitor provides a lot of charge to equilibriate with the DAQ's ADC and amplifiers a bit before they start the slow settling to the voltage output of the source.

Another thing that will help is to just not use different voltage ranges. Instead, on your channel A, use an instrumentation amplifier with gain, say a gain of 50. Then you can use the same voltage range for all channels which will help, since voltage range switching on the DAQ increases the time it takes for the ADC and amplifier to settle to the voltage from the source.

vslm698 commented 9 years ago

Hi frejanordsiek, very appreciate for your detailed answer and suggestion. To double confirm if the issue is related to hardware or electronic, we used NI software (Labview) to collect the voltage data. But this issue can't be repeated at NI software with the same configuration (same channel setting and frequency). so it means this issue may be not caused by hardware. I have discussed this with NI software engineer, but they said they don't support third part languages (such as: python and C++). As I don't know how Labview set channels internally, I have no other way but ask support at here.

frejanordsiek commented 9 years ago

Did you setup the channels in the same order in both python and LabView. Order matters a ton here. Even in the case of two channels, it still matters since it does: read 1st channel in list, read 2nd channel in list, put measurements in buffer and other miscellaneous tasks, read 1st channel in list again, and so on. Or at least, I think that end step is in there. If you have more than 2 channels, the order matters a ton. If the issue remains after double checking that, then that suggests a driver issue or some weird issue with LabView.

vslm698 commented 9 years ago

Yes, I use the same order to setup each channel. As we plan to measure power consumption with NI DAQ, Channel A measures the voltage of a high precision resistor(about 10 milliohm), which can be used to calculate current. Channel B measures the voltage of input. At first I followed the hardware spec to use Diff Mode for Channel A and NRSE Mode for Channel B,but the output data is abnormal,so I switched to use the default mode(DAQmx_Val_Cfg_Default). However, the output of channel is not accurate, which will impact the total power result.

codedragon commented 9 years ago

What happens if you use the C code directly? Does it give you the same reading as pydaqmx or labview?

vslm698 commented 9 years ago

Good suggestion, I will have a try with C language, and update the result later.

clade commented 9 years ago

The C code should give the same result as the python code using PyDAQmx. But, you will have official support from NI. At this point, this is probably a good solution.

vslm698 commented 9 years ago

When building the sample C code at vs2012, it reports LNK2019 error, though the NIDAQmx.lib has been added to the Link Input property. Anyway, I will try to fix this. For the accuracy, I have discussed with NI engineers for about 2 weeks, but they seems not friendly to support Python or C code, and didn't give me any useful suggestion. so I ask support at here, and get lots of your professional reply. The root cause for this issue is still not clear, I will keep on investigating, and welcome any suggestion, Thanks!

vslm698 commented 9 years ago

Thanks all for your great support and suggestion, I have worked around this issue. I use loop function to set each channel, set channels from 16 to 23 to be 0.1v, while setting channels from 24 to 31 to be 5, and then this issue can't be repeated.