Python U6 readings do not match test panel | LabJack
 

Python U6 readings do not match test panel

15 posts / 0 new
Last post
creese
creese's picture
Python U6 readings do not match test panel

Hello.

I am using a U6 Pro to measure a voltage input that should be micro to millivolts. LJ Control Panel shows tens of volts when in differential mode, as I would expect. When executing python code to read it, however, I am getting consistently negative values, regardless of the polarity of the input. The same is true when I use single-ended inputs. I am using the code below:

from datalib import gettimestring
import u6
result = {}
device = u6.U6()
result['readtime'] = gettimestring()
result['value'] = device.getAIN(positiveChannel, resolutionIndex, gainIndex, settlingFactor, differential)
device.close()

For positive channel, I am using 0 for differential across AIN0 and AIN1, and have also tried 2 for AIN2-AIN3. I have tried various gain and resolution settings with no luck. I have a counter set up and it seems to be working fine, so otherwise this seems pretty straightforward.

Thanks,

Colin

LabJack Support
labjack support's picture
Remove your connections and

Remove your connections and instead try the following (with GainIndex=0 for +/-10V range):

AIN0 = VS
AIN1 = GND
Should read +5V

AIN0 =GND
AIN1 = VS
Should read -5V

AIN0 = VS
AIN1 = VS
Should read 0V

Make sure you don't have totally floating signals:

https://labjack.com/support/app-notes/differential-analog-inputs

creese
creese's picture
I get the results above.

I get the results above.

As I mentioned, I have tried this in differential and single-channel modes. Same results

If I set it to autorange, regardless of the polarity of my inputs (i.e. one to AIN2, one to GND), I get about negative 2mV. If I increase the gain, it simply lowers the magnitude to 10s of negative microvolts.

Also as I mentioned, when I open a LabJack control panel with the terminals connected as above (I just move the USB over to my Windows laptop from my Pi), the results are as I would expect. Shining a light on the pyranometer produces the results expected. Swapping terminals results in a change in polarity and a signal of the magnitude that I should be reading. 

From what I can tell, this is an issue either with LJ Python or my programming. Please point me to what I can test to determine which and how to solve it.

Thanks,

Colin

LabJack Support
labjack support's picture
I get the results above.

I get the results above.

So when you use the VS & GND jumpers your Python program works fine?   That would suggest that the problem is with your signal, and perhaps LJControlPanel just happens to give reasonable looking values whereas your Python program just happens to give obviously bad values.

Try connecting a DMM to AIN2 & GND at the same time as your signal.  Does the DMM reading agree with the Python reading?  Does the reading change depending on whether the DMM is connected or not?

creese
creese's picture
Yes, the jumpers show the

Yes, the jumpers show the expected results.

As I wrote above, I can shine light on the device and the value in LJ Control Panel goes up and down as expected, per the spec sheet. This is a signal, not noise.

I don't currently have a DMM that measures less than a millivolt available. 

LabJack Support
labjack support's picture
Sometimes a weak or

Sometimes a weak or improperly connected signal can give readings under certain situations that are reasonable enough that the appear right, but then when you change something the problem is exposed.  For example, if you just connected a signal pair to AIN2 & AIN3 with no ground reference, you could have a floating signal that sits up near the 13V rail and sometimes seems to work.

Note that on the +/-10V range the absolute accuracy is +/-0.01% full-span or +/-2mV.  Changes in settings might cause readings to change within this error band and still be in spec.

Following are some things that can affect readings.  With a good signal, the effect of these is minimal and certainly within specs, but with a weak signal these can expose the problem and lead to big differences:

ResolutionIndex (0 equates to 8 on a U6 and 9 on a U6-Pro)
Range (test panel defaults to +/-10V)
SettlingFactor (test panel uses 7 which is 2000us per Section 5.2.5.2)
Number of channels scanned.
Scan order ... particularly which channel is sampled immediately before.
Scan interval.

creese
creese's picture
I am still unclear on how to

I am still unclear on how to troubleshoot this. 

I have used the examples the read an instrument that I know is reading correctly via LJControl Panel. I am confident this isn't a random signal as you imply. I can watch it respond to light per the datasheet as I vary it. 

I have used the default parameters as you describe above, and the result is the same. There is a not a "getAIN" function that accepts a list of channels, so the best I can do is iterate in a loop over several channels (the instrument is on AIN2):

CODE:

def readU6Analog(positiveChannel, resolutionIndex=0, gainIndex=0, settlingFactor=0, differential=False):
    from datalib import gettimestring
    import u6
     
    device = u6.U6()
    result= {['readtime'] : gettimestring()}
    try:
        result['value'] = device.getAIN(positiveChannel, resolutionIndex, gainIndex, settlingFactor, differential)
    except:
        #handle stuff ...
        pass
    device.close()

    return result

for i in range(4):
   labjack.readU6Analog(i,12,3,7)

OUTPUT:

{'value': 0.010109889201523671, 'readtime': '2016-05-20 10:17:10'}
{'value': 0.010109889201523671, 'readtime': '2016-05-20 10:17:11'}
{'value': -6.72246924421875e-05, 'readtime': '2016-05-20 10:17:11'}
{'value': -0.010586390215710936, 'readtime': '2016-05-20 10:17:11'}

And yes, the results are identical if I do not open and close the instrument each time I make a reading. 

LabJack Support
labjack support's picture
After opening your U6, get

After opening your U6, get the calibration constants and then perform your analog input readings and see if that helps:

device = u6.U6()
device.getCalibrationData()

#Your analog input reading/readings

LabJack Support
labjack support's picture
See if reading the cal data

See if reading the cal data makes much difference, but anyway in your test I see that AIN0, AIN1, and AIN3 all railed at 10mV (perhaps they are floating).  AIN2 I'm guessing is your signal?  It is reading -67uV, and you expect a different value correct?

In that test, does the reading from AIN2 change at all depending on whether you jumper AIN1 to VS or GND?

Another test is to use a different small signal.  I suggest using DAC0 or DAC1.  Jumper either to AIN2 and go into the test panel and set the DAC to 0.008 volts and confirm that it reads about that on AIN2.  Sometimes the DAC output will not go that low, so if neither of your DACs will go under 10mV you will have to use the 100mV AIN range for this test.  Once you have this going in the test panel you can close LJCP and see what it reads in your Python program.

creese
creese's picture
The readings are accurate.

The readings are accurate. They are just not getting into Python. So it is either reading the wrong thing, or doing something different in the sampling. 

Yes, the inputs are railed, as I still have them connected to Vs from the previous test. 

Please see output from LJUDLogger. The signal is there and legitimate. This is me passing a flashlight over the sensor at different heights. I will try getting the calibration constants.

creese
creese's picture
getCalibrationData() worked.

getCalibrationData() worked. I'll test to see whether I have to do this once per read or if once per session is enough, but if you have ideas, let me know.

Also - I tried to post a question previously regarding closing all open sessions in the case of catching (or not catching an error), but it never showed up on the board. When running python from the command line, I notice that I can exit python and then restart it. Presumably it gracefully closes all open instances of the device object. How would one do this manually without stopping python?

Thanks.

LabJack Support
labjack support's picture
getCalibrationData should be

getCalibrationData should be called after opening the U6 in your application. It gets the calibration constants from the U6 and stores it into the U6 object. Afterwards, analog related functions that convert readings to a voltage value use the calibration constants for the conversion.

In LabJackPython, to close the U6 object and to release the device handle use the close method:

device.close()

creese
creese's picture
My question was what to do

My question was what to do when you don't have an object to call the close method. If, for example, you don't successfully catch an error and/or don't return an object to a calling function. Ideally, there would be a sessiondata = U6.getAllOpenSessions() and device = U6.attach(sessionhandle) or U6.closeAll(). Either would be fine. As it is, if I lose the object, the calling instance has to terminate, or the hardware must be disconnected and reconnected.

Thanks.

LabJack Support
labjack support's picture
On Linux and Mac OS X, there

On Linux and Mac OS X, there is only the close call for the device currently opened in the object. There is no close all in LabJackPython or the Exodriver library. Disconnecting/reconnecting will also free up the handle.

As for Windows, which it seems like you are using and I didn't catch in my previous response, you can use the UD library call Close which closes all handles in the application, or exit the application to close device handles. The UD library does not support closing individual handles, and closes all of them.. The LabJackPython U6/Device close function doesn't do anything on Windows. Here's how a call to Close looks in LabJackPython:

import LabJackPython

LabJackPython.Close() #This calls the UD library's Close function

creese
creese's picture
I'm on debian linux, in this

I'm on debian linux, in this case on a Pi, so it appears I am out of luck. It's a recurring script, so if I throw in a stop flag after devices are read if there is a LabJack error, that should do it. Otherwise, handling all the errors is the way to go. You just never know, unfortunately. Things happen, and sometimes they happen between open() and close().

C