I am trying to trigger the AD2 analog channels. I am having great difficulty surpassing 500 trigger events per second. I'm working with Python 3.7 to 3.9. I am working on a Windows 10 Pro PC with 8 GB of RAM. The amount of data seems not to be the issue (only about a 1000 samples per trigger event). It seems more to do with the re-arming time or reading the done status.
I tried the sample script AnalongIn_Trigger.py, and modified it with a digital out signal as the input trigger to the analog channel. About 500 triggers a second was the maximum it could do. I tried so many variations on this that they are too numerous to show here. Since external triggering did not work for Analog channels, I thought maybe I would play with the digital side more. I then tried using the AnalogInDigitalIn_Acquistion.py script. See the changes I made below. I attempted to obtain 4000 trigger per second rate. I got 350 triggers per second -- worse overall than the Analog-only Trigger.
Is there anything I can do to speed up the trigger rate? In the example code below, if I throw away the digital data (which I don't need) and set the second parameter in dwf.FDwfDigitalInStatus to 0 (dwf.FDwfDigitalInStatus(hdwf, c_int(0), byref(sts)) ), I get a speed up to about 500 triggers per second. If I set the second parameter of dwf.FDwfAnalogInStatus to 0, I get to about 1400 triggers per second. But the data is nonsense on the Analog channel -- a bunch of noisy spikes. So I can't use that setting.
I also found that when I set the triggers to over 500 triggers per second (for example, to 2000 or 4000), my triggering time is not consistent in the AD2. I thought I might get a consistent 0.002 seconds when the triggering rate max'ed out, but it is not. The trigger intervals fluctuate all over the place. So bottom line, I can't get even a 500 trigger per second performance at a consistent periodic value. This means I can't take FFT's on the data collected over time, which is used in Doppler processing.
Does anyone know what the maximum trigger rate of the AD2 is? If that is greater than 500 triggers/s, what do I do to maximize trigger rates through code? Can the code below be improved?
Sorry for the novella, but I've invested a lot of time in this and was trying to be thorough.
Modified AnalogInDigitalIn_Acquisition.py:
from ctypes import *
import math
import time
import matplotlib.pyplot as plt
import sys
version = create_string_buffer(16)
dwf.FDwfGetVersion(version)
print("DWF Version: "+str(version.value))
#open device
print("Opening first device")
dwf.FDwfDeviceOpen(c_int(-1), byref(hdwf))
if hdwf.value == 0:
szerr = create_string_buffer(512)
dwf.FDwfGetLastErrorMsg(szerr)
print(str(szerr.value))
print("failed to open device")
quit()
print("Generating signal on DIO 0")
# generate on DIO-0 25khz pulse (100MHz/10000/(7+3)), 30% duty (7low 3high)
dwf.FDwfDigitalOutEnableSet(hdwf, c_int(0), c_int(1))
dwf.FDwfDigitalOutDividerSet(hdwf, c_int(0), c_int(20)) #<--Note that this row and the next yields a 200 ns pulse @ 4000 times per sec
dwf.FDwfDigitalOutCounterSet(hdwf, c_int(0), c_int(1249), c_int(1))
dwf.FDwfDigitalOutConfigure(hdwf, c_int(1))
# For synchronous analog/digital acquisition set DigitalInTriggerSource to AnalogIn, start DigitalIn then AnalogIn
# configure DigitalIn
dwf.FDwfDigitalInTriggerSourceSet(hdwf, c_ubyte(4)) # trigsrcAnalogIn
#sample rate = system frequency / divider, 100MHz/1
dwf.FDwfDigitalInDividerSet(hdwf, c_int(1))
# 16bit per sample format
dwf.FDwfDigitalInSampleFormatSet(hdwf, c_int(16))
# set number of sample to acquire
dwf.FDwfDigitalInBufferSizeSet(hdwf, c_int(cSamples))
dwf.FDwfDigitalInTriggerPositionSet(hdwf, c_int(int(cSamples/2))) # trigger position in middle of buffer
# configure AnalogIn
dwf.FDwfAnalogInFrequencySet(hdwf, c_double(1e8))
dwf.FDwfAnalogInBufferSizeSet(hdwf, c_int(cSamples))
dwf.FDwfAnalogInTriggerPositionSet(hdwf, c_double(0)) # trigger position in middle of buffer
dwf.FDwfAnalogInChannelEnableSet(hdwf, c_int(0), c_bool(True))
dwf.FDwfAnalogInChannelOffsetSet(hdwf, c_int(0), c_double(-2.0))
dwf.FDwfAnalogInChannelRangeSet(hdwf, c_int(0), c_double(5.0))
#trigger on digital signal
dwf.FDwfAnalogInTriggerSourceSet(hdwf, c_byte(3)) # trigsrcDetectorDigitalIn
dwf.FDwfDigitalInTriggerSet(hdwf, c_int(0), c_int(0), c_int(1), c_int(0)) # DIO-0 rising edge
# trigger on analog signal
##dwf.FDwfAnalogInTriggerSourceSet(hdwf, c_byte(2)) # trigsrcDetectorAnalogIn
##dwf.FDwfAnalogInTriggerTypeSet(hdwf, c_int(0)) # trigtypeEdge
##dwf.FDwfAnalogInTriggerChannelSet(hdwf, c_int(1)) # first channel
##dwf.FDwfAnalogInTriggerLevelSet(hdwf, c_double(1.5)) # 1.5V
##dwf.FDwfAnalogInTriggerConditionSet(hdwf, c_int(0)) # trigcondRisingPositive
#wait at least 2 seconds for the offset to stabilize
time.sleep(2)
# start DigitalIn and AnalogIn
dwf.FDwfDigitalInConfigure(hdwf, c_int(True), c_int(True)) #Set 2nd param to True to reset Auto trigger timeout
dwf.FDwfAnalogInConfigure(hdwf, c_int(True), c_int(True)) #Set 2nd param to True to reset Auto trigger timeout
iTrigger = 0
StartT=time.time()
for iTrigger in range(128):
while True:
#time.sleep(1)
dwf.FDwfDigitalInStatus(hdwf, c_int(1), byref(sts))
if sts.value == 2 : # done
dwf.FDwfAnalogInStatus(hdwf, c_int(1), byref(sts))
break
# read data
#dwf.FDwfDigitalInStatusData(hdwf, rgwDigital, c_int(sizeof(c_uint16)*cSamples))
dwf.FDwfAnalogInStatusData(hdwf, c_int(0), rgdAnalog, c_int(cSamples)) # get channel 1 data
#dwf.FDwfAnalogInStatusData(hdwf, 1, rgdAnalog, cSamples) # get channel 2 data
Question
eradarhughes
I am trying to trigger the AD2 analog channels. I am having great difficulty surpassing 500 trigger events per second. I'm working with Python 3.7 to 3.9. I am working on a Windows 10 Pro PC with 8 GB of RAM. The amount of data seems not to be the issue (only about a 1000 samples per trigger event). It seems more to do with the re-arming time or reading the done status.
I tried the sample script AnalongIn_Trigger.py, and modified it with a digital out signal as the input trigger to the analog channel. About 500 triggers a second was the maximum it could do. I tried so many variations on this that they are too numerous to show here. Since external triggering did not work for Analog channels, I thought maybe I would play with the digital side more. I then tried using the AnalogInDigitalIn_Acquistion.py script. See the changes I made below. I attempted to obtain 4000 trigger per second rate. I got 350 triggers per second -- worse overall than the Analog-only Trigger.
Is there anything I can do to speed up the trigger rate? In the example code below, if I throw away the digital data (which I don't need) and set the second parameter in dwf.FDwfDigitalInStatus to 0 (dwf.FDwfDigitalInStatus(hdwf, c_int(0), byref(sts)) ), I get a speed up to about 500 triggers per second. If I set the second parameter of dwf.FDwfAnalogInStatus to 0, I get to about 1400 triggers per second. But the data is nonsense on the Analog channel -- a bunch of noisy spikes. So I can't use that setting.
I also found that when I set the triggers to over 500 triggers per second (for example, to 2000 or 4000), my triggering time is not consistent in the AD2. I thought I might get a consistent 0.002 seconds when the triggering rate max'ed out, but it is not. The trigger intervals fluctuate all over the place. So bottom line, I can't get even a 500 trigger per second performance at a consistent periodic value. This means I can't take FFT's on the data collected over time, which is used in Doppler processing.
Does anyone know what the maximum trigger rate of the AD2 is? If that is greater than 500 triggers/s, what do I do to maximize trigger rates through code? Can the code below be improved?
Sorry for the novella, but I've invested a lot of time in this and was trying to be thorough.
Modified AnalogInDigitalIn_Acquisition.py:
from ctypes import *
import math
import time
import matplotlib.pyplot as plt
import sys
if sys.platform.startswith("win"):
dwf = cdll.dwf
elif sys.platform.startswith("darwin"):
dwf = cdll.LoadLibrary("/Library/Frameworks/dwf.framework/dwf")
else:
dwf = cdll.LoadLibrary("libdwf.so")
hdwf = c_int()
sts = c_byte()
cSamples = 1200
rgdAnalog = (c_double*cSamples)()
rgwDigital = (c_uint16*cSamples)()
version = create_string_buffer(16)
dwf.FDwfGetVersion(version)
print("DWF Version: "+str(version.value))
#open device
print("Opening first device")
dwf.FDwfDeviceOpen(c_int(-1), byref(hdwf))
if hdwf.value == 0:
szerr = create_string_buffer(512)
dwf.FDwfGetLastErrorMsg(szerr)
print(str(szerr.value))
print("failed to open device")
quit()
print("Generating signal on DIO 0")
# generate on DIO-0 25khz pulse (100MHz/10000/(7+3)), 30% duty (7low 3high)
dwf.FDwfDigitalOutEnableSet(hdwf, c_int(0), c_int(1))
dwf.FDwfDigitalOutDividerSet(hdwf, c_int(0), c_int(20)) #<--Note that this row and the next yields a 200 ns pulse @ 4000 times per sec
dwf.FDwfDigitalOutCounterSet(hdwf, c_int(0), c_int(1249), c_int(1))
dwf.FDwfDigitalOutConfigure(hdwf, c_int(1))
# For synchronous analog/digital acquisition set DigitalInTriggerSource to AnalogIn, start DigitalIn then AnalogIn
# configure DigitalIn
dwf.FDwfDigitalInTriggerSourceSet(hdwf, c_ubyte(4)) # trigsrcAnalogIn
#sample rate = system frequency / divider, 100MHz/1
dwf.FDwfDigitalInDividerSet(hdwf, c_int(1))
# 16bit per sample format
dwf.FDwfDigitalInSampleFormatSet(hdwf, c_int(16))
# set number of sample to acquire
dwf.FDwfDigitalInBufferSizeSet(hdwf, c_int(cSamples))
dwf.FDwfDigitalInTriggerPositionSet(hdwf, c_int(int(cSamples/2))) # trigger position in middle of buffer
# configure AnalogIn
dwf.FDwfAnalogInFrequencySet(hdwf, c_double(1e8))
dwf.FDwfAnalogInBufferSizeSet(hdwf, c_int(cSamples))
dwf.FDwfAnalogInTriggerPositionSet(hdwf, c_double(0)) # trigger position in middle of buffer
dwf.FDwfAnalogInChannelEnableSet(hdwf, c_int(0), c_bool(True))
dwf.FDwfAnalogInChannelOffsetSet(hdwf, c_int(0), c_double(-2.0))
dwf.FDwfAnalogInChannelRangeSet(hdwf, c_int(0), c_double(5.0))
#trigger on digital signal
dwf.FDwfAnalogInTriggerSourceSet(hdwf, c_byte(3)) # trigsrcDetectorDigitalIn
dwf.FDwfDigitalInTriggerSet(hdwf, c_int(0), c_int(0), c_int(1), c_int(0)) # DIO-0 rising edge
# trigger on analog signal
##dwf.FDwfAnalogInTriggerSourceSet(hdwf, c_byte(2)) # trigsrcDetectorAnalogIn
##dwf.FDwfAnalogInTriggerTypeSet(hdwf, c_int(0)) # trigtypeEdge
##dwf.FDwfAnalogInTriggerChannelSet(hdwf, c_int(1)) # first channel
##dwf.FDwfAnalogInTriggerLevelSet(hdwf, c_double(1.5)) # 1.5V
##dwf.FDwfAnalogInTriggerConditionSet(hdwf, c_int(0)) # trigcondRisingPositive
#wait at least 2 seconds for the offset to stabilize
time.sleep(2)
# start DigitalIn and AnalogIn
dwf.FDwfDigitalInConfigure(hdwf, c_int(True), c_int(True)) #Set 2nd param to True to reset Auto trigger timeout
dwf.FDwfAnalogInConfigure(hdwf, c_int(True), c_int(True)) #Set 2nd param to True to reset Auto trigger timeout
iTrigger = 0
StartT=time.time()
for iTrigger in range(128):
while True:
#time.sleep(1)
dwf.FDwfDigitalInStatus(hdwf, c_int(1), byref(sts))
if sts.value == 2 : # done
dwf.FDwfAnalogInStatus(hdwf, c_int(1), byref(sts))
break
# read data
#dwf.FDwfDigitalInStatusData(hdwf, rgwDigital, c_int(sizeof(c_uint16)*cSamples))
dwf.FDwfAnalogInStatusData(hdwf, c_int(0), rgdAnalog, c_int(cSamples)) # get channel 1 data
#dwf.FDwfAnalogInStatusData(hdwf, 1, rgdAnalog, cSamples) # get channel 2 data
EndT = time.time()
DeltaT=EndT-StartT
print('Delta Time = ', DeltaT)
print('Measured PRF = ', 128/DeltaT)
Link to comment
Share on other sites
3 answers to this question
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now