Measurement Computing   Easy to Use | Easy to Integrate | Easy to Support catalog banner

Python for Windows USB-QUAD08 Example

Expand / Collapse
 

Python for Windows USB-QUAD08 Example


The following Python for Windows example demonstrates device discovery and a continuous background acquisition. 

Once started, the acquisition is monitored using the get status function that returns total count and buffer index position. Data is retrieved from the device buffer when it is more than half full (index > half). When this happens, it transfers data from the device buffer to the user buffer. The acquisition loop continues to monitor the index and when it rolls over to zero, transfers data from the upper half of the device buffer. It continues to do this back-n-forth or ping-ponging between the low and upper halves. 

Channel 0 is configured to read a quadrature encoder and channel 1 will provide a totalize count. 

To install the Python for Windows support, copy the following URL into your browser and follow the instructions provided.
https://github.com/mccdaq/mcculw

This example was built using Python 3.8.5 and PyCharm. The code module is provided via a download link at the end of this article.

from __future__ import absolute_import, division, print_function

import time

from builtins import *  # @UnusedWildImport
from time import sleep
from ctypes import cast, POINTER, c_double, c_ushort, c_ulong
from mcculw import ul
from mcculw.enums import ScanOptions, FunctionType, Status
from mcculw.ul import ULError, a_input_mode
from mcculw.enums import InterfaceType
from mcculw.enums import CounterMode
from mcculw.enums import CounterDebounceMode
from mcculw.enums import CounterDebounceTime
from mcculw.enums import CounterEdgeDetection
from mcculw.enums import CounterTickSize


use_device_detection = True


def run_example():
    board_num = 0
    board_index = 0
    find_device = "USB-QUAD08"
    if use_device_detection:
        board_num = -1
        ul.ignore_instacal()
        dev_list = ul.get_daq_device_inventory(InterfaceType.USB)
        if len(dev_list) > 0:
            for device in dev_list:
                if str(device) == find_device:
                    print(f"Found {find_device} board number = {board_index}")
                    print(f"Serial number: {device.unique_id}")
                    print(f"Product type: {hex(device.product_id)}")
                    board_num = board_index
                    ul.create_daq_device(board_num, device)
                board_index = board_index + 1
            if board_num == -1:
                print(f"Device {find_device} not found")
                return
        else:
            print("No devices detected")
            return
    # **********End of Discovery************

    rate = 200
    points_per_channel = 40
    low_chan = 0
    high_chan = 1
    num_chans = 2

    total_count = points_per_channel * num_chans
    half_count = int(total_count / 2)
    # The SCALEDATA option, returns volts instead of A/D counts
    scan_options = ScanOptions.CONTINUOUS | ScanOptions.BACKGROUND | ScanOptions.CTR32BIT

    memhandle = ul.win_buf_alloc_32(total_count)
    buf_data = cast(memhandle, POINTER(c_ulong))

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


    try:
        ul.c_config_scan(board_num,
                         low_chan,
                         CounterMode.ENCODER | CounterMode.ENCODER_MODE_BIT_32,
                         CounterDebounceTime.DEBOUNCE500ns,
                         CounterDebounceMode.TRIGGER_AFTER_STABLE,
                         CounterEdgeDetection.RISING_EDGE,
                         CounterTickSize.TICK20PT83ns,
                         low_chan )

        ul.c_config_scan(board_num,
                         high_chan,
                         CounterMode.TOTALIZE | CounterMode.BIT_32,
                         CounterDebounceTime.DEBOUNCE500ns,
                         CounterDebounceMode.TRIGGER_AFTER_STABLE,
                         CounterEdgeDetection.RISING_EDGE,
                         CounterTickSize.TICK20PT83ns,
                         high_chan)


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

        # Create a format string that aligns the data in columns

        # plus two for curr_index and curr_count
        row_format = "{:8}" * (num_chans)

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

        print(row_format.format(*labels))

        # boolean flag used to toggle reading upper and lower buffer
        read_lower = True
        # Start updating the displayed values
        status, curr_count, curr_index = ul.get_status(
            board_num, FunctionType.CTRFUNCTION)

        last = 0
        diff = 0
        while status != Status.IDLE and curr_count < 5000:
            # 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 = []
                if (curr_index > half_count) and (read_lower == True):

                    ul.win_buf_to_array_32(memhandle, buf_data, 0, int(half_count))
                    print('{:d}\t\t{:d}'.format(buf_data[0], buf_data[1]))
                    read_lower = False

                elif (curr_index < half_count) and (read_lower == False):

                    ul.win_buf_to_array_32(memhandle, buf_data, int(half_count), int(half_count))
                    print('{:d}\t\t{:d}'.format(buf_data[0], buf_data[1]))
                    read_lower = True

            sleep(0.1)
            status, curr_count, curr_index = ul.get_status(
                board_num, FunctionType.CTRFUNCTION)

        # 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:
        print("UL error\n", 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)


if __name__ == '__main__':
    run_example()



Rate this Article:

Attachments


C_ConfigScanQuad08.py C_ConfigScanQuad08.py (5.49 KB, 46 views)

Add Your Comments


For comments email TechSupport@mccdaq.com.

Details
Article ID: 50831

Last Modified:3/2/2021 8:29:47 AM

Article has been viewed 392 times.

Options