Jump to content

As of July 17, 2015, the LabJack forums here at forums.labjack.com are shut down. New registrations, topics, and replies are disabled. All forums are in a read-only state for archive purposes.

Please visit our current forums at labjack.com/forums to view and make new posts. To post on the current forums, use your labjack.com login account. Your old LabJack forums login credentials have been retired. There are no longer separate logins for labjack.com and LabJack forums.


Configuring U3 for 2-channel streaming using exodriver

U3 exodriver Linux C

  • Please log in to reply
3 replies to this topic

#1 mhgreen

  • Members
  • 2 posts

Posted 02 June 2015 - 02:41 PM



Hardware and Environment: I have a U3 (purchased in 2013), and I have successfully installed exodriver on Ubuntu 14.04 LTS from the Labjack github page. I can run the all of the examples without errors.


Goal: I would like to do streaming analog input on two channels within a larger C++ program. This larger program is an OpenGL-based graphics program. There is a main loop, in which each iteration (graphics frame) lasts about 16.7 msec (corresponding to a frame rate of 60Hz). During each frame (i.e. main loop iteration), I would like to read all of the available data on the U3 buffer into my own, userspace buffer. It does not matter whether there is variability in the amount of available data on each iteration - I just want to read everything that's there quickly and move on, so that nothing is blocking and slowing down the frame rate. For my application, I need scan rates of at least 5kHz, preferably closer to 10 kHz. For the 10 kHz scan rate, this corresponds to loading the U3 buffer with 334 samples per frame, which I think is within its limits (512-984 samples).


What I have learned from the docs: In section 4.3.7 of of the "high level driver" documentation (Windows only), streaming mode is described in detail. From this discussion, the "wait mode" I need corresponds to LJ_swNONE.


Where I am totally lost: The "low-level" exodriver functions for configuring the U2, and configuring streaming mode seem to require a deep knowledge of byte-by-byte communication with the U3 and the details of U3 operation. To be more specific, I will refer to the u3Stream.c file included with exodriver examples (attached).


In the ConfigIO_example function, which bytes of the sendBuff should I modify and what values should I use to obtain a configuration in which I have two analog inputs (single ended), say aIN0 and aIN1?


In the StreamConfig_example function, again, which bytes of the sendBuff should I modify to obtain two single-ended analog inputs? Furthermore, how can I set the scan rate ... using scanInterval? 


Apology: I realize that it might require a novel-length response to fully answer these questions ... i.e. a rundown of exactly how the U3 works. Or maybe not?  If someone could refer me to the relevant documentation that would answer my questions that would be great. Generally, I could really use an overview of how timers and counters, and FIOAnalog and EIOAnalog should be configured. Also if there is any "higher level" interface on the Linux platform that could do what I need to do, please let me know! Thanks! ... and sorry! Sadly, I am a biologist and not an engineer.


Attached Files

#2 LabJack Support

LabJack Support
  • Admin
  • 8677 posts

Posted 02 June 2015 - 05:15 PM

The high-level UD driver and its functions are only available on Windows. Other operating systems such as Linux have the Exodriver which basically provides USB communications where you setup the low-level packets. There is a high-level Python interface, but for C/C++ we only provide the code in the examples.


Low-level documentation is here along with the command/response packets subsection:





In section 5.2 you will see the documentation for the ConfigIO, StreamConfig, etc. command/responses.


For your configuration:


ConfigIO command:

    sendBuff[1] = (uint8)(0xF8);  //Command byte
    sendBuff[2] = (uint8)(0x03);  //Number of data words
    sendBuff[3] = (uint8)(0x0B);  //Extended command number
    for(int i = 4; i < 12; i++)
        sendBuff[i] = 0;
    sendBuff[6] = 1 << 2;   //Writemask: Set bit 2 for FIOAnalog changes to take effect
    sendBuff[8] = 4 << 4 ;  //TimerCounterConfig: bits 0-1: Number of timers enabled = 0
                            //                    bit 2: Enable Counter0 = 0 (disable)
                            //                    bit 3: Enable Counter1 = 0 (disable)
                            //                    bits 4-7: TimerCounterPinOffset = 4 (FIO4)

    sendBuff[10] = 1 + 1<<1;  //FIOAnalog: Configure FIO0 and FIO1 to analog inputs, FIO2-7 as digital I/O.
                              //           binary 00000011 or decimal 3
    extendedChecksum(sendBuff, 12);

StreamConfig command:

    sendBuff[1] = (uint8)(0xF8);  //Command byte
    sendBuff[2] = 2 + 3;  //Number of data words = NumChannels + 3
    sendBuff[3] = (uint8)(0x11);  //Extended command number
    sendBuff[6] = 2;  //NumChannels = 2
    sendBuff[7] = 25; //SamplesPerPacket = 25 (Maximum which is recommended)
    sendBuff[8] = 0;  //Reserved
    sendBuff[9] = 1;  //ScanConfig:
                      // Bit 7: Reserved
                      // Bit 6: Reserved
                      // Bit 3: Internal stream clock frequency = b0: 4 MHz
                      // Bit 2: Divide Clock by 256 = b0
                      // Bits 0-1: Resolution = b01: 11.9-bit effective

    //Scan Rate = ClockFrequency/ScanInterval or interval between scans = ScanInterval/ClockFrequency 
    scanInterval = 4000; //Scan Rate = 4MHz/4000 = 1000 scans/second
    sendBuff[10] = (uint8)(scanInterval & (0x00FF));  //Scan interval (low byte)
    sendBuff[11] = (uint8)(scanInterval / 256);       //Scan interval (high byte)
    //First Channel Stream Config.
    sendBuff[12] = 0;   //PChannel = 0 (AIN0/FIO0)
    sendBuff[13] = 31;  //NChannel = 31: Single Ended
    //Second Channel Stream Config.
    sendBuff[14] = 1;   //PChannel = 1 (AIN1/FIO1)
    sendBuff[15] = 31;  //NChannel = 31: Single Ended
    extendedChecksum(sendBuff, 16);

In general, stream mode and timer/counters are documented here:





As for FIOAnalog and EIOAnalog, those settings are for configuring FIO and EIO lines to analog inputs (1) or digital I/O (0). They are 8-bit values, where each bit corresponds to a line. Bit 0 = FIO0/EIO0 = 1, bit 1 = FIO1/EIO1 = 2, bit 2 = FIO2/EIO2. The ConfigIO code I provided above and most examples demonstrates setting these. General Flexible I/O documentation can be found here:




Regarding timer/counters, refer to the timer/counter documentation I linked to, the timer/counter C example and the low-level documentation for the command/responses used in the example. Note to set the timer/counter lines need to be configured for digital I/O.


Last, regarding your graphic based application it is recommended to create a separate thread for reading stream data to prevent other code from delaying your stream read loop which could lead to stream buffer overflows. This should also help with slowdown on your graphical thread due to the code running in parallel.

#3 LabJack Support

LabJack Support
  • Admin
  • 8677 posts

Posted 02 June 2015 - 05:20 PM

To add to my previous post, set the scan interval to 400 for a scan rate of 10000 (4MHz/400). For 2 channels the max. scan rate is 25000. The max. sample rate in general is 50000 samples/second where SampleRate = ScanRate*#Channels.

#4 mhgreen

  • Members
  • 2 posts

Posted 04 June 2015 - 08:45 AM

Thank you for the detailed response! I'll see if I can get a lightweight thread going to do the I/O.

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users