Jump to content
  • 0

Adjust Digital IO system frequency in Python API


HarissonJones

Question

Recommended Posts

  • 0

Thank you @attila. I do not see this reflected when reading out the clock info, like this

internal_frequency = c_double()
dwf.FDwfDigitalOutInternalClockInfo(hdwf, byref(internal_frequency))
print(internal_frequency.value)

It still returns 100MHz. Is that correct?

Edited by HarissonJones
Link to comment
Share on other sites

  • 0

Attila and all:  When I enter the code suggested to my AD3,  

dwf.FDwfDeviceParamSet(hdwf, DwfParamFrequency, c_int(83360000)) # 8x 10.42MHz
 

The system clock returns as 83333333.33333     Happens with some frequencies, others it gets right.   But I can't get 83.36 MHz,  for example.   Any ideas why it is not giving me what I want?

Thank you.

Link to comment
Share on other sites

  • 0

Hi @Steve_3

On AD3 the supported frequencies are limited by the device PLL and its 25MHz reference clock.
To obtain other frequencies external reference clock can be supplied through trigger 1 IO, with 10.42MHz ref clock it can generate 83.36MHz

image.pngimage.png


A distribution of the supported frequency steps looks like this, 50-125MHz
image.png

Link to comment
Share on other sites

  • 0

Hi @Steve_3

The PLL has a fractional option for finer frequency synthesis. This is not used since it introduces jitter which can affect the ADC and DAC performance. Depending on use, like for digital signals it could be acceptable. If you need this, I could try enabling it next week.

Link to comment
Share on other sites

  • 0

Thank you,  but for the moment, I can just use the frequencies that are available.   But as you mentioned phase jitter,  I have found phase stability problems in undersampling signals-   averaging is not adding up properly due to phase jitter, when I mix down and fully sample it is fine.    The signal is only at 3.3 MHz,   I was surprised to see this.  That's a very general question,  I was planning on gathering a specific example, but as phase jitter came up...    I am using the standard clock rate of 100 MHz, and using a sampling rate of 1MS/sec.    

 

Link to comment
Share on other sites

  • 0

Sure.  Here is the output from a script that outputs a 4 msec pulse at 3.3 MHz.   There is a 5 msec predelay before the pulse.  The scope is triggered at a the same time the RF pulse starts,  using an external trigger (dio1 connected to external trigger 1).  1 MS/sec sampling rate, 8000 acquisition points.   Only one scope channel is enabled.   I then run a loop where I average 1, then 2,  4,  and 8 acquisitions.   The screenshot shows the last acquisition highlighed,  on the left are all four acquisitions,  and then the calculated "signal-to-noise" ratio in the list below.  I'd have expected the "signal", which I calculate as the accumulated signal (from the number of averages) over a region of the pulse to increase by the number of acquisitions,  and the noise to increase by the square root of that.     

As you can see, this is not the case,  indeed the signal is averaging to zero in the case of four acquisitions.   The noise is more as I'd expect.  This is typical behavior,  but random where the signal tends to average to zero- indicating that I'm not phase stable.

Surely I'm missing something.  Happy to send the script,  but if you guys have any example of undersampling I'd be happy to look at that and figure out what I'd doing wrong.

Thanks for looking.   Oh- (edit)- The output from waveform generator 0 is directly routed to scope input 0.

Screenshot2023-11-02121546.thumb.png.3c756bb155dcb1cdf9f589cd05513b85.png

Edited by Steve_3
Link to comment
Share on other sites

  • 0

Thanks Attila.  Yes, using the low input range.    I've tried a variety of approaches, including resetting and re-opening the AD2s with each acquisition.   Same results.  It seems that undersampling is working fine, but the samples are offset a bit with respect to the sine wave each time.   So this works as expected unless you need to average data.    Code is attached-  I am very new to python and the ad2,  so I am assuming I'm doing something wrong.    Appreciate any help, and realize that you don't have time to debug bad code.  

test_undersampling_v2.py

Link to comment
Share on other sites

  • 0

Yes,   but it should work with any frequency (except a multiple of sampling rate).  Purposely undersampling,  and all I'm looking for is to get the same waveform (plus or minus noise) each time.   If that were the case, taking multiple acquisitions and adding them should make the signal sum and the noise sum as  the square root of N.   But, there appears to be at least a small timing offset between the sampling and the sine wave -  This is very evident if you enter, say 5 MHz as the sampling rate.  The samples should hit the sine wave at the same point,  even at the zero point, each time.   The signal fluctuates with each acquisition in my code.   I should try waveforms,  hadn't thought of that, as I only use python. I assume waveforms has the ability to average data.  I'll try that to see if the issue is in my code or something more fundamental that I'm missing.

Link to comment
Share on other sites

  • 0

Hi @Steve_3

The fundamental problem is that the sampling is not synchronized.
The Scope with decimate sampling for 1MHz stores every 100th ADC conversion, but this sampling is not synchronized with the AWG output, so consequent captures can have 100 phases. This Scope sampling start can not be synchronized with any trigger source. The only option would be using 100MHz sampling, but the AD2 is limited up to 16ki samples with the 2nd device configuration.

Link to comment
Share on other sites

  • 0

Hi @Steve_3

It comes to mind now, to have consistent capture phases trigger the AWG on Scope.

dwf.FDwfAnalogOutTriggerSourceSet(hdwf, c_int(ChNum), trigsrcAnalogIn)
dwf.FDwfAnalogOutConfigure(hdwf, c_int(0), c_int(1))
dwf.FDwfAnalogInConfigure(hdwf, c_int(1), c_int(1))

You can also set:
AnalogOutRepeatSet 0 infinite
AnalogOutRepeatTriggerSet 1
This way, new generator outputs are automatically performed by the device for each capture. There is no need to reconfigure the Scope or AWG in the loop, just read the captures:
def trigger_and_read_ch0(rgdSamples,numSamp):
    while True:
        dwf.FDwfAnalogInStatus(hdwf, c_int(1), byref(sts))
        if sts.value == DwfStateDone.value:
            break
    dwf.FDwfAnalogInStatusData(hdwf, 0, rgdSamples, numSamp)  # get channel 1 data
    y = 0
    return y

image.png

Link to comment
Share on other sites

  • 0

Hi Atilla-    This code works great, though I don't quite understand some details.   On me, but,  perhaps you can explain why the RF pulses won't repeat?   You modified these two lines in my original code:

    dwf.FDwfAnalogOutWaitSet(hdwf, c_int(ChNum), c_double(pd))  # wait time
    dwf.FDwfAnalogOutRepeatSet(hdwf, c_int(ChNum), c_int(Nreps))  # repetitions

removing the first line and changing Nreps to zero.   When I tried to change it to generate two pulses with each trigger,   the code no longer worked.  It doesn't even appear to generate two pulses.   

Certainly it is the intended operation, but I'm curious why I can't generate two repeated pulses,  with a seperation of pd, each time the Analog in is started.  I'd think the trigger simply starts the AO,  and it would not care if it was one or two (or more repeated pulses).     

Thanks for reading!

Also-  (edit)-  is there a formula for the AM modulation?   (using the custom function waveform)  Can't find this in the manual.  

Edited by Steve_3
just added a second question.
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...