Jump to content
Fourth of July -- Digilent US offices closed ×

Ergest

Members
  • Posts

    6
  • Joined

  • Last visited

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

Ergest's Achievements

Newbie

Newbie (1/4)

0

Reputation

  1. 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)
  2. Hello, I am trying to generate a signal using Python. I have an array to_tx which is about 60k samples and want to generate it using AD2. I do not get any error on the code, but nothing gets generated. from ctypes import * import time from dwfconstants import * 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() chIn = c_int(0) # Scope 1 chOut = c_int(0) # Wavegen 1 nBufferIn = c_int() nBufferOut = c_int() version = create_string_buffer(16) dwf.FDwfGetVersion(version) # print("DWF Version: "+str(version.value)) # prevent temperature drift 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: print("failed to open device") cSamples = 4096 # Convert the numpy array to ctypes array prefill = (c_double * cSamples)(*to_tx[0:cSamples]) dwf.FDwfAnalogOutNodeEnableSet(hdwf, chOut, 0, c_int(1)) dwf.FDwfDeviceAutoConfigureSet(hdwf, c_int(0)) dwf.FDwfAnalogInBufferSizeInfo(hdwf, None, byref(nBufferIn)) # get the size of input buffer dwf.FDwfAnalogOutNodeDataInfo(hdwf, c_int(0), AnalogOutNodeCarrier, None, byref(nBufferOut)) # get te size of output buffer nBuffer = nBufferIn.value + nBufferOut.value dwf.FDwfAnalogOutNodeDataSet(hdwf, chOut, 0, prefill, c_int(cSamples)) # prefill the buffer with 4096 samples dwf.FDwfAnalogOutNodeEnableSet(hdwf, chOut, AnalogOutNodeCarrier, c_int(1)) dwf.FDwfAnalogOutNodeFunctionSet(hdwf, chOut, AnalogOutNodeCarrier, funcPlay) # do not use fractional step increments dwf.FDwfAnalogOutNodeFrequencySet(hdwf, chOut, AnalogOutNodeCarrier, c_double(Fs / cSamples)) dwf.FDwfAnalogOutNodeAmplitudeSet(hdwf, chOut, AnalogOutNodeCarrier, c_double(3.0)) dwf.FDwfAnalogOutNodeOffsetSet(hdwf, chOut, 0, c_double(0)) dwf.FDwfAnalogOutRunSet(hdwf, chOut, c_double(cSamples/Fs)) dwf.FDwfAnalogOutRepeatSet(hdwf, chOut, c_int(1)) # repeat only once times dwf.FDwfAnalogOutConfigure(hdwf, chOut, c_int(1)) dwf.FDwfAnalogOutReset(hdwf, chOut) # Track the position in the 'to_tx' array to_tx_position = cSamples cBuffer = 0 cFree = c_int(0) cAvailable = c_int(0) cLost = c_int(0) cCorrupted = c_int(0) sts = c_ubyte(0) while to_tx_position < len(to_tx): print("Current position:", to_tx_position) if dwf.FDwfAnalogOutStatus(hdwf, chOut, byref(sts)) != 1: print("AnalogOutStatus error") break dwf.FDwfAnalogOutNodePlayStatus(hdwf, chOut, AnalogOutNodeCarrier, byref(cFree), byref(cLost), byref(cCorrupted)) print("cFree:", cFree.value, "cLost:", cLost.value, "cCorrupted:", cCorrupted.value) if cLost.value != 0 or cCorrupted.value != 0: print("Output buffer issue") break if cFree.value > 0: end_position = min(to_tx_position + cFree.value, len(to_tx)) data_chunk = (c_double * (end_position - to_tx_position))(*to_tx[to_tx_position:end_position]) print("Sending chunk of size:", len(data_chunk)) if dwf.FDwfAnalogOutNodePlayData(hdwf, chOut, 0, byref(data_chunk), cFree) != 1: szerr = create_string_buffer(512) dwf.FDwfGetLastErrorMsg(szerr) print("Error:", szerr.value) break to_tx_position += cFree.value dwf.FDwfAnalogOutConfigure(hdwf, chOut, c_int(1)) print("New position:", to_tx_position) dwf.FDwfAnalogOutReset(hdwf, chOut) dwf.FDwfDeviceClose(hdwf)
  3. Hi @attila, Thank you for all your help in this matter. I use the following scriot to generate white Gaussian noise and bandpass it from 3k-5kHz: from scipy.signal import butter, filtfilt import numpy as np import matplotlib.pyplot as plt import scipy.signal as sg # Define the sample rate and the number of samples fs = 100e3 num_samples = 4096 # Number of samples def bandpass_filter(signal, lowcut, highcut, f, order=5): nyq = 0.5 * f low = lowcut / nyq high = highcut / nyq b, a = butter(order, [low, high], btype='band') y = filtfilt(b, a, signal) return y # Generate white noise np.random.seed(0) white_noise = np.random.normal(1, 2, num_samples) # Define the bandwidth of the signal (1 kHz) lower_cutoff = 3000 # Hz upper_cutoff = 8000 # Hz # Apply bandpass filter band_limited_signal_adjusted = bandpass_filter(white_noise, lower_cutoff, upper_cutoff, fs) plt.figure(figsize=(10, 4)) plt.plot(band_limited_signal_adjusted) plt.title('Adjusted Band-limited Signal') plt.xlabel('Time (seconds)') plt.ylabel('Amplitude') plt.grid(True) plt.show() plt.figure() f, P = sg.welch(band_limited_signal_adjusted, fs) plt.plot(f / 1e3, 10 * np.log10(P)) plt.xlabel('Frequency [kHz]') plt.ylabel('PSD [dBm/Hz]') # Frequency shift fc = 50e3 # 50 kHz # Time array t = np.arange(num_samples) / fs # Complex exponential for frequency shifting complex_exponential = np.exp(1j * 2 * np.pi * fc * t) # Shift the signal pass_band_band_limited_signal = np.real(band_limited_signal_adjusted * complex_exponential) plt.figure() f, P = sg.welch(pass_band_band_limited_signal, fs) plt.plot(f / 1e3, 10 * np.log10(P)) plt.xlabel('Frequency [kHz]') plt.ylabel('PSD [dBm/Hz]') Then I followed the examples from AnalogOut_Play.py / AnalogOutIn_PlayRecord.py to write the following code: from ctypes import * import time from dwfconstants import * 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") cSamples = len(pass_band_band_limited_signal) hdwf = c_int() # Convert the numpy array to ctypes array rgdSamples = (c_double * cSamples)(*pass_band_band_limited_signal) channel = c_int(0) version = create_string_buffer(16) dwf.FDwfGetVersion(version) print("DWF Version: "+str(version.value)) # prevent temperature drift 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: print("failed to open device") # 0 = the device will be configured only when calling FDwf###Configure dwf.FDwfDeviceAutoConfigureSet(hdwf, c_int(0)) dwf.FDwfAnalogOutNodeEnableSet(hdwf, channel, AnalogOutNodeCarrier, c_int(1)) dwf.FDwfAnalogOutNodeFunctionSet(hdwf, channel, 0, funcCustom) dwf.FDwfAnalogOutNodeDataSet(hdwf, channel, 0, rgdSamples, c_int(cSamples)) #dwf.FDwfAnalogOutNodeFrequencySet(hdwf, channel, 0, c_double(fs)) dwf.FDwfAnalogOutFrequencySet(hdwf, channel, c_double(fs)) dwf.FDwfAnalogOutNodeAmplitudeSet(hdwf, channel, 0, c_double(4)) dwf.FDwfAnalogOutNodeOffsetSet(hdwf, channel, 0, c_double(0)) dwf.FDwfAnalogOutRepeatSet(hdwf, channel, c_int(10000000)) # repeat dwf.FDwfAnalogOutConfigure(hdwf, channel, c_int(1)) dwf.FDwfAnalogOutReset(hdwf, channel) dwf.FDwfDeviceClose(hdwf) I have connected the BNC cable from AD2 to my picoscope and here is what I get in the spectrum analyzer. I also saved the 4096 samples in a file and upload to the waveform app, but it didn't solve anything. However when I generate a sweep from the Waveform app, I see the expected frequency spectrum. Best, Ergest
  4. I still can't get this working. Is the device capable of producing a flat frequency response for, let's say, a 5 kHz bandwidth
  5. What are the limitations of implementing this in Python, and are there any exemplary guides for accomplishing this in the Waveform application? Should I script the generation of OFDM symbols or simply import them from a .csv file? Solely reading the file appears insufficient. The OFDM consists of more than 62k samples. It's uncertain whether the buffer can manage this volume, but surprisingly, when I examine the time domain of the generated signal, it seems to encompass the entire signal, although the frequency spectrum is incorrect.
  6. Hi, I'm using an Analog Discovery 2 board with Python to transmit and record signals for an OFDM system. However, the output signal, when checked with a spectrum analyzer, shows peaks instead of a flat frequency response. I've tried using the AnalogOut_Custom.py script but it's not working as expected. Can anyone suggest how to get a better frequency response with this setup, or any similar project that can show me the path? Also, how does the 'cSamples' variable affect the OFDM symbol samples? Edit: This is what the spectrum analyzer shows: It is completely off, since I am using a center frequency of 5 kHz and a bandwidth of 3 kHz, 1024 subcarriers. Thanks for any help!
×
×
  • Create New...