Skip to content
Snippets Groups Projects
Commit 92d185d1 authored by Alexandros Asonitis's avatar Alexandros Asonitis
Browse files

changes memrsistor 1-6

parent 366e0ceb
No related branches found
No related tags found
No related merge requests found
...@@ -30,9 +30,11 @@ import os ...@@ -30,9 +30,11 @@ import os
#these are the quick sampling checks #these are the quick sampling checks
def test_contacts(): def regular_contact_check():
device = module.HP4155a('GPIB0::17::INSTR') device = module.HP4155a('GPIB0::17::INSTR')
resistances = {}
smu = [1,2,3,4] smu = [1,2,3,4]
for i in range(1,4): # iterate through smus 1-4 for i in range(1,4): # iterate through smus 1-4
for j in range(4,i,-1): for j in range(4,i,-1):
...@@ -82,10 +84,126 @@ def test_contacts(): ...@@ -82,10 +84,126 @@ def test_contacts():
V = device.return_data(f'V{i}') V = device.return_data(f'V{i}')
I = device.return_data(f'I{i}') I = device.return_data(f'I{i}')
R = V[0]/I[0] R = V[0]/I[0]
print(f"R{i}{j}:{R} Ohm") print(f"R{i}{j}:{'{:.2e}'.format(R)} Ohm")
resitances[f"{i}-{j}"] = R
#print(f"Contact check of smu{i} and smu{j} failed!") #print(f"Contact check of smu{i} and smu{j} failed!")
del device del device
return resistances
def EBL():
# EBL are SMUs 1-4 and 2-3
device = module.HP4155a('GPIB0::17::INSTR')
resistances = {}
for i,j in zip(range(1,3),range(4,2,-1)): #loop simultaneously 1-4,2-3 pairs
device.reset()
device.measurement_mode('SAMP')
device.sampling_mode('LIN')
device.number_of_points(1)
device.integration_time('MED')
device.initial_interval(2e-3)
device.filter_status('OFF')
#remove total sampling time
device.auto_sampling_time('ON')
#disable vmus and vsus
device.disable_vsu(1)
device.disable_vsu(2)
device.disable_vmu(1)
device.disable_vmu(2)
device.smu_mode_meas(i,'V') #one smu is measuring
device.smu_mode_meas(j,'COMM') #one smu is ground
#set voltage and compliance
device.constant_smu_sampling(i,0.01)
device.constant_smu_comp(i,'MAX')
#smus to remove
smu_disable = smu.copy()
smu_disable.remove(i)
smu_disable.remove(j)
for number in smu_disable:
device.smu_disable_sweep(number)
device.display_variable('X','@TIME')
device.display_variable('Y1',f'I{i}')
device.single_measurement()
while device.operation_completed() == False:
time.sleep(2)
device.autoscaling()
V = device.return_data(f'V{i}')
I = device.return_data(f'I{i}')
R = V[0]/I[0]
print(f"R{i}{j}:{'{:.2e}'.format(R)} Ohm")
resitances[f"{i}-{j}"] = R
del device
return resistances
def OL():
# OL smu 3-4,1-2
device = module.HP4155a('GPIB0::17::INSTR')
resistances= {}
for i,j in zip(range(3,0,-2),range(4,1,-2)): #loop simultaneously 3-4 , 1-2 pairs
device.reset()
device.measurement_mode('SAMP')
device.sampling_mode('LIN')
device.number_of_points(1)
device.integration_time('MED')
device.initial_interval(2e-3)
device.filter_status('OFF')
#remove total sampling time
device.auto_sampling_time('ON')
#disable vmus and vsus
device.disable_vsu(1)
device.disable_vsu(2)
device.disable_vmu(1)
device.disable_vmu(2)
device.smu_mode_meas(i,'V') #one smu is measuring
device.smu_mode_meas(j,'COMM') #one smu is ground
#set voltage and compliance
device.constant_smu_sampling(i,0.01)
device.constant_smu_comp(i,'MAX')
#smus to remove
smu_disable = smu.copy()
smu_disable.remove(i)
smu_disable.remove(j)
for number in smu_disable:
device.smu_disable_sweep(number)
device.display_variable('X','@TIME')
device.display_variable('Y1',f'I{i}')
device.single_measurement()
while device.operation_completed() == False:
time.sleep(2)
device.autoscaling()
V = device.return_data(f'V{i}')
I = device.return_data(f'I{i}')
R = V[0]/I[0]
print(f"R{i}{j}:{'{:.2e}'.format(R)} Ohm")
resitances[f"{i}-{j}"] = R
del device
return resistances
...@@ -146,6 +264,7 @@ def sweep(start,stop,step,comp,integration,device): ...@@ -146,6 +264,7 @@ def sweep(start,stop,step,comp,integration,device):
#sampling check #sampling check
def sampling_check(voltage,device): def sampling_check(voltage,device):
# red color code red = '\033[91m'
device.measurement_mode('SAMP') device.measurement_mode('SAMP')
...@@ -158,7 +277,7 @@ def sampling_check(voltage,device): ...@@ -158,7 +277,7 @@ def sampling_check(voltage,device):
device.sampling_mode('LIN') device.sampling_mode('LIN')
device.number_of_points(5) device.number_of_points(5)
device.integration_time('MED') device.integration_time('LONG')
device.initial_interval(2e-3) device.initial_interval(2e-3)
device.filter_status('OFF') device.filter_status('OFF')
...@@ -372,26 +491,6 @@ def choose_folder(): ...@@ -372,26 +491,6 @@ def choose_folder():
#create or append to file a new measurement(now locally) we dont need that anymore!!!
def create_remote_file(sample_series,field,DUT,folder):
filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt"
file=os.path.join(folder,filename)#the whole file with location
date = str(datetime.today().replace(microsecond=0))
#check loop (once the return is called the function is over)
while True:
try:#you cannot write in every directory
with open(file,'a') as f:
title = f"Memristor Measurement"+"\n\n"+f"Sample series:{sample_series.value}" +"\n"+f"field:{field.value}"+"\n"+f"DUT:{DUT.value}"+"\n"+f"Date:{date}"+"\n\n"
f.write(title)
return file
except:
information_box(f"You cannot write in the directory: {folder}!")
#again
folder=choose_folder()
file=os.path.join(folder,filename)#the whole file with location
#write the header #write the header
def write_header(file,sample_series,field,DUT): def write_header(file,sample_series,field,DUT):
date = str(datetime.today().replace(microsecond=0)) date = str(datetime.today().replace(microsecond=0))
...@@ -441,3 +540,24 @@ def setup_memristor(): ...@@ -441,3 +540,24 @@ def setup_memristor():
device.user_function('R','OHM','V2/I2') device.user_function('R','OHM','V2/I2')
return device return device
def save_contact_check(R,file): #save contact check to file
"""
Parameters:
-Resistances list
-File to save
"""
with open(file,'a') as f:
f.write("\n\nContact Check Results:\n")
df = pd.DataFrame(R.items(), columns=['SMU pair', 'Resistance (Ohm)'])
f.write(df.to_string())
f.write("\n\n")
\ No newline at end of file
...@@ -87,6 +87,8 @@ full=widgets.Button(description='FULL SWEEP') ...@@ -87,6 +87,8 @@ full=widgets.Button(description='FULL SWEEP')
number = widgets.BoundedIntText(value=1,min=1,max=sys.maxsize,step=1,description='full sweeps:',disabled=False) #number of measuremts for the full sweep number = widgets.BoundedIntText(value=1,min=1,max=sys.maxsize,step=1,description='full sweeps:',disabled=False) #number of measuremts for the full sweep
retention_button=widgets.Button(description='RETENTION') retention_button=widgets.Button(description='RETENTION')
contact_check = widgets.Button(description = 'CONTACT CHECK') contact_check = widgets.Button(description = 'CONTACT CHECK')
qcc = widgets.Button(description = 'QUICK CONTACT CHECK')
qcc_select = widgets.RadioButtons(description = 'QCC type:',options = ['EBL','OL'])
#parameter boxes #parameter boxes
...@@ -149,6 +151,12 @@ duration=widgets.BoundedFloatText( ...@@ -149,6 +151,12 @@ duration=widgets.BoundedFloatText(
description='Duration(s):', description='Duration(s):',
) )
auto_qcc = widgets.Checkbox(
description = 'Auto QCC after Reset:',
style = {'description_width': 'initial'},
value = True
)
#align a button with a checkbox or integer bounded texts horizontaly #align a button with a checkbox or integer bounded texts horizontaly
line1 = widgets.HBox([set,Vset,CC_vset]) line1 = widgets.HBox([set,Vset,CC_vset])
line2 = widgets.HBox([reset,Vreset,CC_vreset]) line2 = widgets.HBox([reset,Vreset,CC_vreset])
...@@ -162,8 +170,8 @@ output = widgets.Output() ...@@ -162,8 +170,8 @@ output = widgets.Output()
#help lists for changing state of the buttons #help lists for changing state of the buttons
information = [sample_series,field,DUT] information = [sample_series,field,DUT]
buttons = [set,reset,full,new,new_folder,retention_button,contact_check] buttons = [set,reset,full,new,new_folder,retention_button,contact_check,qcc,qcc_select]
parameters = [Vset,CC_vset,Vreset,CC_vreset,step,integration_time,number,sampling,Vretention,period,duration] parameters = [Vset,CC_vset,Vreset,CC_vreset,step,integration_time,number,sampling,Vretention,period,duration,auto_qcc]
#choose folder directory #choose folder directory
folder=choose_folder() folder=choose_folder()
...@@ -171,10 +179,9 @@ folder=choose_folder() ...@@ -171,10 +179,9 @@ folder=choose_folder()
#display all at the end #display all at the end
display(all_text_boxes) display(all_text_boxes)
print()
display(contact_check) hbox = widgets.HBox([contact_check,qcc,qcc_select]) #HBox wirth contact checks
print() display(hbox)
cons_widgets,cons_dict = constant_pulse() cons_widgets,cons_dict = constant_pulse()
sweep_widgets,sweep_dict = sweep_pulse() sweep_widgets,sweep_dict = sweep_pulse()
...@@ -199,13 +206,30 @@ add_widgets_to_list(sweep_dict,all_widgets) ...@@ -199,13 +206,30 @@ add_widgets_to_list(sweep_dict,all_widgets)
""" the above is what happens when the programm starts all the rest have to be written into button trigger functions""" """ the above is what happens when the programm starts all the rest have to be written into button trigger functions"""
def on_contact_check_clicked(b): def on_contact_check_clicked(b):
global first,folder,file,temp_file
with output: with output:
global first,folder,file,temp_file
clear_output(wait = True) clear_output(wait = True)
change_state(all_widgets) change_state(all_widgets)
change_state(buttons) change_state(buttons)
change_state(parameters) change_state(parameters)
test_contacts() #during first button press
if first == True:
change_state(information)#disable all widgets that are relevant about the information of the sample
filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt"
file = os.path.join(folder,filename)
#write header to temp_file
write_header(temp_file,sample_series,field,DUT)
first = False
R = regular_contact_check()
save_contact_check(R,temp_file)
#upload results
temp_file,file,folder=upload_results(temp_file,file,folder)
information_box("Contact Check Completed") information_box("Contact Check Completed")
...@@ -213,6 +237,43 @@ def on_contact_check_clicked(b): ...@@ -213,6 +237,43 @@ def on_contact_check_clicked(b):
change_state(buttons) change_state(buttons)
change_state(parameters) change_state(parameters)
def on_qcc_clicked(b):
global first,folder,file,temp_file
with output:
global first,folder,file,temp_file
clear_output(wait = True)
change_state(all_widgets)
change_state(buttons)
change_state(parameters)
#during first button press
if first == True:
change_state(information)#disable all widgets that are relevant about the information of the sample
filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt"
file = os.path.join(folder,filename)
#write header to temp_file
write_header(temp_file,sample_series,field,DUT)
first = False
if qcc_select.value == 'EBL':
R = EBL()
else: # OL
R = OL()
save_contact_check(R,temp_file)
#upload results
temp_file,file,folder=upload_results(temp_file,file,folder)
information_box("Quick Contact Check Completed")
change_state(all_widgets)
change_state(buttons)
change_state(parameters)
def on_set_button_clicked(b): def on_set_button_clicked(b):
global first,folder,file,temp_file global first,folder,file,temp_file
with output: with output:
...@@ -242,9 +303,8 @@ def on_set_button_clicked(b): ...@@ -242,9 +303,8 @@ def on_set_button_clicked(b):
if valid == True: if valid == True:
if sampling.value == True: #do sampling set before set process(100mV) if sampling.value == True: #do sampling set before set process(100mV)
R_mean_before = sampling_check(0.1,device) R_mean_before = sampling_check(-0.01,device)
R_mean_before = round(R_mean_before,1)#round 1 decimal point print(f"Average Resistance(Sampling Check):{'{:.2e}'.format(R_mean_before)} Ohm")
print(f"Average Resistance(Sampling Check):{R_mean_before:e} Ohm")
first_sampling = False first_sampling = False
#execute measurement,plot results and save them #execute measurement,plot results and save them
...@@ -256,8 +316,7 @@ def on_set_button_clicked(b): ...@@ -256,8 +316,7 @@ def on_set_button_clicked(b):
if sampling.value == True: #do sampling set after set process(10mV) if sampling.value == True: #do sampling set after set process(10mV)
R_mean_after = sampling_check(0.01,device) R_mean_after = sampling_check(0.01,device)
R_mean_after = round(R_mean_after,1) print(f"Average Resistance(Sampling Check):{'{:.2e}'.format(R_mean_after)} Ohm")
print(f"Average Resistance(Sampling Check):{R_mean_after:e} Ohm")
first_sampling = False first_sampling = False
title = f"SET Memristor:"+"\n\n"+f"Set Voltage={Vset.value}V"+"\n"+f"current compliance={CC_vset.value}A"+"\n" title = f"SET Memristor:"+"\n\n"+f"Set Voltage={Vset.value}V"+"\n"+f"current compliance={CC_vset.value}A"+"\n"
...@@ -310,8 +369,7 @@ def on_reset_button_clicked(b): ...@@ -310,8 +369,7 @@ def on_reset_button_clicked(b):
if valid == True: if valid == True:
if sampling.value == True: #do sampling set before reset process(10mV) if sampling.value == True: #do sampling set before reset process(10mV)
R_mean_before = sampling_check(0.01,device) R_mean_before = sampling_check(0.01,device)
R_mean_before = round(R_mean_before,1)#round 1 decimal point print(f"Average Resistance(Sampling Check):{'{:.2e}'.format(R_mean_before)} Ohm")
print(f"Average Resistance(Sampling Check):{R_mean_before:e} Ohm")
first_sampling = False first_sampling = False
#execute measurement,plot results and save them #execute measurement,plot results and save them
...@@ -321,9 +379,8 @@ def on_reset_button_clicked(b): ...@@ -321,9 +379,8 @@ def on_reset_button_clicked(b):
print(df) print(df)
if sampling.value == True: #do sampling set after reset process(100mV) if sampling.value == True: #do sampling set after reset process(100mV)
R_mean_after = sampling_check(0.1,device) R_mean_after = sampling_check(-0.01,device)
R_mean_after = round(R_mean_after,1) print(f"Average Resistance(Sampling Check):{'{:.2e}'.format(R_mean_after)} Ohm")
print(f"Average Resistance(Sampling Check):{R_mean_after:e} Ohm")
first_sampling = False first_sampling = False
title =f"RESET Memristor:"+"\n\n"+f"Reset Voltage={Vreset.value}V"+"\n"+f"current compliance={CC_vreset.value}A"+"\n" title =f"RESET Memristor:"+"\n\n"+f"Reset Voltage={Vreset.value}V"+"\n"+f"current compliance={CC_vreset.value}A"+"\n"
...@@ -331,6 +388,14 @@ def on_reset_button_clicked(b): ...@@ -331,6 +388,14 @@ def on_reset_button_clicked(b):
title = title + f"R(Ohm) Before/After"+"\n"+f"{R_mean_before} {R_mean_after}"+"\n" title = title + f"R(Ohm) Before/After"+"\n"+f"{R_mean_before} {R_mean_after}"+"\n"
write_to_file(temp_file,title,df) write_to_file(temp_file,title,df)
#Quick Contact Check after reset Process
if auto_qcc.value == True:
if qcc_select.value == 'EBL':
R=EBL()
else: # OL
R=OL()
save_contact_check(R,temp_file)
#upload results #upload results
temp_file,file,folder=upload_results(temp_file,file,folder) temp_file,file,folder=upload_results(temp_file,file,folder)
...@@ -409,26 +474,30 @@ def on_full_button_clicked(b): ...@@ -409,26 +474,30 @@ def on_full_button_clicked(b):
#execute number of measurements #execute number of measurements
for i in range(number.value):#here it is easier to implement the sampling checks for i in range(number.value):#here it is easier to implement the sampling checks
if sampling.value == True: #before set(100mv) if sampling.value == True: #before set(100mv)
R_mean_init = sampling_check(0.1,device) R_mean_init = sampling_check(-0.01,device)
R_mean_init = round(R_mean_init,1)
resistances.append(R_mean_init) resistances.append(R_mean_init)
V12,I12 = sweep(0,Vset.value,step.value,CC_vset.value,integration_time.value,device) #set V12,I12 = sweep(0,Vset.value,step.value,CC_vset.value,integration_time.value,device) #set
#after set/before set #after set/before reset
if sampling.value == True: #before set(10mv) if sampling.value == True: #before set(10mv)
R_mean_set = sampling_check(0.01,device) R_mean_set = sampling_check(0.01,device)
R_mean_set = round(R_mean_set,1)
resistances.append(R_mean_set) resistances.append(R_mean_set)
V34,I34 = sweep(0,Vreset.value,step.value,CC_vreset.value,integration_time.value,device) #reset V34,I34 = sweep(0,Vreset.value,step.value,CC_vreset.value,integration_time.value,device) #reset
#Quick Contact Check after reset Process
if auto_qcc.value == True:
if qcc_select.value == 'EBL':
R = EBL()
else: # OL
R = OL()
#no reason to do check at the end because the next loop will do that(not anymore) more sampling checks #no reason to do check at the end because the next loop will do that(not anymore) more sampling checks
#after reset #after reset
if sampling.value == True:#-0.1V if sampling.value == True:#-0.1V
R_mean_reset = sampling_check(-0.1,device) R_mean_reset = sampling_check(-0.01,device)
R_mean_reset = round(R_mean_reset,1)
resistances.append(R_mean_reset) resistances.append(R_mean_reset)
...@@ -445,6 +514,9 @@ def on_full_button_clicked(b): ...@@ -445,6 +514,9 @@ def on_full_button_clicked(b):
f.write(df.to_string()) f.write(df.to_string())
f.write("\n\n") f.write("\n\n")
if auto_qcc.value == True:
save_contact_check(R,temp_file)
#plot results #plot results
ax1.plot(V,I) ax1.plot(V,I)
...@@ -641,3 +713,4 @@ new.on_click(on_new_sample_button_clicked) ...@@ -641,3 +713,4 @@ new.on_click(on_new_sample_button_clicked)
new_folder.on_click(on_new_folder_button_clicked) new_folder.on_click(on_new_folder_button_clicked)
retention_button.on_click(on_retention_button_clicked) retention_button.on_click(on_retention_button_clicked)
contact_check.on_click(on_contact_check_clicked) contact_check.on_click(on_contact_check_clicked)
qcc.on_click(on_qcc_clicked)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment