« Close

Datasheets and User Guides

App Notes

Software & Driver

 

LJFuse (Experimental)

LJFuse Overview

LJFuse is a file I/O interface. It makes communicating with a LabJack device simple on Linux and Mac OS X. Really simple. Trivial, really.

Introduction

It's been said that everything's a file in UNIX. LJFuse adopts that philosophy and makes the connections on a LabJack device into files on the filesystem. To do so, it uses FUSE on Linux and MacFUSE on Mac OS X. p. For example, to read analog input AIN0, read a file named "AIN0".

For example, to read analog input AIN0, read a file named "AIN0".

  
$ cat MyU6/connection/AIN0
3.300
  

To set DAC0 to 2.4V, write "2.4" to a file named "DAC0".

  
$ echo 2.4 > MyU6/connection/DAC0
$ cat MyU6/connection/DAC0   # Read the DAC0 to verify it was set
2.400
  

To set FIO0 to digital output high, write a "1" to "FIO0".

  
$ echo 1 > MyU6/connection/FIO0-dir  # Set the direction to output
$ echo 1 > MyU6/connection/FIO0      # Set the state to output high
$ cat MyU6/connection/FIO0           # Read the value back
1    
  

You can do this from any program that knows how read and write files. Your program doesn't need to know about USB communication, drivers, or the LabJack API. The details are hidden by LJFuse.

Quickstart

Check the requirements (in short, a working LabJackPython installation on Linux or Mac OS X), and download the source code for LJFuse from GitHub. Click the “ZIP” or "Download Source" button on the GitHub page to download.

Connect a LabJack and run LJFuse like this:

  
$ python ljfuse.py
  

After LJFuse starts, change to the “root-ljfuse/” directory it created and look around:

  
$ cd root-ljfuse/
$ ls
HOW_TO_UNMOUNT.txt  My U6/  README.txt

There are “README.txt” files in every subdirectory with context-specific help.

When done, unmount LJFuse. The file “HOW_TO_UNMOUNT.txt” has instructions.

  
$ cat HOW_TO_UNMOUNT.txt

Requirements

  • A U3, U6, or UE9 over USB with the latest firmware. The U3 requires 1.26 or higher; the U6 requires 1.15; and the UE9 requires Control firmware 2.13 and Comm firmware 1.5. Check the beta folders of the firmware section if the release version doesn’t meet the requirements.
  • LabJackPython
  • Exodriver, the Linux and Mac OS X driver
  • On Mac OS X, LJFuse requires MacFUSE. On Linux, LJFuse uses the kernel’s fuse implementation.

LJSocket is not required, but LJFuse will automatically access LabJack devices opened by LJSocket. On Mac OS X, LJSocket also has the benefit of allowing LJFuse to run in the background (instead of tying up a terminal window).

Running

Plug in a U3, U6, or UE9 and run:

  
$ python ljfuse.py

On Mac OS X, it will print

  
$ python ljfuse.py
Making directory root-ljfuse for LJFuse
Mounting LJFuse at root-ljfuse.
When done, eject it from the Finder or run `umount LJFuse' (without quotes).
$

On Linux, it will print

  
$ python ljfuse.py 
Making directory root-ljfuse for LJFuse
Mounting LJFuse at root-ljfuse.
Unmount it with `fusermount -u root-ljfuse' (without quotes).
$

In either case, change to the “root-ljfuse/” directory and look around. There are “README.txt” files in every subdirectory with context-specific help.

  
$ cd root-ljfuse/
$ ls
HOW_TO_UNMOUNT.txt  My U6/     README.txt

Example session

In this session, we have a U3-HV and U6 connected when running LJFuse:

  
$ python ljfuse.py
Making directory root-ljfuse for LJFuse
Mounting LJFuse at root-ljfuse.
When done, eject it from the Finder or run `umount LJFuse' (without quotes).
$ cd root-ljfuse/
$ ls
HOW_TO_UNMOUNT.txt  My U3-HV/           My U6/              README.txt
  

LJFuse made two directories, one for the U3-HV and one for the U6. It also made two text files with documentation.

You can rename a device by renaming its directory. The name of the device is saved in its flash memory:

  
$ mv "My U3-HV" "Marcel"
$ ls
HOW_TO_UNMOUNT.txt  Marcel/             My U6/              README.txt
$ mv "My U6" MyU6
$ ls
HOW_TO_UNMOUNT.txt  Marcel/             MyU6/               README.txt
  

Inside a device’s subdirectory, there are files relating to the device’s attributes:

  
$ cd MyU6/
$ ls
README.txt       firmwareVersion  serialNumber
connection/      modbus/
$ cat firmwareVersion 
1.15
  

The “connection/” subdirectory is the most interesting. It contains files for the different connections on the device.

  
$ cd connection/
$ ls
AIN0        DAC0        FIO1        FIO3        FIO5        FIO7
AIN1        DAC1        FIO1-dir    FIO3-dir    FIO5-dir    FIO7-dir
AIN2        FIO0        FIO2        FIO4        FIO6        README.txt
AIN3        FIO0-dir    FIO2-dir    FIO4-dir    FIO6-dir
  

Wire a jumper from DAC0 to AIN0 and run:

  
$ echo 1.5 > DAC0     # Set DAC0 to 1.5V
$ cat DAC0            # Verify that it set
1.500
$ cat AIN0            # Read AIN0
1.499
  

Connect an LED from FIO2 to GND (short side in GND) and toggle it:

  
$ cat FIO2-dir        # Check the direction of FIO2
0    
$ echo 1 > FIO2-dir   # Set FIO2 to output
$ cat FIO2-dir        # Verify the direction changed
1    
$ echo 1 > FIO2       # Set FIO2 high, turning LED on
$ echo 0 > FIO2       # Set FIO2 low, turning LED off
$ while true          # Show off a little
> do                  # Toggle the LED once per second
>   echo 1 > FIO2
>   sleep 1
>   echo 0 > FIO2
>   sleep 1
> done
^C                    # Hit Ctrl-C to quit
  

We hope these examples demonstrate how quickly and easy LJFuse makes it to communicate with your LabJack.

Shell tricks

The shell can operate on the files in the “connection/” directory to ask interesting questions. For example, which FIO connections are set to digital output?

  
$ grep 1 FIO?-dir
FIO0-dir:1    
FIO2-dir:1    
  

Answer: FIO0 and FIO2. Here’s how to set them all to digital output:

  
$ for fiodir in FIO?-dir
> do
>   echo 1 > $fiodir
> done
  

Verify that it worked:

  
$ grep 1 FIO?-dir
FIO0-dir:1    
FIO1-dir:1    
FIO2-dir:1    
FIO3-dir:1    
FIO4-dir:1    
FIO5-dir:1    
FIO6-dir:1    
FIO7-dir:1    
  

Here’s how to ask if a value is above a threshold. Carrying on with a previous example, wire a jumper connecting DAC0 to AIN0.

  
$ cat DAC0
1.500
$ cat AIN0
1.499
$ THRESHOLD=1.6
$ AIN0=$(cat AIN0)
$ if [ $(echo "$AIN0 > $THRESHOLD" | bc) -eq 1 ]
> then
>   echo "AIN0: $AIN0 above threshold $THRESHOLD"
> else
>   echo "AIN0: $AIN0 below threshold $THRESHOLD"
> fi
AIN0: 1.499 below threshold 1.6
$ echo 2.0 > DAC0
$ cat DAC0
2.000
$ cat AIN0
1.999
$ AIN0=$(cat AIN0)
$ if [ $(echo "$AIN0 > $THRESHOLD" | bc) -eq 1 ]
> then
>   echo "AIN0: $AIN0 above threshold $THRESHOLD"
> else
>   echo "AIN0: $AIN0 below threshold $THRESHOLD"
> fi
AIN0: 1.999 above threshold 1.6
  

Exiting and unmounting LJFuse

To stop LJFuse, all applications and terminal windows must exit the LJFuse “root-ljfuse/” directory and its subdirectories.

  
$ pwd
/path/to/LJFuse/root-ljfuse/MyU6/connection
$ cd ../../..
$ pwd
/path/to/LJFuse
  

On Linux run:

  
$ fusermount -u root-ljfuse
  

On Mac OS X, find the LJFuse icon in the Finder and eject it. You could also run:

  
$ umount LJFuse
  

If unmounting returns an error, double check that all applications and terminal windows have exited LJFuse directories. Since 10.6, the Mac OS X Finder will report which application is using a volume when trying to eject it.

Programming language examples

The following examples illustrate how to

  1. Read AIN0 once per second and log timestamp and value
  2. Toggle an LED on FIO0

in many different programming languages. The examples would not be out of place in any introductory programming book. All they do is basic file I/O.

Shell

C

Python

Ruby

PHP

Perl

Java

Scala

LabVIEW

32 comments

Has anyone experience in using the LabJack interface with the programming language Runtime Revolution?

To use the LabJack DLL wrapping a DLL in C is required. 


Perhaps it is even easier with LJFuse.............

Any language that can do file I/O can use LJFuse. A Mac OS X or Linux user using any language that isn't C or Python is better off with LJFuse.

I'm very excited about using LJFuse to talk to the LabJack.  Have you been able to run any performance tests using a compiled language?  It would be interesting to see a table showing the different ways to talk to the LabJack and the different speeds that you can achive.  For example, using C, what is the performance of using LJFuse versus making direct calls to the driver?

As of right now, we haven't run any benchmarking tests on LJFuse. It is not at the top of our queue, but we will try to get some numbers soon.

It would be my guess that LJFuse will lose against direct calls to the driver. Any performance hit is more than worth it for the languages we don't directly support, or users new to the LabJack.

I'm trying to get LJFuse up and running on OSX 10.6.5, with python 2.6.6.  I want to talk to it with Ruby, but Ruby-libusb support seems dated/questionable, so LJFuse looked like the best shot.

I installed current exodriver, no apparent errors and the u6BasicConfigU6 example runs fine.

I installed MacFUSE, no apparent errors.

Installed fusepy, no apparent errors.

download and untar ljfuse, and then run python ljfuse.py:

 


 

Traceback (most recent call last):

  File "ljfuse.py", line 25, in <module>

    from fuse import FUSE, Operations, LoggingMixIn, fuse_get_context

  File "/Users/aaronstewart/Downloads/LJFuse/fuse.py", line 243, in <module>

    raise EnvironmentError('Unable to find libfuse')

EnvironmentError: Unable to find libfuse

 


 

Thoughts?

 

MacFUSE needs to be installed first.  Quoting the requirements, "On Mac OS X, LJFuse requires MacFUSE. On Linux, LJFuse uses the kernel’s fuse implementation."

I have MacFUSE version 2.0.3 installed.

Sorry, I somehow missed that in your first comment.  Have you tried restarting your Mac.

It has been restarted since the various installations.

/usr/local/lib/libfuse.dylib is present, and symlinks to /usr/local/lib/libfuse.0.dylib.

Also, if you check the /usr/local/lib directory do you see libfuse.dylib .  I believe that's what fuse.py is looking for, and should have been installed by MacFUSE.

Hi Is there any way to make LJFuse communicate with a LabJack UE9 via ethernet/IP? /Roger

Not at this time, but it is planned for the future.

Right now Modbus is probably the simplest interface if you want to talk to a UE9 from some unsupported software.

Is it possible to use Ljfuse with labJack U12. I tried following the above steps, and get no error meeages, but myroot-ljfuse directory only contains HOW_TO_UNMOUNT.txt  README.txt i.e. no "my U12". Then I noticed that U12 is not amongst the products listed in the requirements.

No, LJFuse does not have U12 support.

Running LJFuse on Ubuntu 11.04 but find that I can't write to U3 - permission denied. As root I can't change permission on the fuse directory. I have it running on a very similar setup on another PC without this problem - any suggestions?

BTW this is a fabulous way to access LabJack.

 

 

First unmount LJFuse (fusermount -u root-ljfuse), then add the current user to the "fuse" group, log off and back on, and try starting LJFuse again not as root.  This command will add you to the "fuse" group (USERNAME is the current user you are logged in as):

sudo usermod -a -G fuse USERNAME

I've seen on certain distributions this is necessary for correct permissions, but usually on Ubuntu this should not be an issue.  If this does not help, can you run the "ls -laR" command on your "root-ljfuse" directory and post the results.

Yes that's fixed it, thanks.

Hi,

I am using U3-HV with python(ubuntu 12.04 machine). I was logging around 18volts through AIN1 using special channel no 32. 

d.configIO(FIOAnalog = 0xF0 , EIOAnalog = 0x10)
    measurements = {
    'V_pan': measurement('V_pan',    1, 32, 'V')
                                     }

 

Now If I want to do the same task while using LJFuse,what should I do? Is the following piece of code ok ?

$ echo 2 > FIO0-dir

 

First you'll want to set the negative channel to 32 for AIN1 like so:

#Create Modbus address 3001 file (AIN1 neg. channel).
#Note AIN/FIO0 is 3000, AIN/FIO1 is 3001, AIN/FIO2 is 3002, ...
$ touch root-ljfuse/My U3/modbus/3001

#Set negative channel to 32
$ echo 32 > root-ljfuse/My U3/modbus/3001

Then you read AIN1 like so (Note that on a U3-HV, FIO0-3 are always analog inputs and named AIN0-3):

$ cat root-ljfuse/My U3/connection/AIN1

The Modbus address list can be found here:

http://labjack.com/support/modbus/ud-modbus

For using the modbus directory help look here:

http://labjack.com/support/ljfuse/advanced

OK did it for AIN0-3. I can read AIN0-3 with $cat command. Now I need to read the analog inputs once a second. So I am trying to run from a text file :

# Read AIN0 once a second
 
from time import time, sleep
 
PATH = "/home/abir/root-ljfuse/u3/connection/AIN0"
 
while True:
f = file(PATH)
print "%d,%f" % (int(time()), float(f.read()))
sleep(1)

But it says:

Traceback (most recent call last):
File "/media/research/Solar/instrumentation_ljfuse.py", line 12, in <module>
print "%d,%f" % (int(time()), float(f.read()))
ValueError: invalid literal for float(): 1.378


what can I do to fix this float() issue?

Use f.readline() instead. I changed the Python example to reflect this. Readings end with a newline ('\n'), but there may be some null characters after the newline that can cause conversion errors.

OK everything is working fine. Except, I can't read voltages greater than 10volts(around) through the dedicated analog inputs(AIN0-AIN3). Even if the voltage increases, the reading from these pins get saturated at 10volts. Applying around 14 volts, I have checked those pin's actual voltages with a multimeter. Yes, the multimeter shows the right voltage. So I guess it's the u3-HV which is not reading the voltage greater than 10volts.

Why is that ? I have done from the ubuntu terminal following:

$touch 3000

$echo 32>3000

And similar command for each of the 4 pins. And yes, in the modbus subdirectory of u3, 3000,3001,3002 and 3003 registers have been created. And when I am reading the pins using following commands:

PATH1 = "/home/abir/root-ljfuse/u3/connection/AIN1"

while True:

f1 = file(PATH1)

print "V_pan= %0.3f"% (float(f1.readline()))

 

The program is running smooth and giving accurate output upto 10volts. At 10 volts, the output is getting saturated. So is the special negative channel(32) for AIN0-AIN4 not working? It should be working for -10to+40 volts, right?

Hello?? Any suggestion ?

Make sure you are running the latest U3 firmware. Special range support through Modbus was added in firmware v1.44:

http://labjack.com/support/firmware/u3

http://labjack.com/support/firmware

Running the latest firmware I was able to read above 10 V in LJFuse. Also, the special range is -10 to +20 V.

I use u3-HV with python on ubuntu 12.04 machine.The files under the "connections" subdirectory [ AIN0-3] , what type of files they are? Are they csv ? If not,what should I change in the ljfuse.py file to make these "connection" files csv ? Actually I am logging data through several I/O pins of u3 and later on I want to merge the corresponding files to a single csv file. 

 

They are text files with a single reading, followed by an endline ('\n') to indicate the end of the reading. When you open/readline/close a file you get a new reading. You can save the readings in an array and not in csv form, and later during your merge make into the csv file format you want. Python has a nice module for making csv files:

http://docs.python.org/2/library/csv.html

If you do want to modify the LJFuse source code, take a look at the ModbusAddrPath through FlexibleIOStatePath classes' read methods, lines 114-209 in ljfuse.py.

Hello,

Could you please show an example of using ljfuse for a PWM output?

I've been struggling with it for a couple days now and I'm stuck.

Here is what I have so far:

cd root-ljfuse

cd @

cd modbus

touch 50500                (open the Pin Offset modbus address)

echo "4" > 50500         (Set offset to four, as specified in Labjack U3 manual section 2.9)

touch 50501                (open the # of PWM channels modbus address)

echo "1" > 50501         (Tell U3 that I will have one PWM output.)

According to to the manual the output will be on the FIO4 screw terminal. 

At this point I'm stuck.   How do I actually set the pulse width???

Sincerely,

Peter Halverson

In another page's comment it looks like you found your answer. For others with similar issues, refer to the "Advanced: Timers & Counters" page for timer/counter examples in LJFuse. A timer configured for PWM is demonstrated there:

http://labjack.com/support/ljfuse/advanced

Can LJFuse be made to work with an LJTick-DAC (connected to a U3-HV)? Also, is there anything special that needs to be done after popping in the LJTick-DAQ?

No, it looks like an LJTick-DAC cannot be used in LJFuse. LJFuse only supports the Modbus protocol, and it looks like there are no specific LJTick-DAC or I²C addresses available on a U3 in the ModBus map.

Normally you connect your LJTick-DAC to DIO lines and using the low-level protocol's I²C function you would get calibration constants and set voltages as demonstrated in the C and Python examples:

C - u3LJTDAC.c
Python - LJTickDAC.py

Is there a way to change the default FIO5-dir (for example) to "2" rather than "0"?

Are you wanting to change the power-up defaults of I/O on a U3/U6/UE9?  On Windows, you can use "Config Defaults" in LJControlPanel.