USB1208FS Linux Issues

Hi,

Our lab is measuring EEG using a Measurement Computing USB1208FS DAQ. We recently have begun converting our lab from MacOSX to Linux due to the direction PTB is heading. However, in doing so, we’ve encountered an issue with the DAQ and communications with PTB on the Linux machines.

We’re using a Linux machine with the following specs:

Dell Precision Compact 3240 (2021)
Memory: 16 GB
Processor: 3.6 GHz NVIDIA Quadro Pro P400 2GB
Running with Ubuntu 18.04
PTB version: 3.0.17
Matlab version: 2020b.

We’re using custom code from Steve Luck’s lab (below called “seDAQ” to initialize the DAQ, which we have been using for years to communicate with the DAQ. However, this code was only ever designed for Mac and PC. We’ve tried to adopt the code to initialize the DAQ for Linux but always get hung up at the same place (see bolded line below).

In trying to communicate with the DAQ, we’ve been able to successfully get to the line of code where it uses the PTB function “DaqDConfigPort”, but it always freezes on the step where it tries to call “PsychHID” and initialize the USB port for the DAQ.

We’ve been able to run “PsychHIDDAQS” or “devices = PsychHID(‘Devices’);” and extract most of the information (though on Linux we fail to get the correct serial and product numbers, despite being able to do so on Mac). However, when we get to the step:

"err=PsychHID(‘SetReport’,daq,2,reportId,report); % Configure digital port."

We always encounter the same error no matter which of the DAQ functions or PsychHID functions we use. They always get hung up on the port configuration. We’ve tried different reportId and report settings and multiple “commonsense” approaches (turning the machine on and off, trying on Mac then trying on Linux, making sure things are plugged in, restarting Matlab, etc.).

The error message is always:

INTERNAL PSYCHTOOLBOX ERROR
error: PsychError_system
general description: Error reported by a system call
specific description: HIDLIB Failed to open USB device!
module name: PsychHID
subfunction call: SetReport
file name: Common/PsychHID/PsychHIDHelpers.c
function name: PsychHIDGetDeviceRecordPtrFromIndex
line number: 249

We have not been able to find a way to get past this step. I (the lead on troubleshooting this problem) do not know enough about C code either to resolve this error.

Any help would be greatly appreciated!


////// seDAQ.m ////////


classdef seDAQ < handle

% returns DAQ object/struct containing information to send out event codes
% to data acquisition device.
%


properties
    
    isPresent   = false;       % whether the DAQ device is present or not

    deviceNum   = NaN;         % number-pointer to DAQ device
    lastCode    = NaN;         % value of last eventCode that was successfully sent out

end % properties


properties(Hidden = true, Constant = true)
    
    RESP                = 'resp';       % 
    EVENT               = 'event';

    EVENT_PORT          = 0;            % value to send eventCode out of event port
    RESP_PORT           = 1;            % value to send eventCode out of response port
    
    CONFIG_OUTPUT       = 0;            % value to designate if port as output
    CONFIG_INPUT        = 1;            % value to designate if port as input

    RESET_EVENTCODE     = 0;            % arbitrary number for resets
    TIME_DELAY          = 0.010;        % (secs) time duration to leave event codes on after sending them out 
    EVENT_CODE_LIMIT    = 255;          % max event code
        
end 

properties(Hidden = true)
    pcIO;                               % input/output (IO) object to send event codes on PCs
    BIOSEMI         = 'Biosemi';
    BRAINPRODUCTS   = 'BrainProducts';
end


methods

    function obj = seDAQ()
        if ismac
            
            obj.deviceNum  = DaqDeviceIndex();
            obj.isPresent = ~isempty(obj.deviceNum);
            
            if(obj.isPresent)
                configPorts(obj);            % Basic DAQ-device Setup %
            end
            
        elseif ispc
            buttonname=questdlg('Please select data acquisition system:','DAQ?',obj.BIOSEMI, obj.BRAINPRODUCTS, obj.BIOSEMI);
            
            switch buttonname
                case obj.BIOSEMI
                    obj.deviceNum = hex2dec('2050');                
                case obj.BRAINPRODUCTS
                    obj.deviceNum = hex2dec('2030');
            end
            
            obj.pcIO      = io64();
            obj.isPresent = ~io64(obj.pcIO);
            
        end 
    end % daq constructor method
    
    function configPorts(obj)
        
        display(sprintf('Configuring ports %d and %d as output ports', obj.EVENT_PORT, obj.RESP_PORT));
        
        DaqDConfigPort(obj.deviceNum, obj.EVENT_PORT, obj.CONFIG_OUTPUT); % configure as output port
        DaqDConfigPort(obj.deviceNum, obj.RESP_PORT,  obj.CONFIG_OUTPUT); % configure as output port
        
    end % configPorts method


    function sendEventCode(obj, eventCode)
        % SENDEVENTCODE     Sends event/response eventCode out to DAQ device.
        % CODE must be an integer 1-254
        
        if(obj.isPresent && (0 < eventCode < obj.EVENT_CODE_LIMIT))
            if ismac
                DaqDOut(obj.deviceNum, obj.EVENT_PORT,  eventCode);                                     % Send event code
                WaitSecs(obj.TIME_DELAY);
                DaqDOut(obj.deviceNum, obj.EVENT_PORT, obj.RESET_EVENTCODE);                                 % Clear event code
                WaitSecs(obj.TIME_DELAY);
            elseif ispc
                io64(obj.pcIO, obj.deviceNum, eventCode);
                WaitSecs(obj.TIME_DELAY);
                io64(obj.pcIO, obj.deviceNum, obj.RESET_EVENTCODE);
                WaitSecs(obj.TIME_DELAY);
            end
        elseif(~obj.isPresent)
            fprintf('Error:\tDAQ device not present\n\tEvent code %03d not sent\n',eventCode);
        elseif(~(0 < eventCode <= obj.EVENT_CODE_LIMIT))
            fprintf('Warning:\tEvent code exceeds limit (%d)\n\t\tEvent code %03d not sent\n', obj.EVENT_CODE_LIMIT, eventCode);
        end

    end
    
end % methods

end

Further, we’ve modified “seDAQ” to contain the following (in the “methods” section under function obj = seDAQ()"

elseif isunix

            obj.deviceNum  = DaqDeviceIndex();
            obj.isPresent = ~isempty(obj.deviceNum);
            
            % Default reportId for 1x08FS devices is 64:
            reportId = 64;
            report = uint8(64);
            
            %reportId = 1;
            %report = uint8([1 0 0]);
            err = PsychHID('SetReport', obj.deviceNum, 2, reportId, report);
            %report = uint8([1 1 0]);
            err = PsychHID('SetReport', obj.deviceNum, 2, reportId, report);

But, we encounter the same error:

INTERNAL PSYCHTOOLBOX ERROR
error: PsychError_system
general description: Error reported by a system call
specific description: HIDLIB Failed to open USB device!
module name: PsychHID
subfunction call: SetReport
file name: Common/PsychHID/PsychHIDHelpers.c
function name: PsychHIDGetDeviceRecordPtrFromIndex
line number: 249

Congratulations to a good choice of OS. Is there a reason why a NVidia card is used, against our advice to avoid NVidia whenever possible? Also, Ubuntu 18.04-LTS or PTB 3.0.17 are no longer supported. Minimum is Ubuntu 20.04.3-LTS with PTB 3.0.18.2 - the latest beta.

Next step is to read help PsychPaidSupportAndServices on how to buy the (currently 150 Euro + Tax) priority support package for up to 1 hour of my time for advice. Once you present a valid authentication token, and your license key has been enabled - which takes anywhere between 1 - 10 business days, i can have a look. Unless we are then already in christmas vacation, in which case nothing will happen until at least the 2nd week of january. Or you have already a license, as any able lab should have since a year, then things will go faster ofc.

-mario

Hi Brad,

USB1208FS (without plus!) in general works well here on any Ubuntu Linux version we have used within the last years.

The code you sent in your latest mail is missing DaqDConfigPort, reportId should be 4 for digital out (see DaqDOut.m) and report should be a triplet of uint8 (last one is the trigger to send). Minimal code working here is:

daqhandle = DaqFind;
DaqDConfigPort( daqhandle, 0, 0 );
PsychHID( ‘SetReport’, daqhandle, 2, 4, uint8( [ 0, 0, 255 ] ) );
WaitSecs( 0.004 );
PsychHID( ‘SetReport’, daqhandle, 2, 4, uint8( [ 0, 0, 0 ] ) );

Hope this helps! Best,
Andreas

It won’t. However paying for priority support will likely, and is the right thing to do anyway.
-mario

Hi Andreas,

Thank you for the suggestion. Unfortunately, this did not resolve the issue. We still get hung up on the same error

INTERNAL PSYCHTOOLBOX ERROR
error: PsychError_system
general description: Error reported by a system call
specific description: HIDLIB Failed to open USB device!
module name: PsychHID
subfunction call: SetReport
file name: Common/PsychHID/PsychHIDHelpers.c
function name: PsychHIDGetDeviceRecordPtrFromIndex
line number: 249

That webpage is not linked and accessible on our main webpage or the “system requirements” section at all?!? It has been stale and outdated for many years, which is why it is supposed to be hidden and inaccessible. I’m surprised why it shows up at all - Google or some other search engine must be quite confused.

Updating Ubuntu and PTB won’t help, it is just one strongly recommended step to get support at all, and an improved experience.
-mario