use iv instead of v curves
This commit is contained in:
parent
579d69f92a
commit
da49bf68d6
@ -1,6 +1,10 @@
|
||||
"""
|
||||
run this before using this library:
|
||||
ipython -i keithley_interactive.py
|
||||
|
||||
always records iv-t curves
|
||||
i-data -> smua.nvbuffer1
|
||||
v-data -> smua.nvbuffer2
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
@ -25,7 +29,7 @@ if __name__ == "__main__":
|
||||
|
||||
|
||||
from .keithley import keithley as _keithley
|
||||
from .utility import data
|
||||
from .utility import data as _data
|
||||
from .utility import file_io
|
||||
from .utility import testing
|
||||
|
||||
@ -61,49 +65,71 @@ def _measure(max_measurements=None, max_points_shown=None, monitor=False):
|
||||
global k, settings, test, _runtime_vars
|
||||
print(f"Starting measurement with:\n\tinterval = {settings['interval']}s\nUse <C-c> to stop. Save the data using 'save_csv()' afterwards.")
|
||||
_runtime_vars["last_measurement"] = dtime.now().isoformat()
|
||||
if not test:
|
||||
_keithley.reset(k, verbose=True)
|
||||
k.write("smua.source.output = 1")
|
||||
k.write("format.data = format.ASCII\nformat.asciiprecision = 12")
|
||||
# jupyter:
|
||||
# clear_output(wait=True)
|
||||
# plt.plot(data)
|
||||
# plt.show()
|
||||
index = []
|
||||
data = []
|
||||
vdata = []
|
||||
idata = []
|
||||
if monitor:
|
||||
plt.ion()
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(ylabel="Voltage [V]")
|
||||
line1, = ax.plot(index, data)
|
||||
fig1, (vax, iax) = plt.subplots(2, 1)
|
||||
|
||||
vline, = vax.plot(index, vdata, color="g")
|
||||
vax.set_ylabel("Voltage [V]")
|
||||
vax.grid(True)
|
||||
|
||||
iline, = iax.plot(index, idata, color="m")
|
||||
iax.set_ylabel("Current [A]")
|
||||
iax.grid(True)
|
||||
try:
|
||||
i = 0
|
||||
while max_measurements is None or i < max_measurements:
|
||||
index.append(i)
|
||||
if test:
|
||||
data.append(testing.testcurve(i))
|
||||
# data.append(tuple(float(v) for v in instr.query("print(smua.measure.v())").strip('\n').split('\t')))
|
||||
else:
|
||||
data.append(k.query("print(smua.measure.v())").strip('\n'))
|
||||
idata.append(testing.testcurve(i, peak_width=1, amplitude=5e-8))
|
||||
vdata.append(-testing.testcurve(i, peak_width=2, amplitude=15))
|
||||
# data.append(np.random.rand())
|
||||
print(f"{i:5d} - {data[-1]:.5f} V", end='\r')
|
||||
else:
|
||||
# data.append(float(k.query("print(smua.measure.v(smua.nvbuffer1))").strip('\n')))
|
||||
i_val, v_val = tuple(float(v) for v in k.query("print(smua.measure.iv(smua.nvbuffer1, smua.nvbuffer2))").strip('\n').split('\t'))
|
||||
idata.append(i_val)
|
||||
vdata.append(v_val)
|
||||
print(f"{i:5d} - {idata[-1]:.12f} A - {vdata[-1]:.5f} V", end='\r')
|
||||
if monitor:
|
||||
# update data
|
||||
line1.set_xdata(index)
|
||||
line1.set_ydata(data)
|
||||
iline.set_xdata(index)
|
||||
iline.set_ydata(idata)
|
||||
vline.set_xdata(index)
|
||||
vline.set_ydata(vdata)
|
||||
# recalculate limits and set them for the view
|
||||
ax.relim()
|
||||
iax.relim()
|
||||
vax.relim()
|
||||
if max_points_shown and i > max_points_shown:
|
||||
ax.set_xlim(i - max_points_shown, i)
|
||||
ax.autoscale_view()
|
||||
iax.set_xlim(i - max_points_shown, i)
|
||||
vax.set_xlim(i - max_points_shown, i)
|
||||
iax.autoscale_view()
|
||||
vax.autoscale_view()
|
||||
# update plot
|
||||
fig.canvas.draw()
|
||||
fig.canvas.flush_events()
|
||||
fig1.canvas.draw()
|
||||
fig1.canvas.flush_events()
|
||||
sleep(settings["interval"])
|
||||
i += 1
|
||||
except KeyboardInterrupt:
|
||||
if not test:
|
||||
k.write("smua.source.output = 0")
|
||||
if monitor:
|
||||
plt.close(fig)
|
||||
plt.close(fig1)
|
||||
print("Measurement stopped" + " "*50)
|
||||
return vdata, idata
|
||||
|
||||
|
||||
def monitor(max_measurements=None, max_points_shown=None, ):
|
||||
def monitor(max_measurements=None, max_points_shown=160):
|
||||
"""
|
||||
Monitor the voltage with matplotlib.
|
||||
|
||||
@ -131,17 +157,23 @@ def measure(max_measurements=None):
|
||||
|
||||
|
||||
def get_dataframe():
|
||||
"""
|
||||
Get a pandas dataframe from the data in smua.nvbuffer1
|
||||
"""
|
||||
global k, settings, _runtime_vars
|
||||
if test:
|
||||
timestamps = np.arange(0, 50, 0.01)
|
||||
ydata = np.array([testing.testcurve(t) for t in timestamps])
|
||||
buffer = np.vstack((timestamps, ydata)).T
|
||||
ydata = np.array([testing.testcurve(t, amplitude=15, peak_width=2) for t in timestamps])
|
||||
ibuffer = np.vstack((timestamps, ydata)).T
|
||||
|
||||
ydata = np.array([-testing.testcurve(t, amplitude=5e-8, peak_width=1) for t in timestamps])
|
||||
vbuffer = np.vstack((timestamps, ydata)).T
|
||||
else:
|
||||
buffer = _keithley.collect_buffer(k, 1)
|
||||
df = data.buffer2dataframe(buffer)
|
||||
ibuffer = _keithley.collect_buffer(k, 1)
|
||||
vbuffer = _keithley.collect_buffer(k, 2)
|
||||
df = _data.buffers2dataframe(ibuffer, vbuffer)
|
||||
df.basename = file_io.get_next_filename(settings["name"], settings["datadir"])
|
||||
df.name = f"{df.basename} @ {_runtime_vars['last-measurement']}"
|
||||
df.columns = ["Time [s]", "Voltage [V]"]
|
||||
return df
|
||||
|
||||
def save_csv():
|
||||
@ -201,6 +233,9 @@ def set(setting, value):
|
||||
return
|
||||
settings[setting] = value
|
||||
|
||||
def name(s:str):
|
||||
global settings
|
||||
settings["name"] = s
|
||||
|
||||
def save_settings():
|
||||
with open(config_path, "w") as file:
|
||||
@ -218,9 +253,10 @@ def help(topic=None):
|
||||
Functions:
|
||||
measure - measure the voltage
|
||||
monitor - measure the voltage with live monitoring in a matplotlib window
|
||||
get_dataframe - return smua.nvbuffer1 as pandas dataframe
|
||||
save_csv - save the last measurement as csv file
|
||||
save_pickle - save the last measurement as pickled pandas dataframe
|
||||
load_dataframe - load a pandas dataframe from csv or pickle
|
||||
load_dataframe - load a pandas dataframe from csv or pickle
|
||||
run_script - run a lua script on the Keithely device
|
||||
Run 'help(function)' to see more information on a function
|
||||
|
||||
@ -238,9 +274,10 @@ Run 'help("topic")' to see more information on a topic""")
|
||||
beep: bool - wether the device should beep or not
|
||||
|
||||
Functions:
|
||||
TODO set("setting", value) - set a setting to a value
|
||||
TODO save_settings() - store the settings as "k-teng.conf" in the working directory
|
||||
TODO load_settings() - load settings from a file
|
||||
name("<name>") - short for set("name", "<name>")
|
||||
set("setting", value) - set a setting to a value
|
||||
save_settings() - store the settings as "k-teng.conf" in the working directory
|
||||
load_settings() - load settings from a file
|
||||
The global variable 'config_path' determines the path used by save/load_settings. Use -c '<path>' to set another path.
|
||||
The serach path is:
|
||||
<working-dir>/k-teng.json
|
||||
|
@ -5,7 +5,7 @@ import numpy as np
|
||||
"""
|
||||
Utility
|
||||
"""
|
||||
script_dir = "scripts/"
|
||||
script_dir = "../scripts/"
|
||||
scripts = {
|
||||
"buffer_reset": "buffer_reset.lua",
|
||||
"smua_reset": "smua_reset.lua",
|
||||
@ -54,7 +54,7 @@ def reset(instr, verbose=False):
|
||||
run_lua(instr, scripts["buffer_reset"], verbose=verbose)
|
||||
|
||||
|
||||
def collect_buffer(instr, buffer_nr=1):
|
||||
def collect_buffer(instr, buffer_nr=1, verbose=False):
|
||||
"""
|
||||
Get the buffer as 2D - np.array
|
||||
@param instr : pyvisa instrument
|
||||
@ -71,7 +71,8 @@ def collect_buffer(instr, buffer_nr=1):
|
||||
instr.write("format.data = format.ASCII\nformat.asciiprecision = 7")
|
||||
timestamps = instr.query_ascii_values(f"printbuffer(1, {buffername}.n, {buffername}.timestamps)", container=np.array)
|
||||
readings = instr.query_ascii_values(f"printbuffer(1, {buffername}.n, {buffername}.readings)", container=np.array)
|
||||
print(f"readings: {readings}, \ntimestamps: {timestamps}")
|
||||
if verbose:
|
||||
print(f"readings from {buffername}: {readings}, \ntimestamps: {timestamps}")
|
||||
buffer = np.vstack((timestamps, readings)).T
|
||||
return buffer
|
||||
|
||||
|
@ -6,3 +6,12 @@ def buffer2dataframe(buffer):
|
||||
df.colums = ["Time [s]", "Voltage [V]"]
|
||||
return df
|
||||
|
||||
def buffers2dataframe(ibuffer, vbuffer):
|
||||
"""
|
||||
@param ibuffer : 2d - array: timestamps, current
|
||||
@param vbuffer : 2d - array: timestamps, voltage
|
||||
@returns DataFrame: timestamps, current, voltage
|
||||
"""
|
||||
df = pd.DataFrame(np.vstack((ibuffer[:,0], ibuffer[:,1], vbuffer[:,1])).T)
|
||||
df.columns = ["Time [s]", "Current [A]", "Voltage [V]"]
|
||||
return df
|
||||
|
@ -2,12 +2,24 @@
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 1,
|
||||
"id": "d1bb781f-f286-44cf-a3e3-181e06281487",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"outputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"ename": "ModuleNotFoundError",
|
||||
"evalue": "No module named 'keithley'",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)",
|
||||
"Cell \u001b[0;32mIn[1], line 12\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mmatplotlib\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m pyplot \u001b[38;5;28;01mas\u001b[39;00m plt\n\u001b[1;32m 11\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mnumpy\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mnp\u001b[39;00m\n\u001b[0;32m---> 12\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mkeithley\u001b[39;00m\n\u001b[1;32m 13\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mfile_io\u001b[39;00m\n\u001b[1;32m 14\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mmeasure\u001b[39;00m\n",
|
||||
"\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'keithley'"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"\"\"\"\n",
|
||||
"INIT:connect to keithley\n",
|
||||
|
@ -1,10 +1,9 @@
|
||||
-- reset smua
|
||||
smua.reset()
|
||||
smua.measure.autorangev = smua.AUTORANGE_ON
|
||||
smua.measure.autorangei = smua.AUTORANGE_ON
|
||||
smua.measure.autozero = smua.AUTOZERO_ONCE
|
||||
-- set output to 0A DC
|
||||
smua.source.output = smua.OUTPUT_OFF
|
||||
smua.source.func = smua.OUTPUT_DCAMPS
|
||||
smua.source.leveli = smua.OUTPUT_OFF
|
||||
|
||||
-- smua.measure.rangev = 20
|
||||
|
Loading…
Reference in New Issue
Block a user