marcelott

Newcomers
  • Content Count

    2
  • Joined

  • Last visited

  1. Hi @attila Very impressed by your speedy response and the ready-to-use example! Thank you very much. I implemented it in my codestructure and it works perfectly well. So apparently the part I was missing is the "iSample" which tracks the overflow of the number of samples we actually want to capture. And to my understanding this overflow is random since the circular buffer is continuously filled and you don't know a priori at which position the buffer was being filled at the time the trigger occurs. By counting the number of samples you transfer from the buffer on the AD2 to the rgSamples1 array in python during the specified record time, you can then a posteriori backcalculate at which position in the buffer the trigger event occured and then you can discard the inital samples which were recorded before the trigger occured. The only change I made when implementing your solution is that I don't shift the acquired samples circularly but I just fill the last couple of array elements of "rgsamples1" with zeroes, as I am not recording a simple sinusoid and thus shifting the first few acquired samples to the end of the vector would be misleading.
  2. Hi. I have troubles using the trigger functions in the SDK to align the recording of a signal with the pattern generator (DigitalOut Instrument on AD2). What I want to do is essentially, using the SDK in a python script is: - I record a signal from the AWG on the AD2 I am sending through an analog circuit using two multiplexers. - I control the multiplexers with the digitalOut instrument on the AD2. - I want to align the starting point of the digitalOut-pattern and the starting point of the AnalogIn acquisition (record-mode, int16 data) As far as I understand from the SDK reference for this purpose I can trigger the analogIn with the digitalOut (use trigsrcDigitalOut from the dwf constants). However, when I implemented this, I get an undefined timelag between the acquistion of data and the start of the digitalOut signal. To illustrate this, I recorded the signal of one of the digital pins I use to generate the pattern for the multiplexers (I record the bare 16int ADC conversions, to read faster from the AD2). I sample at 1Mhz and the the pattern I output on this particular pin starts with (1,0,...) at 100Hz. As you can see, the timelag seems to be around ca. 1.5 ms. I also did another experiment, trying out the same thing in the WaveForms Software. Instead of outputting a custom pattern, I just output a clock at 100Hz on the same digital pin and record this signal through channel 1 of the oscilloscope. From what I understand, the two experiments should be pretty much equal, so I am puzzled I get this delay of approximately 1.5ms when I implement it with SDK functions. Does anyone have an explanation why the trigger is not correctly aligned in my python script, and why this timelag is not deterministic? Any help would be greatly appreciated! (PS: I can provide a code snippet, but right now my code is shared from different fies & classes, so it is not straightforward to copy it to here...) updated: I have a code snippet for illustration below: import math import sys import time from ctypes import * import matplotlib.pyplot as plt import numpy from dwfconstants import * 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() sts = c_byte() hzAcq = c_double(1e6) nSamples = 2 ** 17 rgSamples = (c_int16 * nSamples)() cAvailable = c_int() cLost = c_int() cCorrupted = c_int() fLost = 0 fCorrupted = 0 # print(DWF version 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 == hdwfNone.value: szerr = create_string_buffer(512) dwf.FDwfGetLastErrorMsg(szerr) print(str(szerr.value)) print("failed to open device") quit() ######################################################################################## # set up pattern generator data = [1, 0, 1, 0, 0, 1, 0, 0, 1] pin = 11 hzSys = c_double() dwf.FDwfDigitalOutInternalClockInfo(hdwf, byref(hzSys)) rgbdata = (c_ubyte * ((len(data) + 7) >> 3))(0) # array to bits in byte array for j in range(len(data)): if data[j] != 0: rgbdata[j >> 3] |= 1 << (j & 7) # var |= value is var = var | value print("bytestream of data " + str(pin) + ": " + str(list(rgbdata))) dwf.FDwfDigitalOutEnableSet(hdwf, c_int(pin), c_int(1)) dwf.FDwfDigitalOutTypeSet(hdwf, c_int(pin), DwfDigitalOutTypeCustom) dwf.FDwfDigitalOutIdleSet(hdwf, c_int(pin), DwfDigitalOutIdleLow) # set Divider to generate output at frequency f_scan. dwf.FDwfDigitalOutDividerSet(hdwf, c_int(pin), c_int(int(hzSys.value / 100))) dwf.FDwfDigitalOutDataSet(hdwf, c_int(pin), byref(rgbdata), c_int(len(data))) dwf.FDwfDigitalOutTriggerSourceSet(hdwf, trigsrcNone) # set up acquisition dwf.FDwfAnalogInChannelEnableSet(hdwf, c_int(0), c_bool(True)) dwf.FDwfAnalogInChannelRangeSet(hdwf, c_int(0), c_double(5)) dwf.FDwfAnalogInAcquisitionModeSet(hdwf, acqmodeRecord) dwf.FDwfAnalogInFrequencySet(hdwf, hzAcq) dwf.FDwfAnalogInRecordLengthSet( hdwf, c_double(nSamples / hzAcq.value) ) # -1 infinite record length dwf.FDwfAnalogInTriggerSourceSet(hdwf, trigsrcDigitalOut) # wait at least 2 seconds for the offset to stabilize time.sleep(2) print(f"Starting oscilloscope. Measure digitalout pin {pin}") dwf.FDwfAnalogInConfigure(hdwf, c_int(0), c_int(1)) # configure digitalOut instrument, don't run yet (enough time to fill buffer with data) dwf.FDwfDigitalOutConfigure(hdwf, c_int(0)) time.sleep(2) cSamples = 0 # start the digitalOut instrument dwf.FDwfDigitalOutConfigure(hdwf, c_int(1)) while cSamples < nSamples: dwf.FDwfAnalogInStatus(hdwf, c_int(1), byref(sts)) if cSamples == 0 and ( sts == DwfStateConfig or sts == DwfStatePrefill or sts == DwfStateArmed ): # Acquisition not yet started. continue dwf.FDwfAnalogInStatusRecord( hdwf, byref(cAvailable), byref(cLost), byref(cCorrupted) ) cSamples += cLost.value if cLost.value: fLost = 1 if cCorrupted.value: fCorrupted = 1 if cAvailable.value == 0: continue if cSamples + cAvailable.value > nSamples: cAvailable = c_int(nSamples - cSamples) dwf.FDwfAnalogInStatusData16( hdwf, c_int(0), byref(rgSamples, sizeof(c_int16) * cSamples), c_int(0), cAvailable, ) # get channel 1 data # dwf.FDwfAnalogInStatusData16(hdwf, c_int(1), byref(rgSamples, sizeof(c_int16)*cSamples), c_int(c), Available) # get channel 2 data cSamples += cAvailable.value dwf.FDwfAnalogOutReset(hdwf, c_int(0)) dwf.FDwfDeviceCloseAll() print("Recording done") if fLost: print("Samples were lost! Reduce frequency") if fCorrupted: print("Samples could be corrupted! Reduce frequency") f = open("record.csv", "w") for v in rgSamples: f.write("%s\n" % v) f.close() plt.plot(numpy.fromiter(rgSamples, dtype=numpy.int16)) plt.show()