Beispiel #1
0
 def is_supported(self):
     daqo_supported = True
     try:
         ul.get_status(self._board_num, FunctionType.DAQOFUNCTION)
     except ULError:
         daqo_supported = False
     return daqo_supported
Beispiel #2
0
 def supports_scan(self):
     scan_supported = True
     try:
         ul.get_status(self._board_num, FunctionType.AIFUNCTION)
     except ULError:
         scan_supported = False
     return scan_supported
    def update_input_displayed_values(self, range_):
        # Get the status from the device
        status, curr_count, curr_index = ul.get_status(self.board_num,
                                                       FunctionType.AIFUNCTION)

        # Display the status info
        self.update_input_status_labels(status, curr_count, curr_index)

        # Update period if necessary
        self.update_input_period(curr_count)

        # Display the values
        self.display_input_values(range_, curr_index, curr_count)

        # Open the directory text file
        self.textfile = open("Rawtext.txt",
                             "a+")  # textfile that the data will be written to

        # Function for the writing of the complete buffer to a text file and stopping the process
        if curr_count >= self.test_time() - 100:
            self.full_file()

        # Call this method again until the stop_input button is pressed
        if status == Status.RUNNING:
            self.after(10, self.update_input_displayed_values, range_)
        else:
            # Free the allocated memory
            ul.win_buf_free(self.input_memhandle)
            self.set_input_ui_idle_state()
 def exit(self):
     status, curr_count, curr_index = ul.get_status(self.board_num,
                                                    FunctionType.AIFUNCTION)
     if status == status.RUNNING:
         self.full_file()
     else:  # else just stop the arena (whether turning or not)
         self.tempo = 2
         self.update_arena_output()
     self.save_inputs()
     self.master.destroy()
Beispiel #5
0
    def update_displayed_values(self):
        # Get the status from the device
        status, curr_count, curr_index = ul.get_status(self.board_num,
                                                       FunctionType.AOFUNCTION)

        # Display the status info
        self.update_status_labels(status, curr_count, curr_index)

        # Call this method again until the stop button is pressed
        if status == Status.RUNNING:
            self.after(100, self.update_displayed_values)
        else:
            # Free the allocated memory
            ul.win_buf_free(self.memhandle)
            self.set_ui_idle_state()
    def stop_input(self):
        self.tempo = 2  # stop turning arena
        self.update_arena_output()

        status, curr_count, curr_index = ul.get_status(self.board_num,
                                                       FunctionType.AIFUNCTION)
        my_array = self.ctypes_array  # save all the collected data
        ul.stop_background(self.board_num, FunctionType.AIFUNCTION)
        open("KHZtext.txt", "w")  # clear existing file
        endfile = open(
            "KHZtext.txt",
            "a+")  # textfile that the data will be written to (kiloherztext)
        millisec = 0  # the time column parameter in milliseconds
        ULAIO01.txt_count = 0  # for the order of the KHZtext file
        self.period = 1
        print("count", curr_count)
        for i in list(
                range(0, curr_count)
        ):  # curr_count should represent the length of the ctypes_array
            eng_value = ul.to_eng_units(self.board_num,
                                        self.ai_props.available_ranges[0],
                                        my_array[i])
            eng_value_proper = (
                "%f " % (eng_value)
            )  # thats how it is supposed to be written into the txt file, but right now it isn't unicode
            endfile.write(
                eng_value_proper.decode("unicode-escape")
            )  # eng_value returns float, but after (4) floats all channels are printed (also: encode to utf8 format)
            ULAIO01.txt_count = ULAIO01.txt_count + 1  # thats why we need the count (know when to newline)
            if self.period < len(
                    self.period_switch
            ) and i == self.period_switch[
                    self.period -
                    1]:  # when we iterated to the point where a new period was started, we need to switch the period parameter
                self.period = self.period + 1
                print("hat funktioniert", self.period)
            if ULAIO01.txt_count == (
                (self.input_high_chan - self.input_low_chan) + 1):
                endfile.write(u"%d %d\n" % (millisec, self.period))
                ULAIO01.txt_count = 0
                millisec = millisec + 10  # for each loop the next millisecond is measured
        Beep(3000, 500)
Beispiel #7
0
    def update_displayed_values(self):
        # Get the status from the device
        status, curr_count, curr_index = ul.get_status(self.board_num,
                                                       FunctionType.AIFUNCTION)

        # Display the status info
        self.update_status_labels(status, curr_count, curr_index)

        # Display the values
        self.display_values(curr_index, curr_count)

        # Call this method again until the stop button is pressed
        if status == Status.RUNNING:
            self.after(100, self.update_displayed_values)
        else:
            # Free the allocated memory
            ul.win_buf_free(self.memhandle)
            # Stop the background operation (this is required even if the
            # scan completes successfully)
            ul.stop_background(self.board_num, FunctionType.AIFUNCTION)
            self.set_ui_idle_state()
    def txt_to_xml(self):

        # del last line in KHZtext: (source: https://stackoverflow.com/questions/1877999/delete-final-line-in-file-with-python)

        file = open("KHZtext.txt", "r+")
        # Move the pointer (similar to a cursor in a text editor) to the end of the file.
        file.seek(0, os.SEEK_END)

        # This code means the following code skips the very last character in the file -
        # i.e. in the case the last line is null we delete the last line
        # and the penultimate one
        pos = file.tell() - 1

        # Read each character in the file one at a time from the penultimate
        # character going backwards, searching for a newline character
        # If we find a new line, exit the search
        while pos > 0 and file.read(1) != "\n":
            pos -= 1
            file.seek(pos, os.SEEK_SET)

        # So long as we're not at the start of the file, delete all the characters ahead of this position
        if pos > 0:
            file.seek(pos, os.SEEK_SET)
            file.truncate()

        status, curr_count, curr_index = ul.get_status(self.board_num,
                                                       FunctionType.AOFUNCTION)
        if status == Status.IDLE:
            datafile = open("KHZtext.txt", "r")  # text with periods for xml
            data = datafile.read()
            xml_name = self.input_filename.get() + ".xml"
            print(xml_name)
            target_folder = os.path.join(os.curdir, "AndersSoft")
            target_file = os.path.join(target_folder,
                                       "Optomotorics_blueprint.xml")
            xml_location = os.path.join(target_folder, xml_name)
            copy("Optomotorics_blueprint.xml", "AndersSoft")
            if os.path.exists(xml_location):
                print("warning")
                showwarning(
                    "Warning",
                    "The specified file already exists, rename the existing one NOW if overwriting should be avoided"
                )
            move(target_file, xml_location)
            tree = et.parse(xml_location)  #C:\Bachelor\FinishedSoft\

            self.firstname = tree.find("./metadata/experimenter/firstname")
            self.firstname.text = str(self.input_firstname.get())

            self.lastname = tree.find("./metadata/experimenter/lastname")
            self.lastname.text = str(self.input_lastname.get())

            self.orcid = tree.find("./metadata/experimenter/orcid")
            self.orcid.text = str(self.input_orcid.get())

            self.fly = tree.find("./metadata/fly")
            self.fly.attribute = str(self.input_flytype.get())

            self.fly_name = tree.find("./metadata/fly/name")
            self.fly_name.text = str(self.input_flyname.get())

            self.fly_description = tree.find("./metadata/fly/description")
            self.fly_description.text = str(self.input_flydescription.get())

            # x = tree.find("./metadata/experiment")
            # x.attribute = str(self.input_experimenttype

            self.experiment_dateTime = tree.find(
                "./metadata/experiment/dateTime")
            self.experiment_dateTime.text = str(self.input_dateTime.get())

            self.experiment_duration = tree.find(
                "./metadata/experiment/duration")
            self.experiment_duration.text = str(self.testtimebox.get())

            self.experiment_description = tree.find(
                "./metadata/experiment/description")
            self.experiment_description.text = str(
                self.input_ExperimentDescription.get())

            self.sample_rate = tree.find("./metadata/experiment/sample_rate")
            self.sample_rate.text = str(self.input_Samplingrate.get())

            self.sequences = int(
                int(self.testtimebox.get()) * 60 /
                int(self.periodbox.get())) + 1
            sequence = tree.find("./sequence")
            sequence.attribute = self.sequences

            # perioddescription
            for i in list(range(1, self.sequences)):
                period = et.SubElement(sequence, "period")
                period.set("number", "%d" % i)
                print(et.tostring(period))
                if i % 2 == 0:
                    type = et.SubElement(period, "type")
                    type.text = "OptomotoR"
                else:
                    type = et.SubElement(period, "type")
                    type.text = "OptomotoL"
                duration = et.SubElement(period, "duration")
                duration.text = str(self.periodbox.get())
                outcome = et.SubElement(period, "outcome")
                outcome.text = str(self.input_outcome.get())
                pattern = et.SubElement(period, "pattern")
                pattern.text = str(self.input_Pattern.get())

            csv = tree.find(
                "./timeseries/csv_data")  # adress the right spot for the data
            csv.text = data  # implement the data in the xml
            tree.write(xml_location)

        file.close()
Beispiel #9
0
    def start_scan(self):
        # Set filename
        self.file_name = window.rec_settings.FolderLabel.text() + '/' + window.rec_settings.NamePrefixLabel.text() + \
            datetime.datetime.now().strftime("_%Y_%m_%d_%H%M%S") + \
            '.wav'

        try:
            # Start the scan
            ul.a_in_scan(
                self.board_num, self.low_chan, self.high_chan, self.ul_buffer_count,
                self.rate, self.ai_range, self.memhandle, self.scan_options)

            self.status = Status.IDLE
            # Wait for the scan to start fully
            while(self.status == Status.IDLE):
                self.status, _, _ = ul.get_status(
                    self.board_num, FunctionType.AIFUNCTION)

            # Create a file for storing the data
            # PYSOUNDFILE MODULE
            temp_file = SoundFile(self.file_name, 'w+', self.rate, 1, 'PCM_16')
            # with SoundFile(self.file_name, 'w', self.rate, 1, 'PCM_16') as f:
            #     print('abro', self.file_name)
            # WAVE MODULE
            # with wave.open('wavemod' + self.file_name, 'w') as f:
            #     f.setnchannels(1)
            #     f.setsampwidth(2)
            #     f.setframerate(self.rate)

            # Start the write loop
            prev_count = 0
            prev_index = 0
            write_ch_num = self.low_chan

            while self.status != Status.IDLE:
                # Get the latest counts
                self.status, curr_count, _ = ul.get_status(
                    self.board_num, FunctionType.AIFUNCTION)

                new_data_count = curr_count - prev_count

                # Check for a buffer overrun before copying the data, so
                # that no attempts are made to copy more than a full buffer
                # of data
                if new_data_count > self.ul_buffer_count:
                    # Print an error and stop writing
                    # QtGui.QMessageBox.information(self, "Error", "A buffer overrun occurred")
                    ul.stop_background(self.board_num, FunctionType.AIFUNCTION)
                    print("A buffer overrun occurred")  # cambiar por critical message
                    break  # VER COMO REEMPLAZAR

                # Check if a chunk is available
                if new_data_count > self.write_chunk_size:
                    self.wrote_chunk = True
                    # Copy the current data to a new array

                    # Check if the data wraps around the end of the UL
                    # buffer. Multiple copy operations will be required.
                    if prev_index + self.write_chunk_size > self.ul_buffer_count - 1:
                        first_chunk_size = self.ul_buffer_count - prev_index
                        second_chunk_size = (
                            self.write_chunk_size - first_chunk_size)

                        # Copy the first chunk of data to the write_chunk_array
                        ul.win_buf_to_array(
                            self.memhandle, self.write_chunk_array, prev_index,
                            first_chunk_size)

                        # Create a pointer to the location in
                        # write_chunk_array where we want to copy the
                        # remaining data
                        second_chunk_pointer = cast(
                            addressof(self.write_chunk_array) + first_chunk_size
                            * sizeof(c_ushort), POINTER(c_ushort))

                        # Copy the second chunk of data to the
                        # write_chunk_array
                        ul.win_buf_to_array(
                            self.memhandle, second_chunk_pointer,
                            0, second_chunk_size)
                    else:
                        # Copy the data to the write_chunk_array
                        ul.win_buf_to_array(
                            self.memhandle, self.write_chunk_array, prev_index,
                            self.write_chunk_size)

                    # Check for a buffer overrun just after copying the data
                    # from the UL buffer. This will ensure that the data was
                    # not overwritten in the UL buffer before the copy was
                    # completed. This should be done before writing to the
                    # file, so that corrupt data does not end up in it.
                    self.status, curr_count, _ = ul.get_status(
                        self.board_num, FunctionType.AIFUNCTION)
                    # Opcion 1: original ( valores altos )
                    if curr_count - prev_count > self.ul_buffer_count:
                        # Print an error and stop writing
                        ul.stop_background(self.board_num, FunctionType.AIFUNCTION)
                        print("BUFFER OVERRUN")
                        QtGui.QMessageBox.critical(self, "Warning", "A buffer overrun occurred")
                        break
                        # VER COMO HACER PARA EVITAR QUE CIERRE EL PROGRAMA:

                    for i in range(self.write_chunk_size):

                        # opcion 1
                        self.chunk_ls.append(self.write_chunk_array[i]-32768)

                    # opcion 4
                    self.chunk_np = np.asarray(self.chunk_ls, dtype=np.int16)
                    # resampled_chunk = samplerate.resample(self.chunk_np, 44100. /
                    #                                       float(self.rate), 'sinc_best')
                    # resampled_chunk = resampy.resample(self.chunk_np, self.rate, 44100)

                    temp_file.write(self.chunk_np)
                    # self.chunk_signal.emit(self.chunk_ls)
                    # self.file_ls.extend(self.chunk_ls)
                    self.chunk_ls = []


                else:
                    self.wrote_chunk = False

                if self.wrote_chunk:
                    self.chunk_signal.emit(self.chunk_np)
                    # Increment prev_count by the chunk size
                    prev_count += self.write_chunk_size
                    # Increment prev_index by the chunk size
                    prev_index += self.write_chunk_size
                    # Wrap prev_index to the size of the UL buffer
                    prev_index %= self.ul_buffer_count

                    if prev_count % self.points_to_write == 0:
                        # self.file_signal.emit(self.file_np)
                        # self.write_wav_file(self.file_ls
                        temp_file.close()
                        self.file_name = window.rec_settings.FolderLabel.text() + '/' + window.rec_settings.NamePrefixLabel.text() + \
                            datetime.datetime.now().strftime("_%Y_%m_%d_%H%M%S") + \
                            '.wav'
                        temp_file = SoundFile(self.file_name, 'w', self.rate, 1, 'PCM_16')
                else:
                    # Wait a short amount of time for more data to be
                    # acquired.
                    time.sleep(0.1)
        except ULError as e:
            print('except')
            # QtGui.QMessageBox.critical(window, 'Error', 'Please restart program')
            self.print_ul_error(e)  # VER FUNCION Y ADAPATAR A PYQT
        finally:
            # Free the buffer in a finally block to prevent errors from causing
            # a memory leak.
            temp_file.close()
            ul.stop_background(self.board_num, FunctionType.AIFUNCTION)
            ul.win_buf_free(self.memhandle)
            self.finished_signal.emit()
Beispiel #10
0
def run_example():
    # By default, the example detects and displays all available devices and
    # selects the first device listed. Use the dev_id_list variable to filter
    # detected devices by device ID (see UL documentation for device IDs).
    # If use_device_detection is set to False, the board_num variable needs to
    # match the desired board number configured with Instacal.
    use_device_detection = True
    dev_id_list = []
    board_num = 0
    rate = 100
    points_per_channel = 1000
    memhandle = None

    try:
        if use_device_detection:
            config_first_detected_device(board_num, dev_id_list)

        daq_dev_info = DaqDeviceInfo(board_num)
        if not daq_dev_info.supports_analog_input:
            raise Exception('Error: The DAQ device does not support '
                            'analog input')

        print('\nActive DAQ device: ', daq_dev_info.product_name, ' (',
              daq_dev_info.unique_id, ')\n', sep='')

        ai_info = daq_dev_info.get_ai_info()

        low_chan = 0
        high_chan = min(3, ai_info.num_chans - 1)
        num_chans = high_chan - low_chan + 1

        total_count = points_per_channel * num_chans

        ai_range = ai_info.supported_ranges[0]

        scan_options = ScanOptions.BACKGROUND

        if ScanOptions.SCALEDATA in ai_info.supported_scan_options:
            # If the hardware supports the SCALEDATA option, it is easiest to
            # use it.
            scan_options |= ScanOptions.SCALEDATA

            memhandle = ul.scaled_win_buf_alloc(total_count)
            # Convert the memhandle to a ctypes array.
            ctypes_array = cast(memhandle, POINTER(c_double))
        elif ai_info.resolution <= 16:
            # Use the win_buf_alloc method for devices with a resolution <= 16
            memhandle = ul.win_buf_alloc(total_count)
            # Convert the memhandle to a ctypes array.
            ctypes_array = cast(memhandle, POINTER(c_ushort))
        else:
            # Use the win_buf_alloc_32 method for devices with a resolution > 16
            memhandle = ul.win_buf_alloc_32(total_count)
            # Convert the memhandle to a ctypes array.
            ctypes_array = cast(memhandle, POINTER(c_ulong))

        # Note: the ctypes array will no longer be valid after win_buf_free is
        # called.
        # A copy of the buffer can be created using win_buf_to_array or
        # win_buf_to_array_32 before the memory is freed. The copy can be used
        # at any time.

        # Check if the buffer was successfully allocated
        if not memhandle:
            raise Exception('Error: Failed to allocate memory')

        # Start the scan
        ul.a_in_scan(
            board_num, low_chan, high_chan, total_count,
            rate, ai_range, memhandle, scan_options)

        # Create a format string that aligns the data in columns
        row_format = '{:>12}' * num_chans

        # Print the channel name headers
        labels = []
        for ch_num in range(low_chan, high_chan + 1):
            labels.append('CH' + str(ch_num))
        print(row_format.format(*labels))

        # Start updating the displayed values
        status, curr_count, curr_index = ul.get_status(
            board_num, FunctionType.AIFUNCTION)
        while status != Status.IDLE:
            # Make sure a data point is available for display.
            if curr_count > 0:
                # curr_index points to the start of the last completed
                # channel scan that was transferred between the board and
                # the data buffer. Display the latest value for each
                # channel.
                display_data = []
                for data_index in range(curr_index, curr_index + num_chans):
                    if ScanOptions.SCALEDATA in scan_options:
                        # If the SCALEDATA ScanOption was used, the values
                        # in the array are already in engineering units.
                        eng_value = ctypes_array[data_index]
                    else:
                        # If the SCALEDATA ScanOption was NOT used, the
                        # values in the array must be converted to
                        # engineering units using ul.to_eng_units().
                        eng_value = ul.to_eng_units(board_num, ai_range,
                                                    ctypes_array[data_index])
                    display_data.append('{:.3f}'.format(eng_value))
                print(row_format.format(*display_data))

            # Wait a while before adding more values to the display.
            sleep(0.5)

            status, curr_count, curr_index = ul.get_status(
                board_num, FunctionType.AIFUNCTION)

        # Stop the background operation (this is required even if the
        # scan completes successfully)
        ul.stop_background(board_num, FunctionType.AIFUNCTION)

        print('Scan completed successfully')
    except Exception as e:
        print('\n', e)
    finally:
        if memhandle:
            # Free the buffer in a finally block to prevent a memory leak.
            ul.win_buf_free(memhandle)
        if use_device_detection:
            ul.release_daq_device(board_num)
def run_example():
    board_num = 0
    rate = 100
    points_per_channel = 1000

    if use_device_detection:
        ul.ignore_instacal()
        if not util.config_first_detected_device(board_num):
            print("Could not find device.")
            return

    ai_props = AnalogInputProps(board_num)
    if ai_props.num_ai_chans < 1:
        util.print_unsupported_example(board_num)
        return

    low_chan = 0
    high_chan = min(3, ai_props.num_ai_chans - 1)
    num_chans = high_chan - low_chan + 1

    total_count = points_per_channel * num_chans

    ai_range = ai_props.available_ranges[0]

    scan_options = ScanOptions.BACKGROUND

    if ScanOptions.SCALEDATA in ai_props.supported_scan_options:
        # If the hardware supports the SCALEDATA option, it is easiest to
        # use it.
        scan_options |= ScanOptions.SCALEDATA

        memhandle = ul.scaled_win_buf_alloc(total_count)
        # Convert the memhandle to a ctypes array.
        # Use the memhandle_as_ctypes_array_scaled method for scaled
        # buffers.
        ctypes_array = util.memhandle_as_ctypes_array_scaled(memhandle)
    elif ai_props.resolution <= 16:
        # Use the win_buf_alloc method for devices with a resolution <= 16
        memhandle = ul.win_buf_alloc(total_count)
        # Convert the memhandle to a ctypes array.
        # Use the memhandle_as_ctypes_array method for devices with a
        # resolution <= 16.
        ctypes_array = util.memhandle_as_ctypes_array(memhandle)
    else:
        # Use the win_buf_alloc_32 method for devices with a resolution > 16
        memhandle = ul.win_buf_alloc_32(total_count)
        # Convert the memhandle to a ctypes array.
        # Use the memhandle_as_ctypes_array_32 method for devices with a
        # resolution > 16
        ctypes_array = util.memhandle_as_ctypes_array_32(memhandle)

    # Note: the ctypes array will no longer be valid after win_buf_free is
    # called.
    # A copy of the buffer can be created using win_buf_to_array or
    # win_buf_to_array_32 before the memory is freed. The copy can be used
    # at any time.

    # Check if the buffer was successfully allocated
    if not memhandle:
        print("Failed to allocate memory.")
        return

    try:
        # Start the scan
        ul.a_in_scan(board_num, low_chan, high_chan, total_count, rate,
                     ai_range, memhandle, scan_options)

        # Create a format string that aligns the data in columns
        row_format = "{:>12}" * num_chans

        # Print the channel name headers
        labels = []
        for ch_num in range(low_chan, high_chan + 1):
            labels.append("CH" + str(ch_num))
        print(row_format.format(*labels))

        # Start updating the displayed values
        status, curr_count, curr_index = ul.get_status(board_num,
                                                       FunctionType.AIFUNCTION)
        while status != Status.IDLE:
            # Make sure a data point is available for display.
            if curr_count > 0:
                # curr_index points to the start of the last completed
                # channel scan that was transferred between the board and
                # the data buffer. Display the latest value for each
                # channel.
                display_data = []
                for data_index in range(curr_index, curr_index + num_chans):
                    if ScanOptions.SCALEDATA in scan_options:
                        # If the SCALEDATA ScanOption was used, the values
                        # in the array are already in engineering units.
                        eng_value = ctypes_array[data_index]
                    else:
                        # If the SCALEDATA ScanOption was NOT used, the
                        # values in the array must be converted to
                        # engineering units using ul.to_eng_units().
                        eng_value = ul.to_eng_units(board_num, ai_range,
                                                    ctypes_array[data_index])
                    display_data.append('{:.3f}'.format(eng_value))
                print(row_format.format(*display_data))

            # Wait a while before adding more values to the display.
            time.sleep(0.5)

            status, curr_count, curr_index = ul.get_status(
                board_num, FunctionType.AIFUNCTION)

        # Stop the background operation (this is required even if the
        # scan completes successfully)
        ul.stop_background(board_num, FunctionType.AIFUNCTION)

        print("Scan completed successfully.")
    except ULError as e:
        util.print_ul_error(e)
    finally:
        # Free the buffer in a finally block to prevent errors from causing
        # a memory leak.
        ul.win_buf_free(memhandle)

        if use_device_detection:
            ul.release_daq_device(board_num)
Beispiel #12
0
def run_example():
    board_num = 0
    rate = 100
    file_name = 'scan_data.csv'

    # The size of the UL buffer to create, in seconds
    buffer_size_seconds = 2
    # The number of buffers to write. After this number of UL buffers are
    # written to file, the example will be stopped.
    num_buffers_to_write = 5

    if use_device_detection:
        ul.ignore_instacal()
        if not util.config_first_detected_device(board_num):
            print("Could not find device.")
            return

    ai_props = AnalogInputProps(board_num)
    if (ai_props.num_ai_chans < 1 or
            not ScanOptions.SCALEDATA in ai_props.supported_scan_options):
        util.print_unsupported_example(board_num)
        return

    low_chan = 0
    high_chan = min(3, ai_props.num_ai_chans - 1)
    num_chans = high_chan - low_chan + 1

    # Create a circular buffer that can hold buffer_size_seconds worth of
    # data, or at least 10 points (this may need to be adjusted to prevent
    # a buffer overrun)
    points_per_channel = max(rate * buffer_size_seconds, 10)

    # Some hardware requires that the total_count is an integer multiple
    # of the packet size. For this case, calculate a points_per_channel
    # that is equal to or just above the points_per_channel selected
    # which matches that requirement.
    if ai_props.continuous_requires_packet_size_multiple:
        packet_size = ai_props.packet_size
        remainder = points_per_channel % packet_size
        if remainder != 0:
            points_per_channel += packet_size - remainder

    ul_buffer_count = points_per_channel * num_chans

    # Write the UL buffer to the file num_buffers_to_write times.
    points_to_write = ul_buffer_count * num_buffers_to_write

    # When handling the buffer, we will read 1/10 of the buffer at a time
    write_chunk_size = int(ul_buffer_count / 10)

    ai_range = ai_props.available_ranges[0]

    scan_options = (ScanOptions.BACKGROUND | ScanOptions.CONTINUOUS |
                    ScanOptions.SCALEDATA)

    memhandle = ul.scaled_win_buf_alloc(ul_buffer_count)

    # Allocate an array of doubles temporary storage of the data
    write_chunk_array = (c_double * write_chunk_size)()

    # Check if the buffer was successfully allocated
    if not memhandle:
        print("Failed to allocate memory.")
        return

    try:
        # Start the scan
        ul.a_in_scan(
            board_num, low_chan, high_chan, ul_buffer_count,
            rate, ai_range, memhandle, scan_options)

        status = Status.IDLE
        # Wait for the scan to start fully
        while(status == Status.IDLE):
            status, _, _ = ul.get_status(
                board_num, FunctionType.AIFUNCTION)

        # Create a file for storing the data
        with open(file_name, 'w') as f:
            print('Writing data to ' + file_name, end='')

            # Write a header to the file
            for chan_num in range(low_chan, high_chan + 1):
                f.write('Channel ' + str(chan_num) + ',')
            f.write(u'\n')

            # Start the write loop
            prev_count = 0
            prev_index = 0
            write_ch_num = low_chan
            while status != Status.IDLE:
                # Get the latest counts
                status, curr_count, _ = ul.get_status(
                    board_num, FunctionType.AIFUNCTION)

                new_data_count = curr_count - prev_count

                # Check for a buffer overrun before copying the data, so
                # that no attempts are made to copy more than a full buffer
                # of data
                if new_data_count > ul_buffer_count:
                    # Print an error and stop writing
                    ul.stop_background(board_num, FunctionType.AIFUNCTION)
                    print("A buffer overrun occurred")
                    break

                # Check if a chunk is available
                if new_data_count > write_chunk_size:
                    wrote_chunk = True
                    # Copy the current data to a new array

                    # Check if the data wraps around the end of the UL
                    # buffer. Multiple copy operations will be required.
                    if prev_index + write_chunk_size > ul_buffer_count - 1:
                        first_chunk_size = ul_buffer_count - prev_index
                        second_chunk_size = (
                            write_chunk_size - first_chunk_size)

                        # Copy the first chunk of data to the
                        # write_chunk_array
                        ul.scaled_win_buf_to_array(
                            memhandle, write_chunk_array, prev_index,
                            first_chunk_size)

                        # Create a pointer to the location in
                        # write_chunk_array where we want to copy the
                        # remaining data
                        second_chunk_pointer = cast(
                            addressof(write_chunk_array) + first_chunk_size
                            * sizeof(c_double), POINTER(c_double))

                        # Copy the second chunk of data to the
                        # write_chunk_array
                        ul.scaled_win_buf_to_array(
                            memhandle, second_chunk_pointer,
                            0, second_chunk_size)
                    else:
                        # Copy the data to the write_chunk_array
                        ul.scaled_win_buf_to_array(
                            memhandle, write_chunk_array, prev_index,
                            write_chunk_size)

                    # Check for a buffer overrun just after copying the data
                    # from the UL buffer. This will ensure that the data was
                    # not overwritten in the UL buffer before the copy was
                    # completed. This should be done before writing to the
                    # file, so that corrupt data does not end up in it.
                    status, curr_count, _ = ul.get_status(
                        board_num, FunctionType.AIFUNCTION)
                    if curr_count - prev_count > ul_buffer_count:
                        # Print an error and stop writing
                        ul.stop_background(board_num, FunctionType.AIFUNCTION)
                        print("A buffer overrun occurred")
                        break

                    for i in range(write_chunk_size):
                        f.write(str(write_chunk_array[i]) + ',')
                        write_ch_num += 1
                        if write_ch_num == high_chan + 1:
                            write_ch_num = low_chan
                            f.write(u'\n')
                else:
                    wrote_chunk = False

                if wrote_chunk:
                    # Increment prev_count by the chunk size
                    prev_count += write_chunk_size
                    # Increment prev_index by the chunk size
                    prev_index += write_chunk_size
                    # Wrap prev_index to the size of the UL buffer
                    prev_index %= ul_buffer_count

                    if prev_count >= points_to_write:
                        break
                    print('.', end='')
                else:
                    # Wait a short amount of time for more data to be
                    # acquired.
                    time.sleep(0.1)

        ul.stop_background(board_num, FunctionType.AIFUNCTION)
    except ULError as e:
        util.print_ul_error(e)
    finally:
        print('Done')

        # Free the buffer in a finally block to prevent errors from causing
        # a memory leak.
        ul.win_buf_free(memhandle)

        if use_device_detection:
            ul.release_daq_device(board_num)
Beispiel #13
0
    def _readBG(self, file_name):
        # file_name = 'C:\\Users\\PVGroup\\Desktop\\frgmapper\\Data\\20190913\\test.data'
        # totalCount = len(self.channels['Number']) * self.__countsPerChannel
        # memhandle = ul.win_buf_alloc_64(totalCount)
        # ctypesArray = ctypes.cast(memhandle, ctypes.POINTER(ctypes.c_ulonglong))

        # The size of the UL buffer to create, in seconds
        buffer_size_seconds = 2
        # The number of buffers to write. After this number of UL buffers are
        # written to file, the example will be stopped.
        num_buffers_to_write = 2

        low_chan = 0
        high_chan = 1
        num_chans = high_chan - low_chan + 1

        # Create a circular buffer that can hold buffer_size_seconds worth of
        # data, or at least 10 points (this may need to be adjusted to prevent
        # a buffer overrun)
        points_per_channel = max(self.__rate * buffer_size_seconds, 10)

        # Some hardware requires that the total_count is an integer multiple
        # of the packet size. For this case, calculate a points_per_channel
        # that is equal to or just above the points_per_channel selected
        # which matches that requirement.
        # if ai_props.continuous_requires_packet_size_multiple:
        # 	packet_size = ai_props.packet_size
        # 	remainder = points_per_channel % packet_size
        # 	if remainder != 0:
        # 		points_per_channel += packet_size - remainder

        ul_buffer_count = points_per_channel * num_chans

        # Write the UL buffer to the file num_buffers_to_write times.
        points_to_write = ul_buffer_count * num_buffers_to_write

        # When handling the buffer, we will read 1/10 of the buffer at a time
        write_chunk_size = int(ul_buffer_count / 100)

        if self.useExtClock:
            scan_options = ScanOptions.BACKGROUND | ScanOptions.CONTINUOUS | ScanOptions.SCALEDATA | ScanOptions.EXTCLOCK
        else:
            scan_options = ScanOptions.BACKGROUND | ScanOptions.CONTINUOUS | ScanOptions.SCALEDATA

        memhandle = ul.scaled_win_buf_alloc(ul_buffer_count)

        # Allocate an array of doubles temporary storage of the data
        write_chunk_array = (c_double * write_chunk_size)()

        # Check if the buffer was successfully allocated
        if not memhandle:
            print("Failed to allocate memory.")
            return

        try:
            # Start the scan
            ul.daq_in_scan(board_num=self.board_num,
                           chan_list=self.channels['Number'],
                           chan_type_list=self.channels['Type'],
                           gain_list=self.channels['Gain'],
                           chan_count=len(self.channels['Number']),
                           rate=self.__rate,
                           pretrig_count=0,
                           total_count=ul_buffer_count,
                           memhandle=memhandle,
                           options=scan_options)

            status = Status.IDLE
            # Wait for the scan to start fully
            while (status == Status.IDLE):
                status, _, _ = ul.get_status(board_num,
                                             FunctionType.DAQIFUNCTION)

            # Create a file for storing the data
            with open(file_name, 'w') as f:
                # print('Writing data to ' + file_name, end='')

                # Write a header to the file
                # for chan_num in range(low_chan, high_chan + 1):
                # 	f.write('Channel ' + str(chan_num) + ',')
                # f.write(u'\n')

                # Start the write loop
                prev_count = 0
                prev_index = 0
                write_ch_num = low_chan
                keepReading = True
                while status != Status.IDLE and keepReading:
                    # Get the latest counts
                    status, curr_count, _ = ul.get_status(
                        board_num, FunctionType.DAQIFUNCTION)

                    new_data_count = curr_count - prev_count

                    # Check for a buffer overrun before copying the data, so
                    # that no attempts are made to copy more than a full buffer
                    # of data
                    if new_data_count > ul_buffer_count:
                        # Print an error and stop writing
                        ul.stop_background(board_num,
                                           FunctionType.DAQIFUNCTION)
                        print("A buffer overrun occurred")
                        break

                    # Check if a chunk is available
                    if new_data_count > write_chunk_size:
                        wrote_chunk = True
                        # Copy the current data to a new array

                        # Check if the data wraps around the end of the UL
                        # buffer. Multiple copy operations will be required.
                        if prev_index + write_chunk_size > ul_buffer_count - 1:
                            first_chunk_size = ul_buffer_count - prev_index
                            second_chunk_size = (write_chunk_size -
                                                 first_chunk_size)

                            # Copy the first chunk of data to the
                            # write_chunk_array
                            ul.scaled_win_buf_to_array(memhandle,
                                                       write_chunk_array,
                                                       prev_index,
                                                       first_chunk_size)

                            # Create a pointer to the location in
                            # write_chunk_array where we want to copy the
                            # remaining data
                            second_chunk_pointer = cast(
                                addressof(write_chunk_array) +
                                first_chunk_size * sizeof(c_double),
                                POINTER(c_double))

                            # Copy the second chunk of data to the
                            # write_chunk_array
                            ul.scaled_win_buf_to_array(memhandle,
                                                       second_chunk_pointer, 0,
                                                       second_chunk_size)
                        else:
                            # Copy the data to the write_chunk_array
                            ul.scaled_win_buf_to_array(memhandle,
                                                       write_chunk_array,
                                                       prev_index,
                                                       write_chunk_size)

                        # Check for a buffer overrun just after copying the data
                        # from the UL buffer. This will ensure that the data was
                        # not overwritten in the UL buffer before the copy was
                        # completed. This should be done before writing to the
                        # file, so that corrupt data does not end up in it.
                        status, curr_count, _ = ul.get_status(
                            board_num, FunctionType.DAQIFUNCTION)
                        if curr_count - prev_count > ul_buffer_count:
                            # Print an error and stop writing
                            ul.stop_background(board_num,
                                               FunctionType.DAQIFUNCTION)
                            print("A buffer overrun occurred")
                            break

                        for i in range(write_chunk_size):
                            f.write(str(write_chunk_array[i]))
                            write_ch_num += 1
                            if write_ch_num == high_chan + 1:
                                write_ch_num = low_chan
                                f.write(u'\n')
                            else:
                                f.write(',')
                    else:
                        wrote_chunk = False

                    if wrote_chunk:
                        # Increment prev_count by the chunk size
                        prev_count += write_chunk_size
                        # Increment prev_index by the chunk size
                        prev_index += write_chunk_size
                        # Wrap prev_index to the size of the UL buffer
                        prev_index %= ul_buffer_count
                        if not self.acquiringBG:  #make sure to wait until after writing to check if we should stop to avoid truncation
                            keepReading = False
                        # if prev_count >= points_to_write:
                        # 	break
                        # f.write('-----\n')
                        # print('.', end='')
                    else:
                        # Wait a short amount of time for more data to be
                        # acquired.
                        time.sleep(0.01)

            ul.stop_background(board_num, FunctionType.DAQIFUNCTION)
        except ULError as e:
            pass
        finally:
            # print('Done')

            # Free the buffer in a finally block to prevent errors from causing
            # a memory leak.
            ul.win_buf_free(memhandle)
Beispiel #14
0
def run_example():
    # By default, the example detects and displays all available devices and
    # selects the first device listed. Use the dev_id_list variable to filter
    # detected devices by device ID (see UL documentation for device IDs).
    # If use_device_detection is set to False, the board_num variable needs to
    # match the desired board number configured with Instacal.
    use_device_detection = True
    dev_id_list = []
    board_num = 0
    rate = 100
    file_name = 'scan_data.csv'
    memhandle = None

    # The size of the UL buffer to create, in seconds
    buffer_size_seconds = 2
    # The number of buffers to write. After this number of UL buffers are
    # written to file, the example will be stopped.
    num_buffers_to_write = 5

    try:
        if use_device_detection:
            config_first_detected_device(board_num, dev_id_list)

        daq_dev_info = DaqDeviceInfo(board_num)
        if not daq_dev_info.supports_analog_input:
            raise Exception('Error: The DAQ device does not support '
                            'analog input')

        print('\nActive DAQ device: ', daq_dev_info.product_name, ' (',
              daq_dev_info.unique_id, ')\n', sep='')

        ai_info = daq_dev_info.get_ai_info()

        low_chan = 0
        high_chan = min(3, ai_info.num_chans - 1)
        num_chans = high_chan - low_chan + 1

        # Create a circular buffer that can hold buffer_size_seconds worth of
        # data, or at least 10 points (this may need to be adjusted to prevent
        # a buffer overrun)
        points_per_channel = max(rate * buffer_size_seconds, 10)

        # Some hardware requires that the total_count is an integer multiple
        # of the packet size. For this case, calculate a points_per_channel
        # that is equal to or just above the points_per_channel selected
        # which matches that requirement.
        if ai_info.packet_size != 1:
            packet_size = ai_info.packet_size
            remainder = points_per_channel % packet_size
            if remainder != 0:
                points_per_channel += packet_size - remainder

        ul_buffer_count = points_per_channel * num_chans

        # Write the UL buffer to the file num_buffers_to_write times.
        points_to_write = ul_buffer_count * num_buffers_to_write

        # When handling the buffer, we will read 1/10 of the buffer at a time
        write_chunk_size = int(ul_buffer_count / 10)

        ai_range = ai_info.supported_ranges[0]

        scan_options = (ScanOptions.BACKGROUND | ScanOptions.CONTINUOUS |
                        ScanOptions.SCALEDATA)

        memhandle = ul.scaled_win_buf_alloc(ul_buffer_count)

        # Allocate an array of doubles temporary storage of the data
        write_chunk_array = (c_double * write_chunk_size)()

        # Check if the buffer was successfully allocated
        if not memhandle:
            raise Exception('Failed to allocate memory')

        # Start the scan
        ul.a_in_scan(
            board_num, low_chan, high_chan, ul_buffer_count,
            rate, ai_range, memhandle, scan_options)

        status = Status.IDLE
        # Wait for the scan to start fully
        while status == Status.IDLE:
            status, _, _ = ul.get_status(board_num, FunctionType.AIFUNCTION)

        # Create a file for storing the data
        with open(file_name, 'w') as f:
            print('Writing data to ' + file_name, end='')

            # Write a header to the file
            for chan_num in range(low_chan, high_chan + 1):
                f.write('Channel ' + str(chan_num) + ',')
            f.write(u'\n')

            # Start the write loop
            prev_count = 0
            prev_index = 0
            write_ch_num = low_chan
            while status != Status.IDLE:
                # Get the latest counts
                status, curr_count, _ = ul.get_status(board_num,
                                                      FunctionType.AIFUNCTION)

                new_data_count = curr_count - prev_count

                # Check for a buffer overrun before copying the data, so
                # that no attempts are made to copy more than a full buffer
                # of data
                if new_data_count > ul_buffer_count:
                    # Print an error and stop writing
                    ul.stop_background(board_num, FunctionType.AIFUNCTION)
                    print('A buffer overrun occurred')
                    break

                # Check if a chunk is available
                if new_data_count > write_chunk_size:
                    wrote_chunk = True
                    # Copy the current data to a new array

                    # Check if the data wraps around the end of the UL
                    # buffer. Multiple copy operations will be required.
                    if prev_index + write_chunk_size > ul_buffer_count - 1:
                        first_chunk_size = ul_buffer_count - prev_index
                        second_chunk_size = (
                            write_chunk_size - first_chunk_size)

                        # Copy the first chunk of data to the
                        # write_chunk_array
                        ul.scaled_win_buf_to_array(
                            memhandle, write_chunk_array, prev_index,
                            first_chunk_size)

                        # Create a pointer to the location in
                        # write_chunk_array where we want to copy the
                        # remaining data
                        second_chunk_pointer = cast(addressof(write_chunk_array)
                                                    + first_chunk_size
                                                    * sizeof(c_double),
                                                    POINTER(c_double))

                        # Copy the second chunk of data to the
                        # write_chunk_array
                        ul.scaled_win_buf_to_array(
                            memhandle, second_chunk_pointer,
                            0, second_chunk_size)
                    else:
                        # Copy the data to the write_chunk_array
                        ul.scaled_win_buf_to_array(
                            memhandle, write_chunk_array, prev_index,
                            write_chunk_size)

                    # Check for a buffer overrun just after copying the data
                    # from the UL buffer. This will ensure that the data was
                    # not overwritten in the UL buffer before the copy was
                    # completed. This should be done before writing to the
                    # file, so that corrupt data does not end up in it.
                    status, curr_count, _ = ul.get_status(
                        board_num, FunctionType.AIFUNCTION)
                    if curr_count - prev_count > ul_buffer_count:
                        # Print an error and stop writing
                        ul.stop_background(board_num, FunctionType.AIFUNCTION)
                        print('A buffer overrun occurred')
                        break

                    for i in range(write_chunk_size):
                        f.write(str(write_chunk_array[i]) + ',')
                        write_ch_num += 1
                        if write_ch_num == high_chan + 1:
                            write_ch_num = low_chan
                            f.write(u'\n')
                else:
                    wrote_chunk = False

                if wrote_chunk:
                    # Increment prev_count by the chunk size
                    prev_count += write_chunk_size
                    # Increment prev_index by the chunk size
                    prev_index += write_chunk_size
                    # Wrap prev_index to the size of the UL buffer
                    prev_index %= ul_buffer_count

                    if prev_count >= points_to_write:
                        break
                    print('.', end='')
                else:
                    # Wait a short amount of time for more data to be
                    # acquired.
                    sleep(0.1)

        ul.stop_background(board_num, FunctionType.AIFUNCTION)
    except Exception as e:
        print('\n', e)
    finally:
        print('Done')
        if memhandle:
            # Free the buffer in a finally block to prevent  a memory leak.
            ul.win_buf_free(memhandle)
        if use_device_detection:
            ul.release_daq_device(board_num)
 def give_curr_count(self):
     status, curr_count, curr_index = ul.get_status(self.board_num,
                                                    FunctionType.AOFUNCTION)
     return curr_count
Beispiel #16
0
 def _get_supports_scan(self):
     try:
         ul.get_status(self._board_num, FunctionType.AIFUNCTION)
     except ULError:
         return False
     return True
Beispiel #17
0
def run_example():
    board_num = 0

    if use_device_detection:
        ul.ignore_instacal()
        if not util.config_first_detected_device(board_num):
            print("Could not find device.")
            return

    ao_props = AnalogOutputProps(board_num)
    if ao_props.num_chans < 1:
        util.print_unsupported_example(board_num)
        return

    low_chan = 0
    high_chan = min(3, ao_props.num_chans - 1)
    num_chans = high_chan - low_chan + 1

    rate = 100
    points_per_channel = 1000
    total_count = points_per_channel * num_chans

    ao_range = ao_props.available_ranges[0]

    # Allocate a buffer for the scan
    memhandle = ul.win_buf_alloc(total_count)
    # Convert the memhandle to a ctypes array
    # Note: the ctypes array will no longer be valid after win_buf_free
    # is called.
    # A copy of the buffer can be created using win_buf_to_array
    # before the memory is freed. The copy can be used at any time.
    ctypes_array = util.memhandle_as_ctypes_array(memhandle)

    # Check if the buffer was successfully allocated
    if not memhandle:
        print("Failed to allocate memory.")
        return

    frequencies = add_example_data(board_num, ctypes_array, ao_range,
                                   num_chans, rate, points_per_channel)

    for ch_num in range(low_chan, high_chan + 1):
        print("Channel " + str(ch_num) + " Output Signal Frequency: " +
              str(frequencies[ch_num - low_chan]))

    try:
        # Start the scan
        ul.a_out_scan(board_num, low_chan, high_chan, total_count, rate,
                      ao_range, memhandle, ScanOptions.BACKGROUND)

        # Wait for the scan to complete
        print("Waiting for output scan to complete...", end="")
        status = Status.RUNNING
        while status != Status.IDLE:
            print(".", end="")

            # Slow down the status check so as not to flood the CPU
            time.sleep(0.5)

            status, _, _ = ul.get_status(board_num, FunctionType.AOFUNCTION)
        print("")

        print("Scan completed successfully.")
    except ULError as e:
        util.print_ul_error(e)
    finally:
        # Free the buffer in a finally block to prevent errors from causing
        # a memory leak.
        ul.win_buf_free(memhandle)
        if use_device_detection:
            ul.release_daq_device(board_num)
Beispiel #18
0
def apply_and_listen(waveform_1d,
                     nzeros_front,
                     nzeros_back,
                     in_channel_start=0,
                     in_channel_end=0,
                     out_channel_start=0,
                     out_channel_end=0,
                     rate=1000000,
                     board_number=0,
                     ul_range=ULRange.BIP10VOLTS,
                     quiet=False,
                     **kwargs):
    """
    Apply a waveform and listen to collect data. Simultaneous output and collection of data. 

    args:
        waveform_1d (numpy.array): Serialized waveform
        nzeros_front (int): Number of zeros padding front of waveform
        nzeros_back (int): Number of zeros padding back of waveform
        in_channel_start (int= 0): Specify which start channel to use when listening and collecting incoming waveform.
        in_channel_end (int= 0): Specify which end channel to use when listening and collecting incoming waveform.
        out_channel_start (int= 0): Specify which start channel to use when outputting the waveform. 
        out_channel_end (int = 0): Specify which end channel to use when outputting waveform. 
        rate (int = 1000000): Rate for daq
        board_number (int = 0): 
        ul_range (ULRange): Range for daq
        quiet (bool): Specify verbosity

    returns:
        (memhandle_in, memhandle_out, data_array_in, data_array_out, count_in, time)


    waveform_1d should be serialized into 1d for all channels
    
    output comes on channels continuous from out_channel_start to out_channel_end
    
    return: memhandle_in, memhandle_out, data_array_in, data_array_out, count_in
    """
    count_out = len(waveform_1d)
    nchannel_out = out_channel_end - out_channel_start + 1
    nchannel_in = in_channel_end - in_channel_start + 1

    rate = int(rate / nchannel_in)
    len_data_without_zeros = (len(waveform_1d) - nzeros_front - nzeros_back)
    period_of_wf = (int(len_data_without_zeros / nchannel_out) / rate)
    if not quiet:
        print('period:', period_of_wf * 1e6, 'us')

    trigger_rate = int((count_out - nzeros_front - nzeros_back) / nchannel_out)

    # Allocate the buffer and cast it to an unsigned short
    memhandle_out = ul.win_buf_alloc(count_out)
    data_array_out = ctypes.cast(memhandle_out, ctypes.POINTER(
        ctypes.c_ushort))  #data_array now points to the correct memory

    # Calculate and store the waveform in Windows buffer
    for i, y in enumerate(waveform_1d):
        data_array_out[i] = int(y)

    count_in = int(nchannel_in * count_out / (nchannel_out))

    memhandle_in = ul.win_buf_alloc(count_in)
    data_array_in = ctypes.cast(memhandle_in, ctypes.POINTER(ctypes.c_ushort))

    options = (None, )

    # Output the waveform
    #import pdb; pdb.set_trace()
    ul.a_in_scan(board_number, in_channel_start, in_channel_end, count_in,
                 rate, ul_range, memhandle_in,
                 ScanOptions.EXTTRIGGER | ScanOptions.BACKGROUND)
    ul.a_out_scan(board_number, out_channel_start, out_channel_end, count_out,
                  rate, ul_range, memhandle_out,
                  ScanOptions.EXTTRIGGER | ScanOptions.BACKGROUND)
    ul.pulse_out_start(0, 0, rate, 0.5)

    while ul.get_status(
            0, FunctionType.AOFUNCTION).status != 0:  #poor mans foreground
        continue

    ul.pulse_out_stop(0, 0)

    ul.stop_background(0, FunctionType.AOFUNCTION)
    ul.stop_background(0, FunctionType.AIFUNCTION)

    timestep = period_of_wf / len_data_without_zeros

    time = []

    for i in range(int(count_out / nchannel_out)):
        shiftedi = i - nzeros_front
        time.append(shiftedi * timestep)

    time = np.array(time)

    return memhandle_in, memhandle_out, data_array_in, data_array_out, count_in, time
Beispiel #19
0
def run_example():
    # By default, the example detects and displays all available devices and
    # selects the first device listed. Use the dev_id_list variable to filter
    # detected devices by device ID (see UL documentation for device IDs).
    # If use_device_detection is set to False, the board_num variable needs to
    # match the desired board number configured with Instacal.
    use_device_detection = True
    dev_id_list = []
    board_num = 0
    memhandle = None

    try:
        if use_device_detection:
            config_first_detected_device(board_num, dev_id_list)

        daq_dev_info = DaqDeviceInfo(board_num)
        if not daq_dev_info.supports_analog_output:
            raise Exception('Error: The DAQ device does not support '
                            'analog output')

        print('\nActive DAQ device: ',
              daq_dev_info.product_name,
              ' (',
              daq_dev_info.unique_id,
              ')\n',
              sep='')

        ao_info = daq_dev_info.get_ao_info()

        low_chan = 0
        high_chan = min(3, ao_info.num_chans - 1)
        num_chans = high_chan - low_chan + 1

        rate = 100
        points_per_channel = 1000
        total_count = points_per_channel * num_chans

        ao_range = ao_info.supported_ranges[0]

        # Allocate a buffer for the scan
        memhandle = ul.win_buf_alloc(total_count)
        # Convert the memhandle to a ctypes array
        # Note: the ctypes array will no longer be valid after win_buf_free
        # is called.
        # A copy of the buffer can be created using win_buf_to_array
        # before the memory is freed. The copy can be used at any time.
        ctypes_array = cast(memhandle, POINTER(c_ushort))

        # Check if the buffer was successfully allocated
        if not memhandle:
            raise Exception('Error: Failed to allocate memory')

        frequencies = add_example_data(board_num, ctypes_array, ao_range,
                                       num_chans, rate, points_per_channel)

        for ch_num in range(low_chan, high_chan + 1):
            print('Channel', ch_num, 'Output Signal Frequency:',
                  frequencies[ch_num - low_chan])

        # Start the scan
        ul.a_out_scan(board_num, low_chan, high_chan, total_count, rate,
                      ao_range, memhandle, ScanOptions.BACKGROUND)

        # Wait for the scan to complete
        print('Waiting for output scan to complete...', end='')
        status = Status.RUNNING
        while status != Status.IDLE:
            print('.', end='')

            # Slow down the status check so as not to flood the CPU
            sleep(0.5)

            status, _, _ = ul.get_status(board_num, FunctionType.AOFUNCTION)
        print('')

        print('Scan completed successfully')
    except Exception as e:
        print('\n', e)
    finally:
        if memhandle:
            # Free the buffer in a finally block to prevent a memory leak.
            ul.win_buf_free(memhandle)
        if use_device_detection:
            ul.release_daq_device(board_num)