Jump to content
  • 0

Varying DI/O Frequency instantaiously


ZGWSU

Question

I've been experimenting with a Analog Discovery system controlled via Python and have determined how to generate a digital signal out, however I have not been able to have the signal change frequency or duty cycle mid run. I have tried just use the function that controls duty cycle a second time however that just seems to overwrite the first.  Below is the python code I have been using, any guidance would be much appreciated. 

-ZG

 

"""
   DWF Python Example
   
   Edit ZG

   Requires:                       
       Python 2.7, numpy
       python-dateutil, pyparsing
"""
from ctypes import *
from dwfconstants import *
import math
import time
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")

#declare ctype variables
hdwf = c_int()
sts = c_byte()

#print DWF version
version = create_string_buffer(16)
dwf.FDwfGetVersion(version)
print "DWF Version: "+version.value

#open device
print "Opening first device"
dwf.FDwfDeviceOpen(c_int(-1), byref(hdwf))

if hdwf.value == hdwfNone.value:
    print "failed to open device"
    quit()

hzSys = c_double()

dwf.FDwfDigitalOutInternalClockInfo(hdwf, byref(hzSys))

# 1kHz pulse on IO pin 1
dwf.FDwfDigitalOutEnableSet(hdwf, c_int(1), c_int(1))
# prescaler to 2kHz, SystemFrequency/1kHz
print "hzSys", hzSys.value
dwf.FDwfDigitalOutDividerSet(hdwf, c_int(1), c_int(int(hzSys.value/1e3)))
print "frequency:", hzSys.value/1e3/2/100
# 1 tick low, 1 tick high
dwf.FDwfDigitalOutCounterSet(hdwf, c_int(1), c_int(4), c_int(6))

# 1kHz pulse on IO pin 1
# prescaler to 2kHz, SystemFrequency/1kHz
print "hzSys", hzSys.value
dwf.FDwfDigitalOutDividerSet(hdwf, c_int(1), c_int(int(hzSys.value/1e3)))
print "frequency:", hzSys.value/1e3/2/100
# 1 tick low, 1 tick high
dwf.FDwfDigitalOutCounterSet(hdwf, c_int(1), c_int(6), c_int(4))

# rgdSamples = (c_byte*4)(*[0x00,0xAA,0x66,0xFF])
# # 1kHz sample rate custom on IO pin 3
# dwf.FDwfDigitalOutEnableSet(hdwf, c_int(3), 1)
# dwf.FDwfDigitalOutTypeSet(hdwf, c_int(3), DwfDigitalOutTypeCustom)
# dwf.FDwfDigitalOutDividerSet(hdwf, c_int(3), c_int(int(hzSys.value/1e3)))
# dwf.FDwfDigitalOutDataSet(hdwf, c_int(3), byref(rgdSamples), c_int(4*8))

dwf.FDwfDigitalOutConfigure(hdwf, c_int(1))

sleepTime = 10
print "Generating output counter for %s seconds..."%sleepTime

time.sleep(sleepTime)

dwf.FDwfDigitalOutReset(hdwf);

dwf.FDwfDeviceCloseAll()
 

Link to comment
Share on other sites

4 answers to this question

Recommended Posts

Hello,

The *Configure call start the generator. In case you want to change the duty: apply settings, *Configure, sleep, modify settings, *Configure, sleep

...

# Initial settings
# 1kHz pulse on IO pin 1
dwf.FDwfDigitalOutEnableSet(hdwf, c_int(1), c_int(1))
# prescaler to 2kHz, SystemFrequency/1kHz
print "hzSys", hzSys.value
dwf.FDwfDigitalOutDividerSet(hdwf, c_int(1), c_int(int(hzSys.value/1e3)))
print "frequency:", hzSys.value/1e3/2/100
# 1 tick low, 1 tick high
dwf.FDwfDigitalOutCounterSet(hdwf, c_int(1), c_int(4), c_int(6))

# rgdSamples = (c_byte*4)(*[0x00,0xAA,0x66,0xFF])
# # 1kHz sample rate custom on IO pin 3
# dwf.FDwfDigitalOutEnableSet(hdwf, c_int(3), 1)
# dwf.FDwfDigitalOutTypeSet(hdwf, c_int(3), DwfDigitalOutTypeCustom)
# dwf.FDwfDigitalOutDividerSet(hdwf, c_int(3), c_int(int(hzSys.value/1e3)))
# dwf.FDwfDigitalOutDataSet(hdwf, c_int(3), byref(rgdSamples), c_int(4*8))


# First run
dwf.FDwfDigitalOutConfigure(hdwf, c_int(1))
sleepTime = 10
print "1. Generating output counter for %s seconds..."%sleepTime
time.sleep(sleepTime)


# Modify settings
# 1kHz pulse on IO pin 1
# prescaler to 2kHz, SystemFrequency/1kHz
print "hzSys", hzSys.value
dwf.FDwfDigitalOutDividerSet(hdwf, c_int(1), c_int(int(hzSys.value/1e3)))
print "frequency:", hzSys.value/1e3/2/100
# 1 tick low, 1 tick high
dwf.FDwfDigitalOutCounterSet(hdwf, c_int(1), c_int(6), c_int(4))


# Second run
dwf.FDwfDigitalOutConfigure(hdwf, c_int(1))
sleepTime = 10
print "2. Generating output counter for %s seconds..."%sleepTime
time.sleep(sleepTime)


dwf.FDwfDigitalOutReset(hdwf);
dwf.FDwfDeviceCloseAll()

Link to comment
Share on other sites

Thank you, this does switch the waveform however there is a 5-15 msec delay when it switches is it possible to set two channels of DIO and have a trigger watch on another channel to alter the output pin to switch between waveforms so that I do not get the delay. If there isn't is there another digilent FPGA that could serve the function that doesn't require an intimate knowledge of VHDL. 

Link to comment
Share on other sites

We could reduce this delay between configurations to 1-5ms but can't get rid of it.

Such pulses could be generated with any microcontroller or FPGA board. For FPGA beside HDL could use Multisim.

You could use the ROM logic to generate 40-60% duty pulses.
Here DIO 0 and 1 is used as state encoding 2/3 or 3/2 steps, DIO 3 is used as signal to switch between 40 and 60% duty, DIO 2 is the output. DIO 4 is your custom pattern.

img1.png

ROM.dwf3work

Link to comment
Share on other sites

So I'm returning to this issue and am still not sure that the solution you suggested will produce the result I'm after.  Ultimately, my application will require that I phase-coherently switch between waveforms. I have found an external multiplexer that can switch between waveforms quite rapidly but I'm wondering how I can program at least one channel of analog discovery (AD) on the fly (i.e. not stopping the output of at least one waveform)?  For example, suppose I want a 250 kHz square wave with a 50% duty cycle, waveform A, to run for 1000 cycles and then switch to a second 248 kHz square wave with a 40% duty cycle, waveform B, that then runs for 3000 cycles before returning to waveform A.  Firstly, can I setup such a scenario and secondly, is there a way for me programmatically alter waveform B without stopping waveform A?  (Then there is a whole other matter of getting a trigger out to the multiplexer to switch between the DIO lines.  Any thoughts or suggestions would be helpful.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...