Hi everyone,
We're trying to implement a ramping function to slowly decrease the power of our DDS signal over 100µs, but we're encountering an issue where we don't observe any change in the optical power.
Our setup involves an AD9910/DDS connected to an AOM. The output light of the AOM is measured by a power diode, and this power measurement is fed back to the SUServo. We're attempting to create the ramp by incrementally changing the setpoint/offset within the set_dds function and introducing a 5µs delay between each increment. Our goal is to achieve a linear decrease in DDS power over the 100µs timeframe.
However, despite these changes, we see no corresponding change in the optical power detected by the power diode. We're wondering if this is a limitation of our system and would appreciate any insights you might have.
Specifically, we're considering two possibilities:
PID Tuning: Could the lack of change be due to improperly tuned PID values in the SUServo? Are our current settings preventing it from responding quickly enough to the changes in the DDS signal? (P = 0.005, I = -10.0, G = 0.0)
SUServo Response Time: Is it possible that the SUServo simply isn't capable of reacting to changes on this timescale (100µs)?
Any advice or suggestions on how to troubleshoot this issue would be greatly appreciated. Perhaps there are alternative methods for implementing this type of ramp function that we should consider?
Example code of how we are changing the beam's power from 100uW to 0uW over 100us but are seeing no change in power.
`class SUServoMinimal(EnvExperiment):
def build(self):
self.setattr_device("core")
self.setattr_device("urukul0_cpld")
self.setattr_device("urukul1_cpld")
self.setattr_device("suservo0")
self.setattr_device("suservo0_ch0")
self.setattr_device("suservo0_ch1")
self.setattr_device("suservo0_ch2")
self.setattr_device("suservo0_ch4")
self.setattr_device("suservo0_ch5")
self.setattr_device("suservo0_ch6")
@kernel
def change_power(self, power: TFloat):
"""
Sets the power output beam.
:param power: TFloat
Power of the beam in uW.
"""
if power < 0.0 or power > 5000.0:
raise ValueError("Power is out of bounds.")
voltage = (power + 4.8) / 340 #Pre-calibrated
setpoint = -voltage * (10.0 ** (1 - 1))
self._adb.set_dds(profile=0, frequency=self._adb_frequency, offset=setpoint)
@kernel
def run(self):
# Prepare core
self.core.reset()
# Initialize and activate SUServo
self.suservo0.init()
self.suservo0.set_config(enable=1)
# Set Sampler gain and Urukul attenuation
g = 1
A = 0.0
self.suservo0.set_pgia_mu(0, g) # set gain on Sampler channel 0 to 10^g
self.urukul0_cpld.set_att(0, A) # set attenuation on Urukul channel 0 to 0
# Set physical parameters
v_t = 0.05 # target input voltage (V) for Sampler channel
f_1 = 70 * MHz # frequency (Hz) of Urukul output
o = -v_t * (10.0 ** (g - 1)) # offset to assign to servo to reach target voltage
# Set PI loop parameters
kp = 0.005 # proportional gain
ki = -10.0 # integrator gain
gl = 0.0 # integrator gain limit
# Input parameters, activate Urukul output (en_out=1),
# activate PI loop (en_iir=1)
self.suservo0_ch0.set_iir(profile=0, adc=0, kp=kp, ki=ki, g=gl)
self.suservo0_ch0.set_dds(profile=0, frequency=f_1, offset=o)
self.suservo0_ch0.set_microwave(en_out=1, en_iir=1, profile=0)
self.change_power(100)
delay(5*us)
for i in range(10,-1,-1):
self.change_power(100*i/10)
delay(5*us)
self.suservo0_ch0.set_microwave(en_out=0, en_iir=1, profile=0)`