def makeAnalogIn(portString, handle, fSamp, nSamp): ## Create a task out of an existing handle # int32 DAQmxCreateTask (const char taskName[], TaskHandle *taskHandle); taskName = '' # Name of the task (I don't know when this would not be an empty string...) input1Pointer = ctypes.byref( handle ) # Equivalent to &setStates in C, the pointer to the task handle pydaqmx.DAQmxCreateTask(taskName, input1Pointer) ## Create Analog In voltage channel # int32 DAQmxCreateAIVoltageChan (TaskHandle taskHandle, const char physicalChannel[], const char nameToAssignToChannel[], int32 terminalConfig, float64 minVal, float64 maxVal, int32 units, const char customScaleName[]); chan = portString # Location of the channel (this should be a physical channel, but it will be used as a virtual channel?) chanName = "" # Name(s) to assign to the created virtual channel(s). "" means physical channel name will be used termConfig = pydaqmx.DAQmx_Val_Diff # Is this singled/double referenced, differential, etc.\ vMin = -10 # Minimum voltage you expect to measure (in units described by variable "units" below) vMax = 10 # Maximum voltage you expect to measure units = pydaqmx.DAQmx_Val_Volts # Units used in vMax/vMin. custUnits = None # If units where DAQmx_Val_FromCustomScale, specify scale. Otherwise, it should be None pydaqmx.DAQmxCreateAIVoltageChan(handle, chan, chanName, termConfig, vMin, vMax, units, custUnits) ## Configure the clock # int32 DAQmxCfgSampClkTiming (TaskHandle taskHandle, const char source[], float64 rate, int32 activeEdge, int32 sampleMode, uInt64 sampsPerChanToAcquire); source = None # If you use an external clock, specify here, otherwise it should be None rate = pydaqmx.float64( fSamp ) # The sampling rate in samples per second per channel. If you use an external source for the Sample Clock, set this value to the maximum expected rate of that clock. edge = pydaqmx.DAQmx_Val_Rising # Which edge of the clock (Rising/Falling) to acquire data sampMode = pydaqmx.DAQmx_Val_FiniteSamps # Acquire samples continuously or just a finite number of samples # sampMode = pydaqmx.DAQmx_Val_ContSamps sampPerChan = pydaqmx.uInt64( nSamp) # Total number of sample to acquire for each channel pydaqmx.DAQmxCfgSampClkTiming(handle, source, rate, edge, sampMode, sampPerChan)
def acquire_analog(self, channel, points, accuracy, limits=(-10.0, 10.0)): """Acquires an analog signal in the specified channel. The execution blocks the rest of the program. channel -- has to be defined as "Dev1/ai0", for example. points -- the total number of points to be acquired accuracy -- the time between acquisitions (in seconds) limits -- the limits of the expected values. A tuple of 2 values. Returns: numpy array of length points """ taskAnalogNumber = self.addTask({ 'name': 'TaskAnalog', 'TaskHandle': nidaq.TaskHandle() }) self.task_Analog = self.getTask(taskAnalogNumber)['TaskHandle'] self.read = nidaq.int32() points = int(points) data = np.zeros((points, ), dtype=np.float64) channel = str.encode(channel) waiting_time = points * accuracy * 1.05 # Adds a 5% waiting time in order to give enough time freq = 1 / accuracy # Accuracy in seconds nidaq.DAQmxCreateTask("", nidaq.byref(self.task_Analog)) nidaq.DAQmxCreateAIVoltageChan(self.task_Analog, channel, "", nidaq.DAQmx_Val_RSE, limits[0], limits[1], nidaq.DAQmx_Val_Volts, None) nidaq.DAQmxCfgSampClkTiming(self.task_Analog, "", freq, nidaq.DAQmx_Val_Rising, nidaq.DAQmx_Val_FiniteSamps, points) # DAQmx Start Code nidaq.DAQmxStartTask(self.task_Analog) nidaq.DAQmxReadAnalogF64(self.task_Analog, points, waiting_time, nidaq.DAQmx_Val_GroupByChannel, data, points, nidaq.byref(self.read), None) self.tasks[taskAnalogNumber]['alive'] = 0 return data
def task_handler(self, samples=None, rate=10e3, max_v=10., min_v=-10.): """Sets up a task handler for an analog input channel. Max sample rate for the PCIe-6320 is 250kS/s.""" if samples is None: # Return the channel parameters return self.params else: self.clear_task() self.params['samples'] = samples self.params['rate'] = rate self.params['max_v'] = max_v self.params['min_v'] = min_v self.chan_name = '{0:}/ai{1:}'.format(self.address, self.chan_num) self.task_handle = pydaq.TaskHandle() pydaq.DAQmxCreateTask('', pydaq.byref(self.task_handle)) pydaq.DAQmxCreateAIVoltageChan(self.task_handle, self.chan_name, '', pydaq.DAQmx_Val_Cfg_Default, self.params['min_v'], self.params['max_v'], pydaq.DAQmx_Val_Volts, None) pydaq.DAQmxCfgSampClkTiming(self.task_handle, '', self.params['rate'], pydaq.DAQmx_Val_Rising, pydaq.DAQmx_Val_FiniteSamps, self.params['samples'])
def makeAnalogIn(self, c, name, portString): ## Create Analog In voltage channel # int32 DAQmxCreateAIVoltageChan (TaskHandle taskHandle, const char physicalChannel[], const char nameToAssignToChannel[], int32 terminalConfig, float64 minVal, float64 maxVal, int32 units, const char customScaleName[]); chan = portString # Location of the channel (this should be a physical channel, but it will be used as a virtual channel?) chanName = "" # Name(s) to assign to the created virtual channel(s). "" means physical channel name will be used termConfig = pydaqmx.DAQmx_Val_Diff # Is this singled/double referenced, differential, etc.\ vMin = -10 # Minimum voltage you expect to measure (in units described by variable "units" below) vMax = 10 # Maximum voltage you expect to measure units = pydaqmx.DAQmx_Val_Volts # Units used in vMax/vMin. custUnits = None # If units where DAQmx_Val_FromCustomScale, specify scale. Otherwise, it should be None pydaqmx.DAQmxCreateAIVoltageChan(self.handleDict[name], chan, chanName, termConfig, vMin, vMax, units, custUnits)
def _setup_channels(self): """ Setup channels to be channels measuring voltage """ pydaq.DAQmxCreateAIVoltageChan( self._task_handle, ','.join(channels ), # Channel, <channel_name>/ai<channel_num> e.g. emg/ai0 '', pydaq.DAQmx_Val_RSE, -10.0, # Max value 10.0, # Min Value pydaq.DAQmx_Val_Volts, # Unit to measure None)
def set_up_ai_channel(self): """ create a task and its virtual channel for the analog input @return: int error code: ok = 0, error = -1 """ if self.analog_in_taskhandle is not None: self.log.info('Analog input already open') return -1 else: task = daq.TaskHandle() daq.DAQmxCreateTask('AnalogIn', daq.byref(task)) daq.DAQmxCreateAIVoltageChan(task, self._ai_channel, '', daq.DAQmx_Val_RSE, 0.0, 10.0, daq.DAQmx_Val_Volts, None) self.analog_in_taskhandle = task # keep the taskhandle accessible return 0
def __init__(self, osas, simulation=False): """ :param osas: dictionary containing OSA configuration info :param simulation: if True we operate in simulation mode """ self.simulation = simulation self.osas = dict(osas) self.handles = {} if self.simulation: self.f0 = {} for osa_name, osa in self.osas.items(): self.f0[osa_name] = np.random.uniform(0, 1) * osa["num_samples"] return try: # Reset all DAQ cards devices = set([osa["device"] for _, osa in self.osas.items()]) for device in devices: PyDAQmx.DAQmxResetDevice(device) for name, osa in self.osas.items(): self.handles[name] = task_handle = PyDAQmx.TaskHandle(0) PyDAQmx.DAQmxCreateTask("osa_" + name, byref(task_handle)) PyDAQmx.DAQmxCreateAIVoltageChan( task_handle, "/{}/{}".format(osa["device"], osa["input_channel"]), "Voltage", PyDAQmx.DAQmx_Val_NRSE, -osa["v_span"] / 2, osa["v_span"] / 2, PyDAQmx.DAQmx_Val_Volts, None) PyDAQmx.DAQmxCfgSampClkTiming(task_handle, None, osa["sample_rate"], PyDAQmx.DAQmx_Val_Rising, PyDAQmx.DAQmx_Val_FiniteSamps, osa["num_samples"]) PyDAQmx.DAQmxCfgDigEdgeStartTrig( task_handle, "/{}/{}".format(osa["device"], osa["trigger_channel"]), PyDAQmx.DAQmx_Val_Falling) except DAQError as err: self.clear() raise OSAException(err)
def getVoltage(): try: taskHandle = tp.TaskHandle() daq.DAQmxCreateTask("",taskHandle) # print "taskHandle Value", taskHandle.value val = tp.float64() daq.DAQmxCreateAIVoltageChan(taskHandle,"Dev1/ai0","",cnst.DAQmx_Val_RSE,0.0,10.0,cnst.DAQmx_Val_Volts,"") daq.DAQmxStartTask(taskHandle) daq.DAQmxReadAnalogScalarF64(taskHandle,5.0,daq.byref(val),None) if not taskHandle == 0 : # print "Stopping Tasks\n" daq.DAQmxStopTask(taskHandle) daq.DAQmxClearTask(taskHandle) return val.value except: errBuff=tp.create_string_buffer(b"",2048) daq.DAQmxGetExtendedErrorInfo(errBuff,2048) print(errBuff.value)
def analogSetup(self, taskNum, channel, points, accuracy, limits=(-10.0, 10.0)): """Prepares the task for an analog measurement. taskNum -- the number of the task (an integer) channel -- has to be defined as 1 or as [1,2], for example, meaning ai1, ai2, etc. points -- the total number of points to be acquired accuracy -- the time between acquisitions (in seconds) limits -- the limits of the expected values. A tuple of 2 values. """ taskAnalogNumber = self.addTask({ 'name': 'TaskAnalog', 'TaskHandle': nidaq.TaskHandle(taskNum) }) self.task_Analog = self.getTask(taskAnalogNumber)['TaskHandle'] points = int(points) dev = 'Dev%s' % self.deviceNumber if type(channel) != type([]): channel = [channel] channels = [] for c in channel: newChannel = '%s/ai%s' % (dev, int(c)) channels.append(newChannel) channels = ', '.join(channels) channels = str.encode(channels) freq = 1 / accuracy # Accuracy in seconds nidaq.DAQmxCreateTask("", nidaq.byref(self.task_Analog)) nidaq.DAQmxCreateAIVoltageChan(self.task_Analog, channels, None, nidaq.DAQmx_Val_RSE, limits[0], limits[1], nidaq.DAQmx_Val_Volts, None) if points > 0: nidaq.DAQmxCfgSampClkTiming(self.task_Analog, "", freq, nidaq.DAQmx_Val_Rising, nidaq.DAQmx_Val_FiniteSamps, points) else: nidaq.DAQmxCfgSampClkTiming(self.task_Analog, "", freq, nidaq.DAQmx_Val_Rising, nidaq.DAQmx_Val_ContSamps, points) return taskAnalogNumber
def channel_info(channels, channel_type): task = create_task() if channel_type in ('di', 'do', 'digital'): mx.DAQmxCreateDIChan(task, channels, '', mx.DAQmx_Val_ChanPerLine) elif channel_type == 'ao': mx.DAQmxCreateAOVoltageChan(task, channels, '', -10, 10, mx.DAQmx_Val_Volts, '') elif channel_type == 'ai': mx.DAQmxCreateAIVoltageChan(task, channels, '', mx.DAQmx_Val_Cfg_Default, -10, 10, mx.DAQmx_Val_Volts, '') channels = ctypes.create_string_buffer('', 4096) mx.DAQmxGetTaskChannels(task, channels, len(channels)) devices = ctypes.create_string_buffer('', 4096) mx.DAQmxGetTaskDevices(task, devices, len(devices)) mx.DAQmxClearTask(task) return { 'channels': [c.strip() for c in channels.value.split(',')], 'devices': [d.strip() for d in devices.value.split(',')], }
def setup_hw_ai(fs, lines, expected_range, callback, callback_samples, sync_ao): # Record AI filter delay task = create_task() lb, ub = expected_range mx.DAQmxCreateAIVoltageChan(task, lines, '', mx.DAQmx_Val_RSE, lb, ub, mx.DAQmx_Val_Volts, '') if sync_ao: mx.DAQmxCfgDigEdgeStartTrig(task, 'ao/StartTrigger', mx.DAQmx_Val_Rising) mx.DAQmxCfgSampClkTiming(task, 'ao/SampleClock', fs, mx.DAQmx_Val_Rising, mx.DAQmx_Val_ContSamps, int(fs)) else: mx.DAQmxCfgSampClkTiming(task, '', fs, mx.DAQmx_Val_Rising, mx.DAQmx_Val_ContSamps, int(fs)) result = ctypes.c_uint32() mx.DAQmxGetBufInputBufSize(task, result) buffer_size = result.value mx.DAQmxGetTaskNumChans(task, result) n_channels = result.value log.debug('Buffer size for %s automatically allocated as %d samples', lines, buffer_size) log.debug('%d channels in task', n_channels) new_buffer_size = np.ceil(buffer_size/callback_samples)*callback_samples mx.DAQmxSetBufInputBufSize(task, int(new_buffer_size)) callback_helper = SamplesAcquiredCallbackHelper(callback, n_channels) cb_ptr = mx.DAQmxEveryNSamplesEventCallbackPtr(callback_helper) mx.DAQmxRegisterEveryNSamplesEvent(task, mx.DAQmx_Val_Acquired_Into_Buffer, int(callback_samples), 0, cb_ptr, None) task._cb_ptr = cb_ptr return task
readPressAvg ) # Equivalent to &setStates in C, the pointer to the task handle pydaqmx.DAQmxCreateTask(taskName, input1Pointer) read = pydaqmx.int32() data = np.zeros((int(nSamp), ), dtype=np.int16) ## Create Analog In voltage channel # int32 DAQmxCreateAIVoltageChan (TaskHandle taskHandle, const char physicalChannel[], const char nameToAssignToChannel[], int32 terminalConfig, float64 minVal, float64 maxVal, int32 units, const char customScaleName[]); chan = "Dev1/ai3" # Location of the channel (this should be a physical channel, but it will be used as a virtual channel?) chanName = "" # Name(s) to assign to the created virtual channel(s). "" means physical channel name will be used termConfig = pydaqmx.DAQmx_Val_Diff # Is this singled/double referenced, differential, etc.\ vMin = -10 # Minimum voltage you expect to measure (in units described by variable "units" below) vMax = 10 # Maximum voltage you expect to measure units = pydaqmx.DAQmx_Val_Volts # Units used in vMax/vMin. custUnits = None # If units where DAQmx_Val_FromCustomScale, specify scale. Otherwise, it should be None pydaqmx.DAQmxCreateAIVoltageChan(readPressAvg, chan, chanName, termConfig, vMin, vMax, units, custUnits) ## Configure the clock # int32 DAQmxCfgSampClkTiming (TaskHandle taskHandle, const char source[], float64 rate, int32 activeEdge, int32 sampleMode, uInt64 sampsPerChanToAcquire); source = None # If you use an external clock, specify here, otherwise it should be None rate = pydaqmx.float64(fSamp) edge = pydaqmx.DAQmx_Val_Rising # Which edge of the clock (Rising/Falling) to acquire data sampMode = pydaqmx.DAQmx_Val_FiniteSamps # Acquire samples continuously or just a finite number of samples sampPerChan = pydaqmx.uInt64(nSamp) pydaqmx.DAQmxCfgSampClkTiming(readPressAvg, source, rate, edge, sampMode, sampPerChan) ## Read from the specified line(s) # int32 DAQmxReadBinaryI16 (TaskHandle taskHandle, int32 numSampsPerChan, float64 timeout, bool32 fillMode, int16 readArray[], uInt32 arraySizeInSamps, int32 *sampsPerChanRead, bool32 *reserved); nSampsPerChan = -1 # -1 in finite mode means wait until all samples are collected and read them timeout = -1 # -1 means wait indefinitely to read the samples
import PyDAQmx as pydaqmx import ctypes, numpy handle = pydaqmx.TaskHandle() pydaqmx.DAQmxCreateTask('', ctypes.byref(handle)) ## Create Analog In voltage channel # int32 DAQmxCreateAIVoltageChan (TaskHandle taskHandle, const char physicalChannel[], const char nameToAssignToChannel[], int32 terminalConfig, float64 minVal, float64 maxVal, int32 units, const char customScaleName[]); chan = '/Dev1/ai2' # Location of the channel (this should be a physical channel, but it will be used as a virtual channel?) chanName = "" # Name(s) to assign to the created virtual channel(s). "" means physical channel name will be used termConfig = pydaqmx.DAQmx_Val_Diff # Is this singled/double referenced, differential, etc.\ vMin = -10 # Minimum voltage you expect to measure (in units described by variable "units" below) vMax = 10 # Maximum voltage you expect to measure units = pydaqmx.DAQmx_Val_Volts # Units used in vMax/vMin. custUnits = None # If units where DAQmx_Val_FromCustomScale, specify scale. Otherwise, it should be None pydaqmx.DAQmxCreateAIVoltageChan(handle, chan, chanName, termConfig, vMin, vMax, units, custUnits) ## Configure the clock # int32 DAQmxCfgSampClkTiming (TaskHandle taskHandle, const char source[], float64 rate, int32 activeEdge, int32 sampleMode, uInt64 sampsPerChanToAcquire); source = None # If you use an external clock, specify here, otherwise it should be None rate = pydaqmx.float64( 100 ) # The sampling rate in samples per second per channel. If you use an external source for the Sample Clock, set this value to the maximum expected rate of that clock. edge = pydaqmx.DAQmx_Val_Rising # Which edge of the clock (Rising/Falling) to acquire data sampMode = pydaqmx.DAQmx_Val_FiniteSamps # Acquire samples continuously or just a finite number of samples sampPerChan = pydaqmx.uInt64( 2) # Total number of sample to acquire for each channel pydaqmx.DAQmxCfgSampClkTiming(handle, source, rate, edge, sampMode, sampPerChan) #int32 __CFUNC DAQmxGetAIDevScalingCoeff(TaskHandle taskHandle, const char channel[], float64 *data, uInt32 arraySizeInElements);
def start(self, test=False, **kwargs): """ 1. Creates a task using settings. 2. Starts the task. 3. Fetches data. You need to call read_and_clean() after start(). kwargs are sent to self() to set parameters. """ # update any last-minute settings self(**kwargs) debug(self.settings) # create the task object. This doesn't return an object, because # National Instruments. Instead, we have this handle, and we need # to be careful about clearing the thing attached to the handle. debug("input task handle") _mx.DAQmxClearTask(self._handle) _mx.DAQmxCreateTask(self["ai_task_name"], _mx.byref(self._handle)) # Loop over all the input channel names and create a channel for each debug("input channels") for n in range(len(self["ai_channels"])): # get the channel-specific attributes name = self["ai_channels"][n] nickname = name.replace("/", "") debug(name) if isinstance(self["ai_terminal_config"], Iterable): ai_terminal_config = self["ai_terminal_config"][n] else: ai_terminal_config = self["ai_terminal_config"] if isinstance(self["ai_min"], Iterable): ai_min = self["ai_min"][n] else: ai_min = self["ai_min"] if isinstance(self["ai_max"], Iterable): ai_max = self["ai_max"][n] else: ai_max = self["ai_max"] if isinstance(self["ai_units"], Iterable): ai_units = self["ai_units"][n] else: ai_units = self["ai_units"] # add an input channel debug(name) _mx.DAQmxCreateAIVoltageChan(self._handle, name, nickname, ai_terminal_config, ai_min, ai_max, ai_units, "") # set the input coupling (optional) if not self["ai_input_couplings"] == None: ai_input_coupling = self["ai_input_couplings"][n] if ai_input_coupling == "AC": _mx.DAQmxSetAICoupling(self._handle, name, _mx.DAQmx_Val_AC) if ai_input_coupling == "DC": _mx.DAQmxSetAICoupling(self._handle, name, _mx.DAQmx_Val_DC) if ai_input_coupling == "GND": _mx.DAQmxSetAICoupling(self._handle, name, _mx.DAQmx_Val_GND) # Configure the clock debug("input clock") # make sure we don't exceed the max ai_max_rate = _mx.float64() _mx.DAQmxGetSampClkMaxRate(self._handle, _mx.byref(ai_max_rate)) if self['ai_rate'] > ai_max_rate.value: print("ERROR: ai_rate is too high! Current max = " + str(ai_max_rate.value)) self.clean() return False _mx.DAQmxCfgSampClkTiming(self._handle, self["ai_clock_source"], self["ai_rate"], self["ai_clock_edge"], self["ai_mode"], self["ai_samples"]) # get the actual ai_rate ai_rate = _mx.float64() _mx.DAQmxGetSampClkRate(self._handle, _mx.byref(ai_rate)) debug("input actual ai_rate =", ai_rate.value) self(ai_rate=ai_rate.value) # Configure the trigger debug("input trigger") _mx.DAQmxCfgDigEdgeStartTrig(self._handle, self.settings["ai_trigger_source"], self.settings["ai_trigger_slope"]) # Set the post-trigger delay try: n = self["ai_delay"] * 10e6 if n < 2: n = 2 _mx.DAQmxSetStartTrigDelayUnits(self._handle, _mx.DAQmx_Val_Ticks) _mx.DAQmxSetStartTrigDelay(self._handle, n) except: _traceback.print_exc() # in test mode, just check that it doesn't fail and clean up. if test: self.clean() # otherwise, start the show! else: debug("input start") try: _mx.DAQmxStartTask(self._handle) except: _traceback.print_exc() return True
# daq.DAQmxCreateAOVoltageChan(outTask, 'DEV1/AO0','', 0, 10, daq.DAQmx_Val_Volts, '') # # daq.DAQmxCfgSampClkTiming(outTask, '', 1000, daq.DAQmx_Val_Rising, daq.DAQmx_Val_ContSamps, 100) # daq.DAQmxWriteAnalogF64(outTask, 10, False, 0, daq.DAQmx_Val_GroupByChannel, np.linspace(3, 10, 1000), daq.byref(written),None) # daq.StartTask(outTask) value = 0.5 task = daq.TaskHandle() daq.DAQmxCreateTask('con', daq.byref(task)) daq.CreateAOVoltageChan(task, "/Dev1/ao2", "", 0, 10.0, daq.DAQmx_Val_Volts, None) daq.StartTask(task) daq.WriteAnalogScalarF64(task, True, 10.0, value, None) daq.StopTask(task) data = np.zeros((100, ), dtype=np.float64) read = daq.TaskHandle() readAta = daq.int32() daq.DAQmxCreateTask("read", daq.byref(read)) daq.DAQmxCreateAIVoltageChan(read, 'Dev1/ai0', '', daq.DAQmx_Val_RSE, 0, 10, daq.DAQmx_Val_Volts, '') daq.DAQmxCfgSampClkTiming(read, '', 100, daq.DAQmx_Val_Rising, daq.DAQmx_Val_FiniteSamps, 1000) # daq.StartTask(outTask) daq.StartTask(read) daq.DAQmxReadAnalogF64(read, 100, 10, daq.DAQmx_Val_GroupByChannel, data, 100, daq.byref(readAta), None) print(data) daq.DAQmxResetDevice('dev1')
def activate_AI(self, taskhandles, channel): daq.DAQmxCreateTask('', daq.byref(taskhandles)) daq.DAQmxCreateAIVoltageChan(taskhandles, channel, '', daq.DAQmx_Val_RSE, 0.0, 10.0, daq.DAQmx_Val_Volts, None) return taskhandles
def setup_hw_ai(channels, callback_duration, callback, task_name='hw_ao'): log.debug('Configuring HW AI channels') # These properties can vary on a per-channel basis lines = get_channel_property(channels, 'channel', True) names = get_channel_property(channels, 'name', True) gains = get_channel_property(channels, 'gain', True) # These properties must be the same across all channels expected_range = get_channel_property(channels, 'expected_range') samples = get_channel_property(channels, 'samples') terminal_mode = get_channel_property(channels, 'terminal_mode') terminal_coupling = get_channel_property(channels, 'terminal_coupling') # Convert to representation required by NI functions lines = ','.join(lines) log.debug('Configuring lines {}'.format(lines)) terminal_mode = NIDAQEngine.terminal_mode_map[terminal_mode] terminal_coupling = NIDAQEngine.terminal_coupling_map[terminal_coupling] task = create_task(task_name) mx.DAQmxCreateAIVoltageChan(task, lines, '', terminal_mode, expected_range[0], expected_range[1], mx.DAQmx_Val_Volts, '') if terminal_coupling is not None: mx.DAQmxSetAICoupling(task, lines, terminal_coupling) properties = setup_timing(task, channels) log_ai.info('AI timing properties: %r', properties) result = ctypes.c_uint32() mx.DAQmxGetTaskNumChans(task, result) n_channels = result.value fs = properties['sample clock rate'] callback_samples = round(callback_duration * fs) mx.DAQmxSetReadOverWrite(task, mx.DAQmx_Val_DoNotOverwriteUnreadSamps) mx.DAQmxSetBufInputBufSize(task, callback_samples*100) mx.DAQmxGetBufInputBufSize(task, result) buffer_size = result.value log_ai.debug('Buffer size for %s set to %d samples', lines, buffer_size) try: info = ctypes.c_int32() mx.DAQmxSetAIFilterDelayUnits(task, lines, mx.DAQmx_Val_SampleClkPeriods) info = ctypes.c_double() mx.DAQmxGetAIFilterDelay(task, lines, info) log_ai.debug('AI filter delay {} samples'.format(info.value)) filter_delay = int(info.value) # Ensure timing is compensated for the planned filter delay since these # samples will be discarded. if samples > 0: setup_timing(task, channels, filter_delay) except mx.DAQError: # Not a supported property. Set filter delay to 0 by default. filter_delay = 0 task._cb = partial(hw_ai_helper, callback, n_channels, filter_delay, fs, names) task._cb_ptr = mx.DAQmxEveryNSamplesEventCallbackPtr(task._cb) mx.DAQmxRegisterEveryNSamplesEvent( task, mx.DAQmx_Val_Acquired_Into_Buffer, int(callback_samples), 0, task._cb_ptr, None) mx.DAQmxTaskControl(task, mx.DAQmx_Val_Task_Reserve) task._names = verify_channel_names(task, names) task._devices = device_list(task) task._sf = dbi(gains)[..., np.newaxis] task._fs = properties['sample clock rate'] properties = get_timing_config(task) log_ai.info('AI timing properties: %r', properties) return task