def __init__(self, analog_channels='/Dev1/ao0:2', output_counter='/Dev1/Ctr0', voltage_range=(10,10)): self._analog_channels = analog_channels self._output_counter = output_counter self._voltage_range=voltage_range # we start with default duty cycle self._duty_cycle = 0.5 self._seconds_per_point = 1000. self._transfer_timeout = 1.0 # we start with unknown length self._length = None # create nidaq tasks self._n_written = ctypes.c_long() self._ao_task = ctypes.c_ulong() self._co_task = ctypes.c_ulong() CHK( dll.DAQmxCreateTask('', ctypes.byref(self._ao_task)) ) CHK( dll.DAQmxCreateTask('', ctypes.byref(self._co_task)) ) CHK( dll.DAQmxCreateAOVoltageChan(self._ao_task, self._analog_channels, '', ctypes.c_double(self._voltage_range[0]), ctypes.c_double(self._voltage_range[1]), DAQmx_Val_Volts, '') ) CHK( dll.DAQmxCreateCOPulseChanFreq( self._co_task, self._output_counter, '', DAQmx_Val_Hz, DAQmx_Val_Low, ctypes.c_double(0), ctypes.c_double(self._seconds_per_point), ctypes.c_double(self._duty_cycle) ) )
def set_timing(self, seconds_per_point, duty_cycle=0.5): if seconds_per_point == self._seconds_per_point and duty_cycle == self._duty_cycle: return CHK( dll.DAQmxSetCOPulseFreq( self._co_task, self._output_counter, ctypes.c_double(1./seconds_per_point) ) ) CHK( dll.DAQmxSetCOPulseDutyCyc( self._co_task, self._output_counter, ctypes.c_double(duty_cycle) ) ) self._seconds_per_point = seconds_per_point self._duty_cycle = duty_cycle
def set_length(self, N): if self._length == N: return if N == 1: CHK( dll.DAQmxSetSampTimingType( self._ao_task, DAQmx_Val_OnDemand) ) else: CHK( dll.DAQmxSetSampTimingType( self._ao_task, DAQmx_Val_SampClk) ) CHK( dll.DAQmxCfgSampClkTiming( self._ao_task, self._output_counter+'InternalOutput', ctypes.c_double(1./self._seconds_per_point), DAQmx_Val_Rising, DAQmx_Val_FiniteSamps, ctypes.c_ulonglong(N)) ) CHK( dll.DAQmxCfgImplicitTiming( self._co_task, DAQmx_Val_FiniteSamps, ctypes.c_ulonglong(N+1)) ) self._length = N
def set_output(self, data): """If len(data)==1, output one point. Else output sequence of points. The shape of data is (n_channels,n_points).""" if data.ndim == 1: N = 1 else: N = data.shape[1] self.set_length(N) if N == 1: CHK( dll.DAQmxWriteAnalogF64( self._ao_task, ctypes.c_long(1), 1, ctypes.c_double(self._transfer_timeout), DAQmx_Val_GroupByChannel, data.ctypes.data, ctypes.byref(self._n_written), None)) else: CHK( dll.DAQmxWriteAnalogF64( self._ao_task, ctypes.c_long(N), 0, ctypes.c_double(self._transfer_timeout), DAQmx_Val_GroupByChannel, data.ctypes.data, ctypes.byref(self._n_written), None)) CHK(dll.DAQmxStartTask(self._ao_task)) CHK(dll.DAQmxStartTask(self._co_task)) CHK( dll.DAQmxWaitUntilTaskDone( self._ao_task, ctypes.c_double(4 * (N + 1) * self._seconds_per_point))) time.sleep(4. * self._seconds_per_point) CHK(dll.DAQmxStopTask(self._co_task)) CHK(dll.DAQmxStopTask(self._ao_task)) return self._n_written
def __del__(self): CHK( dll.DAQmxClearTask(self._ao_task) ) CHK( dll.DAQmxClearTask(self._co_task) )