Having spent the first 5 years of my engineering career as a test engineer in a manufacturing setting, I'm a big fan of automated testing for the sake of repeatable and accurate results by proxy of some removable of human error. The ADP3450 has the capability to be configured to run a sequence of measurements from a Python script uploaded to the embedded Linux image of its FPGA, which makes it my favorite of my USB test equipment.
As a test run into setting up a series of measurements to run in an automated sequence, I setup a loop-back between one of the oscilloscope and waveform generator channels, configured the waveform generator to output a sinusoid waveform, then recorded a cycle of the waveform and printed it to the terminal using termplotlib.
Boot into Linux ModeIn order to run a sequence of tests a Python script will making the appropriate function calls to the hardware via a Linux operating system. So the first step is to reboot the ADP3450 into Linux mode if it's in standard (no-OS) mode.
Connect to the USB port on the back of the ADP3450 and power it on.
Launch WaveForms, then under Settings > Device Manager, select your ADP3450 (single-click) from the list then select Boot. Select Linux then click Apply & Reboot.
Upon reboot, you'll see the ADP3450 listed as a USB Linux connection (I also have my ADP3450 connected to my local network so it shows up a second time as an Ethernet connection as well).
Seeing the ADP3450 appear in the list as a USB Linux option is all we needed from Waveforms to verify the device did indeed reboot properly. At this point though, we'll close WaveForms as it will prevent the Python script from being able to connect to the device instance of the hardware to control it.
Connect Serial TerminalUsing your serial terminal of choice connect to the device serial port of the ADP3450. Log in with the default username and password unless you've changed it:
- Username: digilent
- Password: digilent
WaveForms not only provides the GUI used to control the ADP3450 from your host PC, it also provides an SDK in the installation of which the API is available in C/C++, C#, Python, and Visual Basic through a dynamic library. This API provides the low level function calls for operations such as connecting to the ADP3450, enabling oscilloscope/waveform generator channel(s), setting buffer sizes, querying device status, resetting the device, setting up triggering, and so on.
Basically any button press you'd make in the WaveForms GUI is a function in this API that is called. It goal then becomes developing higher level functions in your own code that accomplish a given task. For example, one function in my Python script is setting up the oscilloscope channel to take a measurement of my target sinusoid signal: starting with enabling the channel, then setting the offset voltage, setting the amplitude range, buffer size, sampling frequency, and finally disabling averaging.
I found some really handy Python functions for very common functions for the oscilloscope and waveform generator here in the WaveForms SDK getting started reference documentation, including operations such as opening/configuration of each, generating a specified type of waveform, recording data, closing out the device handle, etc. You can also read some more detail about the SDK backend in the getting started guide.
Using the Python functions I found in the WaveForms SDK getting started guide, I composed the main function of my Python script to open the ADP3450 device, configure the waveform generator to output a 1kHz sine wave and the oscilloscope to record it, then print one period of the recorded sine wave data out to the terminal using the termplotlib library.
Note: Since we're sampling in the time domain, the ideal sampling rate is 10 times that of the max frequency of the target signal being measured.
# initialize the platform by loading the WaveForms dynamic library and connect to the host PC
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
hdwf = ctypes.c_int()
sts = ctypes.c_byte()
rgdSamples = (ctypes.c_double*8000)()
print("Opening first device found...")
dwf.FDwfDeviceConfigOpen(ctypes.c_int(-1), ctypes.c_int(0), ctypes.byref(hdwf))
if hdwf.value == 0:
print("failed to open device")
szerr = create_string_buffer(512)
dwf.FDwfGetLastErrorMsg(szerr)
print(str(szerr.value))
quit()
print("ADP3450 device open!")
scope_samp_freq = 10e06
buffer_size = 8192
# add new here
print("Configuring the instrument buffer.")
cBufMax = ctypes.c_int()
dwf.FDwfAnalogInBufferSizeInfo(hdwf, 0, ctypes.byref(cBufMax))
print("Device buffer size: "+str(cBufMax.value))
print("Configuring oscilloscope channel 1...")
scope_open(hdwf, scope_samp_freq, 8192, 0, 1)
print("Wait at least 2 seconds for the offset to stabilize...")
time.sleep(2)
print("Configuring waveform generator channel 1...")
wave_generate(hdwf, 1, constants.funcSine, 0, 1e03, 1, 50, 0, 0, 0)
print("Record waveform from oscilloscope...")
rgdSamples = scope_record(hdwf, 1, scope_samp_freq, buffer_size)
while True:
dwf.FDwfAnalogInStatus(hdwf, ctypes.c_int(1), ctypes.byref(sts))
if sts.value == DwfStateDone.value :
break
time.sleep(0.1)
print("Acquisition done!")
print("Closing all devices...")
dwf.FDwfDeviceCloseAll()
print("Plot window...")
x = numpy.linspace(0, 2*numpy.pi, len(rgdSamples), dtype=numpy.float32)
y = numpy.array(rgdSamples, dtype=numpy.float32)
fig = tpl.figure()
fig.plot(x, y, width=100, height=50)
fig.show()
Upload ScriptUsing a USB thumbdrive, upload the python scripts to the ADP3450's Linux filesystem. If you have your ADP3450 connected to your local network, you could probably transfer the script by connecting via SSH, but the USB thumb drive is easier for now.
Note: I've previously discovered when updating the firmware of my ADP3450's FPGA, only particular brands of USB thumbdrives seem to work such that they are detected and mountable by the ADP3450's Linux filesystem. SanDisk is my go-to brand for use with the ADP3450.
Plug the USB thumbdrive into one of the four ports in the back of the ADP3450. Mount the USB drive in the filesystem then change directories into it. Copy the Python script to the home directory and run the sync command to verify the data transfer from the copy command is fully completed before unmounting the USB drive.
digilent@ADPro:~$ sudo fdisk -l
digilent@ADPro:~$ sudo mount /dev/sda1 /mnt
digilent@ADPro:~$ cd /mnt
digilent@ADPro:/mnt$ sudo cp -R ./ /home/digilent/
digilent@ADPro:/mnt$ sync
Return to the home directory and unmount the USB thumbdrive before physically removing from the system.
digilent@ADPro:/mnt$ cd ~
digilent@ADPro:~$ sudo umount /mnt
RunFinally run the Python script of the automated test sequence on the ADP3450:
digilent@ADPro:~$ sudo python3 ./automated_test0.py
And see the print out in the serial terminal:
I've attached my script below, it's a good starting point for you to play with modifying the main part of the function to get an intuitive understanding of what the functions are doing to setup and control the ADP3450 hardware.
Comments