class PulseGenerator: def __init__(self, channel, start_src=None): self._task = None self._channel = channel # TODO implement external start def __del__(self): if self._task is not None: self._task.close() def start(self, samples, high_time, low_time, initial_delay=0): if self._task is not None: self._task.close() self._task = Task('timer') self._timer = self._task.co_channels.add_co_pulse_chan_time( self._channel, high_time=high_time, low_time=low_time, initial_delay=initial_delay) self._task.timing.samp_quant_samp_per_chan = samples self._task.timing.samp_timing_type = SampleTimingType.IMPLICIT self._task.start() def stop(self): self._task.stop() @property def done(self): return self._task.is_task_done()
class BaseChannel: """ Base class to implement a channel """ def __init__(self, channel, channel_name): self._thread = None self._stop = False self._channel = channel self._data = np.zeros(0) self.sample_readies = 0 self.enabled = True # Create the task self._task = Task('task' + channel_name) # Configure reader. self._task.in_stream.read_all_avail_samp = True self._reader = CounterReader(self._task.in_stream) # Configure timing def __del__(self): self._task.close() def start(self, samples): self._task.stop() self._data = np.zeros(samples) self.sample_readies = 0 if not self.enabled: return if samples == 1: self._task.timing.samp_quant_samp_per_chan = 2 else: self._task.timing.samp_quant_samp_per_chan = samples self._stop = False self._thread = threading.Thread(target=self._read, args=[samples]) self._task.start() self._thread.start() @property def data(self): return self._data[:self.sample_readies] @property def done(self): return self._task.is_task_done() def stop(self): self._stop = True self._task.stop() def _read(self, samples): i = 0 while not self._stop and samples != 0: self._data[i] = self._reader.read_one_sample_double(timeout=-1) i += 1 samples -= 1 self.sample_readies += 1 self._task.stop()
class PulseCounter: """ Class to implement a pulse counter """ def __init__(self, channel, channel_name, gate_src, timebase_src, edge=Edge.RISING): self._data = None self.sample_readies = 0 self._channel = channel self._task = Task('task' + channel_name) self._counter = self._task.ci_channels.add_ci_pulse_width_chan( channel, channel_name, units=TimeUnits.TICKS, starting_edge=edge) self._counter.ci_ctr_timebase_src = timebase_src self._counter.ci_pulse_width_term = gate_src self._task.in_stream.read_all_avail_samp = True self._reader = CounterReader(self._task.in_stream) self._thread = None self._stop = False def __del__(self): self._task.close() def start(self, samples): self._data = np.zeros(samples) self._task.stop() self._data = np.zeros(samples) self._task.timing.samp_quant_samp_per_chan = samples self._task.timing.samp_timing_type = SampleTimingType.IMPLICIT self._counter.ci_data_xfer_mech = \ DataTransferActiveTransferMode.INTERRUPT self._thread = threading.Thread(target=self._read, args=[samples]) self._task.start() self._stop = False self._thread.start() @property def done(self): return self._task.is_task_done() def stop(self): self._stop = True self._task.stop() def _read(self, samples): i = 0 while not self._stop and samples != 0: self._data[i] = self._reader.read_one_sample_double(timeout=-1) i += 1 samples -= 1 @property def data(self): return self._data