This commit is contained in:
2026-06-04 13:48:26 +02:00
parent 7098e822fa
commit 7d4bee568b
4 changed files with 123 additions and 83 deletions
+2 -2
View File
@@ -15,10 +15,10 @@ def V_source_state(on_off = 'off'):
# Set voltage of SIM928
def set_voltage(V_value=1e-3):
if abs(V_value) < 1e-3:
print ('Voltage too low (<|3 mV|), it is set to 0 mV')
print ('\nVoltage too low (<|3 mV|), it is set to 0 mV')
V_value = 0
elif abs(V_value) > 39:
print ('Voltage setting too high (>39V), it is set to 39V')
print ('\nVoltage setting too high (>39V), it is set to 39V')
V_value = 40e-3
V_value = round(V_value,3) # rounding to mV, otherwise the source does not set the voltage because it lacks the precision
command = 'VOLT ' + str(V_value) # set voltage
+10 -10
View File
@@ -1,16 +1,16 @@
# Experiment parameters
[experiment]
V_start = -1.0
step_size = 0.5
V_end = 1.0
time_average = 3 # time over which to collect voltage average (time per measurement)
sample_name = "test"
contact_1 = "test1"
contact_2 = "test1"
light = "MIR"
V_start = -0.1
step_size = 0.01
V_end = 0.1
time_average = 2 # time over which to collect voltage average (time per measurement)
sample_name = "barrucada?"
contact_pos = "B"
contact_neg = "C"
light = "dark"
temp = 300
amplifier = "SR570"
gain = 1e7 # amplifier gain
gain = 1e4 # amplifier gain
# Instrument addresses: typically do NOT need to be changed
@@ -21,7 +21,7 @@ SIM928_port = 1
# V_start, step size, V_end, time average, sample name, contact 1, contact 2, light, temperature, amplifier, amplifier gain
# V_scan(-1.0, 0.05, 1.0, .1, "test", "test1", "test1", "MIR", 300, "SR570", 10**(7)) #amplifier sensitivity = 1/gain
#V_scan(-1.0, 0.1, 1.0, 1.0, "SHADWELL", "posContactC", "negContactF", "MIR", 18, "SR570", 10**(8)) #amplifier sensitivity = 1/gain
# V_scan(-1.0, 0.1, 1.0, 1.0, "SHADWELL", "posContactC", "negContactF", "MIR", 18, "SR570", 10**(8)) #amplifier sensitivity = 1/gain
#V_scan(0.0, 0.1, 1.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
#V_scan(0.0, 0.2, -2.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
#V_scan(0.0, 0.2, 2.0, 1.0, "Sun", "posContactB", "negContactH", "MIR", 18, "SR570", 10**(9)) #amplifier sensitivity = 1/gain
+108 -70
View File
@@ -90,7 +90,7 @@ def measure_V(time_average=10, time_interval=0.2):
# Function to do I-V measurements
# Currently doesn't read the voltage that was set, due to issues with querying through mainframe
# Errors caluclated incorrectly
def V_scan(V_start=1e-3, step_size=1e-3, V_end=2e-3, time_average=10, sample_name='no_name', contact_1 = '', contact_2 = '', light = 'Dark', temp=777, amplifier='SR570', gain=10**3, number_of_loops=0):
def V_scan(V_start=1e-3, step_size=1e-3, V_end=2e-3, time_average=10, sample_name='no_name', contact_pos = '', contact_neg = '', light = 'Dark', temp=777, amplifier='SR570', gain=10**3, number_of_loops=0):
Keithley.clear() # clear the buffer
gain = int(gain) # make sure the gain is an Int
@@ -106,85 +106,123 @@ def V_scan(V_start=1e-3, step_size=1e-3, V_end=2e-3, time_average=10, sample_nam
SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.V_source_state("off")) #set source off
# open a file to write data to
# file_path = Path(__file__).parent / "data"
# time_start = datetime.datetime.now().strftime("%d%m%Y_%H%M%S")
# filename_root = "iv_%s_%s_%s_%s_%s_scan_at_%sK_%s" % \
# (time_start, sample_name, contact_1, contact_2, light, temp, amplifier)
# filename = filename_root + "_averaging%ss.txt" % (time_average)
# plotname = filename_root + "_averaging%ss.png" % (time_average)
# filename2 = filename_root + "_raw.txt"
# full_name = os.path.join(file_path, filename)
# full_plotname = os.path.join(file_path, plotname)
file_path = Path(__file__).parent / "data"
filename_root = "iv_%s_%s_pos%s_neg%s_%s_scan_at_%sK_%s" % \
(data_id, sample_name, contact_pos, contact_neg, light, temp, amplifier)
filename = filename_root + "_averaging%ss.txt" % (time_average)
plotname = filename_root + "_averaging%ss.png" % (time_average)
filename2 = filename_root + "_raw.txt"
full_name = os.path.join(file_path, filename)
full_plotname = os.path.join(file_path, plotname)
# full_name2 = os.path.join(file_path, filename2)
#data_file=open(str(full_name),'w')
# with open(str(full_name),'w') as data_file, open(str(full_name2),'w') as raw_V_file:
# data_file.write("Time\tVoltage_source[V]\tVoltage_meas[V]\tVoltage_meas_err[V]\tGain[V/A]\n")
data_file=open(str(full_name),'w')
# save metadata before loop
file_path = Path(__file__).parent / "data"
file_path.mkdir(exist_ok=True)
h5_path = file_path / f"{filename[0:-4]}.h5"
with h5py.File(h5_path, "w") as f:
f.attrs["V_start"] = V_start
f.attrs["step_size"] = step_size
f.attrs["V_end"] = V_end
f.attrs["time_average"] = time_average
f.attrs["sample_name"] = sample_name
f.attrs["contact_pos"] = contact_pos
f.attrs["contact_neg"] = contact_neg
f.attrs["light"] = light
f.attrs["temp"] = temp
f.attrs["amplifier"] = amplifier
f.attrs["gain"] = gain
with open(str(full_name),'w') as data_file: #, open(str(full_name2),'w') as raw_V_file:
data_file.write("Time\tVoltage_source[V]\tVoltage_avg[V]\tVoltage_meas_err[V]\tGain[V/A]\tVoltage_meas\n")
# raw_V_file.write("Voltage_source[V]\tVoltage_meas[V]\n")
# just for ploting here
V_plot_list = []
V_err_plot_list = []
V_scan_plot_list = []
# A loop over all currents
i=0
# set_voltage(V_scan_list[0])
# time.sleep(5) #wait 3 sec to avoid large noise on first measurement
for V_scan_item in V_scan_list:
V_avg_list = []
V_err_list = []
V_source_list = []
V_raw_lists = []
time_list = []
time_start_iteration= datetime.datetime.now()
i = i+1
set_voltage(V_scan_item)
time.sleep(2) #wait 5 sec for signal to settle
i=0
for V_scan_item in V_scan_list:
Keithley.clear()
time_start_iteration= datetime.datetime.now()
set_voltage(V_scan_item)
time.sleep(2) #wait 5 sec for signal to settle
# measure+read+write the data
V_source = V_scan_item
# V_source = read_source_V()
[V_list, V_avg, V_err] = measure_V(time_average=time_average, time_interval=0.2)
time_now = datetime.datetime.now()
# measure+read+write the data
V_source = V_scan_item
# V_source = read_source_V()
[V_list, V_avg, V_err] = measure_V(time_average=time_average, time_interval=0.2)
time_now = datetime.datetime.now()
# data_string = "%s\t %s\t %.5e\t %.5e\t %s\n"\
# %(time_now, V_source, V_avg, V_err, gain)
# data_file.write(str(data_string))
# raw_V_file.write("%s\t %s\n" %(V_source, V_list))
data_string = "%s\t %s\t %.5e\t %.5e\t %s\t %s\n"\
%(time_now, V_source, V_avg, V_err, gain, V_list)
data_file.write(str(data_string))
# raw_V_file.write("%s\t %s\n" %(V_source, V_list))
V_plot_list.append(V_avg)
V_err_plot_list.append(V_err)
V_scan_plot_list.append(V_source)
V_avg_list.append(V_avg)
V_err_list.append(V_err)
V_source_list.append(V_source)
V_raw_lists.append(V_list)
time_list.append(time_now)
#make plot
# plt.close()
# plt.plot(V_scan_plot_list, V_plot_list,'+')
# plt.title(str(sample_name))
# plt.xlabel('Source Voltage / V')
# plt.ylabel('Measured voltage / V')
# plt.draw()
# plt.pause(0.1)
# plt.show(block=False)
# iteration_time = datetime.datetime.now()-time_start_iteration
# remaining_time = iteration_time.total_seconds()*(len(V_scan_list)-i)
# print(time.strftime('Remaining time: %H:%M:%S',\
# time.gmtime(remaining_time)))
#make plot
plt.close()
plt.plot(V_source_list, V_avg_list,'+')
plt.title(str(sample_name))
plt.xlabel('Source Voltage / V')
plt.ylabel('Measured voltage / V')
plt.draw()
plt.pause(0.1)
plt.show(block=False)
i = i+1
iteration_time = datetime.datetime.now()-time_start_iteration
remaining_time = iteration_time.total_seconds()*(len(V_scan_list)-i)
print(time.strftime('Remaining time: %H:%M:%S',\
time.gmtime(remaining_time)))
I_list = [V_avg_list[i]/gain for i in range(len(V_avg_list))]
I_err_list = [V_err_list[i]/gain for i in range(len(V_avg_list))]
plt.close()
plt.figure()
plt.errorbar(V_source_list, I_list, yerr=I_err_list, fmt='+')
plt.title(str(sample_name))
plt.xlabel('Source Voltage / V')
plt.ylabel('I / A')
plt.tight_layout()
plt.grid()
plt.savefig(full_plotname)
plt.draw()
plt.pause(0.001)
plt.show(block=False)
plt.close()
I_list = [V_plot_list[i]/gain for i in range(len(V_plot_list))]
I_err_list = [V_err_plot_list[i]/gain for i in range(len(V_plot_list))]
# plt.close()
# plt.figure()
# plt.errorbar(V_scan_plot_list, I_list, yerr=I_err_list, fmt='+')
# plt.title(str(sample_name))
# plt.xlabel('Source Voltage / V')
# plt.ylabel('I / A')
# plt.tight_layout()
# plt.grid()
# plt.savefig(full_plotname)
# plt.draw()
# plt.pause(0.001)
# plt.show(block=False)
# plt.close()
# data_file.close()
data_file.close()
# raw_V_file.close()
file_path = Path(__file__).parent / "data"
file_path.mkdir(exist_ok=True)
with h5py.File(file_path / f"{filename[0:-4]}.h5", "a") as f:
f.create_dataset("V_source", data=V_source_list)
f.create_dataset("V_avg", data=V_avg_list)
f.create_dataset("V_err", data=V_err_list)
f.create_dataset("V_raw", data=V_raw_lists)
f.create_dataset("timestamps", data=[str(t) for t in time_list])
f.create_dataset("I", data=I_list)
f.create_dataset("I_err", data=I_err_list)
set_voltage(0)
SIM900_comm.send_command(SIM900, SIM928_port, SIM928_comm.V_source_state("off")) #set source off
+3 -1
View File
@@ -2,8 +2,10 @@
import tomllib
from iv_functions import V_scan
import h5py
with open("automated-iv-curves/config.toml", "rb") as f:
cfg = tomllib.load(f)
V_scan(**cfg["experiment"])
V_scan(**cfg["experiment"])