Jump to content
  • 0

Two analog input channels acquisition triggered by external signal (T1) - AD2 (Python)


Alessandro

Question

Good morning,
I'm Alessandro.
I'm trying to acquire from two analog input channels of the Analog Discovery 2, whose acquisition must be triggered by an external Arduino signal (0V->5V square wave) at port T1. One acquired analog input channel (called SIGNAL) is a multi-step analog signal at KHz rate (BLUE in the pictures) that I want to sample at each bit (samples are shown in BLACK).

Then the Arduino trigger signal is split and fed it to the remaining analog input of the Analog Discovery, so that this trigger is present both at T1 port (to trigger the acquisition) and recorded at the remaining analog input of the Analog Discovery (called TRIGGER, shown in ORANGE in the pictures).
Therefore it is possible to see when the acquisition of SIGNAL happens with respect to the TRIGGER rising edge.

As you can see from the pictures, TRIGGER rising edge is synchronized with the SIGNAL, but the acquisition sometimes happens 2 samples in advance. Do you know why this could happen? I would like to start the acquisition everytime with the TRIGGER rising edge. Thank you.

Here it is the Python code I used to acquire the signal:

sts = c_byte()
sampling_frequency = 10000 #500000
hzAcq = c_double(sampling_frequency)
nSamples = 300
rgdSamples1 = (c_double * nSamples)()
rgdSamples2 = (c_double * nSamples)()
rgwDigital = (c_uint16 * nSamples)()
cAvailable = c_int()
cLost = c_int()
cCorrupted = c_int()
fLost = 0
fCorrupted = 0
sampling_time = 1 / sampling_frequency


############ set up acquisition ################
dwf.FDwfAnalogInChannelEnableSet(hdwf, c_int(0),c_bool(True))  # the acquired channel is the scope 1+,1-
dwf.FDwfAnalogInAcquisitionModeSet(hdwf, c_int(3))  # record
dwf.FDwfAnalogInFrequencySet(hdwf, hzAcq)
sRecord = nSamples / hzAcq.value
dwf.FDwfAnalogInRecordLengthSet(hdwf, c_double(sRecord))  # -1 infinite record length
dwf.FDwfAnalogInTriggerPositionSet(hdwf, c_double(0.0 * sRecord))  # trigger at time zero


############ set up trigger ######################
dwf.FDwfAnalogInTriggerAutoTimeoutSet(hdwf, c_double(0))  # disable autotrigger
dwf.FDwfAnalogInTriggerSourceSet(hdwf, trigsrcExternal1)  # trigsrcDetectorAnalogIn
dwf.FDwfAnalogInTriggerTypeSet(hdwf, c_int(0))  # trigtypeEdge
dwf.FDwfAnalogInTriggerChannelSet(hdwf, c_int(1))  # channel 2 is used as TRIGGER (+2,-2)
dwf.FDwfAnalogInTriggerLevelSet(hdwf, c_double(1.8))  # 0V
# dwf.FDwfAnalogInTriggerHysteresisSet(hdwf, c_double(0.01)) # 0.01V
dwf.FDwfAnalogInTriggerConditionSet(hdwf, c_int(0))  # trigcondRisingPositive

################# ACQUISITION #########################
    
sts = c_byte(0)
rgdSamples1 = (c_double * nSamples)(0)
rgdSamples2 = (c_double * nSamples)(0)
rgwDigital = (c_uint16 * nSamples)(0)
cAvailable = c_int(0)
cLost = c_int(0)
cCorrupted = c_int(0)
fLost = 0
fCorrupted = 0
print("Starting oscilloscope")
# dwf.FDwfAnalogInConfigure(hdwf, c_int(0), c_int(1))
dwf.FDwfAnalogInConfigure(hdwf, c_int(True), c_int(True))

iSample = 0

while True:
dwf.FDwfAnalogInStatus(hdwf, c_int(1), byref(sts))
dwf.FDwfAnalogInStatusRecord(hdwf, byref(cAvailable), byref(cLost), byref(cCorrupted))
iSample += cLost.value
iSample %= nSamples

if cLost.value:
	fLost = 1
if cCorrupted.value:
	fCorrupted = 1

iBuffer = 0
while cAvailable.value > 0:
  cSamples = cAvailable.value
  # we are using circular sample buffer, make sure to not overflow
  if iSample + cAvailable.value > nSamples:
  	cSamples = nSamples - iSample
  dwf.FDwfAnalogInStatusData2(hdwf, c_int(0), byref(rgdSamples1, sizeof(c_double) * iSample), c_int(iBuffer),
  c_int(cSamples))  # get channel 1 data
  dwf.FDwfAnalogInStatusData2(hdwf, c_int(1), byref(rgdSamples2, sizeof(c_double) * iSample), c_int(iBuffer),
  c_int(cSamples))  # get channel 2 data
  dwf.FDwfDigitalInStatusData(hdwf, rgwDigital, c_int(sizeof(c_uint16) * nSamples))
  iBuffer += cSamples
  cAvailable.value -= cSamples
  iSample += cSamples
  # print(str(cAvailable.value), str(cSamples), str(iSample), str(iBuffer))
  iSample %= nSamples
  # print(str(cAvailable.value),str(cSamples),str(iSample), str(iBuffer))

  if sts.value == 2:  # when sts assumes value equal to 2 it exits from the loop (end of acquisition)
  	break


if iSample != 0:
	rgdSamples1 = rgdSamples1[iSample:] + rgdSamples1[:iSample]
	rgdSamples2 = rgdSamples2[iSample:] + rgdSamples2[:iSample]

if fLost:
	print("Samples were lost! Reduce frequency")
if fCorrupted:
	print("Samples could be corrupted! Reduce frequency")
rgdSamples1 = numpy.array(rgdSamples1, dtype=float)
rgdSamples2 = numpy.array(rgdSamples2, dtype=float)

NO_shifted.png

shifted.png

Edited by Alessandro
Link to comment
Share on other sites

3 answers to this question

Recommended Posts

  • 0

Hi @Alessandro

See the following:

image.png

from ctypes import *
from dwfconstants import *
import math
import time
import matplotlib.pyplot as plt
import sys
import numpy

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")

#declare ctype variables
hdwf = c_int()

version = create_string_buffer(16)
dwf.FDwfGetVersion(version)
print("DWF Version: "+str(version.value))

dwf.FDwfParamSet(DwfParamOnClose, c_int(0)) # 0 = run, 1 = stop, 2 = shutdown

#open device
print("Opening first device")
dwf.FDwfDeviceOpen(c_int(-1), byref(hdwf))

if hdwf.value == hdwfNone.value:
    szerr = create_string_buffer(512)
    dwf.FDwfGetLastErrorMsg(szerr)
    print(szerr.value)
    print("failed to open device")
    quit()

dwf.FDwfDeviceAutoConfigureSet(hdwf, c_int(0)) # 0 = the device will only be configured when FDwf###Configure is called


sts = c_byte()
sampling_frequency = 10000 #500000
hzAcq = c_double(sampling_frequency)
nSamples = 300
rgdSamples1 = (c_double * nSamples)()
rgdSamples2 = (c_double * nSamples)()
rgwDigital = (c_uint16 * nSamples)()
cAvailable = c_int()
cLost = c_int()
cCorrupted = c_int()
fLost = 0
fCorrupted = 0
sampling_time = 1 / sampling_frequency


############ set up acquisition ################
dwf.FDwfAnalogInChannelEnableSet(hdwf, c_int(0),c_int(1))  # the acquired channel is the scope 1+,1-
dwf.FDwfAnalogInFrequencySet(hdwf, hzAcq)
dwf.FDwfAnalogInBufferSizeSet(hdwf, c_int(nSamples)) 
dwf.FDwfAnalogInTriggerPositionSet(hdwf, c_double(0.5*nSamples/hzAcq.value)) 


############ set up trigger ######################
dwf.FDwfAnalogInTriggerSourceSet(hdwf, trigsrcExternal1)  # trigsrcDetectorAnalogIn

################# ACQUISITION #########################
    
sts = c_byte(0)
rgdSamples1 = (c_double * nSamples)(0)
rgdSamples2 = (c_double * nSamples)(0)
rgwDigital = (c_uint16 * nSamples)(0)
print("Starting oscilloscope")
# dwf.FDwfAnalogInConfigure(hdwf, c_int(0), c_int(1))
dwf.FDwfAnalogInConfigure(hdwf, c_int(True), c_int(True))

iSample = 0

while True:
    if dwf.FDwfAnalogInStatus(hdwf, c_int(1), byref(sts)) != 1:
        szerr = create_string_buffer(512)
        dwf.FDwfGetLastErrorMsg(szerr)
        print("Error:")
        print(szerr.value)
        quit()
    if sts.value == DwfStateDone.value :
        break
    time.sleep(0.1)

dwf.FDwfAnalogInStatusData(hdwf, 0, rgdSamples1, nSamples) # get channel 1 data
dwf.FDwfAnalogInStatusData(hdwf, 1, rgdSamples2, nSamples) # get channel 2 data

print("Acquisition done")

if fLost:
	print("Samples were lost! Reduce frequency")
if fCorrupted:
	print("Samples could be corrupted! Reduce frequency")
rgdSamples1 = numpy.array(rgdSamples1, dtype=float)
rgdSamples2 = numpy.array(rgdSamples2, dtype=float)

plt.plot(numpy.fromiter(rgdSamples1, dtype = numpy.float))
plt.plot(numpy.fromiter(rgdSamples2, dtype = numpy.float))
plt.show()

 

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...