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

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

ADwin: Implemented using multiple PID channels for one AnalogOut (than used to...

ADwin: Implemented using multiple PID channels for one AnalogOut (than used to work, but we broke it with the last code changes where we split up PID init).
parent 273af970
No related branches found
No related tags found
No related merge requests found
......@@ -120,15 +120,8 @@ class ADwinAnalogOut(AnalogOut):
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}!")
if isinstance(pid_no,AnalogIn) and isinstance(pid_no.parent_device,_ADwinCard):
pid_no = int(pid_no.connection) + pid_no.parent_device.start_index
self.pid_no = pid_no
self.P = P
self.I = I
self.D = D
self.PID_min = limits[0]
self.PID_max = limits[1]
self.parent_device.PID_init[pid_no] = [P,I,D,*limits]
def set_PID(self,t,pid_no,set_output=0):
......@@ -148,8 +141,9 @@ class ADwinAnalogOut(AnalogOut):
'last' means that the output from the PID loop is kept as 'set_target'.
"""
# Error check of bounds for set_output
if set_output!="last":
if set_output<self.PID_min or set_output>self.PID_max:
if set_output!="last" and pid_no is not None:
PID_min,PID_max = self.parent_device.PID_init[pid_no][-2:]
if set_output<PID_min or set_output>PID_max:
raise LabscriptError(
f"{self.name}: PID 'set_output={set_output}' must be within ({self.PID_min},{self.PID_max})"
)
......@@ -212,16 +206,14 @@ class ADwinAnalogOut(AnalogOut):
def add_instruction(self,time,instruction,units=None):
# Overwrite Output.add_instruction without limit check, becasue the value can be off-limits when this is the target value of the PID
limits_temp = self.limits
if hasattr(self,"pid_no"):
self.limits = (-10,10)
self.limits = (-10,10)
super().add_instruction(time,instruction,units)
self.limits = limits_temp
def expand_timeseries(self,all_times,flat_all_times_len):
# Overwrite Output.add_instruction without limit check, becasue the value can be off-limits when this is the target value of the PID
limits_temp = self.limits
if hasattr(self,"pid_no"):
self.limits = (-10,10)
self.limits = (-10,10)
super().expand_timeseries(all_times,flat_all_times_len)
self.limits = limits_temp
......@@ -339,6 +331,7 @@ class ADwinAO8(_ADwinCard):
def __init__(self, name, parent_device, module_address, num_AO=8, **kwargs):
self.num_AO = num_AO
self.start_index = module_start_index[int(module_address)]
self.PID_init = {}
super().__init__(name, parent_device, module_address, **kwargs)
......@@ -414,19 +407,20 @@ class ADwinAO8(_ADwinCard):
PID_table = []
PID_config = []
for pid_no in self.PID_init:
P,I,D,PID_min,PID_max = self.PID_init[pid_no]
if isinstance(pid_no,AnalogIn) and isinstance(pid_no.parent_device,_ADwinCard):
pid_no = int(pid_no.connection) + pid_no.parent_device.start_index
PID_min = ADC(PID_min,self.resolution_bits,self.min_V,self.max_V)
PID_max = ADC(PID_max,self.resolution_bits,self.min_V,self.max_V)
PID_config.append(np.array([(pid_no,P,I,D,PID_min,PID_max)], dtype=PID_config_dtypes))
for output in sorted(self.child_devices, key=lambda dev:int(dev.connection)):
output.expand_output()
# Get input channels for PID, collect changed for time table and store bare channels as dataset
if output.PID:
# Get PID parameters
if not hasattr(output,"pid_no"):
raise LabscriptError(f"For {self.name} you try to use a PID, but never set the parameters via {self.name}.init_PID().")
PID_config. append(
np.array([
(output.pid_no,output.P,output.I,output.D,ADC(output.PID_min,self.resolution_bits,self.min_V,self.max_V),ADC(output.PID_max,self.resolution_bits,self.min_V,self.max_V))
], dtype=PID_config_dtypes)
)
PID_array = np.zeros(len(output.PID),dtype=PID_table_dtypes)
PID_times = np.array(list(output.PID.keys()))
PID_times.sort()
......@@ -451,6 +445,9 @@ class ADwinAO8(_ADwinCard):
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)
# Error check, if PID was initialized
if output.PID[t]['PID_channel']!=0 and output.PID[t]['PID_channel'] not in self.PID_init:
raise LabscriptError(f"PID for AnalogOutput {output.name} at t={t} (pidno {PID_array['PID_channel'][i]} was never initialized!")
# 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