简体   繁体   中英

Analog Discovery 2 with Python API

I ma using the AD2 and I am trying to get python to control it. I followed the intrusions here https://digilent.com/reference/test-and-measurement/guides/waveforms-sdk-getting-started

I have tied the positive Power Supply to Scope Ch. 1 positive and Ground to Scope Ch. 1 negative, I have tied the negative Power Supply to Scope Ch. 2 positive and Ground to Scope Ch. 2 negative just as a simple test.

in the code I connected to the AD2 then I set up the the variable power supply to output +3V and -2V.

the I opened the oscilloscope and and tried to ready the voltages on the two channels and one last measurement I tried to use the multimeter. all I get as an output 0.0

any help world be great because this involves some hardware if you have an idea on how to fic my problem but you don't have the AD2 I am able to arange a zoom meeting so you can see the testing, or if you have some already written code that you know works and would be willing to shar it would be great

import ctypes                     # import the C compatible data types
from sys import platform, path    # this is needed to check the OS type and get the PATH
from os import sep                # OS specific file path separators
 
# load the dynamic library, get constants path (the path is OS specific)
if platform.startswith("win"):
    # on Windows
    dwf = ctypes.cdll.dwf
    constants_path = "C:" + sep + "Program Files (x86)" + sep + "Digilent" + sep + "WaveFormsSDK" + sep + "samples" + sep + "py"
elif platform.startswith("darwin"):
    # on macOS
    lib_path = sep + "Library" + sep + "Frameworks" + sep + "dwf.framework" + sep + "dwf"
    dwf = ctypes.cdll.LoadLibrary(lib_path)
    constants_path = sep + "Applications" + sep + "WaveForms.app" + sep + "Contents" + sep + "Resources" + sep + "SDK" + sep + "samples" + sep + "py"
else:
    # on Linux
    dwf = ctypes.cdll.LoadLibrary("libdwf.so")
    constants_path = sep + "usr" + sep + "share" + sep + "digilent" + sep + "waveforms" + sep + "samples" + sep + "py"
 
# import constants
path.append(constants_path)

import dwfconstants as constants

class data:
    """
        stores the device handle and the device name
    """
    handle = ctypes.c_int(0)
    name = ""

    """ stores the sampling frequency and the buffer size """
    sampling_frequency = 20e06
    buffer_size = 8192
 
def open_AD2():
    """
        open the first available device
    """
    # this is the device handle - it will be used by all functions to "address" the connected device
    device_handle = ctypes.c_int()

    # connect to the first available device
    dwf.FDwfDeviceOpen(ctypes.c_int(-1), ctypes.byref(device_handle))
    data.handle = device_handle
    return data

def open_oscilloscope(device_data, sampling_frequency=20e06, buffer_size=8192, offset=0, amplitude_range=5):
    """
        initialize the oscilloscope
        parameters: - device data
                    - sampling frequency in Hz, default is 20MHz
                    - buffer size, default is 8192
                    - offset voltage in Volts, default is 0V
                    - amplitude range in Volts, default is ±5V
    """
    # enable all channels
    dwf.FDwfAnalogInChannelEnableSet(device_data.handle, ctypes.c_int(0), ctypes.c_bool(True))
 
    # set offset voltage (in Volts)
    dwf.FDwfAnalogInChannelOffsetSet(device_data.handle, ctypes.c_int(0), ctypes.c_double(offset))
 
    # set range (maximum signal amplitude in Volts)
    dwf.FDwfAnalogInChannelRangeSet(device_data.handle, ctypes.c_int(0), ctypes.c_double(amplitude_range))
 
    # set the buffer size (data point in a recording)
    dwf.FDwfAnalogInBufferSizeSet(device_data.handle, ctypes.c_int(buffer_size))
 
    # set the acquisition frequency (in Hz)
    dwf.FDwfAnalogInFrequencySet(device_data.handle, ctypes.c_double(sampling_frequency))
 
    # disable averaging (for more info check the documentation)
    dwf.FDwfAnalogInChannelFilterSet(device_data.handle, ctypes.c_int(-1), constants.filterDecimate)
    data.sampling_frequency = sampling_frequency
    data.buffer_size = buffer_size
    return

def measure_oscilloscope(device_data, channel):
    """
        measure a voltage
        parameters: - device data
                    - the selected oscilloscope channel (1-2, or 1-4)
 
        returns:    - the measured voltage in Volts
    """
    # set up the instrument
    dwf.FDwfAnalogInConfigure(device_data.handle, ctypes.c_bool(False), ctypes.c_bool(False))
 
    # read data to an internal buffer
    dwf.FDwfAnalogInStatus(device_data.handle, ctypes.c_bool(False), ctypes.c_int(0))
 
    # extract data from that buffer
    voltage = ctypes.c_double()   # variable to store the measured voltage
    dwf.FDwfAnalogInStatusSample(device_data.handle, ctypes.c_int(channel - 1), ctypes.byref(voltage))
 
    # store the result as float
    voltage = voltage.value
    return voltage

def record_oscilloscope(device_data, channel):
    """
        record an analog signal
        parameters: - device data
                    - the selected oscilloscope channel (1-2, or 1-4)
        returns:    - buffer - a list with the recorded voltages
                    - time - a list with the time moments for each voltage in seconds (with the same index as "buffer")
    """
    # set up the instrument
    dwf.FDwfAnalogInConfigure(device_data.handle, ctypes.c_bool(False), ctypes.c_bool(True))
 
    # read data to an internal buffer
    while True:
        status = ctypes.c_byte()    # variable to store buffer status
        dwf.FDwfAnalogInStatus(device_data.handle, ctypes.c_bool(True), ctypes.byref(status))
 
        # check internal buffer status
        if status.value == constants.DwfStateDone.value:
                # exit loop when ready
                break
 
    # copy buffer
    buffer = (ctypes.c_double * data.buffer_size)()   # create an empty buffer
    dwf.FDwfAnalogInStatusData(device_data.handle, ctypes.c_int(channel - 1), buffer, ctypes.c_int(data.buffer_size))
 
    # calculate aquisition time
    time = range(0, data.buffer_size)
    time = [moment / data.sampling_frequency for moment in time]
 
    # convert into list
    buffer = [float(element) for element in buffer]
    return buffer, time

def close_oscilloscope(device_data):
    """
        reset the scope
    """
    dwf.FDwfAnalogInReset(device_data.handle)
    return

class function:
    """ function names """
    custom = constants.funcCustom
    sine = constants.funcSine
    square = constants.funcSquare
    triangle = constants.funcTriangle
    noise = constants.funcNoise
    dc = constants.funcDC
    pulse = constants.funcPulse
    trapezium = constants.funcTrapezium
    sine_power = constants.funcSinePower
    ramp_up = constants.funcRampUp
    ramp_down = constants.funcRampDown

def generate_function(device_data, channel, function, offset, frequency=1e03, amplitude=1, symmetry=50, wait=0, run_time=0, repeat=0, data=[]):
    """
        generate an analog signal
        parameters: - device data
                    - the selected wavegen channel (1-2)
                    - function - possible: custom, sine, square, triangle, noise, ds, pulse, trapezium, sine_power, ramp_up, ramp_down
                    - offset voltage in Volts
                    - frequency in Hz, default is 1KHz
                    - amplitude in Volts, default is 1V
                    - signal symmetry in percentage, default is 50%
                    - wait time in seconds, default is 0s
                    - run time in seconds, default is infinite (0)
                    - repeat count, default is infinite (0)
                    - data - list of voltages, used only if function=custom, default is empty
    """
    # enable channel
    channel = ctypes.c_int(channel - 1)
    dwf.FDwfAnalogOutNodeEnableSet(device_data.handle, channel, constants.AnalogOutNodeCarrier, ctypes.c_bool(True))
 
    # set function type
    dwf.FDwfAnalogOutNodeFunctionSet(device_data.handle, channel, constants.AnalogOutNodeCarrier, function)
 
    # load data if the function type is custom
    if function == constants.funcCustom:
        data_length = len(data)
        buffer = (ctypes.c_double * data_length)()
        for index in range(0, len(buffer)):
            buffer[index] = ctypes.c_double(data[index])
        dwf.FDwfAnalogOutNodeDataSet(device_data.handle, channel, constants.AnalogOutNodeCarrier, buffer, ctypes.c_int(data_length))
 
    # set frequency
    dwf.FDwfAnalogOutNodeFrequencySet(device_data.handle, channel, constants.AnalogOutNodeCarrier, ctypes.c_double(frequency))
 
    # set amplitude or DC voltage
    dwf.FDwfAnalogOutNodeAmplitudeSet(device_data.handle, channel, constants.AnalogOutNodeCarrier, ctypes.c_double(amplitude))
 
    # set offset
    dwf.FDwfAnalogOutNodeOffsetSet(device_data.handle, channel, constants.AnalogOutNodeCarrier, ctypes.c_double(offset))
 
    # set symmetry
    dwf.FDwfAnalogOutNodeSymmetrySet(device_data.handle, channel, constants.AnalogOutNodeCarrier, ctypes.c_double(symmetry))
 
    # set running time limit
    dwf.FDwfAnalogOutRunSet(device_data.handle, channel, ctypes.c_double(run_time))
 
    # set wait time before start
    dwf.FDwfAnalogOutWaitSet(device_data.handle, channel, ctypes.c_double(wait))
 
    # set number of repeating cycles
    dwf.FDwfAnalogOutRepeatSet(device_data.handle, channel, ctypes.c_int(repeat))
 
    # start
    dwf.FDwfAnalogOutConfigure(device_data.handle, channel, ctypes.c_bool(True))
    return

def close_function(device_data, channel=0):
    """
        reset a wavegen channel, or all channels (channel=0)
    """
    channel = ctypes.c_int(channel - 1)
    dwf.FDwfAnalogOutReset(device_data.handle, channel)
    return

def _switch_fixed(device_data, master_state, positive_state, negative_state):
    """
        turn the power supplies on/off
        parameters: - device data
                    - master switch - True = on, False = off
                    - positive supply switch - True = on, False = off
                    - negative supply switch - True = on, False = off
    """
    # enable/disable the positive supply
    dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(0), ctypes.c_int(0), ctypes.c_int(positive_state))
 
    # enable the negative supply
    dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(1), ctypes.c_int(0), ctypes.c_int(negative_state))
 
    # start/stop the supplies - master switch
    dwf.FDwfAnalogIOEnableSet(device_data.handle, ctypes.c_int(master_state))
    return

def _switch_variable_(device_data, master_state, positive_state, negative_state, positive_voltage, negative_voltage):
    """
        turn the power supplies on/off
        parameters: - device data
                    - master switch - True = on, False = off
                    - positive supply switch - True = on, False = off
                    - negative supply switch - True = on, False = off
                    - positive supply voltage in Volts
                    - negative supply voltage in Volts
    """
    # set positive voltage
    positive_voltage = max(0, min(5, positive_voltage))
    dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(0), ctypes.c_int(1), ctypes.c_double(positive_voltage))
 
    # set negative voltage
    negative_voltage = max(-5, min(0, negative_voltage))
    dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(1), ctypes.c_int(1), ctypes.c_double(negative_voltage))
 
    # enable/disable the positive supply
    dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(0), ctypes.c_int(0), ctypes.c_int(positive_state))
 
    # enable the negative supply
    dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(1), ctypes.c_int(0), ctypes.c_int(negative_state))
 
    # start/stop the supplies - master switch
    dwf.FDwfAnalogIOEnableSet(device_data.handle, ctypes.c_int(master_state))
    return

def open_multimeter(device_data):
    """
        initialize the digital multimeter
    """
    # enable the DMM
    dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(3), ctypes.c_int(0), ctypes.c_double(1.0))
    return

def measure_multimeter(device_data, mode, ac=False, range=0, high_impedance=False):
    """
        measure a voltage/current/resistance/continuity/temperature
        parameters: - device data
                    - mode: "voltage", "low current", "high current", "resistance", "continuity", "diode", "temperature"
                    - ac: True means AC value, False means DC value, default is DC
                    - range: voltage/current/resistance/temperature range, 0 means auto, default is auto
                    - high_impedance: input impedance for DC voltage measurement, False means 10MΩ, True means 10GΩ, default is 10MΩ
 
        returns:    - the measured value in V/A/Ω/°C, or None on error
    """
    # set voltage mode
    if mode == "voltage":
        # set coupling
        if ac:
            dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(3), ctypes.c_int(1), constants.DwfDmmACVoltage)
        else:
            dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(3), ctypes.c_int(1), constants.DwfDmmDCVoltage)
 
        # set input impedance
        if high_impedance:
            dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(3), ctypes.c_int(5), ctypes.c_double(1))
        else:
            dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(3), ctypes.c_int(5), ctypes.c_double(0))
 
    # set high current mode
    elif mode == "high current":
        # set coupling
        if ac:
            dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(3), ctypes.c_int(1), constants.DwfDmmACCurrent)
        else:
            dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(3), ctypes.c_int(1), constants.DwfDmmDCCurrent)
 
    # set low current mode
    elif mode == "low current":
        # set coupling
        if ac:
            dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(3), ctypes.c_int(1), constants.DwfDmmACLowCurrent)
        else:
            dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(3), ctypes.c_int(1), constants.DwfDmmDCLowCurrent)
 
    # set resistance mode
    elif mode == "resistance":
        dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(3), ctypes.c_int(1), constants.DwfDmmResistance)
 
    # set continuity mode
    elif mode == "continuity":
        dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(3), ctypes.c_int(1), constants.DwfDmmContinuity)
 
    # set diode mode
    elif mode == "diode":
        dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(3), ctypes.c_int(1), constants.DwfDmmDiode)
 
    # set temperature mode
    elif mode == "temperature":
        dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(3), ctypes.c_int(1), constants.DwfDmmTemperature)
 
    # set range
    dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(3), ctypes.c_int(2), ctypes.c_double(range))
 
    # fetch analog I/O status
    if dwf.FDwfAnalogIOStatus(device_data.handle) == 0:
        # signal error
        return None
 
    # get reading
    measurement = ctypes.c_double()
    dwf.FDwfAnalogIOChannelNodeStatus(device_data.handle, ctypes.c_int(3), ctypes.c_int(3), ctypes.byref(measurement))
 
    return measurement.value

def close_multimeter(device_data):
    """
        reset the instrument
    """
    # disable the DMM
    dwf.FDwfAnalogIOChannelNodeSet(device_data.handle, ctypes.c_int(3), ctypes.c_int(0), ctypes.c_double(0))
    # reset the instrument
    dwf.FDwfAnalogIOReset(device_data.handle)
    return

def close(device_data):
    """
        close a specific device
    """
    dwf.FDwfDeviceClose(device_data.handle)
    return

def main():
    print("Starting")

    device = open_AD2()

    _switch_variable_(device, True, True, False, 3, 3)

    open_oscilloscope(device)
    measurement = measure_oscilloscope(device, 1)
    print(measurement)

    measurement = measure_oscilloscope(device, 2)
    print(measurement)
    close_oscilloscope(device)




    open_multimeter(device)
    measurement = measure_multimeter(device, "voltage")
    print(measurement)
    close_multimeter(device)

    print("Finishing" )
    #close(device)

if __name__ == "__main__":
    main()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM