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.