*** Wartungsfenster jeden ersten Mittwoch vormittag im Monat ***

Skip to content
Snippets Groups Projects
Commit caa31e50 authored by Schabbauer, Johannes's avatar Schabbauer, Johannes
Browse files

Added starting value to ADwin PID controls

parent 4391dc39
1 merge request!4PID improvements for ADwin
......@@ -169,6 +169,7 @@ class ADwinProIIWorker(Worker):
self.adw.SetData_Float(PIDs["PID_D"], 27, 1, PIDs.shape[0])
self.adw.SetData_Long(PIDs["PID_min"], 28, 1, PIDs.shape[0])
self.adw.SetData_Long(PIDs["PID_max"], 29, 1, PIDs.shape[0])
self.adw.SetData_Long(PIDs["PID_start"], 30, 1, PIDs.shape[0])
AIN = group["ANALOG_IN/TIMES"]
if fresh or not np.array_equal(AIN[:],self.smart_cache["AIN"]):
print("AIN programmed.")
......
......@@ -97,7 +97,7 @@ class ADwinAnalogOut(AnalogOut):
self.PID = {} # instructions for PID settings
def set_PID(self,t,PID_AnalogIn,P=0,I=0,D=0,limits=None):
def set_PID(self,t,PID_AnalogIn,P=0,I=0,D=0,limits=None, start=0):
"""(De-)activate PID for analog output, or change settings
Parameters
......@@ -115,12 +115,20 @@ class ADwinAnalogOut(AnalogOut):
Differential parameter
limits : tuple of float, optional
Limits for output voltage, defaults to output limits
start : float or "last"
Inital value of the output when the PID is turned on, assigned to the I part.
If start="last" when the PID is turned on, the I value from the PID earlier
in the shot is kept. If start="last" when the PID is turned off, the last output
value is kept as "set_target".
"""
if limits is None:
# Use the Output limits if there are none specified here.
limits = self.limits
if limits[0]<self.limits[0] or limits[1]>self.limits[1]:
raise LabscriptError(f"Limits of {self.name} with PID must not be larger than channel limits {self.limits}!")
# TURN OFF PID
if PID_AnalogIn is None:
self.PID[t] = {
"PID_channel": 0,
......@@ -128,7 +136,9 @@ class ADwinAnalogOut(AnalogOut):
"I": I,
"D": D,
"limits": limits,
"start": start,
}
# TURN ON PID
elif (isinstance(PID_AnalogIn,AnalogIn) and isinstance(PID_AnalogIn.parent_device,_ADwinCard)) \
or isinstance(PID_AnalogIn,int):
self.PID[t] = {
......@@ -137,6 +147,7 @@ class ADwinAnalogOut(AnalogOut):
"I": I,
"D": D,
"limits": limits,
"start": start,
}
# TODO: Do we need scale factors for setting a PID with integer?
else:
......@@ -344,7 +355,7 @@ class ADwinAO8(_ADwinCard):
output_dtypes = [("n_cycles",np.int32),("channel",np.int32),("value",np.int32)]
PID_dtypes = [
("n_cycles",np.int32),("AOUT_channel",np.int32),("PID_channel",np.int32),
("PID_P",np.float64),("PID_I",np.float64),("PID_D",np.float64),("PID_min",np.int32),("PID_max",np.int32)
("PID_P",np.float64),("PID_I",np.float64),("PID_D",np.float64),("PID_min",np.int32),("PID_max",np.int32),("PID_start",np.int32)
]
outputs = []
PID_channels = []
......@@ -380,6 +391,12 @@ class ADwinAO8(_ADwinCard):
limits = output.PID[t]['limits']
PID_array["PID_min"][i] = ADC(limits[0],self.resolution_bits,self.min_V,self.max_V)
PID_array["PID_max"][i] = ADC(limits[1],self.resolution_bits,self.min_V,self.max_V)
if output.PID[t]["start"]=="last":
# When we want to use the previous value during the shot,
# we use a value that's out of the 16 bit ADC range to identify.
PID_array["PID_start"][i] = 100_000
else:
PID_array["PID_start"][i] = ADC(output.PID[t]['start'],self.resolution_bits,self.min_V,self.max_V)
# The ADwin has 16 bit output resolution, so we quantize the Voltage to the right values
quantized_output = ADC(output.raw_output,self.resolution_bits,self.min_V,self.max_V)
out = np.empty(quantized_output.size,dtype=output_dtypes)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment