diff --git a/ADwinProII/labscript_devices_ADwin_modules.py b/ADwinProII/labscript_devices_ADwin_modules.py index 6c11b2b9fe9525620620336fbc8587eb947db79c..9f4c9c623868a64e3694943256587a705c7cee88 100644 --- a/ADwinProII/labscript_devices_ADwin_modules.py +++ b/ADwinProII/labscript_devices_ADwin_modules.py @@ -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)