From 7c5dca87c90e4493707e6d588e77cbf1333c9351 Mon Sep 17 00:00:00 2001 From: "matthias@arch" Date: Thu, 6 Apr 2023 22:55:24 +0200 Subject: [PATCH] initial commit --- buffer_reset.lua | 10 ++++ file_io.py | 24 ++++++++++ main.py | 118 +++++++++++++++++++++++++++++++++++++++++++++++ measure.py | 48 +++++++++++++++++++ readme.md | 15 ++++++ 5 files changed, 215 insertions(+) create mode 100644 buffer_reset.lua create mode 100644 file_io.py create mode 100644 main.py create mode 100644 measure.py create mode 100644 readme.md diff --git a/buffer_reset.lua b/buffer_reset.lua new file mode 100644 index 0000000..cff8735 --- /dev/null +++ b/buffer_reset.lua @@ -0,0 +1,10 @@ +smua.nvbuffer1.clear() +smua.nvbuffer1.fillmode = smua.FILL_ONCE +smua.nvbuffer1.appendmode = 1 +smua.nvbuffer1.collecttimestamps = 1 + +smua.nvbuffer2.clear() +smua.nvbuffer2.fillmode = smua.FILL_ONCE +smua.nvbuffer2.appendmode = 1 +smua.nvbuffer2.collecttimestamps = 1 + diff --git a/file_io.py b/file_io.py new file mode 100644 index 0000000..1f3f314 --- /dev/null +++ b/file_io.py @@ -0,0 +1,24 @@ +from os import listdir, path + +def get_next_filename(basename, directory=".", digits=3): + files = listdir(directory) + files.sort() + files.reverse() + lowest_number = 0 + for file in files: + if not path.isfile(file): continue + if not file.startswith(basename): continue + try: + number = int(file.split('.')[0].strip(basename)) + if number < lowest_number: continue + except ValueError: + continue + + + + + + + + + diff --git a/main.py b/main.py new file mode 100644 index 0000000..24dff7c --- /dev/null +++ b/main.py @@ -0,0 +1,118 @@ +import pyvisa + +import npyscreen as nps +import + + +class Keithley(nps.NPSAppManaged): + """Managed Application. Contains the Praktimatika PKTSession, so that all forms and widgets can access it.""" + def onStart(self): + self.version = "alpha 1" + self.settings = { + "print_output": True, + "copy_clip": True, + "dec_sep": ",", + "theme": "Default" + } + self.load_settings() + self.themes = { + "Default": nps.Themes.DefaultTheme, + "Colourful": nps.Themes.ColorfulTheme, + "Elegant": nps.Themes.ElegantTheme, + "Transparent-Light Font": nps.Themes.TransparentThemeLightText, + "Transparent-Dark Font": nps.Themes.TransparentThemeDarkText, + } + + theme = nps.Themes.DefaultTheme + if self.settings["theme"] in self.themes: + theme = self.themes[self.settings["theme"]] + + nps.setTheme(theme) + + # stores a selected ... to be accessible for all forms: (name, value) + self.function = ("", None) + self.variable = ("", None) + self.array = ("", None) + self.constant = ("", None) + + + self.start = self.addForm("MAIN", StartupMenu, name='Praktimatika Startup') + # self.addForm("start", StartupMenu, name='Praktimatika Startup') + self.home = self.addForm("home", tui_home.HomeMenu, name=f"Praktimatika Home (Version {self.version})") + # APP MENUS + self.f_settings = self.addForm("settings", tui_home.Settings, name="Praktimatika Settings") + self.save = self.addForm("save", SaveMenu, name="Save Praktimatika PKTSession") + self.impor = self.addForm("import", tui_import.ImportMenu, name="Import Arrays from a spreadsheet") + + # FUNCTION MENUS + self.func = self.addForm("m_fun", tui_user_functions.UserFuncMenu, name="Function Menu") + self.func_calc = self.addForm("m_fun_calc", tui_user_functions.UserFuncCalc2, name="Calculation Menu") + + # BUILTIN FUNCTION MENUS + self.weighted_median = self.addForm("weighted_median", tui_functions.WeightedMedian, name="Weighted Median") + self.error_prop = self.addForm("error_prop", tui_user_functions.ErrorPropagation, name="Error Propagation") + self.curve_fit = self.addForm("curve_fit", tui_user_functions.CurveFit, name="Curve Fitting") + # PLOT MENUS + self.plot = self.addForm("plot", tui_plot.AxesMenu, name="Plot Menu") # remove! + self.pl_fig = self.addForm("pl_fig", tui_plot.FigMenu, name="Plot Menu - Figure") + self.pl_ax = self.addForm("pl_ax", tui_plot.AxesMenu, name="Plot Menu - Axis") + self.pl_pl = self.addForm("pl_pl", tui_plot.PlotMenu, name="Plot Menu - Data") + # Add Menus + self.add_fun = self.addForm("add_fun", tui_add.AddFun, name="Add Functions") + self.edit_fun = self.addForm("edit_fun", tui_add.EditFunc, name="Edit Function") + self.add_arr = self.addForm("add_arr", tui_add.AddArr, name="Add Arrays & Values") + self.save_arr = self.addForm("save_arr", tui_functions.SaveVec, name="Save Array") + # TOOLS + self.latex = self.addForm("latex_table", tui_tools.LatexTable, name="Create Latex Table") + + + @staticmethod + def exit_app(): + if nps.notify_yes_no("Are you sure you want to exit?", title='Exit'): + sys.exit() + + + # + # Settings + # + def load_settings(self): + try: + with open("keithley.conf", "r") as file: + raw_list = file.readlines() + file.close() + for line in raw_list: + if "#" in line: # ignore commented lines + continue + line = line.replace("\n", "") + temp_list = line.split(" = ") + if temp_list[1] == "True": + temp_list[1] = True + elif temp_list[1] == "False": + temp_list[1] = False + self.settings.update({temp_list[0]: temp_list[1]}) + except FileNotFoundError: + nps.notify_confirm("Could not load settings from 'keithley.conf'. File not found.") + except IndexError: + nps.notify_confirm("Could not load settings from 'keithley.conf'. Invalid file structure") + + def save_settings(self): + with open("praktimatika.conf", "w") as file: + text = "# Praktimatika Config File. \n" \ + "# Content here will be overwritten when the settings are saved.\n" + for key, val in self.settings.items(): + text += f"{key} = {val}\n" + file.write(text) + + @staticmethod + def show_error(message, exception: BaseException): + """ + Shows an Error Message in an nps.notify_confirm Form + :param message: string, message + :param exception: Exception + :return: + """ + nps.notify_confirm(f"{message}:\n{exception}\nin file {exception.__traceback__.tb_frame.f_code.co_filename}\n" + f"in line {exception.__traceback__.tb_lineno}") + +if __name__ == '__main__': + TestApp = Keithley().run() diff --git a/measure.py b/measure.py new file mode 100644 index 0000000..3d21342 --- /dev/null +++ b/measure.py @@ -0,0 +1,48 @@ +from time import sleep +import numpy as np +from matplotlib import pyplot as plt + +smua_settings = """ +display.clear() +display.settext('starting') +smua.reset() +smua.measure.autorangev = smua.AUTORANGE_ON +smua.source.output = smua.OUTPUT_OFF +-- max 20 V expected +smua.measure.rangev = 20 + +""" + +script_dir = "" + +scripts = { + "buffer_reset": "scripts/buffer_reset.lua", +} + +def run_lua(instr, script_path): + with open(script_dir + script_path, "r") as file: + script = file.read() + instr.write(script) + + +def measureV(count=100, interval=0.05) + """ + """ + data = [] + for i in range(1000): + data.append(tuple(float(v) for v in keithley.query("print(smua.measure.v())").strip('\n').split('\t'))) + # print(i, data[-1]) + # clear_output(wait=True) + plt.plot(data) + plt.show() + sleep(0.05) + +def collect_buffer(instr, buffer_nr=1): + """ + get the buffer in double precision binary format as np.array + """ + if buffer_nr == 2: buffername = "smua.nvbuffer2" + else: buffername = "smua.nvbuffer1" + instr.write("format.data = format.DREAL\nformat.byteorder = format.LITTLEENDIAN") + buffer = instr.query_ascii_values(f"printbuffer(1, {buffername}.n, {buffername})", datatype='d', container=np.array) + return buffer diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..e9d3b40 --- /dev/null +++ b/readme.md @@ -0,0 +1,15 @@ +# TENG scripts +Helper scripts for measuring TENG-based sensor output from a Keithley 2611B using pyvisa in a jupyter notebook +## Requirements +- Measure Voltage +- Measure Voltage and Current +- Save to host +- Live view +- autofilenames +- press buttons for start and fin +- settings: + - interval + - count +- run arbitrary command +- run lua script +