Example #1
0
    def __init__(self, bufferSize=20_000):
        self.taskIn_ = nidaqmx.Task()
        self.taskIn_.ai_channels.add_ai_voltage_chan("MyDAQ1/ai0:1")
        self.taskIn_.timing.cfg_samp_clk_timing(
            rate=200_000,
            sample_mode=constants.AcquisitionType.CONTINUOUS,
            samps_per_chan=bufferSize)

        self.analogMultiChannelReader_ = stream_readers.AnalogMultiChannelReader(
            self.taskIn_.in_stream)
        self.taskIn_.register_every_n_samples_acquired_into_buffer_event(
            bufferSize, self.callback)

        self.taskOut_ = nidaqmx.Task()
        self.taskOut_.co_channels.add_co_pulse_chan_time('myDAQ1/ctr0')
        self.taskOut_.timing.cfg_implicit_timing(
            sample_mode=nidaqmx.constants.AcquisitionType.CONTINUOUS)

        self.counterWriter_ = stream_writers.CounterWriter(
            self.taskOut_.out_stream, True)

        self.write_ = False

        self.counterWriter_.write_one_sample_pulse_time(
            .00095, .0015, timeout=nidaqmx.constants.WAIT_INFINITELY)
        time.sleep(3.0)
    def prepare_task(self, trig=True):

        try:
            if self.task is not None:
                self.close()
                # time.sleep(2) # Necessary??

            # Open the measurement task
            self.task = daq.Task("Monitor")

            # print "Task Handle: {}".format(self.task.name)

            add_ai_chan = self.task.ai_channels.add_ai_voltage_chan
            add_ai_chan(self.mychans,
                        terminal_config=self.Terminal_Config)

            set_timing = self.task.timing.cfg_samp_clk_timing
            set_timing(self.sample_rate,
                       sample_mode=self.Acquisition_Type)

            if trig:
                set_trig = self.task.triggers.start_trigger.cfg_dig_edge_start_trig
                set_trig("PFI0")

            self.task.start()

            self.task_in_stream = daq._task_modules.in_stream.InStream(self.task)
            self.reader = stream_readers.AnalogMultiChannelReader(self.task_in_stream)

            return
        except KeyboardInterrupt:
            self.close()
            # TODO : Proper traceback here
            raise KeyboardInterrupt
Example #3
0
 def streamer(self, value):
     if value is not None:
         raise AttributeError("Hey! You can't set this manually!")
     
     # If read mode, StreamReader.
     if not self.write_mode:
         if self.nchannels > 1:
             reader = sr.AnalogMultiChannelReader(
                     self.__task.in_stream)
         else:
             reader = sr.AnalogSingleChannelReader(
                     self.__task.in_stream)
         self.__streamer = reader
     # Else, StreamWriter for PWM output channel
     else:
         self.__streamer = sw.CounterWriter(
                 self.__task.out_stream)
     
     # Reconfigure channels' streamer
     if self.nchannels > 0:
         try:
             self.pins.streamer = self.__streamer
         except:
             raise AttributeError("Coudn't set streamer to channels")
Example #4
0
    def open(self):
        # AI
        self.t_in = {}

        for c in self.ai_chan_list:
            kwargs = dict(c)
            kwargs.pop("name", None)
            kwargs.pop("type", None)
            if c['type'] == 'voltage':
                kwargs['max_val'] = kwargs.get('max_val', 5)
                kwargs['min_val'] = kwargs.get('min_val', 0)
            for k in kwargs:
                if isinstance(kwargs[k], str):
                    if k == "thermocouple_type":
                        kwargs[k] = thermocouple_type[kwargs[k]]
                    elif k == "units":
                        kwargs[k] = units[kwargs[k]]
            if not c['type'] in self.t_in:
                self.t_in[c['type']] = nidaqmx.Task()
            try:
                getattr(self.t_in[c['type']].ai_channels,
                        "add_ai_%s_chan" % c['type'])(c['name'], **kwargs)
            except Exception:
                print("Invalid channel settings in nidaqmx:" + str(c))
                raise
        self.stream_in = {}
        for chan_type, t in self.t_in.items():
            self.stream_in[chan_type] = \
                stream_readers.AnalogMultiChannelReader(t.in_stream)
        # AO
        if self.ao_channels:
            self.t_out = nidaqmx.Task()
            self.stream_out = stream_writers.AnalogMultiChannelWriter(
                self.t_out.out_stream, auto_start=True)

        for c in self.ao_channels:
            kwargs = dict(c)
            kwargs.pop("name", None)
            kwargs.pop("type", None)
            kwargs['max_val'] = kwargs.get('max_val', 5)
            kwargs['min_val'] = kwargs.get('min_val', 0)
            self.t_out.ao_channels.add_ao_voltage_chan(c['name'], **kwargs)
        # DI
        if self.di_channels:
            self.t_di = nidaqmx.Task()
        for c in self.di_channels:
            kwargs = dict(c)
            kwargs.pop("name", None)
            kwargs.pop("type", None)
            self.t_di.di_channels.add_di_chan(c['name'], **kwargs)
        if self.di_channels:
            self.di_stream = stream_readers.DigitalMultiChannelReader(
                self.t_di.in_stream)

        # DO
        if self.do_channels:
            self.t_do = nidaqmx.Task()
        for c in self.do_channels:
            kwargs = dict(c)
            kwargs.pop("name", None)
            kwargs.pop("type", None)
            self.t_do.do_channels.add_do_chan(c['name'], **kwargs)
        if self.do_channels:
            self.do_stream = stream_writers.DigitalMultiChannelWriter(
                self.t_do.out_stream)
Example #5
0
        output_array -= pidconstant * delta
        
    elif max(samples) < (pidvalue-0.1):
         delta = pidvalue - max(samples)
         output_array += pidconstant * delta
         
    return 0

# Now I start the actual PID loop        
with nid.Task() as write_task, nid.Task() as read_task:

    # First I configure the reading
    read_task.ai_channels.add_ai_voltage_chan(
        flatten_channel_string(channels_to_read),
        max_val=10, min_val=-10)
    reader = sr.AnalogMultiChannelReader(read_task.in_stream)
    
    # Now I configure the writing
    write_task.ao_channels.add_ao_voltage_chan(
            flatten_channel_string(channels_to_write),
            max_val=10, min_val=-10)
    writer = sw.AnalogMultiChannelWriter(write_task.out_stream)

    # source task.
    # Start the read and write tasks before starting the sample clock
    # source task.

    read_task.start()
    read_task.register_every_n_samples_acquired_into_buffer_event(
            20, # Every 20 samples, call callback function
            callback) 
Example #6
0
measTime = 10  # measurement time in seconds
rate = 10000  # sampling rate in Hz

with nidaqmx.Task() as task:
    # add channels to task
    task.ai_channels.add_ai_voltage_chan(
        physical_channel='Dev1/ai0',
        name_to_assign_to_channel='B',
        units=nidaqmx.constants.VoltageUnits.VOLTS)
    task.ai_channels.add_ai_voltage_chan(
        physical_channel='Dev1/ai1',
        name_to_assign_to_channel='H',
        units=nidaqmx.constants.VoltageUnits.VOLTS)

    # set sampling rate
    task.timing.cfg_samp_clk_timing(
        rate=rate,
        sample_mode=constants.AcquisitionType.CONTINUOUS,
        samps_per_chan=measTime * rate)

    # start tasks
    task.start()

    # measure
    reader = stream_readers.AnalogMultiChannelReader(task.in_stream)
    data = np.zeros((2, measTime * rate))
    reader.read_many_sample(data, measTime * rate)

    # start tasks
    task.stop()
Example #7
0
    def start_continuous_acq_n_gen(self):
        self._ao_task = ni.Task()
        self._ai_task = ni.Task()
        ai_args = {
            'min_val':
            self.ai_min_val,
            'max_val':
            self.ai_max_val,
            'terminal_config':
            ni.constants.TerminalConfiguration[self.ai_terminal_config]
        }

        self._ai_task.ai_channels.add_ai_voltage_chan(self.ai_a_name,
                                                      **ai_args)
        self._ai_task.ai_channels.add_ai_voltage_chan(self.ai_b_name,
                                                      **ai_args)

        self._ai_task.timing.cfg_samp_clk_timing(
            rate=self.ai_fs,
            sample_mode=ni.constants.AcquisitionType.CONTINUOUS,
            samps_per_chan=self._input_frame_len)

        self._ai_task.triggers.start_trigger.cfg_dig_edge_start_trig(
            "ao/StartTrigger", trigger_edge=ni.constants.Edge.RISING)

        # Below is a bit clumsy EAFP but we have to be careful writing to properties because they may or may not be
        # present depending on device type while the "double locking" system with both OVERRIDE and property needing
        # change requires user to really know what he is doing. In most cases if some control attribute is not
        # implemented in a device, it can work without issues just with the default settings though. On NI6211,
        # this code is debugged with, only the default output buffer had to be changed to prevent underflow at high
        # UBS data rates. I leave this code though for users to experiment in case of issues with other DAQ models.

        if self.ATTEMPT_OVERRIDE_DEFAULT_INPUT_BUFFER_SIZE:
            try:
                self._ai_task.in_stream.input_buf_size = self.sw_input_buffer_size
            except ni.errors.DaqError as exc:
                print(exc)
                print('ATTEMPT_OVERRIDE_DEFAULT_INPUT_BUFFER_SIZE failed')

        if self.ATTEMPT_OVERRIDE_DEFAULT_INPUT_OVERWRITE_BEHAVIOUR is True:
            try:
                if self.INPUT_OVERWRITE is False:
                    self._ai_task.in_stream.over_write = ni.constants.OverwriteMode.DO_NOT_OVERWRITE_UNREAD_SAMPLES
                elif self.INPUT_OVERWRITE is True:
                    self._ai_task.in_stream.over_write = ni.constants.OverwriteMode.OVERWRITE_UNREAD_SAMPLES
            except ni.errors.DaqError as exc:
                print(exc)
                print(
                    'ATTEMPT_OVERRIDE_DEFAULT_INPUT_OVERWRITE_BEHAVIOUR failed'
                )

        ao_args = {'min_val': self.ao_min_val, 'max_val': self.ao_max_val}

        ao_chan_a = self._ao_task.ao_channels.add_ao_voltage_chan(
            self.ao_a_name, **ao_args)
        ao_chan_b = self._ao_task.ao_channels.add_ao_voltage_chan(
            self.ao_b_name, **ao_args)

        if self.ATTEMPT_OVERRIDE_DEFAULT_USB_XFER is True:
            try:
                ao_chan_a.ao_usb_xfer_req_count = self.AO_USB_XFER_REQ_COUNT
                ao_chan_b.ao_usb_xfer_req_count = self.AO_USB_XFER_REQ_COUNT
                ao_chan_a.ao_usb_xfer_req_size = self.AO_USB_XFER_REQ_SIZE
                ao_chan_b.ao_usb_xfer_req_size = self.AO_USB_XFER_REQ_SIZE
            except ni.errors.DaqError as exc:
                print(exc)
                print('ATTEMPT_OVERRIDE_DEFAULT_USB_XFER failed')

        self._ao_task.timing.cfg_samp_clk_timing(
            rate=self.ao_fs,
            samps_per_chan=self._output_frame_len,  #TODO bug on dev1
            sample_mode=ni.constants.AcquisitionType.CONTINUOUS)

        if self.ATTEMPT_OVERRIDE_DEFAULT_OUTPUT_REGENERATION_MODE is True:
            try:
                if self.ALLOW_OUTPUT_REGENERATION is False:
                    self._ao_task.out_stream.regen_mode = ni.constants.RegenerationMode.DONT_ALLOW_REGENERATION  # prevents DAQ card from repeating output, it just waits for more data to be added to the buffer- > but on cards that cant handle to automatically pause output generation when out of buffer this setting will case random and unexpected crash!
                elif self.ALLOW_OUTPUT_REGENERATION is True:
                    self._ao_task.out_stream.regen_mode = ni.constants.RegenerationMode.ALLOW_REGENERATION
            except ni.errors.DaqError as exc:
                print(exc)
                print(
                    'ATTEMPT_OVERRIDE_DEFAULT_OUTPUT_REGENERATION_MODE failed')

        if self.ATTEMPT_OVERRIDE_DEFAULT_UNDERFLOW_BEHAVIOR_TO_PAUSE is True:
            try:
                self._ao_task.timing.implicit_underflow_behavior = ni.constants.UnderflowBehavior.AUSE_UNTIL_DATA_AVAILABLE  # SIC!
            except ni.errors.DaqError as exc:
                print(exc)
                print('Could not OVERRIDE_DEFAULT_UNDEFLOW_BEHAVIOR')
                if self._ao_task.out_stream.regen_mode == ni.constants.RegenerationMode.DONT_ALLOW_REGENERATION:
                    print(
                        'WARNING: Your device does not support pause in case of output underflow while auto '
                        'regeneration of the AO buffer is not allowed.\n  '
                        'In case of output buffer underflow due to system resources the application will crash!\n  '
                        'To prevent this warning and risk of crash its highly recommended to set _out_stream.regen_'
                        'mode to ALLOW_REGENERATION.\n  '
                        'This will allow output glitches in theory but will prevent '
                        'application from crashing on output buffer underflow.'
                    )

        if self.ATTEMPT_OVERRIDE_DEFAULT_OUTPUT_BUFFER_SIZE is True:
            try:
                self._ao_task.out_stream.output_buf_size = self.sw_output_buffer_size
                # seems like buffer is not calculating correct and we must call out explicitly on NI6211.
                # Not setting this property leads to a chain of very confusing warnings/glitches.
            except ni.errors.DaqError as exc:
                print(exc)

        self._stream_reader = stream_readers.AnalogMultiChannelReader(
            self._ai_task.in_stream)
        self._stream_writer = stream_writers.AnalogMultiChannelWriter(
            self._ao_task.out_stream)

        # fill AO buffer with data
        self.function_gen.generate()
        buffer_frame = self.function_gen.output_frame

        for frames in range(self.CM_OUTPUT_FRAMES_PER_BUFFER - 1):  # TODO UGLY
            self.function_gen.generate()
            buffer_frame = np.append(buffer_frame,
                                     self.function_gen.output_frame,
                                     axis=1)

        self._ao_task.write(buffer_frame)

        self._ai_task.register_every_n_samples_acquired_into_buffer_event(
            self._input_frame_len, self.reading_task_callback)

        self._ao_task.register_every_n_samples_transferred_from_buffer_event(
            self._output_frame_len, self.writing_task_callback)

        self._ai_task.start()  # arm but do not trigger the acquisition
        self._ao_task.start(
        )  # trigger both generation and acquisition simultaneously

        self.cm_measurement_is_running = True