def getSampleMode(self): sampleMode = c_int(0) daqmx(dll.DAQmxGetSampQuantSampMode, (self.handle, byref(sampleMode))) return { constants['DAQmx_Val_FiniteSamps']: self.FINITE, constants['DAQmx_Val_ContSamps']: self.CONTINUOUS }
def getSamplingRate(self): """ get sampling rate in Hz """ samplingRate = c_double(0) daqmx(dll.DAQmxGetSampClkRate, (self.handle, byref(samplingRate))) return samplingRate.value
def createChannel(self, channelDict): """ create new DAQmx virtual channel @param channelDict: keys should be those members of L{AITask.PARAMETERS} and only AITask.PHYSICAL_CHANNEL is required. consult DAQmx C documentation for further information. @type channelDict: dictionary """ physical_channel = channelDict[self.PHYSICAL_CHANNEL] name = channelDict.get(self.NAME, None) trmcfg_keys, trmcfg_vals, _ = zip(*self.TERMINAL_CONFIGS) terminal_config = trmcfg_vals[trmcfg_keys.index( channelDict.get(self.TERMINAL_CONFIG, self.TERM_DEFAULT))] vrng_keys, vrng_vals = zip(*self.VOLTAGE_RANGES) voltage_range = vrng_vals[vrng_keys.index( channelDict.get(self.VOLTAGE_RANGE, self.V10))] daqmx(dll.DAQmxCreateAIVoltageChan, (self.handle, channelDict[self.PHYSICAL_CHANNEL], name, terminal_config, c_double(-1. * voltage_range), c_double(voltage_range), constants['DAQmx_Val_Volts'], None)) if self.DESCRIPTION in channelDict: self.setChannelDescription( channelDict.get(self.NAME, channelDict[self.PHYSICAL_CHANNEL]), channelDict[self.DESCRIPTION])
def start(self): daqmx( dll.DAQmxStartTask, ( self.handle, ) )
def createChannel(self, physicalChannel, name=None, initialCount=0, polarity='external', edge='rising'): deviceName = physicalChannel.split('/')[0] if not deviceName: deviceName = physicalChannel.split('/')[ 1] #avoid leading slash if user included it size = c_uint32(0) daqmx(dll.DAQmxGetDevCIMaxSize, (deviceName, byref(size))) self.size = size.value if self.size != 32: self.offset = initialCount initialCount = 0 polarities = { 'up': constants['DAQmx_Val_CountUp'], 'down': constants['DAQmx_Val_CountDown'], 'external': constants['DAQmx_Val_ExtControlled'] } edges = { 'rising': constants['DAQmx_Val_Rising'], 'falling': constants['DAQmx_Val_Falling'], } daqmx(dll.DAQmxCreateCICountEdgesChan, (self.handle, physicalChannel, name, edges[edge], initialCount, polarities[polarity]))
def start_counting(self): daqmx( dll.DAQmxStartTask, ( self.handle, ) )
def unset_trigger(self): daqmx( dll.DAQmxDisableStartTrig, ( self.handle, ) )
def readSamples(self): bufSize = c_uint32(0) daqmx( dll.DAQmxGetBufInputBufSize, ( self.handle, byref(bufSize) ) ) bufSize = bufSize.value samples = numpy.zeros(bufSize) samplesRead = c_int(0) daqmx( dll.DAQmxReadAnalogF64, ( self.handle, constants['DAQmx_Val_Auto'], c_double(TIMEOUT), constants['DAQmx_Val_GroupByChannel'], samples.ctypes.data_as(POINTER(c_double)), bufSize, byref(samplesRead), None ) ) samplesRead = samplesRead.value channels = self.getChannels() byChannel = numpy.reshape(samples[:len(channels) * samplesRead],(len(channels),samplesRead)) return {channel: data for channel, data in zip(channels,byChannel)}
def stop(self): daqmx( dll.DAQmxStopTask, ( self.handle, ) )
def set_sampling_rate(self,sampling_rate): daqmx( dll.DAQmxSetSampClkRate, ( self.handle, c_double(sampling_rate) ) )
def stop_counting(self): self.count = self._get_count() daqmx( dll.DAQmxStopTask, ( self.handle, ) )
def commitTask(self): daqmx( dll.DAQmxTaskControl, ( self.handle, constants['DAQmx_Val_Task_Commit'] ) )
def startSampling(self): self.busy = True AITask.startSampling(self) daqmx(dll.DAQmxWaitUntilTaskDone, (self.handle, c_double(constants['DAQmx_Val_WaitInfinitely']))) while self.busy: continue return self.samples
def clearTask(self): daqmx( dll.DAQmxClearTask, ( self.handle, ) ) self.removeTaskName(self.name)
def createChannel(self, physicalChannel, name=None, minVal=0.0, maxVal=10.0): daqmx(dll.DAQmxCreateAOVoltageChan, (self.handle, physicalChannel, name, c_double(minVal), c_double(maxVal), constants['DAQmx_Val_Volts'], None))
def set_sample_quantity(self,sample_quantity): daqmx( dll.DAQmxSetSampQuantSampPerChan, ( self.handle, c_uint64(sample_quantity) # !!! ) )
def setChannelPhysicalChannel(self,channel,physicalChannel): daqmx( dll.DAQmxSetPhysicalChanName, ( self.handle, channel, physicalChannel, ) )
def writeState(self, state): daqmx( dll.DAQmxWriteDigitalScalarU32, ( self.handle, True, c_double(TIMEOUT), int(state) * 2**self.exponent, ##HACK None))
def setChannelDescription(self,channel,description): daqmx( dll.DAQmxSetChanDescr, ( self.handle, channel, str(description), ) )
def getChannels(self): """ get list of channels belonging to this task @returns: list of virtual channel identifiers """ channels = create_string_buffer(BUF_SIZE) daqmx(dll.DAQmxGetTaskChannels, (self.handle, channels, BUF_SIZE)) return parseStringList(channels.value)
def getSamplesPerChannel(self): """ Get the number of samples per channel delivered to the callback """ samplesPerChannel = c_uint64(0) daqmx(dll.DAQmxGetSampQuantSampPerChan, (self.handle, byref(samplesPerChannel))) return samplesPerChannel.value
def readCounts(self): counts = c_int32(0) daqmx(dll.DAQmxReadCounterScalarU32, (self.handle, c_double(TIMEOUT), byref(counts), None)) if self.getSize() == 32: return c_int32(counts.value).value else: adjustedVal = self.twos_comp(counts.value, self.getSize()) + self.offset return adjustedVal
def is_triggering(self): trigger_type = c_int32(0) daqmx( dll.DAQmxGetStartTrigType, ( self.handle, byref(trigger_type) ) ) return trigger_type.value == constants['DAQmx_Val_DigEdge']
def get_sample_quantity(self): sample_quantity = c_uint64(0) daqmx( dll.DAQmxGetSampQuantSampPerChan, ( self.handle, byref(sample_quantity) ) ) return sample_quantity.value
def _setSamplesPerChannel(self,samplesPerChannel): daqmx( dll.DAQmxSetSampQuantSampPerChan, ( self.handle, c_uint64( samplesPerChannel ) ) )
def get_sampling_rate(self): sampling_rate = c_double(0) daqmx( dll.DAQmxGetSampClkRate, ( self.handle, byref(sampling_rate) ) ) return sampling_rate.value
def get_max_sampling_rate(self): max_sampling_rate = c_double(0.) daqmx( dll.DAQmxGetSampClkMaxRate, ( self.handle, byref(max_sampling_rate) ) ) return max_sampling_rate.value
def write_sample( self, sample ): daqmx( dll.DAQmxWriteAnalogScalarF64, ( self.handle, True, c_double(TIMEOUT), c_double(sample), None ) )
def get_max(self): max_value = c_double(0) daqmx( dll.DAQmxGetAOMax, ( self.handle, self.get_channels()[0], byref(max_value) ) ) return max_value.value
def get_trigger_source(self): source = create_string_buffer(BUF_SIZE) daqmx( dll.DAQmxGetDigEdgeStartTrigSrc, ( self.handle, source, BUF_SIZE ) ) return source.value
def startSampling(self): """ start a new acquisition """ if self.acquiring: raise SitzException( 'startSampling requested with task already acquiring') self.acquiring = True daqmx(dll.DAQmxStartTask, (self.handle, ))
def get_min(self): min_value = c_double(0) daqmx( dll.DAQmxGetAOMin, ( self.handle, self.get_channels()[0], byref(min_value) ) ) return min_value.value
def _configureTiming(self, highTime, lowTime): daqmx(dll.DAQmxSetCOPulseHighTime, ( self.handle, None, c_double(highTime), )) daqmx(dll.DAQmxSetCOPulseLowTime, ( self.handle, None, c_double(lowTime), ))
def __init__(self,name): Task.__init__(self,name) daqmx( dll.DAQmxCfgImplicitTiming, ( self.handle, constants['DAQmx_Val_FiniteSamps'], c_uint64(200) ) ) self.stopped = False
def writeVoltage( self, voltage ): daqmx( dll.DAQmxWriteAnalogScalarF64, ( self.handle, True, c_double(TIMEOUT), c_double(voltage), None ) )
def write_state( self, state ): daqmx( dll.DAQmxWriteDigitalScalarU32, ( self.handle, True, c_double(TIMEOUT), int(state) * 2 ** self.exponent, None ) )
def createChannel( self, physicalChannel, name=None ): daqmx( dll.DAQmxCreateDIChan, ( self.handle, physicalChannel, name, constants['DAQmx_Val_ChanForAllLines'] ) ) self.exponent = int(physicalChannel.split('line')[-1]) ##HACK
def startSampling(self): self.busy = True AITask.startSampling(self) daqmx( dll.DAQmxWaitUntilTaskDone, ( self.handle, c_double(constants['DAQmx_Val_WaitInfinitely']) ) ) while self.busy: continue return self.samples
def createChannel(self,channelDict): """ create new DAQmx virtual channel @param channelDict: keys should be those members of L{AITask.PARAMETERS} and only AITask.PHYSICAL_CHANNEL is required. consult DAQmx C documentation for further information. @type channelDict: dictionary """ physical_channel = channelDict[self.PHYSICAL_CHANNEL] name = channelDict.get(self.NAME,None) trmcfg_keys, trmcfg_vals, _ = zip(*self.TERMINAL_CONFIGS) terminal_config = trmcfg_vals[ trmcfg_keys.index( channelDict.get( self.TERMINAL_CONFIG, self.TERM_DEFAULT ) ) ] vrng_keys, vrng_vals = zip(*self.VOLTAGE_RANGES) voltage_range = vrng_vals[ vrng_keys.index( channelDict.get( self.VOLTAGE_RANGE, self.V10 ) ) ] daqmx( dll.DAQmxCreateAIVoltageChan, ( self.handle, channelDict[self.PHYSICAL_CHANNEL], name, terminal_config, c_double(-1. * voltage_range), c_double(voltage_range), constants['DAQmx_Val_Volts'], None ) ) if self.DESCRIPTION in channelDict: self.setChannelDescription( channelDict.get(self.NAME,channelDict[self.PHYSICAL_CHANNEL]), channelDict[self.DESCRIPTION] )
def setSamplingRate(self,samplingRate): """ set sampling rate in Hz """ daqmx( dll.DAQmxSetSampClkRate, ( self.handle, c_double(samplingRate) ) ) self.setCallbackRate(self.getCallbackRate())
def getChannelDescription(self,channel): description = ( c_char * BUF_SIZE )() daqmx( dll.DAQmxGetChanDescr, ( self.handle, channel, description, BUF_SIZE ) ) return description.value
def getChannelPhysicalChannel(self,channel): physicalChannel = create_string_buffer(BUF_SIZE) daqmx( dll.DAQmxGetPhysicalChanName, ( self.handle, channel, physicalChannel, BUF_SIZE ) ) return physicalChannel.value
def stopSampling(self): """ halt sample acquisition if task is running. @raise SitzException: stop requested when task already stopped """ if not self.acquiring: raise SitzException( 'stopSampling requested when task was not sampling') daqmx(dll.DAQmxStopTask, (self.handle, )) self.acquiring = False
def setChannelVoltageRange(self, channel, voltage_range): vrng_keys, vrng_vals = zip(*self.VOLTAGE_RANGES) max = vrng_vals[vrng_keys.index(voltage_range)] min = -1. * max daqmx(dll.DAQmxSetAIMax, ( self.handle, channel, c_double(max), )) daqmx(dll.DAQmxSetAIMin, ( self.handle, channel, c_double(min), ))
def createChannel(self, physicalChannel, name=None, highTime=.01, lowTime=.01, idleState='low', initialDelay=0): idleStates = { 'high': constants['DAQmx_Val_High'], 'low': constants['DAQmx_Val_Low'] } daqmx(dll.DAQmxCreateCOPulseChanTime, (self.handle, physicalChannel, name, constants['DAQmx_Val_Seconds'], idleStates[idleState], c_double(initialDelay), c_double(lowTime), c_double(highTime)))
def getTimingConfiguration(self): highTime = c_double(0.0) lowTime = c_double(0.0) # only look at first channel daqmx(dll.DAQmxGetCOPulseHighTime, ( self.handle, None, byref(highTime), )) daqmx(dll.DAQmxGetCOPulseLowTime, ( self.handle, None, byref(lowTime), )) return highTime.value, lowTime.value
def readSamples(self): bufSize = c_uint32(0) daqmx(dll.DAQmxGetBufInputBufSize, (self.handle, byref(bufSize))) bufSize = bufSize.value samples = numpy.zeros(bufSize) samplesRead = c_int(0) daqmx(dll.DAQmxReadAnalogF64, (self.handle, constants['DAQmx_Val_Auto'], c_double(TIMEOUT), constants['DAQmx_Val_GroupByChannel'], samples.ctypes.data_as( POINTER(c_double)), bufSize, byref(samplesRead), None)) samplesRead = samplesRead.value channels = self.getChannels() byChannel = numpy.reshape(samples[:len(channels) * samplesRead], (len(channels), samplesRead)) return {channel: data for channel, data in zip(channels, byChannel)}
def __init__(self, name=None): """ create a daqmx task object @param name: task identifier. must be unique. If omitted a unique id will be generated. @type name: string """ if name is None: name = self.generateUniqueTaskName() self._task_names.append(name) self.name = name handle = c_int(0) daqmx(dll.DAQmxCreateTask, (name, byref(handle))) self.handle = handle.value
def _generatePulses(self, numPulses, callback): # I DONT KNOW WHAT "THREAD SAFE" IS, BUT I WOULD BET THIS ISN'T THAT. # A GOOD USE FOR THIS WOULD BE TO LET THE CALLBACK JUST FIRE A DEFERRED # THAT'S WHAT I'M GONNA DO def _callback(handle, status, callbackData): daqmx(dll.DAQmxStopTask, (self.handle, )) # before anyone can access pulser, do the following : # -> set busy to False, to let the first hook know pulser is free # -> get list of currently scheduled hooks # -> execute them in order received # -> -> one hook may busy the pulser, leading subsequent hooks attempts to queue # -> if pulser still free after hooks, execute callback, otherwise queue with self.lock: self.busy = False hooks = copy(self._hooks) self._hooks = [] for hook in hooks: hook() if self.busy: self._hooks.append(callback) else: callback() return 0 DAQmxDoneEventCallbackPtr = CFUNCTYPE(c_int, c_void_p, c_int, c_void_p) c_callback = DAQmxDoneEventCallbackPtr(_callback) self.c_callback = c_callback daqmx( dll.DAQmxRegisterDoneEvent, ( self.handle, 0, #executed in thread None, None)) if numPulses is not None: daqmx( dll.DAQmxRegisterDoneEvent, ( self.handle, 0, #executed in thread self.c_callback, None)) daqmx( dll.DAQmxCfgImplicitTiming, (self.handle, constants['DAQmx_Val_ContSamps' if numPulses is None else 'DAQmx_Val_FiniteSamps'], c_uint64(0 if numPulses is None else numPulses))) self.busy = True daqmx(dll.DAQmxStartTask, (self.handle, ))
def _callback(handle, status, callbackData): daqmx(dll.DAQmxStopTask, (self.handle, )) # before anyone can access pulser, do the following : # -> set busy to False, to let the first hook know pulser is free # -> get list of currently scheduled hooks # -> execute them in order received # -> -> one hook may busy the pulser, leading subsequent hooks attempts to queue # -> if pulser still free after hooks, execute callback, otherwise queue with self.lock: self.busy = False hooks = copy(self._hooks) self._hooks = [] for hook in hooks: hook() if self.busy: self._hooks.append(callback) else: callback() return 0
def configureExternalTrigger(self, trigSrc, trigEdge=RISING): """ configure task to begin acquisition on external trigger @param trigSrc: physical channel of trigger source @type trigSrc: string @param trigEdge: waveform edge to trigger on @type trigEdge: AITask.RISING, AITask.FALLING """ trigEdgeTypes = { self.RISING: constants[ 'DAQmx_Val_Rising'], # look up the DAQmx constant code for the rising edge. see daqmx\daqmxconstants* self.FALLING: constants[ 'DAQmx_Val_Falling'], # look up the DAQmx constant code for the fall edge. } daqmx(dll.DAQmxCfgDigEdgeStartTrig, (self.handle, trigSrc, trigEdgeTypes[trigEdge]))
def __init__(self, channelDicts=None): """ create an analog input task @param channelDicts: tuple of dictionaries that can be unpacked into the L{createChannel} method (e.g. C{({AITask.PHYSICAL_CHANNEL:'dev0/ai1',...},...)}) """ Task.__init__(self) if channelDicts is None: channelDicts = tuple([]) self.callback = None self.acquiring = False def callback(handle, eType, samples, callbackData): samples = self.readSamples() self.stopSampling() if self.callback is not None: self.callback(samples) return 0 DAQmxDoneEventCallbackPtr = CFUNCTYPE(c_int, c_void_p, c_int, c_uint32, c_void_p) c_callback = DAQmxDoneEventCallbackPtr(callback) self.c_callback = c_callback daqmx(dll.DAQmxRegisterDoneEvent, (self.handle, 0, self.c_callback, None)) for channelDict in channelDicts: self.createChannel(channelDict) daqmx(dll.DAQmxSetSampTimingType, (self.handle, constants['DAQmx_Val_SampClk'])) daqmx(dll.DAQmxSetSampQuantSampMode, (self.handle, constants['DAQmx_Val_FiniteSamps'])) sampClkMaxRate = c_double() daqmx(dll.DAQmxGetSampClkMaxRate, (self.handle, byref(sampClkMaxRate))) daqmx(dll.DAQmxSetSampClkRate, (self.handle, sampClkMaxRate))
def stop(self): daqmx(dll.DAQmxStopTask, (self.handle, ))
def getChannelVoltageRange(self, channel): max = c_double() daqmx(dll.DAQmxGetAIMax, (self.handle, channel, byref(max))) vrng_keys, vrng_vals = zip(*self.VOLTAGE_RANGES) return vrng_keys[vrng_vals.index(max.value)]
def setChannelPhysicalChannel(self, channel, physicalChannel): daqmx(dll.DAQmxSetPhysicalChanName, ( self.handle, channel, physicalChannel, ))
def setChannelDescription(self, channel, description): daqmx(dll.DAQmxSetChanDescr, ( self.handle, channel, str(description), ))
def start(self): daqmx(dll.DAQmxStartTask, (self.handle, ))
def getChannelTerminalConfig(self, channel): terminalConfig = c_int32() daqmx(dll.DAQmxGetAITermCfg, (self.handle, channel, byref(terminalConfig))) return zip(*self.TERMINAL_CONFIGS)[0][zip( *self.TERMINAL_CONFIGS)[1].index(terminalConfig.value)]
def getChannelPhysicalChannel(self, channel): physicalChannel = create_string_buffer(BUF_SIZE) daqmx(dll.DAQmxGetPhysicalChanName, (self.handle, channel, physicalChannel, BUF_SIZE)) return physicalChannel.value
def setChannelTerminalConfig(self, channel, terminalConfig): daqmx(dll.DAQmxSetAITermCfg, (self.handle, channel, zip(*self.TERMINAL_CONFIGS)[1][zip( *self.TERMINAL_CONFIGS)[0].index(terminalConfig)]))