Jump to content
  • 0

Analog Discovery 2 - Python loop


Ergest

Question

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)
    

    

 

Edited by Ergest
Link to comment
Share on other sites

0 answers to this question

Recommended Posts

There have been no answers to this question yet

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...