def CCDTrig_open(freq, data): taskHandle = tp.TaskHandle() taskCounter = tp.TaskHandle() nsamples = len(data) idata = data.astype(tp.uInt32) startdata = N.array((5,5),dtype=tp.uInt32) try: daq.DAQmxCreateTask("",taskCounter) daq.DAQmxCreateCOPulseChanFreq(taskCounter,"Dev1/ctr0","",daq.DAQmx_Val_Hz,daq.DAQmx_Val_Low,0.0,freq,0.50) daq.DAQmxCfgImplicitTiming(taskCounter,daq.DAQmx_Val_ContSamps,1000) # print "taskCounter Value", taskCounter.value ## Create Digital Channel daq.DAQmxCreateTask("",taskHandle) # print "taskHandle Value", taskHandle.value daq.DAQmxCreateDOChan(taskHandle,"Dev1/port0/line0:7","",daq.DAQmx_Val_ChanForAllLines) daq.DAQmxCfgSampClkTiming(taskHandle,"Ctr0InternalOutput",freq,daq.DAQmx_Val_Rising,daq.DAQmx_Val_FiniteSamps,nsamples) ## Register done events (error checking) # q = daq.DAQmxRegisterDoneEvent(taskHandle,0,None,None) # print q,'c' # q = daq.DAQmxRegisterDoneEvent(taskCounter,0,None,None) # print q,'d' ## write startup values daq.DAQmxWriteDigitalU32(taskHandle,2,0,10.0,cnst.DAQmx_Val_GroupByChannel,startdata,None,None) daq.DAQmxStartTask(taskHandle) daq.DAQmxStopTask(taskHandle) ## load trigger sequence daq.DAQmxWriteDigitalU32(taskHandle,nsamples,0,10.0,cnst.DAQmx_Val_GroupByChannel,idata,None,None) print("Data Written\n") ## start counter daq.DAQmxStartTask(taskCounter) return taskHandle,taskCounter except: errBuff=tp.create_string_buffer(b"",2048) daq.DAQmxGetExtendedErrorInfo(errBuff,2048) print(errBuff.value)
def set_up_line(self, length=100): """ Sets up the analoque output for scanning a line. @param int length: length of the line in pixel @return int: error code (0:OK, -1:error) """ self._line_length = length if length < np.inf: daq.DAQmxCfgSampClkTiming(self._scanner_ao_task, # set up sample clock for task timing self._my_scanner_clock_channel+'InternalOutput', # use these pulses as clock self._scanner_clock_frequency, # maximum expected clock frequency daq.DAQmx_Val_Falling, daq.DAQmx_Val_FiniteSamps, # generate sample on falling edge, generate finite number of samples self._line_length) # samples to generate # set timing for scanner pulse and count task. daq.DAQmxCfgImplicitTiming(self._scanner_counter_daq_task, daq.DAQmx_Val_FiniteSamps, self._line_length+1) # read samples from beginning of acquisition, do not overwrite daq.DAQmxSetReadRelativeTo(self._scanner_counter_daq_task, daq.DAQmx_Val_CurrReadPos) # do not read first sample daq.DAQmxSetReadOffset(self._scanner_counter_daq_task, 1) daq.DAQmxSetReadOverWrite(self._scanner_counter_daq_task, daq.DAQmx_Val_DoNotOverwriteUnreadSamps) return 0
def __init__(self, period=.1, duty_cycle=0.5, counter="Dev1/ctr0", reset=False): if reset: daq.DAQmxResetDevice(counter.split('/')[0]) taskHandle = daq.TaskHandle() daq.DAQmxCreateTask("", daq.byref(taskHandle)) daq.DAQmxCreateCOPulseChanFreq(taskHandle, counter, "", daq.DAQmx_Val_Hz, daq.DAQmx_Val_Low, 0.0, 1 / float(period), duty_cycle) daq.DAQmxCfgImplicitTiming(taskHandle, daq.DAQmx_Val_ContSamps, 1000) self.taskHandle = taskHandle
def setup_hw_di(fs, lines, callback, callback_samples, start_trigger=None, clock=None, task_name='hw_di'): ''' M series DAQ cards do not have onboard timing engines for digital IO. Therefore, we have to create one (e.g., using a counter or by using the analog input or output sample clock. ''' task = create_task(task_name) mx.DAQmxCreateDIChan(task, lines, '', mx.DAQmx_Val_ChanForAllLines) # Get the current state of the lines so that we know what happened during # the first change detection event. Do this before configuring the timing # of the lines (otherwise we have to start the master clock as well)! mx.DAQmxStartTask(task) initial_state = read_digital_lines(task, 1) mx.DAQmxStopTask(task) # M-series acquisition boards don't have a dedicated engine for digital # acquisition. Use a clock to configure the acquisition. if clock is not None: clock_task = create_task('{}_clock'.format(task_name)) mx.DAQmxCreateCOPulseChanFreq(clock_task, clock, '', mx.DAQmx_Val_Hz, mx.DAQmx_Val_Low, 0, fs, 0.5) mx.DAQmxCfgImplicitTiming(clock_task, mx.DAQmx_Val_ContSamps, int(fs)) clock += 'InternalOutput' if start_trigger: mx.DAQmxCfgDigEdgeStartTrig(clock_task, start_trigger, mx.DAQmx_Val_Rising) setup_timing(task, clock, -1, None) else: setup_timing(task, fs, -1, start_trigger) cb_helper = DigitalSamplesAcquiredCallbackHelper(callback) cb_ptr = mx.DAQmxEveryNSamplesEventCallbackPtr(cb_helper) mx.DAQmxRegisterEveryNSamplesEvent(task, mx.DAQmx_Val_Acquired_Into_Buffer, int(callback_samples), 0, cb_ptr, None) task._cb_ptr = cb_ptr task._cb_helper = cb_helper task._initial_state = initial_state rate = ctypes.c_double() mx.DAQmxGetSampClkRate(task, rate) mx.DAQmxTaskControl(task, mx.DAQmx_Val_Task_Reserve) mx.DAQmxTaskControl(clock_task, mx.DAQmx_Val_Task_Reserve) return [task, clock_task]
def set_odmr_length(self, length=100): """ Sets up the trigger sequence for the ODMR and the triggered microwave. @param int length: length of microwave sweep in pixel @return int: error code (0:OK, -1:error) """ self._odmr_length = length try: daq.DAQmxCfgImplicitTiming( # define task self._scanner_clock_daq_task, daq.DAQmx_Val_FiniteSamps, self._odmr_length) # + 1) except BaseException: self.log.exception('Error while setting up ODMR counter.') return -1 return 0
def set_up_scanner_clock(self, clock_frequency = None, clock_channel = None): """ Configures the hardware clock of the NiDAQ card to give the timing. @param float clock_frequency: if defined, this sets the frequency of the clock @param string clock_channel: if defined, this is the physical channel of the clock @return int: error code (0:OK, -1:error) """ if self._scanner_clock_daq_task != None: self.logMsg('Another clock is already running, close this one first.', \ msgType='error') return -1 self._scanner_clock_daq_task = daq.TaskHandle() # create handle for task, this task will generate pulse signal for photon counting if clock_frequency != None: self._scanner_clock_frequency = float(clock_frequency) if clock_channel != None: self._scanner_clock_channel = clock_channel daq.DAQmxCreateTask('', daq.byref(self._scanner_clock_daq_task)) # create task for pulse_out, here the parameter self.pulse_out_task has to be passed by reference (passing a pointer) daq.DAQmxCreateCOPulseChanFreq( self._scanner_clock_daq_task, # the task to which to add the channels that this function creates self._scanner_clock_channel, # use this counter; the name to assign to the created channel 'Clock Task', # name to assign to channel (NIDAQ uses by default the physical channel name as the virtual channel name. If name is specified, then you must use the name when you refer to that channel in other NIDAQ functions) daq.DAQmx_Val_Hz, #units daq.DAQmx_Val_Low, #idle state 0, #initial delay self._scanner_clock_frequency / 2., #pulse frequency, divide by 2 such that length of semi period = count_interval 0.5 ) #duty cycle of pulses, 0.5 such that high and low duration are both = count_interval # set timing to continuous, i.e. set only the number of samples to # acquire or generate without specifying timing daq.DAQmxCfgImplicitTiming( self._scanner_clock_daq_task, #define task daq.DAQmx_Val_ContSamps, #continuous running 1000) #buffer length daq.DAQmxStartTask(self._scanner_clock_daq_task) return 0
def setup_hw_di(fs, lines, callback, callback_samples, clock=None): ''' M series DAQ cards do not have onboard timing engines for digital IO. Therefore, we have to create one (e.g., using a counter or by using the analog input or output sample clock. ''' task = create_task() mx.DAQmxCreateDIChan(task, lines, '', mx.DAQmx_Val_ChanForAllLines) # Get the current state of the lines so that we know what happened during # the first change detection event. Do this before configuring the timing # of the lines (otherwise we have to start the master clock as well)! mx.DAQmxStartTask(task) initial_state = read_digital_lines(task, 1) mx.DAQmxStopTask(task) if clock is None: clock = '' if 'Ctr' in clock: clock_task = create_task() mx.DAQmxCreateCOPulseChanFreq(clock_task, clock, '', mx.DAQmx_Val_Hz, mx.DAQmx_Val_Low, 0, fs, 0.5) mx.DAQmxCfgImplicitTiming(clock_task, mx.DAQmx_Val_ContSamps, int(fs)) clock += 'InternalOutput' else: clock_task = None mx.DAQmxCfgSampClkTiming(task, clock, fs, mx.DAQmx_Val_Rising, mx.DAQmx_Val_ContSamps, int(fs)) callback_helper = DigitalSamplesAcquiredCallbackHelper(callback) 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 task._initial_state = initial_state return [task, clock_task]
def set_up_clock(self, clock_frequency=None, clock_channel=None, scanner=False, idle=False, delay=2.0): """ Configures the hardware clock of the NiDAQ card to give the timing. @param float clock_frequency: if defined, this sets the frequency of the clock in Hz @param string clock_channel: if defined, this is the physical channel of the clock within the NI card. @param bool scanner: if set to True method will set up a clock function for the scanner, otherwise a clock function for a counter will be set. @param bool idle: set whether idle situation of the counter (where counter is doing nothing) is defined as True = 'Voltage High/Rising Edge' False = 'Voltage Low/Falling Edge' @return int: error code (0:OK, -1:error) """ if not scanner and self._clock_daq_task is not None: self.log.error( 'Another counter clock is already running, close this one first.' ) return -1 if scanner and self._scanner_clock_daq_task is not None: self.log.error( 'Another scanner clock is already running, close this one first.' ) return -1 # Create handle for task, this task will generate pulse signal for # photon counting my_clock_daq_task = daq.TaskHandle() smiq = daq.TaskHandle() switch = daq.TaskHandle() cam = daq.TaskHandle() # assign the clock frequency, if given if clock_frequency is not None: if not scanner: self._clock_frequency = float(clock_frequency) else: self._scanner_clock_frequency = float(clock_frequency) self._smiq_clock_frequency = float(clock_frequency) / 2. self._switch_clock_frequency = float(clock_frequency) / 2. self._cam_clock_frequency = float(clock_frequency) else: if not scanner: self._clock_frequency = self._default_clock_frequency else: self._scanner_clock_frequency = self._default_scanner_clock_frequency # use the correct clock in this method if scanner: my_clock_frequency = self._scanner_clock_frequency * 2 else: my_clock_frequency = self._clock_frequency * 2 # assign the clock channel, if given if clock_channel is not None: if not scanner: self._clock_channel = clock_channel else: self._scanner_clock_channel = clock_channel # use the correct clock channel in this method if scanner: my_clock_channel = self._scanner_clock_channel self._smiq_channel = self._smiq_channel self._switch_channel = self._switch_channel self._cam_channel = self._cam_channel else: my_clock_channel = self._clock_channel # check whether only one clock pair is available, since some NI cards # only one clock channel pair. if self._scanner_clock_channel == self._clock_channel: if not ((self._clock_daq_task is None) and (self._scanner_clock_daq_task is None)): self.log.error( 'Only one clock channel is available!\n' 'Another clock is already running, close this one first ' 'in order to use it for your purpose!') return -1 if self.pseudo_pulsed: self.clock_duty = self.duty_value / ( 1 / self._scanner_clock_frequency) / 2 self.switch_duty = self.duty_value / ( 1 / self._switch_clock_frequency) / 2 self.switch_delay = 0 else: self.clock_duty = 0.9998 self.switch_duty = 0.5 self.switch_delay = 0 # Adjust the idle state if necessary my_idle = daq.DAQmx_Val_High if idle else daq.DAQmx_Val_Low try: # create task for clock task_name = 'ScannerClock' if scanner else 'CounterClock' daq.DAQmxCreateTask(task_name, daq.byref(my_clock_daq_task)) # create a digital clock channel with specific clock frequency: daq.DAQmxCreateCOPulseChanFreq( # The task to which to add the channels my_clock_daq_task, # which channel is used? my_clock_channel, # Name to assign to task (NIDAQ uses by # default the physical channel name as # the virtual channel name. If name is specified, then you must use the name # when you refer to that channel in other NIDAQ functions) 'Clock Producer', # units, Hertz in our case daq.DAQmx_Val_Hz, # idle state my_idle, # initial delay delay, my_clock_frequency / 2, self.clock_duty) daq.DAQmxCfgImplicitTiming( # Define task my_clock_daq_task, daq.DAQmx_Val_ContSamps, # buffer length which stores temporarily the number of # generated samples 1000) ############################## # Configure SMIQ trigger clock ############################## duty_cycle = 0.1 d = 0 daq.DAQmxCreateTask('mySmiqTask', daq.byref(smiq)) # Create channel to generate digital pulses that freq and dutyCycle # define and adds the channel to the task daq.DAQmxCreateCOPulseChanFreq( smiq, self. _smiq_channel, # The name of the counter to use to create virtual channels "mySmiqChannel", # The name to assign to the created virtual channel daq.DAQmx_Val_Hz, # The units in which to specify freq. daq.DAQmx_Val_Low, # The resting state of the output terminal. d, # The amount of time in seconds to wait before generating the # first pulse. self._smiq_clock_frequency, # The frequency at which to generate pulses. duty_cycle, # The width of the pulse divided by the pulse period. ) j = 1000 # # Sets only the number of samples to acquire or generate without specifying timing. daq.DAQmxCfgImplicitTiming( smiq, # daq.DAQmx_Val_ContSamps, daq.DAQmx_Val_ContSamps, # Acquire or generate samples until you stop the task. j # the buffer size ) daq.DAQmxCfgDigEdgeStartTrig(smiq, my_clock_channel + 'InternalOutput', daq.DAQmx_Val_Rising) ############################## # Configure switch trigger clock ############################## duty_cycle = 0.5 d = 0 daq.DAQmxCreateTask('mySwitchTask', daq.byref(switch)) # Create channel to generate digital pulses that freq and dutyCycle # define and adds the channel to the task daq.DAQmxCreateCOPulseChanFreq( switch, self. _switch_channel, # The name of the counter to use to create virtual channels "mySwitchChannel", # The name to assign to the created virtual channel daq.DAQmx_Val_Hz, # The units in which to specify freq. daq.DAQmx_Val_High, # The resting state of the output terminal. self.switch_delay, # The amount of time in seconds to wait before generating the # first pulse. self._switch_clock_frequency, # The frequency at which to generate pulses. self.switch_duty, # The width of the pulse divided by the pulse period. ) j = 1000 # # Sets only the number of samples to acquire or generate without specifying timing. daq.DAQmxCfgImplicitTiming( switch, # daq.DAQmx_Val_ContSamps, daq.DAQmx_Val_ContSamps, # Acquire or generate samples until you stop the task. j # the buffer size ) daq.DAQmxCfgDigEdgeStartTrig(switch, my_clock_channel + 'InternalOutput', daq.DAQmx_Val_Rising) ############################## # Configure cam trigger clock ############################## duty_cycle = 0.1 d = (1. / self._cam_clock_frequency) / 4. d = 0 daq.DAQmxCreateTask('myCamTask', daq.byref(cam)) # Create channel to generate digital pulses that freq and dutyCycle # define and adds the channel to the task daq.DAQmxCreateCOPulseChanFreq( cam, self. _cam_channel, # The name of the counter to use to create virtual channels "myCamChannel", # The name to assign to the created virtual channel daq.DAQmx_Val_Hz, # The units in which to specify freq. daq.DAQmx_Val_Low, # The resting state of the output terminal. d, # The amount of time in seconds to wait before generating the # first pulse. self._cam_clock_frequency, # The frequency at which to generate pulses. duty_cycle, # The width of the pulse divided by the pulse period. ) j = 1000 # # Sets only the number of samples to acquire or generate without specifying timing. daq.DAQmxCfgImplicitTiming( cam, # daq.DAQmx_Val_ContSamps, daq.DAQmx_Val_ContSamps, # Acquire or generate samples until you stop the task. j # the buffer size ) daq.DAQmxCfgDigEdgeStartTrig(cam, my_clock_channel + 'InternalOutput', daq.DAQmx_Val_Rising) if scanner: self._scanner_clock_daq_task = my_clock_daq_task # Added the daq tasks to class variables self._smiq_clock_daq_task = smiq self._switch_clock_daq_task = switch self._cam_clock_daq_task = cam else: # actually start the preconfigured clock task daq.DAQmxStartTask(my_clock_daq_task) self._clock_daq_task = my_clock_daq_task except BaseException: self.log.exception('Error while setting up clock.') return -1 return 0
def create_task(self): # need to check if task exists and fail #self.task = PyDAQmx.Task() self.task_handle = mx.TaskHandle(0) mx.DAQmxCreateTask("", byref(self.task_handle)) if self.mode == 'large_range': logger.debug('counter_chan {}'.format(self.counter_chan)) logger.debug('input_terminal {}'.format(self.input_terminal)) mx.DAQmxCreateCIFreqChan( self.task_handle, counter=str(self.counter_chan), nameToAssignToChannel="", minVal=5e1, # applies measMethod is DAQmx_Val_LargeRng2Ctr maxVal=1e8, # applies measMethod is DAQmx_Val_LargeRng2Ctr units=DAQmx_Val_Hz, edge=DAQmx_Val_Rising, measMethod=DAQmx_Val_LargeRng2Ctr, measTime=1.0, # applies measMethod is DAQmx_Val_HighFreq2Ctr divisor=100, # applies measMethod is DAQmx_Val_LargeRng2Ctr customScaleName=None, ) elif self.mode == 'high_freq': mx.DAQmxCreateCIFreqChan( self.task_handle, counter=self.counter_chan, nameToAssignToChannel="", minVal=1e1, # applies measMethod is DAQmx_Val_LargeRng2Ctr maxVal=1e7, # applies measMethod is DAQmx_Val_LargeRng2Ctr units=DAQmx_Val_Hz, edge=DAQmx_Val_Rising, measMethod=DAQmx_Val_HighFreq2Ctr, measTime=0.05, # applies measMethod is DAQmx_Val_HighFreq2Ctr divisor=100, # applies measMethod is DAQmx_Val_LargeRng2Ctr customScaleName=None, ) elif self.mode == 'low_freq': mx.DAQmxCreateCIFreqChan( self.task_handle, counter=self.counter_chan, nameToAssignToChannel="", minVal=1e1, # applies measMethod is DAQmx_Val_LargeRng2Ctr maxVal=1e7, # applies measMethod is DAQmx_Val_LargeRng2Ctr units=DAQmx_Val_Hz, edge=DAQmx_Val_Rising, measMethod=DAQmx_Val_LowFreq1Ctr, measTime=0.05, # applies measMethod is DAQmx_Val_HighFreq2Ctr divisor=100, # applies measMethod is DAQmx_Val_LargeRng2Ctr customScaleName=None, ) ### data = c_int32(0) ### self.task.GetCIDataXferMech(channel=self.counter_chan, data=data ) ### print "XFmethod" , data.value # set DMA #self.task.SetCIDataXferMech(channel=self.counter_chan, data=DAQmx_Val_DMA) ### self.task.GetReadOverWrite(data=byref(data)) ### print "overwrite", data.value #Set the input terminal of the counter mx.DAQmxSetCIFreqTerm(self.task_handle, channel=self.counter_chan, data=self.input_terminal) #Set the counter channel to continuously sample into a buffer. The size of the #buffer is set by sampsPerChan. mx.DAQmxCfgImplicitTiming(self.task_handle, sampleMode=DAQmx_Val_ContSamps, sampsPerChan=1000) mx.DAQmxSetReadOverWrite(self.task_handle, DAQmx_Val_OverwriteUnreadSamps) ### self.task.GetReadOverWrite(data=byref(data)) ### print "overwrite", data.value # Sample buffer self._sample_buffer_count = c_int32(0) self.sample_buffer = np.zeros((SAMPLE_BUFFER_SIZE, ), dtype=np.float64)
def set_up_counter(self, counter_channel = None, photon_source = None, clock_channel = None): """ Configures the actual counter with a given clock. @param string counter_channel: if defined, this is the physical channel of the counter @param string photon_source: if defined, this is the physical channel where the photons are to count from @param string clock_channel: if defined, this specifies the clock for the counter @return int: error code (0:OK, -1:error) """ if self._clock_daq_task == None and clock_channel == None: self.logMsg('No clock running, call set_up_clock before starting the counter.', \ msgType='error') return -1 if self._counter_daq_task != None: self.logMsg('Another counter is already running, close this one first.', \ msgType='error') return -1 self._counter_daq_task = daq.TaskHandle() # this task will count photons with binning defined by pulse_out_task if counter_channel != None: self._counter_channel = counter_channel if photon_source != None: self._photon_source = photon_source if clock_channel != None: my_clock_channel = clock_channel else: my_clock_channel = self._clock_channel daq.DAQmxCreateTask('', daq.byref(self._counter_daq_task)) # create task for counter_in, here the parameter self.counter_in_task has to be passed by reference (passing a pointer) # set up semi period width measurement in photon ticks, i.e. the width # of each pulse (high and low) generated by pulse_out_task is measured # in photon ticks. # (this task creates a channel to measure the time between state # transitions of a digital signal and adds the channel to the task # you choose) daq.DAQmxCreateCISemiPeriodChan(self._counter_daq_task, # The task to which to add the channels that this function creates self._counter_channel, # use this counter; the name to assign to the created channel 'Counting Task', #name 0, #expected minimum value self._max_counts/2./self._clock_frequency, #expected maximum value daq.DAQmx_Val_Ticks, #units of width measurement, here photon ticks '') # set the pulses to counter self._trace_counter_in daq.DAQmxSetCISemiPeriodTerm( self._counter_daq_task, self._counter_channel, my_clock_channel+'InternalOutput') # set the timebase for width measurement as self._photon_source daq.DAQmxSetCICtrTimebaseSrc( self._counter_daq_task, self._counter_channel, self._photon_source ) daq.DAQmxCfgImplicitTiming( self._counter_daq_task, daq.DAQmx_Val_ContSamps, 1000) # read most recent samples daq.DAQmxSetReadRelativeTo(self._counter_daq_task, daq.DAQmx_Val_CurrReadPos) daq.DAQmxSetReadOffset(self._counter_daq_task, 0) #unread data in buffer will be overwritten daq.DAQmxSetReadOverWrite(self._counter_daq_task, daq.DAQmx_Val_DoNotOverwriteUnreadSamps) daq.DAQmxStartTask(self._counter_daq_task) return 0