@@ -194,6 +194,100 @@ def perform_keithley_zero_check(keithley):
194194# --- Main Program Execution ---
195195
196196
197+ def stabilize_temperature (lakeshore , target_temp ):
198+ """Actively controls the heater to reach and stabilize at the target temperature."""
199+ print (f"\n Moving to start temperature of { target_temp } K using active control..." )
200+ while True :
201+ current_temp = lakeshore .get_temperature (SENSOR_INPUT )
202+
203+ if current_temp > target_temp + 0.2 : # System is too warm
204+ print (f"Cooling... Current: { current_temp :.4f} K > Target: { target_temp } K" , end = '\r ' )
205+ lakeshore .set_heater_range (HEATER_OUTPUT , 'off' )
206+ else : # System is too cold or within tolerance
207+ print (f"Heating... Current: { current_temp :.4f} K <= Target: { target_temp } K" , end = '\r ' )
208+ lakeshore .set_heater_range (HEATER_OUTPUT , 'medium' )
209+ lakeshore .set_setpoint (HEATER_OUTPUT , target_temp )
210+
211+ if abs (current_temp - target_temp ) < 0.1 : # Stabilization tolerance
212+ print (f"\n Stabilized at { current_temp :.4f} K. Waiting 5 seconds before starting ramp." )
213+ time .sleep (5 )
214+ break
215+ time .sleep (2 )
216+
217+
218+ def run_measurement_loop (lakeshore , keithley , filename , end_temp , safety_cutoff , source_voltage , delay ):
219+ """Runs the main data acquisition loop, logging data and updating the plot."""
220+ plt .ion ()
221+ fig , (ax1 , ax2 ) = plt .subplots (2 , 1 , figsize = (8 , 8 ))
222+ fig .suptitle ('Live R-T Measurement' , fontsize = 16 )
223+ line1 , = ax1 .plot ([], [], 'b-o' , markersize = 3 )
224+ ax1 .set_xlabel ('Elapsed Time (s)' )
225+ ax1 .set_ylabel ('Temperature (K)' )
226+ ax1 .set_title ('Temperature Ramp Profile' )
227+ ax1 .grid (True , linestyle = ':' )
228+ line2 , = ax2 .plot ([], [], 'r-s' , markersize = 3 )
229+ ax2 .set_xlabel ('Temperature (K)' )
230+ ax2 .set_ylabel ('Resistance (Ω)' )
231+ ax2 .set_title ('Resistance vs. Temperature' )
232+ ax2 .grid (True , linestyle = ':' )
233+ ax2 .set_yscale ('log' )
234+ fig .tight_layout (rect = [0 , 0.03 , 1 , 0.95 ])
235+ time_data , temp_data , res_data = [], [], []
236+
237+ start_time = time .time ()
238+
239+ with open (filename , 'w' , newline = '' ) as file :
240+ writer = csv .writer (file )
241+ writer .writerow (["Timestamp" , "Elapsed Time (s)" , "Temperature (K)" , "Heater Output (%)" ,
242+ "Applied Voltage (V)" , "Measured Current (A)" , "Resistance (Ohm)" ])
243+
244+ while True :
245+ elapsed_time = time .time () - start_time
246+ current_temp = lakeshore .get_temperature (SENSOR_INPUT )
247+ heater_output = lakeshore .get_heater_output (HEATER_OUTPUT )
248+
249+ time .sleep (delay )
250+ resistance = keithley .resistance
251+ current = abs (source_voltage / resistance ) if resistance != 0 else float ('inf' )
252+
253+ status_str = (
254+ f"Time: { elapsed_time :7.2f} s | "
255+ f"Temp: { current_temp :8.4f} K | "
256+ f"Resistance: { resistance :9.3e} Ω"
257+ )
258+ print (status_str , end = '\r ' )
259+
260+ with open (filename , 'a' , newline = '' ) as file :
261+ writer = csv .writer (file )
262+ writer .writerow ([
263+ datetime .now ().strftime ('%Y-%m-%d %H:%M:%S' ),
264+ f"{ elapsed_time :.2f} " , f"{ current_temp :.4f} " , f"{ heater_output :.2f} " ,
265+ f"{ source_voltage :.4e} " , f"{ current :.4e} " , f"{ resistance :.4e} "
266+ ])
267+
268+ time_data .append (elapsed_time )
269+ temp_data .append (current_temp )
270+ res_data .append (resistance )
271+
272+ line1 .set_data (time_data , temp_data )
273+ ax1 .relim ()
274+ ax1 .autoscale_view ()
275+ line2 .set_data (temp_data , res_data )
276+ ax2 .relim ()
277+ ax2 .autoscale_view ()
278+ fig .canvas .draw ()
279+ fig .canvas .flush_events ()
280+
281+ if current_temp >= safety_cutoff :
282+ print (f"\n \n !!! SAFETY CUTOFF REACHED at { current_temp :.4f} K (Limit: { safety_cutoff } K) !!!" )
283+ break
284+ if current_temp >= end_temp :
285+ print (f"\n \n Target temperature of { end_temp } K reached." )
286+ break
287+
288+ time .sleep (2 )
289+
290+
197291def main ():
198292 """Main function to run the R-T experiment."""
199293 root = tk .Tk ()
@@ -225,128 +319,22 @@ def main():
225319 keithley = Keithley6517B (KEITHLEY_VISA )
226320 print (f"Successfully connected to: { keithley .id } " )
227321 perform_keithley_zero_check (keithley )
228-
322+
229323 keithley .source_voltage = source_voltage
230324 keithley .current_nplc = 1
231325 keithley .enable_source ()
232326 print (f"\n Keithley source enabled and set to { source_voltage } V." )
233327
234328 # --- Setup Live Plot ---
235329 plt .ion ()
236- fig , (ax1 , ax2 ) = plt .subplots (2 , 1 , figsize = (8 , 8 ))
237- fig .suptitle ('Live R-T Measurement' , fontsize = 16 )
238- line1 , = ax1 .plot ([], [], 'b-o' , markersize = 3 )
239- ax1 .set_xlabel ('Elapsed Time (s)' )
240- ax1 .set_ylabel ('Temperature (K)' )
241- ax1 .set_title ('Temperature Ramp Profile' )
242- ax1 .grid (True , linestyle = ':' )
243- line2 , = ax2 .plot ([], [], 'r-s' , markersize = 3 )
244- ax2 .set_xlabel ('Temperature (K)' )
245- ax2 .set_ylabel ('Resistance (Ω)' )
246- ax2 .set_title ('Resistance vs. Temperature' )
247- ax2 .grid (True , linestyle = ':' )
248- ax2 .set_yscale ('log' )
249- fig .tight_layout (rect = [0 , 0.03 , 1 , 0.95 ])
250- time_data , temp_data , res_data = [], [], []
251-
252- # --- NEW: Go to Start Temp and Stabilize with Active Control ---
253- print (
254- f"\n Moving to start temperature of { start_temp } K using active control..." )
255- while True :
256- current_temp = lakeshore .get_temperature (SENSOR_INPUT )
257-
258- # Active heating/cooling logic
259- if current_temp > start_temp + 0.2 : # System is too warm
260- print (
261- f"Cooling... Current: { current_temp :.4f} K > Target: { start_temp } K" ,
262- end = '\r ' )
263- lakeshore .set_heater_range (HEATER_OUTPUT , 'off' )
264- else : # System is too cold or within tolerance
265- print (
266- f"Heating... Current: { current_temp :.4f} K <= Target: { start_temp } K" ,
267- end = '\r ' )
268- lakeshore .set_heater_range (HEATER_OUTPUT , 'medium' )
269- lakeshore .set_setpoint (HEATER_OUTPUT , start_temp )
270-
271- # Check for stabilization
272- if abs (current_temp - start_temp ) < 0.1 : # Stabilization tolerance
273- print (
274- f"\n Stabilized at { current_temp :.4f} K. Waiting 5 seconds before starting ramp." )
275- time .sleep (5 )
276- break
277- time .sleep (2 ) # Interval for checking stabilization status
330+ stabilize_temperature (lakeshore , start_temp )
278331
279332 # --- Start Ramp and Data Logging ---
280333 lakeshore .setup_ramp (HEATER_OUTPUT , rate )
281334 lakeshore .set_setpoint (HEATER_OUTPUT , end_temp )
282- # Ensure heater is on for the ramp
283335 lakeshore .set_heater_range (HEATER_OUTPUT , 'medium' )
284336 print (f"Ramp started towards { end_temp } K at { rate } K/min." )
285-
286- start_time = time .time ()
287-
288- with open (filename , 'w' , newline = '' ) as file :
289- writer = csv .writer (file )
290- writer .writerow (["Timestamp" ,
291- "Elapsed Time (s)" ,
292- "Temperature (K)" ,
293- "Heater Output (%)" ,
294- "Applied Voltage (V)" ,
295- "Measured Current (A)" ,
296- "Resistance (Ohm)" ])
297-
298- # --- Main experiment loop ---
299- while True :
300- elapsed_time = time .time () - start_time
301- current_temp = lakeshore .get_temperature (SENSOR_INPUT )
302- heater_output = lakeshore .get_heater_output (HEATER_OUTPUT )
303-
304- time .sleep (delay )
305- resistance = keithley .resistance
306- current = abs (
307- source_voltage /
308- resistance ) if resistance != 0 else float ('inf' )
309-
310- status_str = (
311- f"Time: { elapsed_time :7.2f} s | "
312- f"Temp: { current_temp :8.4f} K | "
313- f"Resistance: { resistance :9.3e} Ω"
314- )
315- print (status_str , end = '\r ' )
316-
317- with open (filename , 'a' , newline = '' ) as file :
318- writer = csv .writer (file )
319- writer .writerow ([
320- datetime .now ().strftime ('%Y-%m-%d %H:%M:%S' ),
321- f"{ elapsed_time :.2f} " , f"{ current_temp :.4f} " , f"{ heater_output :.2f} " ,
322- f"{ source_voltage :.4e} " , f"{ current :.4e} " , f"{ resistance :.4e} "
323- ])
324-
325- time_data .append (elapsed_time )
326- temp_data .append (current_temp )
327- res_data .append (resistance )
328-
329- line1 .set_data (time_data , temp_data )
330- ax1 .relim ()
331- ax1 .autoscale_view ()
332- line2 .set_data (temp_data , res_data )
333- ax2 .relim ()
334- ax2 .autoscale_view ()
335- fig .canvas .draw ()
336- fig .canvas .flush_events ()
337-
338- # --- Check for End Conditions ---
339- if current_temp >= safety_cutoff :
340- print (
341- f"\n \n !!! SAFETY CUTOFF REACHED at { current_temp :.4f} K (Limit: { safety_cutoff } K) !!!" )
342- break
343- if current_temp >= end_temp :
344- print (f"\n \n Target temperature of { end_temp } K reached." )
345- break
346-
347- # The main data logging interval. Should be independent of Keithley
348- # delay.
349- time .sleep (2 )
337+ run_measurement_loop (lakeshore , keithley , filename , end_temp , safety_cutoff , source_voltage , delay )
350338
351339 except ConnectionError as e :
352340 print (f"\n Could not start experiment due to a connection failure: { e } " )
0 commit comments