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

Memristor Debugging part 1

parent 13fa93de
No related branches found
No related tags found
No related merge requests found
...@@ -105,7 +105,10 @@ def regular_contact_check(device): ...@@ -105,7 +105,10 @@ def regular_contact_check(device):
""" """
R=contact_check(i,j,device) R=contact_check(i,j,device)
resistances[f"{i}-{j}"] = R resistances[f"{i}-{j}"] = R
return resistances
#convert dictionary to df
df = pd.DataFrame(resistances.items(), columns=['SMU pair', 'Resistance (Ohm)'])
return df
def EBL(device): def EBL(device):
# EBL are SMUs 1-4 and 2-3 # EBL are SMUs 1-4 and 2-3
...@@ -113,7 +116,10 @@ def EBL(device): ...@@ -113,7 +116,10 @@ def EBL(device):
for i,j in zip(range(1,3),range(4,2,-1)): #loop simultaneously 1-4,2-3 pairs for i,j in zip(range(1,3),range(4,2,-1)): #loop simultaneously 1-4,2-3 pairs
R = contact_check(i,j,device) R = contact_check(i,j,device)
resistances[f"{i}-{j}"] = R resistances[f"{i}-{j}"] = R
return resistances
#convert dictionary to df
df = pd.DataFrame(resistances.items(), columns=['SMU pair', 'Resistance (Ohm)'])
return df
def OL(device): def OL(device):
# OL smu 3-4,1-2 # OL smu 3-4,1-2
...@@ -121,9 +127,10 @@ def OL(device): ...@@ -121,9 +127,10 @@ def OL(device):
for i,j in zip(range(3,0,-2),range(4,1,-2)): #loop simultaneously 3-4 , 1-2 pairs for i,j in zip(range(3,0,-2),range(4,1,-2)): #loop simultaneously 3-4 , 1-2 pairs
R = contact_check(i,j,device) R = contact_check(i,j,device)
resistances[f"{i}-{j}"] = R resistances[f"{i}-{j}"] = R
return resistances
#convert dictionary to df
df = pd.DataFrame(resistances.items(), columns=['SMU pair', 'Resistance (Ohm)'])
return df
#double sweep from start to stop and then from start to stop #double sweep from start to stop and then from start to stop
def sweep(start,stop,step,comp,integration,device): #step cannot be negative def sweep(start,stop,step,comp,integration,device): #step cannot be negative
...@@ -352,9 +359,16 @@ def create_retention_data_frame(x,y): ...@@ -352,9 +359,16 @@ def create_retention_data_frame(x,y):
#write results to file #write results to file
def write_to_file(file,title,df): def write_to_file(file,title:list,df):
#append escape character after each element
index = 1
while index <= len(title):
title.insert(index,"\n")
index = index+2
#write to file
with open(file,'a') as f: with open(file,'a') as f:
f.write(title) f.writelines(title)
f.write("\n") f.write("\n")
f.write(df.to_string()) f.write(df.to_string())
f.write("\n\n") f.write("\n\n")
...@@ -489,21 +503,6 @@ def upload_results(source_file,target_file,target_file_dir): ...@@ -489,21 +503,6 @@ def upload_results(source_file,target_file,target_file_dir):
#and then try again #and then try again
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("Contact Check Results:\n")
df = pd.DataFrame(R.items(), columns=['SMU pair', 'Resistance (Ohm)'])
f.write(df.to_string())
f.write("\n\n")
......
...@@ -36,7 +36,7 @@ def check_pulse(dictionary): ...@@ -36,7 +36,7 @@ def check_pulse(dictionary):
#sweep pulse measurement #sweep pulse measurement
def sweep_meas(dict,device): def sweep_meas(dictionary,device):
smu_v = device.smu_dict() smu_v = device.smu_dict()
smu_ground = device.smu_dict() smu_ground = device.smu_dict()
parameters = device.var1_dict() parameters = device.var1_dict()
...@@ -55,14 +55,14 @@ def sweep_meas(dict,device): ...@@ -55,14 +55,14 @@ def sweep_meas(dict,device):
) )
parameters.update( parameters.update(
mode ='SING', mode ='SING',
start = dict['start'].value, start = dictionary['start'].value,
stop = dict['stop'].value, stop = dictionary['stop'].value,
step = dict["stop"].value-dict["start"].value)/(dict["pulses"].value-1, #define the number of steps given specific pulses step = (dictionary["stop"].value-dictionary["start"].value)/(dictionary["pulses"].value-1), #define the number of steps given specific pulses
comp = dict["comp"].value, comp = dictionary['comp'].value,
pcomp = 0, pcomp = 0,
base = dict["base"].value, base = dictionary["base"].value,
width = dict["width"].value, width = dictionary["width"].value,
period= dict["period"].value period= dictionary["period"].value
) )
device.smu_disable(1) device.smu_disable(1)
device.smu_disable(3) device.smu_disable(3)
...@@ -81,7 +81,7 @@ def sweep_meas(dict,device): ...@@ -81,7 +81,7 @@ def sweep_meas(dict,device):
device.setup_pulse(parameters) device.setup_pulse(parameters)
device.integration_time(dict["integration"].value) device.integration_time(dictionary["integration"].value)
t0 = time.time() t0 = time.time()
device.single_measurement() device.single_measurement()
...@@ -98,7 +98,7 @@ def sweep_meas(dict,device): ...@@ -98,7 +98,7 @@ def sweep_meas(dict,device):
R_i = np.divide(V_i,I_i) R_i = np.divide(V_i,I_i)
expected_time = dict["period"].value*dict["pulses"].value expected_time = dictionary["period"].value*dictionary["pulses"].value
times = (elapsed_time,expected_time) times = (elapsed_time,expected_time)
values = (V_i,I_i,R_i) values = (V_i,I_i,R_i)
...@@ -157,7 +157,7 @@ def save_sweep(folder,sample_dict,values,times,sweep_dict): ...@@ -157,7 +157,7 @@ def save_sweep(folder,sample_dict,values,times,sweep_dict):
f.write(df.to_string()) f.write(df.to_string())
f.write("\n\n\n") f.write("\n\n\n")
def constant_meas(dict,device): def constant_meas(dictionary,device):
smu_v = device.smu_dict() smu_v = device.smu_dict()
smu_ground = device.smu_dict() smu_ground = device.smu_dict()
sweep_params = device.var1_dict() sweep_params = device.var1_dict()
...@@ -185,17 +185,17 @@ def constant_meas(dict,device): ...@@ -185,17 +185,17 @@ def constant_meas(dict,device):
mode ='SING', mode ='SING',
start = 0, start = 0,
stop = 10, stop = 10,
step = 10/(dict["pulses"].value-1, #define the number of steps given specific pulses step = 10/(dictionary["pulses"].value-1), #define the number of steps given specific pulses
comp = 0.1, comp = 0.1,
pcomp = 0, pcomp = 0,
base = dict["base"].value, base = dictionary["base"].value,
width = dict["width"].value, width = dictionary["width"].value,
period= dict["period"].value period= dictionary["period"].value
) )
#the constant smu #the constant smu
cons = { cons = {
'value':dict["voltage"].value, 'value':dictionary["voltage"].value,
'comp':dict["comp"].value 'comp':dictionary["comp"].value
} }
device.measurement_mode("SWE") device.measurement_mode("SWE")
...@@ -217,7 +217,7 @@ def constant_meas(dict,device): ...@@ -217,7 +217,7 @@ def constant_meas(dict,device):
device.range_mode(3,"AUTO") device.range_mode(3,"AUTO")
device.integration_time(dict["integration"].value) device.integration_time(dictionary["integration"].value)
device.variables_to_save(['@INDEX','V2','I2','R']) device.variables_to_save(['@INDEX','V2','I2','R'])
...@@ -236,7 +236,7 @@ def constant_meas(dict,device): ...@@ -236,7 +236,7 @@ def constant_meas(dict,device):
R_i = device.return_values('R') R_i = device.return_values('R')
expected_time = dict["period"].value*dict["pulses"].value expected_time = dictionary["period"].value*dictionary["pulses"].value
times = (elapsed_time,expected_time) times = (elapsed_time,expected_time)
values = (V_i,I_i,R_i) values = (V_i,I_i,R_i)
......
...@@ -197,18 +197,22 @@ def on_contact_check_clicked(b): ...@@ -197,18 +197,22 @@ def on_contact_check_clicked(b):
with output: with output:
clear_output(wait = True) clear_output(wait = True)
change_state(all_widgets) change_state(all_widgets)
device.inst.lock_excl()
filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt" filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt"
file = os.path.join(folder,filename) file = os.path.join(folder,filename)
R = regular_contact_check(device) R = regular_contact_check(device)
save_contact_check(R,temp_file) date = str(datetime.today().replace(microsecond=0))
title = [f"Full Contact Check ({qcc_select.value}) at {date}"]
write_to_file(temp_file,title,R)
#upload results #upload results
temp_file,file,folder=upload_results(temp_file,file,folder) temp_file,file,folder=upload_results(temp_file,file,folder)
information_box("Contact Check Completed") information_box("Contact Check Completed")
device.inst.unlock()
change_state(all_widgets) change_state(all_widgets)
...@@ -217,29 +221,34 @@ def on_qcc_clicked(b): ...@@ -217,29 +221,34 @@ def on_qcc_clicked(b):
with output: with output:
clear_output(wait = True) clear_output(wait = True)
change_state(all_widgets) change_state(all_widgets)
device.inst.lock_excl()
filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt" filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt"
file = os.path.join(folder,filename) file = os.path.join(folder,filename)
device.inst.lock_excl()
if qcc_select.value == 'EBL': if qcc_select.value == 'EBL':
R = EBL(device) R = EBL(device)
else: # OL else: # OL
R = OL(device) R = OL(device) #df
save_contact_check(R,temp_file) date = str(datetime.today().replace(microsecond=0))
title = [f"Quick Contact Check ({qcc_select.value}) at {date}"]
write_to_file(temp_file,title,R)
#upload results #upload results
temp_file,file,folder=upload_results(temp_file,file,folder) temp_file,file,folder=upload_results(temp_file,file,folder)
information_box("Quick Contact Check Completed") information_box("Quick Contact Check Completed")
device.inst.unlock()
change_state(all_widgets) change_state(all_widgets)
def on_set_button_clicked(b): def on_set_button_clicked(b):
global first,folder,file,temp_file global folder,temp_file
with output: with output:
#disable buttons #disable buttons
change_state(all_widgets) change_state(all_widgets)
...@@ -247,8 +256,6 @@ def on_set_button_clicked(b): ...@@ -247,8 +256,6 @@ def on_set_button_clicked(b):
filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt" filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt"
file = os.path.join(folder,filename) file = os.path.join(folder,filename)
device = setup_memristor()
#lock the device #lock the device
device.inst.lock_excl() device.inst.lock_excl()
...@@ -268,7 +275,7 @@ def on_set_button_clicked(b): ...@@ -268,7 +275,7 @@ def on_set_button_clicked(b):
V12,I12 = sweep(0,Vset.value,step.value,CC_vset.value,integration_time.value,device) V12,I12 = sweep(0,Vset.value,step.value,CC_vset.value,integration_time.value,device)
plot_sweep(V12,I12,'SET') plot_sweep(V12,I12,'SET')
df = create_data_frame(V12,I12) df = create_data_frame(V12,I12)
print(df) display(df)
if sampling.value == True: #do sampling set after set process(10mV) if sampling.value == True: #do sampling set after set process(10mV)
...@@ -276,9 +283,10 @@ def on_set_button_clicked(b): ...@@ -276,9 +283,10 @@ def on_set_button_clicked(b):
print(f"Average Resistance(Sampling Check):{'{:.2e}'.format(R_mean_after)} Ohm") print(f"Average Resistance(Sampling Check):{'{:.2e}'.format(R_mean_after)} 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" date = str(datetime.today().replace(microsecond=0))
title = [f"SET Memristor at {date}",f"Set Voltage={Vset.value}V",f"current compliance={CC_vset.value}A"]
if sampling.value == True: if sampling.value == True:
title = title + f"R(Ohm) Before/After"+"\n"+f"{R_mean_before} {R_mean_after}"+"\n" title.extend([f"R(Ohm) Before/After",f"{R_mean_before} {R_mean_after}"])
write_to_file(temp_file,title,df) write_to_file(temp_file,title,df)
#upload results #upload results
...@@ -290,15 +298,12 @@ def on_set_button_clicked(b): ...@@ -290,15 +298,12 @@ def on_set_button_clicked(b):
#unlock device #unlock device
device.inst.unlock() device.inst.unlock()
del device
change_state(all_widgets) change_state(all_widgets)
def on_reset_button_clicked(b): def on_reset_button_clicked(b):
global folder,temp_file global folder,temp_file
with output: with output:
change_state(all_widgets) change_state(all_widgets)
device = setup_memristor()
filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt" filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt"
file = os.path.join(folder,filename) file = os.path.join(folder,filename)
...@@ -322,25 +327,28 @@ def on_reset_button_clicked(b): ...@@ -322,25 +327,28 @@ def on_reset_button_clicked(b):
V34,I34 = sweep(0,Vreset.value,step.value,CC_vreset.value,integration_time.value,device) V34,I34 = sweep(0,Vreset.value,step.value,CC_vreset.value,integration_time.value,device)
plot_sweep(V34,I34,'RESET') plot_sweep(V34,I34,'RESET')
df = create_data_frame(V34,I34) df = create_data_frame(V34,I34)
print(df) display(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.01,device) R_mean_after = sampling_check(-0.01,device)
print(f"Average Resistance(Sampling Check):{'{:.2e}'.format(R_mean_after)} Ohm") print(f"Average Resistance(Sampling Check):{'{:.2e}'.format(R_mean_after)} 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" date = str(datetime.today().replace(microsecond=0))
title =[f"RESET Memristor at {date}",f"Reset Voltage={Vreset.value}V",f"current compliance={CC_vreset.value}A"]
if sampling.value == True: if sampling.value == True:
title = title + f"R(Ohm) Before/After"+"\n"+f"{R_mean_before} {R_mean_after}"+"\n" title.extend([f"R(Ohm) Before/After",f"{R_mean_before} {R_mean_after}"])
write_to_file(temp_file,title,df) write_to_file(temp_file,title,df)
#Quick Contact Check after reset Process #Quick Contact Check after reset Process
if auto_qcc.value == True: if auto_qcc.value == True:
if qcc_select.value == 'EBL': if qcc_select.value == 'EBL':
R=EBL() R=EBL(device)
else: # OL else: # OL
R=OL() R=OL(device)
save_contact_check(R,temp_file)
title = [f"Automatic Quick Contact Check({qcc_select.value}) after Reset"]
write_to_file(temp_file,title,R)
#upload results #upload results
temp_file,file,folder=upload_results(temp_file,file,folder) temp_file,file,folder=upload_results(temp_file,file,folder)
...@@ -351,8 +359,6 @@ def on_reset_button_clicked(b): ...@@ -351,8 +359,6 @@ def on_reset_button_clicked(b):
#unlock device #unlock device
device.inst.unlock() device.inst.unlock()
del device
change_state(all_widgets) change_state(all_widgets)
def on_full_button_clicked(b): def on_full_button_clicked(b):
...@@ -363,8 +369,6 @@ def on_full_button_clicked(b): ...@@ -363,8 +369,6 @@ def on_full_button_clicked(b):
filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt" filename=f"{sample_series.value}_{field.value}_{DUT.value}.txt"
file = os.path.join(folder,filename) file = os.path.join(folder,filename)
device= setup_memristor()
# lock device # lock device
device.inst.lock_excl() device.inst.lock_excl()
...@@ -372,31 +376,11 @@ def on_full_button_clicked(b): ...@@ -372,31 +376,11 @@ def on_full_button_clicked(b):
#check values #check values
valid = check_values(step.value,Vset.value,Vreset.value) valid = check_values(step.value,Vset.value,Vreset.value)
date = str(datetime.today().replace(microsecond=0))
#during first button press
if first == True and valid == True:
#disable checkboxes, text fields etc.
change_state(information)
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 #set first to false irrelvant if it is in the if statement or not
if valid == True: if valid == True:
with open(temp_file,'a') as f: with open(temp_file,'a') as f:
f.write(f"{number.value} full sweeps with parameters:") header =[f"{number.value} full sweeps with parameters:",f"Set Voltage = {Vset.value}V",f"Current compliance set = {CC_vset.value}A",f"Reset Voltage = {Vreset.value}V",f"Current compliance reset = {CC_vreset.value}A"]
f.write("\n")
f.write(f"Set Voltage = {Vset.value}V")
f.write("\n")
f.write(f"Current compliance set = {CC_vset.value}A")
f.write("\n")
f.write(f"Reset Voltage = {Vreset.value}V")
f.write("\n")
f.write(f"Current compliance reset = {CC_vreset.value}A")
f.write("\n\n")
plt.figure().clear() plt.figure().clear()
fig, (ax1, ax2) = plt.subplots(2,sharex=True,figsize=(8,6)) #the plots share the same x axis fig, (ax1, ax2) = plt.subplots(2,sharex=True,figsize=(8,6)) #the plots share the same x axis
...@@ -434,9 +418,9 @@ def on_full_button_clicked(b): ...@@ -434,9 +418,9 @@ def on_full_button_clicked(b):
#Quick Contact Check after reset Process #Quick Contact Check after reset Process
if auto_qcc.value == True: if auto_qcc.value == True:
if qcc_select.value == 'EBL': if qcc_select.value == 'EBL':
R = EBL() R = EBL(device)
else: # OL else: # OL
R = OL() R = OL(device)
#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
...@@ -452,15 +436,19 @@ def on_full_button_clicked(b): ...@@ -452,15 +436,19 @@ def on_full_button_clicked(b):
#create data frame and save to file #create data frame and save to file
df = create_data_frame(V,I) df = create_data_frame(V,I)
f.write(f"{i+1} Iteration") if i == 0 :
f.write("\n") header.extend([f"{i+1} Iteration"])
title = header.copy()
else:
title = [f"{i+1} Iteration"]
if sampling.value == True: if sampling.value == True:
f.write(f"R(Ohm) INIT/SET/RESET"+"\n"+f"{R_mean_init} {R_mean_set} {R_mean_reset}"+"\n") title.extend([f"R(Ohm) INIT/SET/RESET",f"{R_mean_init} {R_mean_set} {R_mean_reset}"])
f.write(df.to_string())
f.write("\n\n") write_to_file(temp_file,title,df)
if auto_qcc.value == True: if auto_qcc.value == True:
save_contact_check(R,temp_file) title= [f"Quick Contact Check({qcc_select.value}) after Reset"]
write_to_file(temp_file,title,R)
#plot results #plot results
...@@ -472,7 +460,7 @@ def on_full_button_clicked(b): ...@@ -472,7 +460,7 @@ def on_full_button_clicked(b):
clear_output() clear_output()
display(fig) display(fig)
#plt.show() #plt.show()
print(df) display(df)
#check for loop termination #check for loop termination
if stop == True: if stop == True:
...@@ -508,14 +496,13 @@ def on_full_button_clicked(b): ...@@ -508,14 +496,13 @@ def on_full_button_clicked(b):
#unlock the device #unlock the device
device.inst.unlock() device.inst.unlock()
del device
change_state(all_widgets) change_state(all_widgets)
#new_folder clicked #new_folder clicked
def on_new_folder_button_clicked(b): def on_new_folder_button_clicked(b):
global folder,file,first global folder
with output: with output:
change_state(all_widgets) change_state(all_widgets)
...@@ -524,12 +511,11 @@ def on_new_folder_button_clicked(b): ...@@ -524,12 +511,11 @@ def on_new_folder_button_clicked(b):
change_state(all_widgets) change_state(all_widgets)
def on_retention_button_clicked(b): def on_retention_button_clicked(b):
global first,folder,file,temp_file global folder,temp_file
with output: with output:
change_state(all_widgets) change_state(all_widgets)
device = setup_memristor()
device.inst.lock_excl() device.inst.lock_excl()
...@@ -542,7 +528,8 @@ def on_retention_button_clicked(b): ...@@ -542,7 +528,8 @@ def on_retention_button_clicked(b):
t,R=retention(Vretention.value,period.value,duration.value,device) t,R=retention(Vretention.value,period.value,duration.value,device)
plot_retention(t,R) plot_retention(t,R)
df=create_retention_data_frame(t,R) df=create_retention_data_frame(t,R)
title =f"Retention Memristor:"+"\n\n"+f"Voltage={Vretention.value}V"+"\n"+f"period={period.value}s"+"\n"+f"duration={duration.value}s"+"\n" date = str(datetime.today().replace(microsecond=0))
title =[f"Retention Memristor at {date}",f"Voltage={Vretention.value}V",f"period={period.value}s",f"duration={duration.value}s"]
write_to_file(temp_file,title,df) write_to_file(temp_file,title,df)
#upload results #upload results
...@@ -552,8 +539,6 @@ def on_retention_button_clicked(b): ...@@ -552,8 +539,6 @@ def on_retention_button_clicked(b):
device.inst.unlock() device.inst.unlock()
del device
change_state(all_widgets) change_state(all_widgets)
......
%% Cell type:code id:df99f5a2-80af-4892-8633-33177239e444 tags: %% Cell type:code id:7611a98c-c1cf-46cb-bdd9-fd3dc6a1f53c tags:
``` python ``` python
%run memristor.py %run memristor.py
``` ```
%% Output %% Output
%% Cell type:code id:38e8523c-17f0-48b4-9501-dd2278ffe8d1 tags: %% Cell type:code id:38e8523c-17f0-48b4-9501-dd2278ffe8d1 tags:
``` python ``` python
print(device.error()) print(device.error())
``` ```
%% Output %% Output
(0, '"No error"\n') (0, '"No error"\n')
%% Cell type:code id:ca8f0bc8-670c-4deb-bedb-8d5d92b978f2 tags: %% Cell type:code id:ca8f0bc8-670c-4deb-bedb-8d5d92b978f2 tags:
``` python ``` python
``` ```
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment