Beispiel #1
0
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 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 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
Beispiel #4
0
class DAQmxSystem(AcquisitionCard):
    def __init__(self):
        super(DAQmxSystem, self).__init__()
        self.task = Task()
        self.reading = False
        self.stop_lock = asyncio.Lock()
        self.read_lock = asyncio.Lock()

    @property
    def samp_clk_max_rate(self):
        return self.task.timing.samp_clk_max_rate

    def possible_trigger_channels(self):
        return [chan.name for chan in self.channels]

    def close(self):
        if self.task:
            self.channels = []
            self.task.close()
            self.task = None

    def add_channel(self, channel_name, terminal_config, voltage_range):
        tc = ConcreteTerminalConfig[terminal_config]
        ai_chan = self.task.ai_channels.add_ai_voltage_chan(
            channel_name,
            terminal_config=tc,
            min_val=-voltage_range,
            max_val=voltage_range,
        )
        self.channels.append(ai_chan)
        self.actual_ranges.append(ai_chan.ai_max)

    def configure_clock(self, sample_rate, samples_per_chan):
        self.task.timing.cfg_samp_clk_timing(sample_rate,
                                             samps_per_chan=samples_per_chan)
        self.sample_rate = sample_rate
        self.samples_per_chan = samples_per_chan

    def configure_trigger(
        self,
        trigger_source=None,
        trigger_level=0,
        trigger_config=TriggerConfig.EdgeRising,
    ):

        st = self.task.triggers.start_trigger
        if trigger_source is None:
            print("disable_start_trig")
            st.disable_start_trig()
        else:
            if trigger_config != TriggerConfig.EdgeRising:
                raise NotImplementedError()  # TODO
            print(
                f"cfg_anlg_edge_start_trig({trigger_source:}, {trigger_level:})"
            )
            st.cfg_anlg_edge_start_trig(trigger_source,
                                        trigger_level=trigger_level)

    def start(self):
        self.task.start()
        self.running = True

    async def stop(self):
        async with self.stop_lock:
            if self.running:
                self.running = False
                while self.reading:
                    await asyncio.sleep(1.0)
                self.task.stop()

    async def read(self, tmo=None):
        async with self.read_lock:
            self.reading = True
            done = False
            start = time.monotonic()
            while self.running:
                try:
                    await self.loop.run_in_executor(None,
                                                    self.task.wait_until_done,
                                                    1.0)
                except DaqError:
                    if tmo and time.monotonic() - start > tmo:
                        raise TimeoutException()
                    else:
                        continue
                done = True
                break
            if done and self.running:
                data = await self.loop.run_in_executor(None, self.task.read,
                                                       READ_ALL_AVAILABLE)
                self.last_read = time.monotonic()
                data = np.array(data)
            else:
                data = None
            self.reading = False
            return data
Beispiel #5
0
class DAQmxSystem(AcquisitionCard):
    """This class is the concrete implementation for NI DAQmx board using
    the :mod:`nidaqmx` module.
    """
    def __init__(self):
        """Constructor method
        """
        super(DAQmxSystem, self).__init__()
        self.task = Task()
        self.reading = False
        self.stop_lock = asyncio.Lock()
        self.read_lock = asyncio.Lock()

    @property
    def samp_clk_max_rate(self):
        """Maximum sample clock rate
        """
        return self.task.timing.samp_clk_max_rate

    def possible_trigger_channels(self):
        """This method returns the list of channels that can be used as trigger.
        """
        return [chan.name for chan in self.channels]

    def close(self):
        """This method closes the active task, if there is one.
        """
        if self.task:
            self.channels = []
            self.task.close()
            self.task = None

    def add_channel(self, channel_name, terminal_config, voltage_range):
        """Concrete implementation of :meth:`pymanip.aiodaq.AcquisitionCard.add_channel`.

        .. todo::
            Actually check the type for terminal_config.

        """
        tc = ConcreteTerminalConfig[terminal_config]
        ai_chan = self.task.ai_channels.add_ai_voltage_chan(
            channel_name,
            terminal_config=tc,
            min_val=-voltage_range,
            max_val=voltage_range,
        )
        self.channels.append(ai_chan)
        self.actual_ranges.append(ai_chan.ai_max)

    def configure_clock(self, sample_rate, samples_per_chan):
        """Concrete implementation of :meth:`pymanip.aiodaq.AcquisitionCard.configure_clock`
        """
        self.task.timing.cfg_samp_clk_timing(sample_rate,
                                             samps_per_chan=samples_per_chan)
        self.sample_rate = sample_rate
        self.samples_per_chan = samples_per_chan

    def configure_trigger(
        self,
        trigger_source=None,
        trigger_level=0,
        trigger_config=TriggerConfig.EdgeRising,
    ):
        """Concrete implementation of :meth:`pymanip.aiodaq.AcquisitionCard.configure_trigger`

        .. todo::
           implement trigger_config other than the defaults value

        """

        st = self.task.triggers.start_trigger
        if trigger_source is None:
            print("disable_start_trig")
            st.disable_start_trig()
        else:
            if trigger_config != TriggerConfig.EdgeRising:
                raise NotImplementedError()  # TODO
            print(
                f"cfg_anlg_edge_start_trig({trigger_source:}, {trigger_level:})"
            )
            st.cfg_anlg_edge_start_trig(trigger_source,
                                        trigger_level=trigger_level)

    def start(self):
        """This method starts the task.
        """
        self.task.start()
        self.running = True

    async def stop(self):
        """This asynchronous method aborts the current task.
        """
        async with self.stop_lock:
            if self.running:
                self.running = False
                while self.reading:
                    await asyncio.sleep(1.0)
                self.task.stop()

    async def read(self, tmo=None):
        """This asynchronous method reads data from the task.
        """
        async with self.read_lock:
            self.reading = True
            done = False
            start = time.monotonic()
            while self.running:
                try:
                    await self.loop.run_in_executor(None,
                                                    self.task.wait_until_done,
                                                    1.0)
                except DaqError:
                    if tmo and time.monotonic() - start > tmo:
                        raise TimeoutException()
                    else:
                        continue
                done = True
                break
            if done and self.running:
                data = await self.loop.run_in_executor(None, self.task.read,
                                                       READ_ALL_AVAILABLE)
                self.last_read = time.monotonic()
                data = np.array(data)
            else:
                data = None
            self.reading = False
            return data