I'm having a problem with a piece of code where I transmit a long signal in chunks. Initially, the code worked fine when it was a single block without separate functions. However, issues arise when I modify it to use functions, intended to send different messages at different times.
The main issue occurs when I try to send a message (even a single one without looping) using these functions - the code gets stuck in the while loop. This happens even if I call the functions in separate Jupyter notebook cells.
From debugging, it seems the 'iRecord' variable doesn't update after the first run. The first message sends fine, but when I put the 'AD2_loop' function in a loop for continuous transmission, it gets stuck in the while loop on the second iteration. Having a sleep time doesn't help either.
I tried closing the device after sending the first message, but then it doesn't reopen on the next attempt, causing the Jupyter kernel to crash.
Any ideas on what might be causing this or how to fix it?
Thanks for any help you can provide!
from dwfconstants import *
import ctypes
import sys
import wave
import math
def AD2(tx, Fs):
length = len(tx)
data = (c_double*int(length))(*tx)
sRun = 1.0*length/Fs
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")
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
hdwf = c_int()
print("Opening first device...")
dwf.FDwfDeviceOpen(c_int(-1), byref(hdwf))
if hdwf.value == 0:
print("Failed to open device")
szerr = create_string_buffer(512)
dwf.FDwfGetLastErrorMsg(szerr)
print(str(szerr.value))
quit()
# the device will only be configured when FDwf###Configure is called
dwf.FDwfDeviceAutoConfigureSet(hdwf, c_int(0))
channel = c_int(0) # AWG 1
dwf.FDwfAnalogOutIdleSet(hdwf, channel, DwfAnalogOutIdleDisable)
print("Staring record...")
record1 = (c_double*length)()
record2 = (c_double*length)()
#set up acquisition
dwf.FDwfAnalogInChannelEnableSet(hdwf, c_int(0), c_int(1)) # channel 1
#dwf.FDwfAnalogInChannelEnableSet(hdwf, c_int(1), c_int(1)) # channel 2
dwf.FDwfAnalogInChannelRangeSet(hdwf, c_int(-1), c_double(5.0))
dwf.FDwfAnalogInChannelOffsetSet(hdwf, c_int(-1), c_double(0))
dwf.FDwfAnalogInAcquisitionModeSet(hdwf, acqmodeRecord)
dwf.FDwfAnalogInFrequencySet(hdwf, c_double(Fs))
dwf.FDwfAnalogInRecordLengthSet(hdwf, c_double(sRun))
dwf.FDwfAnalogInTriggerPositionSet(hdwf, c_double(0))
dwf.FDwfAnalogInTriggerSourceSet(hdwf, trigsrcAnalogOut1)
dwf.FDwfAnalogInConfigure(hdwf, c_int(0))
dwf.FDwfAnalogOutNodeEnableSet(hdwf, channel, 0, c_int(1))
dwf.FDwfAnalogOutNodeFunctionSet(hdwf, channel, 0, funcPlay)
# maybe we do not need this
dwf.FDwfAnalogOutRepeatSet(hdwf, channel, c_int(1))
dwf.FDwfAnalogOutRunSet(hdwf, channel, c_double(sRun)) # set the time the insturment will run in seconds
dwf.FDwfAnalogOutNodeFrequencySet(hdwf, channel, 0, c_double(Fs))
dwf.FDwfAnalogOutNodeAmplitudeSet(hdwf, channel, 0, c_double(1))
dwf.FDwfAnalogInChannelOffsetSet(hdwf, c_int(0), c_double(0.0))
iRecord = 0
iPlay = 0
return dwf, hdwf, channel, data, record1, record2, iRecord, iPlay, length
def AD2_loop(dwf, hdwf, channel, tx, record1, record2, iRecord, iPlay, length):
print(iRecord, iPlay)
data = (c_double*int(length))(*tx)
dataLost = c_int(0)
dataFree = c_int(0)
dataAvailable = c_int(0)
dataCorrupted = c_int(0)
sts = c_ubyte(0)
totalLost = 0
totalCorrupted = 0
# prime the buffer with the first chunk of data
cBuffer = c_int(0)
dwf.FDwfAnalogOutNodeDataInfo(hdwf, channel, 0, 0, byref(cBuffer))
if cBuffer.value > length : cBuffer.value = length
dwf.FDwfAnalogOutNodeDataSet(hdwf, channel, 0, data, cBuffer)
iPlay += cBuffer.value
dwf.FDwfAnalogOutConfigure(hdwf, channel, c_int(1))
# loop to send out and read in data chunks
while iRecord < length :
if dwf.FDwfAnalogOutStatus(hdwf, channel, byref(sts)) != 1: # handle error
print("Error")
szerr = create_string_buffer(512)
dwf.FDwfGetLastErrorMsg(szerr)
print(szerr.value)
break
# play, analog out data chunk
if sts.value == DwfStateRunning.value and iPlay < length : # running and more data to stream
dwf.FDwfAnalogOutNodePlayStatus(hdwf, channel, 0, byref(dataFree), byref(dataLost), byref(dataCorrupted))
totalLost += dataLost.value
totalCorrupted += dataCorrupted.value
if iPlay + dataFree.value > length : # last chunk might be less than the free buffer size
dataFree.value = length - iPlay
if dataFree.value > 0 :
if dwf.FDwfAnalogOutNodePlayData(hdwf, channel, 0, byref(data, iPlay*sizeof(c_double)), dataFree) != 1: # offset for double is *8 (bytes)
print("Error")
break
iPlay += dataFree.value
if dwf.FDwfAnalogInStatus(hdwf, c_int(1), byref(sts)) != 1: # handle error
print("Error")
szerr = create_string_buffer(512)
dwf.FDwfGetLastErrorMsg(szerr)
print(szerr.value)
break
# record, analog in data chunk
if sts.value == DwfStateRunning.value or sts.value == DwfStateDone.value : # recording or done
dwf.FDwfAnalogInStatusRecord(hdwf, byref(dataAvailable), byref(dataLost), byref(dataCorrupted))
iRecord += dataLost.value
totalLost += dataLost.value
totalCorrupted += dataCorrupted.value
if dataAvailable.value > 0 :
if iRecord+dataAvailable.value > length :
dataAvailable = c_int(length-iRecord)
dwf.FDwfAnalogInStatusData(hdwf, c_int(0), byref(record1, sizeof(c_double)*iRecord), dataAvailable) # get channel 1 data chunk
dwf.FDwfAnalogInStatusData(hdwf, c_int(1), byref(record2, sizeof(c_double)*iRecord), dataAvailable) # get channel 2 data chunk
iRecord += dataAvailable.value
print("Lost: "+str(totalLost))
print("Corrupted: "+str(totalCorrupted))
print("done")
plt.plot(record2)
plt.show()
return record2, iRecord, iPlay
def AD2_close(dwf, hdwf, channel):
dwf.FDwfAnalogOutReset(hdwf, channel)
dwf.FDwfDeviceClose(hdwf)
Question
Ergest
Hello,
I'm having a problem with a piece of code where I transmit a long signal in chunks. Initially, the code worked fine when it was a single block without separate functions. However, issues arise when I modify it to use functions, intended to send different messages at different times.
The main issue occurs when I try to send a message (even a single one without looping) using these functions - the code gets stuck in the while loop. This happens even if I call the functions in separate Jupyter notebook cells.
From debugging, it seems the 'iRecord' variable doesn't update after the first run. The first message sends fine, but when I put the 'AD2_loop' function in a loop for continuous transmission, it gets stuck in the while loop on the second iteration. Having a sleep time doesn't help either.
I tried closing the device after sending the first message, but then it doesn't reopen on the next attempt, causing the Jupyter kernel to crash.
Any ideas on what might be causing this or how to fix it?
Thanks for any help you can provide!
from dwfconstants import * import ctypes import sys import wave import math def AD2(tx, Fs): length = len(tx) data = (c_double*int(length))(*tx) sRun = 1.0*length/Fs 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") 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 hdwf = c_int() print("Opening first device...") dwf.FDwfDeviceOpen(c_int(-1), byref(hdwf)) if hdwf.value == 0: print("Failed to open device") szerr = create_string_buffer(512) dwf.FDwfGetLastErrorMsg(szerr) print(str(szerr.value)) quit() # the device will only be configured when FDwf###Configure is called dwf.FDwfDeviceAutoConfigureSet(hdwf, c_int(0)) channel = c_int(0) # AWG 1 dwf.FDwfAnalogOutIdleSet(hdwf, channel, DwfAnalogOutIdleDisable) print("Staring record...") record1 = (c_double*length)() record2 = (c_double*length)() #set up acquisition dwf.FDwfAnalogInChannelEnableSet(hdwf, c_int(0), c_int(1)) # channel 1 #dwf.FDwfAnalogInChannelEnableSet(hdwf, c_int(1), c_int(1)) # channel 2 dwf.FDwfAnalogInChannelRangeSet(hdwf, c_int(-1), c_double(5.0)) dwf.FDwfAnalogInChannelOffsetSet(hdwf, c_int(-1), c_double(0)) dwf.FDwfAnalogInAcquisitionModeSet(hdwf, acqmodeRecord) dwf.FDwfAnalogInFrequencySet(hdwf, c_double(Fs)) dwf.FDwfAnalogInRecordLengthSet(hdwf, c_double(sRun)) dwf.FDwfAnalogInTriggerPositionSet(hdwf, c_double(0)) dwf.FDwfAnalogInTriggerSourceSet(hdwf, trigsrcAnalogOut1) dwf.FDwfAnalogInConfigure(hdwf, c_int(0)) dwf.FDwfAnalogOutNodeEnableSet(hdwf, channel, 0, c_int(1)) dwf.FDwfAnalogOutNodeFunctionSet(hdwf, channel, 0, funcPlay) # maybe we do not need this dwf.FDwfAnalogOutRepeatSet(hdwf, channel, c_int(1)) dwf.FDwfAnalogOutRunSet(hdwf, channel, c_double(sRun)) # set the time the insturment will run in seconds dwf.FDwfAnalogOutNodeFrequencySet(hdwf, channel, 0, c_double(Fs)) dwf.FDwfAnalogOutNodeAmplitudeSet(hdwf, channel, 0, c_double(1)) dwf.FDwfAnalogInChannelOffsetSet(hdwf, c_int(0), c_double(0.0)) iRecord = 0 iPlay = 0 return dwf, hdwf, channel, data, record1, record2, iRecord, iPlay, length def AD2_loop(dwf, hdwf, channel, tx, record1, record2, iRecord, iPlay, length): print(iRecord, iPlay) data = (c_double*int(length))(*tx) dataLost = c_int(0) dataFree = c_int(0) dataAvailable = c_int(0) dataCorrupted = c_int(0) sts = c_ubyte(0) totalLost = 0 totalCorrupted = 0 # prime the buffer with the first chunk of data cBuffer = c_int(0) dwf.FDwfAnalogOutNodeDataInfo(hdwf, channel, 0, 0, byref(cBuffer)) if cBuffer.value > length : cBuffer.value = length dwf.FDwfAnalogOutNodeDataSet(hdwf, channel, 0, data, cBuffer) iPlay += cBuffer.value dwf.FDwfAnalogOutConfigure(hdwf, channel, c_int(1)) # loop to send out and read in data chunks while iRecord < length : if dwf.FDwfAnalogOutStatus(hdwf, channel, byref(sts)) != 1: # handle error print("Error") szerr = create_string_buffer(512) dwf.FDwfGetLastErrorMsg(szerr) print(szerr.value) break # play, analog out data chunk if sts.value == DwfStateRunning.value and iPlay < length : # running and more data to stream dwf.FDwfAnalogOutNodePlayStatus(hdwf, channel, 0, byref(dataFree), byref(dataLost), byref(dataCorrupted)) totalLost += dataLost.value totalCorrupted += dataCorrupted.value if iPlay + dataFree.value > length : # last chunk might be less than the free buffer size dataFree.value = length - iPlay if dataFree.value > 0 : if dwf.FDwfAnalogOutNodePlayData(hdwf, channel, 0, byref(data, iPlay*sizeof(c_double)), dataFree) != 1: # offset for double is *8 (bytes) print("Error") break iPlay += dataFree.value if dwf.FDwfAnalogInStatus(hdwf, c_int(1), byref(sts)) != 1: # handle error print("Error") szerr = create_string_buffer(512) dwf.FDwfGetLastErrorMsg(szerr) print(szerr.value) break # record, analog in data chunk if sts.value == DwfStateRunning.value or sts.value == DwfStateDone.value : # recording or done dwf.FDwfAnalogInStatusRecord(hdwf, byref(dataAvailable), byref(dataLost), byref(dataCorrupted)) iRecord += dataLost.value totalLost += dataLost.value totalCorrupted += dataCorrupted.value if dataAvailable.value > 0 : if iRecord+dataAvailable.value > length : dataAvailable = c_int(length-iRecord) dwf.FDwfAnalogInStatusData(hdwf, c_int(0), byref(record1, sizeof(c_double)*iRecord), dataAvailable) # get channel 1 data chunk dwf.FDwfAnalogInStatusData(hdwf, c_int(1), byref(record2, sizeof(c_double)*iRecord), dataAvailable) # get channel 2 data chunk iRecord += dataAvailable.value print("Lost: "+str(totalLost)) print("Corrupted: "+str(totalCorrupted)) print("done") plt.plot(record2) plt.show() return record2, iRecord, iPlay def AD2_close(dwf, hdwf, channel): dwf.FDwfAnalogOutReset(hdwf, channel) dwf.FDwfDeviceClose(hdwf)
Link to comment
Share on other sites
0 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