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
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