Low-level Commands Quickstart | LabJack
« Close

Datasheets and User Guides

App Notes

Software & Driver


Low-level Commands Quickstart

This quickstart uses a U3-HV, but the principles apply to all LabJack devices.

Opening the device

Here’s how to open a U3:

>>> import u3
>>> d = u3.U3()

The constructor for the U3 class will try to automatically open the first found U3. This is good if you only have one U3 connected.

Basic I/O: DAC0, AIN0, FIO4, FIO6

First, before we perform any other operation we will get your LabJack device’s calibration data. This only needs to be performed once after opening your device. The calibration data will be used by functions that convert binary data to voltage/temperature and vice versa.

>>> d.getCalibrationData()

Wire a jumper from DAC0 to AIN0, connect an LED from FIO4 to VS and jumper FIO6 to GND. Wire the anode (longer-lead) of the LED to VS and the cathode to FIO4. For more information on controlling LEDs, refer to the LED app note . The LED connection we are using is configuration 2 in the app note.

Setting the DAC is a U3 Feedback command, so we’ll use the U3 class getFeedback() function. For every Feedback command, there is a corresponding class in u3.py. The 8-bit DAC0 feedback command from Section has a class named DAC0_8. Here’s how to use it:

>>> DAC0_VALUE = d.voltageToDACBits(1.5, dacNumber = 0, is16Bits = False)
>>> d.getFeedback(u3.DAC0_8(DAC0_VALUE))        # Set DAC0 to 1.5 V

As the documentation in Section states, the 8-bit DAC0 feedback command takes a value between 0 and 255 (inclusive) and the output of the DAC is between 0 and 4.95 V. The variable DAC0_VALUE converts between the two. Reading from an analog input is also a feedback command. As Section of the U3 User’s Guide states, the feedback command returns a 16-bit unsigned value that we must convert into a voltage. Here’s how to do that:

>>> ain0bits, = d.getFeedback(u3.AIN(0)) # Read from raw bits from AIN0
>>> print(ain0bits)
>>> ainValue = d.binaryToCalibratedAnalogVoltage(ain0bits, isLowVoltage = False, channelNumber = 0)
>>> print(ainValue)

Similar to setting DAC0, we use the getFeedback() function and the AIN class from the u3 module (u3.AIN). The getFeedback() function always returns a list (more on that later), and so we use a trailing comma after ain0bits:

>>> ain0bits, = d.getFeedback(u3.AIN(0))

to automatically unpack the first value in the list. The U3 class has a function binaryToCalibratedAnalogVoltage() that knows how to apply the proper calibration constants to convert the reading into a voltage. The function applies different constants based on whether we are using a U3-LV (default) or one of the high-voltage inputs on the U3-HV. When using a high-voltage input, we specify isLowVoltage = False. For the U3-HV, the channel number (channelNumber) also needs to be specified so the correct calibrations constants are applied.

Because reading an analog input is such a common operation, the U3 class provides a getAIN() function that calls getFeedback() and binaryToCalibratedAnalogVoltage() with the correct parameters:

>>> ainValue = d.getAIN(0)  # Read from AIN0 in one function
>>> print(ainValue)

Setting a digital line’s state and direction is also done with feedback commands. The relevant ones are BitStateRead, BitStateWrite, BitDirRead, and BitDirWrite.

# Check which FIOs are analog and which are digital
>>> configDict = d.configIO()
>>> configDict["FIOAnalog"]
# Set the first four (0-3) to analog (15 = 1111 binary) and the rest to digital
>>> d.configIO(FIOAnalog = 15)
>>> d.getFeedback(u3.BitDirWrite(4, 1))   # Set FIO4 to digital output
>>> d.getFeedback(u3.BitStateWrite(4, 0)) # Set FIO4 to output low
>>> d.getFeedback(u3.BitStateWrite(4, 1)) # Set FIO4 to output high

Note the call to configIO(), which is not a feedback command, but a low-level command in Section 5.2.3. All the low-level commands in Section 5.2 are implemented as functions of the U3 class.

The getFeedback() function also accepts a list of feedback commands, and it accepts multiple arguments directly. For example, here’s how to set FIO4 for digital output and output high at the same time:

>>> outputDirCmd = u3.BitDirWrite(4, 1)
>>> outputHighCmd = u3.BitStateWrite(4, 1)
>>> cmdList = [outputDirCmd, outputHighCmd]
>>> d.getFeedback(cmdList) # Pass a list of commands
[None, None]
>>> d.getFeedback(outputDirCmd, outputHighCmd) # Or pass the commands as arguments
[None, None]

which is exactly what the setFIOState() convenience function does:

>>> d.setFIOState(4, 1) # Set FIO output high in one function
>>> d.setFIOState(4, 0) # Set FIO output low in one function

When you pass multiple feedback commands to getFeedback(), the function processes them sequentially. Here is an example of checking the direction of FIO4 (it’s set to output from above), set the FIO4 direction to input, and read FIO4 direction:

# Multiple feedback commands
#    Read FIO4's direction
#    Set FIO4's direction to input
#    Read FIO4's direction again
>>> d.getFeedback(u3.BitDirRead(4), u3.BitDirWrite(4, 0), u3.BitDirRead(4))
[1, None, 0]

Now lets set FIO6’s direction to input and read its state:

# Set FIO6's direction to input and read its state
>>> d.getFeedback(u3.BitDirWrite(6, 0), u3.BitStateRead(6))
[None, 0]
# Disconnect from GND
>>> d.getFeedback(u3.BitStateRead(6))
# Reconnect to GND
>>> d.getFeedback(u3.BitStateRead(6))

To get the actual state (first value of the list), don’t forget to unpack it:

>>> v, = d.getFeedback(u3.BitStateRead(6))
>>> v
>>> v = d.getFeedback(u3.BitStateRead(6))[0]
>>> v

which is exactly what the getFIOState() convenience function does:

>>> d.getFIOState(6)

We’ve recreated all the Modbus Quickstart (readRegister() and writeRegister()) operations on DAC0, AIN0, FIO4 and FIO6 using low-level commands. Many low-level commands are feedback commands, so they are passed into getFeedback(), which is a very flexible function that can perform many operations on your device at once. To go beyond the basic low-level operations (basic analog and digital), explore the other built-in commands and the LabJackPython source as described in the sections below.

Low-level commands as built-in functions

Section 5.2 of the U3 User’s Guide describes the low-level commands. All the low-level commands in the U3 User’s Guide have been defined as functions in the U3 LabJackPython class.

For example, we can get helpful information by calling the configU3() command. Note that in Section 5.2.2 of the U3 User’s Guide is a description of ConfigU3.

Here we are going to call configU3 with no arguments to perform only a read.

>>> print(d.configU3())
    'LocalID': 5, 
    'SerialNumber': 32003XXXX, 
    'DAC1Enable': 1,
    'EIODirection': 0,
    'DeviceName': 'U3-HV',

The configU3() function sets the power-up defaults of the U3. To change the U3’s behavior for this session only, use configIO(). For example, to set the first five FIO lines to analog for this session, call configIO with the FIOAnalog keyword argument:

>>> d.configIO(FIOAnalog = 0x1F)
{'DAC1Enable': 0, 'FIOAnalog': 31, 'EIOAnalog': 0, 'TimerCounterConfig': 64}

The value 0x1F is a bitmask with the lower 5 bits set to 1, signifying the first five FIOs. To make this setting survive power cycles, call configU3() instead of configIO():

>>> d.configU3(FIOAnalog = 0x1F)
'FIOAnalog': 31,
>>> d.close()
>>> # Unplug the U3 and plug it back in
>>> d.open()
>>> d.configU3()
'FIOAnalog': 31,

Examining the source

Some of the best low-level documentation of LabJackPython is in the docstrings of the source code. For example, the u3.py module has many examples for the low-level commands. The feedback commands are implemented as classes at the bottom of the module, and every feedback command has a docstring with an example of how to use it.



Could you please tell us how to use the PWM feature?  Is it supported in LJ Python?

Thank you...

Peter H.

Yes, it is supported in LabJackPython. Take a look at the PWM-looping.py looping example in the LabJackPython download. It demonstrates Modbus usage for for the UE9, U3 and U6, and low-level usage (commented out code) for the U3 and U6.

General timer/counter documentation is here:


Note if using a U3 that the lines the timers/counters are on need to be configured for digital I/O.

plummer's picture

print labjackHere.Device1.configU3(EIODirection = 0xFF)

print labjackHere.Device1.configU3(CIODirection = 0xFF)

^^^^ above does NOT work to change two things

print labjackHere.Device1.configU3(EIODirection = 0xFF , CIODirection = 0xFF)

^^^ above DOES work to change two things.

See how I combined the two commands into one line. That works! 

LabJack Support's picture

For further clarification, configU3 (ConfigU3) is for power up settings and configIO (ConfigIO) is for current settings (no flash writes). These Python methods are using these low-level command-responses:


When setting the power up FIO, EIO, CIO direction and state with the configU3 method, and in general with the ConfigU3 low-level command, they need to be set in one command. The command either writes all or none of the digital I/O settings. If a set of directions or states are not set in the method call, the setting is defaulted to zero (input/low) in the low-level command.

Thank you for providing your code for others who may be confused about this functionality.