Moku model: Moku Pro
Operating system: Windows
**Software version: 3.1.2, firmware 587
Bug/support request description:
Apologies, this is maybe a niche bug.
It seems that there is a small frequency offset/error between different channels in the arbitrary waveform generator. This only occurs when the frequencies are an order of magnitudes apart or more. It is usually small (7 milliHertz - 2 Hertz) but over the course of a 1-10 second experiment, it can cause signals to drift entirely out of phase. This is just a guess, but perhaps clock divisor/ multiplier is different in each channel, and their ratios are either non-rational, or the minimum resolutions do not coincide at the same frequency points…
I have found that I can often correct for this by adding small frequency increments to either waveform to compensate for the drift. But I have to do it dynamically depending on the difference between the two generated frequencies, as well as the number of points used in the waveform…
I have included some Python code to replicate the issue.
If I am missing something? is there is a simpler way to fix this? Any help would be greatly appreciated…
** Code/Steps to replicate **
from moku.instruments import Oscilloscope, MultiInstrument, ArbitraryWaveformGenerator
from time import sleep
show_error = True # Change to false to show the correction
moku_ip= "XXXXXXXXXXXXX"
mim = MultiInstrument(moku_ip, force_connect=True, platform_id=4)
arb = mim.set_instrument(1, ArbitraryWaveformGenerator)
osc = mim.set_instrument(2, Oscilloscope)
mim.set_connections([
{"source": "Slot1OutA", "destination": "Slot2InA"},
{"source": "Slot1OutB", "destination": "Slot2InB"}])
osc.set_trigger(type="Edge", edge="Rising", source="ChannelB", level=300e-3, nth_event=4
arb.enable_output(1, enable=True)
arb.enable_output(2, enable=True)
if show_error:
# Frequency ratio is exactly 15, but the waveforms drift out of phase
arb.generate_waveform(channel=1, sample_rate='Auto', lut_data=list([1,1,1,1,0,1,0,1,1,0,0,1,0,0,0]), frequency=150e3, amplitude=1)
arb.generate_waveform(channel=2, sample_rate='Auto', lut_data=list([1,1,1,1,0,1,0,1,1,0,0,1,0,0,0]), frequency=10e3, amplitude=1)
else:
# Frequency ratio is 14.99997... and now the waveforms are syncronised
# The larger the gap in frequency, the larger the correction required.
arb.generate_waveform(channel=1, sample_rate='Auto', lut_data=list([1,1,1,1,0,1,0,1,1,0,0,1,0,0,0]), frequency=149.999995e3, amplitude=1)
arb.generate_waveform(channel=2, sample_rate='Auto', lut_data=list([1,1,1,1,0,1,0,1,1,0,0,1,0,0,0]), frequency=10e3, amplitude=1)
osc.set_trigger(type="Edge", edge="Rising", source="ChannelB", level=300e-3, nth_event=4)
osc.set_timebase(-10e-6, 10e-6)
d1 = osc.get_data()
sleep(2)
d2 = osc.get_data()
plt.plot(np.array(d1["ch2"]) + 0.01) # Small offset just to show that the position of the trigger waveform is the same
plt.plot(np.array(d1["ch1"]) + 0.55)
plt.plot(d2["ch2"])
plt.plot(np.array(d2["ch1"]) + 0.55)
plt.show()
mim.relinquish_ownership()