Example #1
0
    def __init__(self, lines, name=None,
            edgeDetected=None, getTS=None, lineNames=None,
            initialState=0, debounce=5.12e-3):
        '''
        Args:
            lines (str): Example: '/dev1/port0/line1' or /dev2/port1/line0:7'
            name (str): Optional name for the task.
            edgeDetected (callable): ...
            getTS (callable): Get timestamp
            lineNames (list of str): ...
            initialState (int or bool): ...
            debounce (float): Available values: 0, 160e-9, 10.24e-6, 5.12e-3
        '''
        super().__init__(lines, name)

        self._edgeDetected = misc.Event(edgeDetected)
        self._getTS        = getTS
        if isinstance(lineNames, str): lineNames = [lineNames]
        self._lineNames    = lineNames
        self._initialState = initialState

        if not SIM:
            self._task.CreateDIChan(self.lines, '', mx.DAQmx_Val_ChanPerLine)
            self._task.CfgChangeDetectionTiming(self.lines, self.lines,
                mx.DAQmx_Val_ContSamps, 100)
            self._task.CfgInputBuffer(0)

            if debounce:
                self._task.SetDIDigFltrMinPulseWidth(lines, debounce)
                self._task.SetDIDigFltrEnable(lines, True)

            # callback pointer is stored such to prevent being garbage collected
            self._callbackPtr = mx.DAQmxSignalEventCallbackPtr(self._callback)
            self._task.RegisterSignalEvent(mx.DAQmx_Val_ChangeDetectionEvent, 0,
                self._callbackPtr, None)

        super()._postInit()

        pypeline.Node.__init__(self)

        if lineNames:
            if len(lineNames) != self.lineCount:
                raise ValueError('When specified, length of `lineNames` '
                    'should match the actual number of `lines`')
Example #2
0
 def __init__(self, interval):
     self._domains = {}
     self._interval = interval
     self.onDomainStateChange = misc.Event(
         "Storage.DomainMonitor.onDomainStateChange")
Example #3
0
    def __init__(self, channels, fs, samples, name=None,
            range=(-10.,10.), regenerate=False, dataNeeded=None, dataChunk=5,
            onbrdBufDuration=5e-3, bufDuration=30,
            accurateFS=True, timebaseSrc=None, timebaseRate=None,
            startTrigger=None):
        '''
        Args:
            channels (str): Example: '/dev1/ao0' or '/dev2/ao0:1'
            fs (float): Output sampling rate. Depending on the timebase clock,
                device might not be able to generate the requested rate
                accurately.
            samples (int): Number of samples to output from the device. If
                set to numpy.inf, task will go into infinite samples mode.
            name (str): Optional name for the task.
            range (tuple of float): Output voltage range. This adjusts the
                output DAC for the best quantization resolution possible.
            regenerate (bool): If True, task will output the indicated number of
                samples periodically until stopped.
            dataNeeded (callable): In infinite samples mode, this function is
                called before starting the task with an empty buffer or before
                sample generation reaches end of the buffer.
            dataChunk (float): In infinite samples mode, how long in seconds
                should be left to the end of buffer until the `dataNeeded`
                event is called.
            onbrdBufDuration (float): In infinite samples mode, deteremines how
                long should the onboard buffer be in seconds. This value affects
                the speed at which samples are transferred from software buffer
                to onboard buffer and is crucial when fast modifications to the
                buffer are needed. However, this only matters when using a PCIe
                DAQ model and not for a USB model. The actual buffer size
                depends on the specified sampling rate and will be clipped
                between 2 and 8191 samples.
            bufDuration (float): In infinite samples mode, determines how long
                should the software buffer be in seconds. The actual buffer size
                depends on the specified sampling rate.
            accurateFS (bool): If True, when device is not able to generate the
                requested sampling frequency accurately, the task will fail and
                a ValueError will be raised. If False, an inaccurate sampling
                frequency will only be reported with a warning.
            timebaseSrc (str): The terminal to use as the timebase for the
                sample clock. When multiple DAQ devices are connected via an
                RTSI cable, this value can be used to synchronize their sampling
                in order to minimize long term offset caused by clock jitter.
                See the following link for information on terminals:
                zone.ni.com/reference/en-XX/help/370466Y-01/mxcncpts/termnames
            timebaseRate (float): The rate of the specified `timebaseSrc` in Hz.
                This value is only needed when using an external timebase.
            startTrigger (str): Configures the task to begin output generation
                on rising edge of a digital signal. Note that the task should
                have already been started for the trigger to work.
                See the following link for information on terminals:
                zone.ni.com/reference/en-XX/help/370466Y-01/mxcncpts/termnames
        '''
        super().__init__(channels, fs, samples, name)

        if samples==np.inf and regenerate:
            raise ValueError('In %s task, cannot regenerate infinite number of '
                'samples' % self.name)

        if SIM and samples!=np.inf:
            raise NotImplementedError('AnalogOutput is not yet implemented for '
                'finite samples in `SIM` mode')

        if not SIM:
            self._task.CreateAOVoltageChan(self.channels, '', *range,
                mx.DAQmx_Val_Volts, '')

        self._nsOffset   = 0
        self._regenerate = regenerate
        self._dataNeeded = misc.Event(dataNeeded, singleCallback=True)
        self._dataChunk  = dataChunk

        if samples==np.inf:
            bufSize = int(np.ceil(fs*bufDuration))

            if not SIM:
                self._task.CfgSampClkTiming('', fs, mx.DAQmx_Val_Rising,
                    mx.DAQmx_Val_ContSamps, 0)
                self._task.SetWriteRegenMode(mx.DAQmx_Val_DoNotAllowRegen)
                onbrdBufSize = int(np.clip(np.ceil(fs*onbrdBufDuration),
                    2, 8191))
                self._task.SetBufOutputOnbrdBufSize(onbrdBufSize)

                self._task.SetBufOutputBufSize(bufSize)

                # this callback acts more like a timer, it doesn't matter after
                # how many samples is it called, it just has to happen before
                # sample generation reaches the end of buffer
                self._callbackPtr = mx.DAQmxEveryNSamplesEventCallbackPtr(
                    self._callback)
                self._task.RegisterEveryNSamplesEvent(
                    mx.DAQmx_Val_Transferred_From_Buffer, int(dataChunk*fs/2),
                    0, self._callbackPtr, None)

        elif regenerate:
            self._task.CfgSampClkTiming('', fs, mx.DAQmx_Val_Rising,
                mx.DAQmx_Val_ContSamps, samples)
            self._task.SetWriteRegenMode(mx.DAQmx_Val_AllowRegen)

        else:
            self._task.CfgSampClkTiming('', fs, mx.DAQmx_Val_Rising,
                mx.DAQmx_Val_FiniteSamps, samples)

        self._postInit(accurateFS, timebaseSrc, timebaseRate, startTrigger)

        if SIM:
            self._simBuffer   = misc.CircularBuffer((self.lineCount, bufSize))
            self._simInterval = 10e-3    # set simulated generation interval
            self._simSink     = None
            self._simSinkMap  = None
Example #4
0
    def __init__(self, channels, fs, samples, name=None,
            range=(-10.,10.), dataAcquired=None, dataChunk=100e-3,
            bufDuration=30, referenced=True,
            accurateFS=True, timebaseSrc=None, timebaseRate=None,
            startTrigger=None):
        '''
        Args:
            channels (str): Example: '/dev1/ai0' or '/dev2/ai0:15'
            fs (float): Input sampling rate. Depending on the timebase clock,
                device might not be able to generate the requested rate
                accurately.
            samples (int): Number of samples to read from the device. If
                set to numpy.inf, task will go into infinite samples mode.
            name (str): Optional name for the task.
            range (tuple of float): Input voltage range. This adjusts the
                output DAC for the best quantization resolution possible.
            dataAcquired (callable): In infinite samples mode, this function is
                called when a specific number of samples are acquired.
            dataChunk (float): In infinite samples mode, how long in seconds
                until the acquired data are read from the device and given to
                the `dataAcquired` event.
            bufDuration (float): In infinite samples mode, determines how long
                should the software buffer be in seconds. The actual buffer size
                depends on the specified sampling rate.
            referenced (bool): Referenced (AI GND) vs. non-referenced (AI SENSE)
                measurement. See:
                http://www.ni.com/white-paper/3344/en/
                zone.ni.com/reference/en-XX/help/370466Y-01/measfunds/refsingleended/
            accurateFS (bool): If True, when device is not able to generate the
                requested sampling frequency accurately, the task will fail and
                a ValueError will be raised. If False, an inaccurate sampling
                frequency will only be reported with a warning.
            timebaseSrc (str): The terminal to use as the timebase for the
                sample clock. When multiple DAQ devices are connected via an
                RTSI cable, this value can be used to synchronize their sampling
                in order to minimize long term offset caused by clock jitter.
                See the following link for information on terminals:
                zone.ni.com/reference/en-XX/help/370466Y-01/mxcncpts/termnames
            timebaseRate (float): The rate of the specified `timebaseSrc` in Hz.
                This value is only needed when using an external timebase.
            startTrigger (str): Configures the task to begin acquisition
                on rising edge of a digital signal. Note that the task should
                have already been started for the trigger to work.
                See the following link for information on trigger sources:
                zone.ni.com/reference/en-XX/help/370466Y-01/mxcncpts/termnames
        '''
        super().__init__(channels, fs, samples, name)

        if SIM and samples!=np.inf:
            raise NotImplementedError('AnalogInput is not yet implemented for '
                'finite samples in `SIM` mode')

        if not SIM:
            config = mx.DAQmx_Val_RSE if referenced else mx.DAQmx_Val_NRSE
            self._task.CreateAIVoltageChan(self.channels, None, config,
                *range, mx.DAQmx_Val_Volts, None)

        self._dataAcquired = misc.Event(dataAcquired)
        self._dataChunk    = dataChunk

        if samples==np.inf:
            bufSize = int(np.ceil(fs*bufDuration))

            if not SIM:
                self._task.CfgSampClkTiming('', fs, mx.DAQmx_Val_Rising,
                    mx.DAQmx_Val_ContSamps, 0)
                self._task.SetBufInputBufSize(bufSize)

                self._callbackPtr = mx.DAQmxEveryNSamplesEventCallbackPtr(
                    self._callback)
                self._task.RegisterEveryNSamplesEvent(
                    mx.DAQmx_Val_Acquired_Into_Buffer, int(dataChunk*fs), 0,
                    self._callbackPtr, None)

        else:
            bufSize = samples

            if not SIM:
                self._task.CfgSampClkTiming('', fs, mx.DAQmx_Val_Rising,
                    mx.DAQmx_Val_FiniteSamps, samples)

        self._postInit(accurateFS, timebaseSrc, timebaseRate,
            startTrigger)

        pypeline.Sampled.__init__(self, fs=self._fs, channels=self._lineCount)

        if SIM:
            self._simBuffer = misc.CircularBuffer((self.lineCount, bufSize))
            # set simulated acquisition interval
            self._simInterval = dataChunk