Files

PySweeperGUI - ArduinoRev4.py
#!/usr/bin python import tkinter as tk import serial import csv import numpy as np import matplotlib.pyplot as plt import tkinter.filedialog # Otherwise it won't compile to .exe from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg import time import serial.tools.list_ports #1/4/2017 #Only UpSweeps #4x4 support (Should be ablke to easily change to any array size by tweeking how 256 is split) #variable array sizes #add auto find ser #Find prettier TkInter Module!!!! class Application(tk.Frame): def __init__(self, master=None): """Application initialization """ tk.Frame.__init__(self, master) try: self.ser=serial.Serial('/dev/ttyUSB0', 115200, timeout=20, parity = serial.PARITY_NONE) #Keithley serial port - COM4: Deskotp, COM5: Laptop except: print("No serial port for keithley") try: self.ser1=serial.Serial('/dev/ttyACM0', 9600, timeout=10, parity = serial.PARITY_NONE) #Arduino serial port except: print("No serial port for arduino") ## ArduinoPorts = [ ## p.device ## for p in serial.tools.list_ports.comports() ## ## if 'Arduino' in p.description ## ] ## KeithleyPorts = [ ## p.device ## for p in serial.tools.list_ports.comports() ## ## if 'USB-Serial' in p.description ## ] ## print(KeithleyPorts) ## ## if len(KeithleyPorts) > 0: ## self.ser=serial.Serial(KeithleyPorts[0], 115200, timeout=10, parity = serial.PARITY_NONE) #Keithley serial port - COM4: Desktop, COM5: Laptop ## print("Keithley is on " + str(KeithleyPorts[0])) ## else: ## print("No serial port for Keithley") ## if len(ArduinoPorts) > 0: ## self.ser1=serial.Serial(ArduinoPorts[0], 9600, timeout=10, parity = serial.PARITY_NONE) #Arduino serial port ## print("Arduino is on " + str(ArduinoPorts[0])) ## else: ## print("No serial port for Arduino") ## ## ports = list(serial.tools.list_ports.comports()) #Print all ports in use ## for p in ports: ## print(p) ## print(p.serial_number) self.fig = plt.Figure(figsize=(7, 6), dpi=100) self.fig.suptitle("I-V Sweep") self.a = self.fig.add_subplot(111) self.a.grid(b=True, which='major', color='r', linestyle='--') self.start = tk.DoubleVar() self.start.set(0.0) self.stop = tk.DoubleVar() self.stop.set(0.5) self.steps = tk.IntVar() self.steps.set(100) self.compliance = tk.DoubleVar() self.compliance.set(0.005) self.delay = tk.DoubleVar() self.delay.set(0.1) self.NPLC = tk.DoubleVar() self.NPLC.set(0.05) self.loops = tk.IntVar() self.loops.set(1) self.loopStep = tk.DoubleVar() self.loopStep.set(0) self.loopComplete = tk.DoubleVar() self.loopComplete.set(0) self.loopCompleteInt = tk.IntVar() self.loopCompleteInt.set(0) self.loopCount = tk.IntVar() self.loopCount.set(1) self.delayLoop = tk.DoubleVar() self.delayLoop.set(0.01) self.QuadCount = tk.IntVar() self.QuadCount.set(0) self.filenamenumber = tk.IntVar() self.filenamenumber.set(0) self.filename = tk.StringVar() self.filename.set("Sweep_") self.filenametext = tk.StringVar() self.setfilename() self.modes = tk.IntVar() self.modes.set(0) self.QUADmode = tk.IntVar() self.QUADmode.set(0) self.holdMode = tk.IntVar() self.holdMode.set(0) #Graph Variables self.XStart = tk.DoubleVar() self.XStart.set(0.0) self.XStop = tk.DoubleVar() self.XStop.set(0.5) self.YStop = tk.DoubleVar() self.YStop.set(0.005) self.YStart = tk.DoubleVar() self.YStart.set(0) self.mux = tk.IntVar() self.mux.set(0) self.arrayRow = tk.IntVar() self.arrayRow.set(2) self.arrayColumn = tk.IntVar() self.arrayColumn.set(2) self.switchKey = tk.IntVar() self.switchKey.set(0) self.perStep = tk.DoubleVar() self.perStep.set(0) self.perComplete = tk.DoubleVar() self.perComplete.set(0) self.perCompleteInt = tk.IntVar() self.perCompleteInt.set(0) self.deviceNumber = tk.IntVar() self.deviceNumber.set(0) self.quadValue = tk.StringVar() self.quadValue.set("") self.quadState=tk.IntVar() self.quad1 = tk.BooleanVar() self.quad1.set(False) self.quad2 = tk.BooleanVar() self.quad2.set(False) self.quad3 = tk.BooleanVar() self.quad3.set(False) self.quad4 = tk.BooleanVar() self.quad4.set(False) self.quad5 = tk.BooleanVar() self.quad5.set(False) self.quad6 = tk.BooleanVar() self.quad6.set(False) self.quad7 = tk.BooleanVar() self.quad7.set(False) self.quad8 = tk.BooleanVar() self.quad8.set(False) self.quad9 = tk.BooleanVar() self.quad9.set(False) self.quad10 = tk.BooleanVar() self.quad10.set(False) self.quad11 = tk.BooleanVar() self.quad11.set(False) self.quad12 = tk.BooleanVar() self.quad12.set(False) self.quad13 = tk.BooleanVar() self.quad13.set(False) self.quad14 = tk.BooleanVar() self.quad14.set(False) self.quad15 = tk.BooleanVar() self.quad15.set(False) self.quad16 = tk.BooleanVar() self.quad16.set(False) self.columnconfigure(0, pad = 2) self.createWidgets() self.grid() def createWidgets(self): self.fileFrame = tk.Frame() self.filenameLabel = tk.Label(text = "File Name: ") self.filenameLabel.grid(row = 0, column = 0, sticky = tk.W, padx = 5, pady = 5, in_ = self.fileFrame) self.filenameEntry = tk.Entry(textvariable = self.filename) self.filenameEntry.grid(row = 0, column = 1, sticky = tk.W, padx = 5, pady = 5, in_ = self.fileFrame) self.filenamenumberEntry = tk.Entry(textvariable = self.filenamenumber, width = 3, justify = tk.RIGHT) self.filenamenumberEntry.grid(row = 0, column = 2, sticky = tk.W, padx = 5, pady = 5, in_ = self.fileFrame) self.setButton = tk.Button(self.fileFrame, text='Set', command=self.setfilename) self.setButton.grid(row = 0, column = 3, sticky = tk.W) self.saveToLabel = tk.Label(text = "Next: ") self.saveToLabel.grid(row = 1, column = 0, sticky = tk.W, padx = 5, pady = 5, in_ = self.fileFrame) self.saveToLabelName = tk.Label(textvariable = self.filenametext) self.saveToLabelName.grid(row = 1, column = 1, sticky = tk.W, padx = 5, pady = 5, in_ = self.fileFrame) self.fileFrame.grid(row = 0, column = 0, sticky = tk.W + tk.N, padx = 5, pady = 5, in_ = self) self.infoFrame = tk.Frame() self.loopCountLabel = tk.Label(text = "Loop:") self.loopCountLabel.grid(row = 0, column = 0, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.infoFrame) self.loopCountVar = tk.Label(textvariable = self.loopCount) self.loopCountVar.grid(row = 0, column = 1, in_ = self.infoFrame) self.perCompleteLabel = tk.Label(text = "Permutation Complete:") self.perCompleteLabel.grid(row = 0, column = 2, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.infoFrame) self.perCompleteVar = tk.Label(textvariable = self.perCompleteInt) self.perCompleteVar.grid(row = 0, column = 3, in_ = self.infoFrame) self.per1Label = tk.Label(text = "%") self.per1Label.grid(row = 0, column = 4, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.infoFrame) self.loopCompleteLabel = tk.Label(text = "Loop Complete:") self.loopCompleteLabel.grid(row = 0, column = 5, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.infoFrame) self.loopCompleteVar = tk.Label(textvariable = self.loopCompleteInt) self.loopCompleteVar.grid(row = 0, column = 6, in_ = self.infoFrame) self.per2Label = tk.Label(text = "%") self.per2Label.grid(row = 0, column = 7, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.infoFrame) self.infoFrame.grid(row = 0, column = 1, in_ = self) self.settingsFrame = tk.Frame() self.startLabel = tk.Label(text = "START(V)") self.startLabel.grid(row = 0, column = 0, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.settingsFrame) self.stopLabel = tk.Label(text = "STOP(V)") self.stopLabel.grid(row = 0, column = 1, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.settingsFrame) self.stepsLabel = tk.Label(text = "STEPS(#)") self.stepsLabel.grid(row = 0, column = 2, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.settingsFrame) self.complianceLabel = tk.Label(text = "COMP.(A)") self.complianceLabel.grid(row = 0, column = 3, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.settingsFrame) self.delayLabel = tk.Label(text = "DELAY(s)") self.delayLabel.grid(row = 0, column = 4, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.settingsFrame) self.loopsLabel = tk.Label(text = "LOOPS(#)") self.loopsLabel.grid(row = 0, column = 5, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.settingsFrame) self.startEntry = tk.Entry(textvariable = self.start, width = 6, justify = tk.RIGHT) self.startEntry.grid(row = 1, column = 0, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.settingsFrame) self.stopEntry = tk.Entry(textvariable = self.stop, width = 6, justify = tk.RIGHT) self.stopEntry.grid(row = 1, column = 1, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.settingsFrame) self.stepsEntry = tk.Entry(textvariable = self.steps, width = 6, justify = tk.RIGHT) self.stepsEntry.grid(row = 1, column = 2, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.settingsFrame) self.complianceEntry = tk.Entry(textvariable = self.compliance, width = 6, justify = tk.RIGHT) self.complianceEntry.grid(row = 1, column = 3, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.settingsFrame) self.delayEntry = tk.Entry(textvariable = self.delay, width = 6, justify = tk.RIGHT) self.delayEntry.grid(row = 1, column = 4, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.settingsFrame) self.loopsEntry = tk.Entry(textvariable = self.loops, width = 6, justify = tk.RIGHT) self.loopsEntry.grid(row = 1, column = 5, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.settingsFrame) self.settingsFrame.grid(row = 1, column = 0, sticky = tk.W + tk.N, padx = 5, pady = 5, in_ = self) self.SweepsettingsFrame = tk.Frame() self.delayLoopLabel = tk.Label(text = "S.Delay(s)") self.delayLoopLabel.grid(row = 2, column = 0, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.settingsFrame) self.delayLoopEntry = tk.Entry(textvariable = self.delayLoop, width = 6, justify = tk.RIGHT) self.delayLoopEntry.grid(row = 3, column = 0, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.settingsFrame) self.NPLCLabel = tk.Label(text = "NPLC") self.NPLCLabel.grid(row = 2, column = 1, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.settingsFrame) self.NPLCEntry = tk.Entry(textvariable = self.NPLC, width = 6, justify = tk.RIGHT) self.NPLCEntry.grid(row = 3, column = 1, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.settingsFrame) self.SweepsettingsFrame.grid(row = 1, column = 0, sticky = tk.W + tk.N, padx = 5, pady = 5, in_ = self) self.GraphsettingsFrame = tk.Frame() self.YStartLabel = tk.Label(text = "Y Start") self.YStartLabel.grid(row = 0, column = 0, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.GraphsettingsFrame) self.YStartEntry = tk.Entry(textvariable = self.YStart, width = 6, justify = tk.RIGHT) self.YStartEntry.grid(row = 1, column = 0, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.GraphsettingsFrame) self.YStopLabel = tk.Label(text = "Y Stop") self.YStopLabel.grid(row = 0, column = 1, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.GraphsettingsFrame) self.YStopEntry = tk.Entry(textvariable = self.YStop, width = 6, justify = tk.RIGHT) self.YStopEntry.grid(row = 1, column = 1, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.GraphsettingsFrame) self.XStartLabel = tk.Label(text = "X Start") self.XStartLabel.grid(row = 0, column = 2, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.GraphsettingsFrame) self.XStartEntry = tk.Entry(textvariable = self.XStart, width = 6, justify = tk.RIGHT) self.XStartEntry.grid(row = 1, column = 2, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.GraphsettingsFrame) self.XStopLabel = tk.Label(text = "X Stop") self.XStopLabel.grid(row = 0, column = 3, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.GraphsettingsFrame) self.XStopEntry = tk.Entry(textvariable = self.XStop, width = 6, justify = tk.RIGHT) self.XStopEntry.grid(row = 1, column = 3, sticky = tk.W+tk.E, padx = 5, pady = 5, in_ = self.GraphsettingsFrame) self.GraphsettingsFrame.grid(row = 2, column = 0, sticky = tk.W + tk.N, padx = 5, pady = 5, in_ = self) self.sweepModeFrame = tk.Frame() self.stairRadio = tk.Radiobutton(self.sweepModeFrame, text ="Staircase sweep", variable = self.modes, value = 0) self.stairRadio.grid(row = 0, column = 0, sticky = tk.W) self.pulsedRadio = tk.Radiobutton(self.sweepModeFrame, text ="Pulsed staircase sweep", variable = self.modes, value = 1) self.pulsedRadio.grid(row = 0, column = 1, sticky = tk.W) self.sweepModeFrame.grid(row = 3, column = 0, sticky = tk.W + tk.N, padx = 5, pady = 5, in_ = self) self.figureCanvas = FigureCanvasTkAgg(self.fig, master=self) self.figureCanvas.get_tk_widget().grid(row = 1, column = 1, columnspan = 15, rowspan = 15, sticky = tk.N, in_ = self) self.ARRAYFrame = tk.Frame() self.ARRAYLabel = tk.Label(text = "Array Size") self.ARRAYLabel.grid(row = 0, column = 0, sticky = tk.W+tk.E, in_ = self.ARRAYFrame) self.ArrayLabel1 = tk.Label(text = " Rows ") self.ArrayLabel1.grid(row = 1 , column = 0, sticky = tk.W, in_ = self.ARRAYFrame) self.ARRAYCheck0 = tk.Checkbutton(self.ARRAYFrame, text ="1", variable = self.arrayRow, offvalue = 0, onvalue = 1, command=self.ARRAYsize) self.ARRAYCheck0.grid(row = 1, column = 1, sticky = tk.W) self.ARRAYCheck1 = tk.Checkbutton(self.ARRAYFrame, text ="2", variable = self.arrayRow, offvalue = 0, onvalue = 2, command=self.ARRAYsize) self.ARRAYCheck1.grid(row = 1, column = 2, sticky = tk.W) self.ARRAYCheck2 = tk.Checkbutton(self.ARRAYFrame, text ="3", variable = self.arrayRow, offvalue = 0, onvalue = 3, command=self.ARRAYsize) self.ARRAYCheck2.grid(row = 1, column = 3, sticky = tk.W) self.ARRAYCheck3 = tk.Checkbutton(self.ARRAYFrame, text ="4", variable = self.arrayRow, offvalue = 0, onvalue = 4, command=self.ARRAYsize) self.ARRAYCheck3.grid(row = 1, column = 4, sticky = tk.W) self.ArrayLabel2 = tk.Label(text = "Columns ") self.ArrayLabel2.grid(row = 2 , column = 0, sticky = tk.W, in_ = self.ARRAYFrame) self.ARRAYCheck5 = tk.Checkbutton(self.ARRAYFrame, text ="1", variable = self.arrayColumn, offvalue = 0, onvalue = 1, command=self.ARRAYsize) self.ARRAYCheck5.grid(row = 2, column = 1, sticky = tk.W) self.ARRAYCheck6 = tk.Checkbutton(self.ARRAYFrame, text ="2", variable = self.arrayColumn, offvalue = 0, onvalue = 2, command=self.ARRAYsize) self.ARRAYCheck6.grid(row = 2, column = 2, sticky = tk.W) self.ARRAYCheck7 = tk.Checkbutton(self.ARRAYFrame, text ="3", variable = self.arrayColumn, offvalue = 0, onvalue = 3, command=self.ARRAYsize) self.ARRAYCheck7.grid(row = 2, column = 3, sticky = tk.W) self.ARRAYCheck8 = tk.Checkbutton(self.ARRAYFrame, text ="4", variable = self.arrayColumn, offvalue = 0, onvalue = 4, command=self.ARRAYsize) self.ARRAYCheck8.grid(row = 2, column = 4, sticky = tk.W) self.ARRAYFrame.grid(row = 4, column = 0, in_ = self) self.QUADAutoFrame = tk.Frame() self.QuadAutoOff = tk.Radiobutton(self.QUADAutoFrame, text ="AutoRunOff", variable = self.QUADmode, value = 0) self.QuadAutoOff.grid(row = 0, column = 0, sticky = tk.W) self.QuadAutoOn = tk.Radiobutton(self.QUADAutoFrame, text ="AutoRunOn", variable = self.QUADmode, value = 1) self.QuadAutoOn.grid(row = 0, column = 1, sticky = tk.W) self.QUADAutoFrame.grid(row = 5, column = 0, sticky = tk.W + tk.N, padx = 5, pady = 5, in_ = self) self.QUADFrame = tk.Frame() self.QUADLabel = tk.Label(text = "Arduino: ") self.QUADLabel.grid(row = 0, column = 0, sticky = tk.W+tk.E, in_ = self.QUADFrame) self.QUADCheck1 = tk.Checkbutton(self.QUADFrame, text ="A0", variable = self.quad1, offvalue = False, onvalue = True, command=self.QUADserial) self.QUADCheck1.grid(row = 1, column = 1, sticky = tk.W) self.QUADCheck2 = tk.Checkbutton(self.QUADFrame, text ="A1", variable = self.quad2, offvalue = False, onvalue = True, command=self.QUADserial) self.QUADCheck2.grid(row = 2, column = 1, sticky = tk.W) self.QUADCheck3 = tk.Checkbutton(self.QUADFrame, text ="A2", variable = self.quad3, offvalue = False, onvalue = True, command=self.QUADserial) self.QUADCheck3.grid(row = 3, column = 1, sticky = tk.W) self.QUADCheck4 = tk.Checkbutton(self.QUADFrame, text ="A3", variable = self.quad4, offvalue = False, onvalue = True, command=self.QUADserial) self.QUADCheck4.grid(row = 4, column = 1, sticky = tk.W) self.QUADCheck5 = tk.Checkbutton(self.QUADFrame, text ="B0", variable = self.quad5, offvalue = False, onvalue = True, state=tk.DISABLED, command=self.QUADserial) self.QUADCheck5.grid(row = 1, column = 2, sticky = tk.W) self.QUADCheck6 = tk.Checkbutton(self.QUADFrame, text ="B1", variable = self.quad6, offvalue = False, onvalue = True, state=tk.DISABLED, command=self.QUADserial) self.QUADCheck6.grid(row = 2, column = 2, sticky = tk.W) self.QUADCheck7 = tk.Checkbutton(self.QUADFrame, text ="B2", variable = self.quad7, offvalue = False, onvalue = True, state=tk.DISABLED, command=self.QUADserial) self.QUADCheck7.grid(row = 3, column = 2, sticky = tk.W) self.QUADCheck8 = tk.Checkbutton(self.QUADFrame, text ="B3", variable = self.quad8, offvalue = False, onvalue = True, state=tk.DISABLED, command=self.QUADserial) self.QUADCheck8.grid(row = 4, column = 2, sticky = tk.W) self.QUADCheck9 = tk.Checkbutton(self.QUADFrame, text ="C0", variable = self.quad9, offvalue = False, onvalue = True, state=tk.DISABLED, command=self.QUADserial) self.QUADCheck9.grid(row = 1, column = 3, sticky = tk.W) self.QUADCheck10 = tk.Checkbutton(self.QUADFrame, text ="C1", variable = self.quad10, offvalue = False, onvalue = True, state=tk.DISABLED, command=self.QUADserial) self.QUADCheck10.grid(row = 2, column = 3, sticky = tk.W) self.QUADCheck11 = tk.Checkbutton(self.QUADFrame, text ="C2", variable = self.quad11, offvalue = False, onvalue = True, state=tk.DISABLED, command=self.QUADserial) self.QUADCheck11.grid(row = 3, column = 3, sticky = tk.W) self.QUADCheck12 = tk.Checkbutton(self.QUADFrame, text ="C3", variable = self.quad12, offvalue = False, onvalue = True, state=tk.DISABLED, command=self.QUADserial) self.QUADCheck12.grid(row = 4, column = 3, sticky = tk.W) self.QUADCheck13 = tk.Checkbutton(self.QUADFrame, text ="D0", variable = self.quad13, offvalue = False, onvalue = True, state=tk.DISABLED, command=self.QUADserial) self.QUADCheck13.grid(row = 1, column = 4, sticky = tk.W) self.QUADCheck14 = tk.Checkbutton(self.QUADFrame, text ="D1", variable = self.quad14, offvalue = False, onvalue = True, state=tk.DISABLED, command=self.QUADserial) self.QUADCheck14.grid(row = 2, column = 4, sticky = tk.W) self.QUADCheck15 = tk.Checkbutton(self.QUADFrame, text ="D2", variable = self.quad15, offvalue = False, onvalue = True, state=tk.DISABLED, command=self.QUADserial) self.QUADCheck15.grid(row = 3, column = 4, sticky = tk.W) self.QUADCheck16 = tk.Checkbutton(self.QUADFrame, text ="D3", variable = self.quad16, offvalue = False, onvalue = True, state=tk.DISABLED, command=self.QUADserial) self.QUADCheck16.grid(row = 4, column = 4, sticky = tk.W) self.QUADFrame.grid(row = 6, column = 0, in_ = self) self.holdModeFrame = tk.Frame() self.holdOffRadio = tk.Radiobutton(self.holdModeFrame, text ="Hold Off", variable = self.holdMode, value = 0) self.holdOffRadio.grid(row = 0, column = 0, sticky = tk.W) self.HoldOnRadio = tk.Radiobutton(self.holdModeFrame, text ="Hold On", variable = self.holdMode, value = 1) self.HoldOnRadio.grid(row = 0, column = 1, sticky = tk.W) self.holdModeFrame.grid(row = 7, column = 0, sticky = tk.W + tk.N, padx = 5, pady = 5, in_ = self) self.buttonsFrame = tk.Frame() self.goButton = tk.Button(self.buttonsFrame, text='GO!', command=self.go) self.goButton.grid(row = 0, column = 2) self.quitButton = tk.Button(self.buttonsFrame, text='Quit', command=self.quit) self.quitButton.grid(row = 0, column = 4) self.buttonsFrame.grid(row = 8, column = 0, in_ = self) def setfilename(self): self.filenametext.set(self.filename.get()+str(self.filenamenumber.get())) print(self.filenametext.get()) def configSweep(self): """Configure Keithley 2400 SMU to perform voltage sweeps Takes the following arguments: -ser: Serial port -start: Starting point of the voltage sweep (in volts) -stop: Ending point of the voltage sweep (in volts) -steps: Number of steps in the sweep -compliance: Current compliance (in amperes) -delay: Delay between points (in seconds) """ self.ser.write("smua.reset()\n".encode()) #Reset SMU self.ser.write("smua.nvbuffer2.clear()\n".encode()) self.ser.write("smua.nvbuffer2.collectsourcevalues = 1\n".encode()) self.ser.write("errorqueue.clear()\n".encode()) self.ser.write("display.screen = display.SMUA\n".encode()) self.ser.write("display.smua.measure.func = display.MEASURE_DCAMPS\n".encode()) self.ser.write("format.data = format.ASCII\n".encode()) self.ser.write("beeper.enable = beeper.OFF \n".encode()) #Turn off beeper self.ser.write("smua.sense = smua.SENSE_LOCAL \n".encode()) #Sense current (DC) self.ser.write("smua.trigger.measure.i(smua.nvbuffer2)\n".encode()) self.ser.write(("smua.source.limiti = "+str(self.compliance.get())+"\n").encode()) #Set compliance (A) self.ser.write(("smua.measure.nplc = "+str(self.NPLC.get())+"\n").encode()) self.ser.write(("smua.trigger.source.linearv("+str(self.start.get())+","+str(self.stop.get())+","+str(self.steps.get()+1)+")\n" ).encode()) #Set sweep start point (V), stop point (V) and steps self.ser.write("smua.trigger.endsweep.action = smua.SOURCE_IDLE\n".encode()) self.ser.write("smua.trigger.source.action = smua.ENABLE\n".encode()) #Change to sweep mode self.ser.write("smua.source.autorangev = smua.AUTORANGE_ON \n".encode()) #Set source range AUTO/BEST/FIXED self.ser.write(("smua.nvbuffer2.fillcount = "+str(self.steps.get()+1)+"\n").encode()) #Set amount of points to store in memory (steps + 1) self.ser.write(("smua.measure.delay = "+str(self.delay.get())+"\n").encode()) #Set delay self.ser.write(("smua.trigger.count = "+str(self.steps.get()+1)+"\n").encode()) def configCustomSweep(self): """Configure Keithley 2400 SMU to perform voltage sweeps Takes the following arguments: -ser: Serial port -start: Starting point of the voltage sweep (in volts) -stop: Ending point of the voltage sweep (in volts) -steps: Number of steps in the sweep -compliance: Current compliance (in amperes) -delay: Delay between points (in seconds) """ stepsize = (self.stop.get()-self.start.get())/self.steps.get() customSweepList = str(self.start.get()) for ii in range(1, self.steps.get() + 1, 1): if ii % 2 == 0: customSweepList = customSweepList + "," + str(self.start.get() + ii * stepsize) else: customSweepList = customSweepList + ",0" self.ser.write("smua.reset()\n".encode()) #Reset SMU self.ser.write("beeper.enable = beeper.OFF \n".encode()) #Turn off beeper self.ser.write(":smua.source.func = smua.OUTPUT_DCVOLTS\n".encode()) #Source Voltage self.ser.write("smua.sense = smua.SENSE_LOCAL \n".encode()) #Sense current (DC) self.ser.write(("smua.source.limiti = "+str(self.compliance.get())+"\n").encode()) #Set compliance (A) self.ser.write("smua.measure.nplc = 0.05\n".encode()) self.ser.write(":SOUR:VOLT:MODE LIST\n".encode()) #Sweep mode: list self.ser.write((":SOUR:LIST:VOLT "+customSweepList+"\n").encode()) #List of values self.ser.write(("defbuffer1.fillcount = "+str(self.steps.get())+"\n").encode()) #Set amount of points to store in memory (steps + 1) self.ser.write(("smua.measure.delay = "+str(self.delay.get())+"\n").encode()) #Set delay def runSweep(self): """Orders the SMU to perform the previously configured sweep. Only takes the serial port as argument. """ self.ser.write("smua.source.output = smua.OUTPUT_ON\n".encode()) self.ser.write("smua.trigger.measure.action = smua.ENABLE\n".encode()) self.ser.write("smua.trigger.initiate()\n".encode()) def recoverData(self, data): """Converts the binary data stream acquired from the SMU into a 2-column human-readable list containing voltage and current (as string lists) for ease of manipulation and its later conversion into csv files. """ datacsv=csv.reader(data.decode().split(',')) #Convert binary data into a csv structure containing strings, and split using the commas (,) as separators list=[] #Empty list that will temporarily keep the extracted data (it comes as series of 5 values V,I,?,?,?) results=[[],[]] #Empty list that will store the data as [[V1, V2..., Vn],[I1,I2,...,In]] for row in datacsv: list.append(row) #Extract data from the csv structure into list for ii in range(0, self.steps.get()+1): for jj in range(0,2): results[jj].append(list.pop(0).pop()) #Extract the first two values of each serias (V,I) into results return results def joinData(self, data1, data2): """Function that merges #Graph Variables self.XStart = tk.DoubleVar() self.XStart.set(0.0) self.XStop = tk.DoubleVar() self.XStop.set(0.5) self.YStop = tk.DoubleVar() self.YStop.set(0.005) self.YStart = tk.DoubleVar() self.YStart.set(-self.YStop.get())two differents sets of data so they can be exported into a single file """ for ii in range(0, len(data2)): data1.append(data2[ii]) #Append the second set of data to the former one return data1 def exportFile(self, dataToExport): with open(self.filenametext.get()+".txt", 'wt') as csvfile: writer = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_NONE) array = np.asarray(dataToExport).T.tolist() #print(array) for ii in range(0, self.steps.get()): writer.writerow(array[ii]) def loopSweeps(self): dataArray = [] for l in range(0,self.loops.get()): self.loopCount.set(l + 1) self.runSweep() self.ser.write(("x = printbuffer(1,"+str(self.steps.get()+1)+",smua.nvbuffer2.sourcevalues, smua.nvbuffer2.readings)\n").encode()) self.ser.write("waitcomplete(0)\n".encode()) output = self.recoverData(self.ser.readline()) self.plotCurve(output) self.loopComplete.set(self.loopComplete.get() + self.loopStep.get()) self.loopCompleteInt.set(int(self.loopComplete.get())) dataArray = self.joinData(dataArray, output) self.ser.write("smua.source.output = smua.OUTPUT_OFF\n".encode()) time.sleep(self.delayLoop.get()) if self.holdMode.get() == 0: self.a.hold(False) elif self.holdMode.get() == 1: self.a.hold(True) self.ser.write("smua.source.output = smua.OUTPUT_OFF\n".encode()) self.loopComplete.set(0) return dataArray def loopSweeps1(self): dataArray = [] for l in range(0,self.loops.get()): self.loopCount.set(l + 1) self.runSweep() self.ser.write(("x = printbuffer(1,"+str(self.steps.get()+1)+",smua.nvbuffer2.sourcevalues, smua.nvbuffer2.readings)\n").encode()) self.ser.write("waitcomplete(0)\n".encode()) output = self.recoverData(self.ser.readline()) self.loopComplete.set(self.loopComplete.get() + self.loopStep.get()) self.loopCompleteInt.set(int(self.loopComplete.get())) dataArray = self.joinData(dataArray, output) time.sleep(self.delayLoop.get()) if self.holdMode.get() == 0: self.a.hold(False) elif self.holdMode.get() == 1: self.a.hold(True) self.ser.write("smua.source.output = smua.OUTPUT_OFF\n".encode()) self.loopComplete.set(0) return dataArray def plotCurve(self, data): if self.modes.get() == 0: self.a.plot(data[0],data[1]) elif self.modes.get() == 1: self.a.scatter(data[0],data[1]) self.a.hold(True) self.a.grid(b=True, which='major', color='r', linestyle='--') self.a.axis([self.XStart.get(), self.XStop.get() , self.YStart.get() , self.YStop.get()]) self.figureCanvas.show() plt.pause(0.001) self.update() def MUXserial(self): #self.ser1.write("OFF".encode()) MUXAddress = self.mux.get() if MUXAddress == 0: self.ser1.write("C0B0A0".encode()) elif MUXAddress == 1: self.ser1.write("C0B0A1".encode()) elif MUXAddress == 2: self.ser1.write("C0B1A0".encode()) elif MUXAddress == 3: self.ser1.write("C0B1A1".encode()) elif MUXAddress == 4: self.ser1.write("C1B0A0".encode()) elif MUXAddress == 5: self.ser1.write("C1B0A1".encode()) elif MUXAddress == 6: self.ser1.write("C1B1A0".encode()) elif MUXAddress == 7: self.ser1.write("C1B1A1".encode()) #self.ser1.write("ON".encode()) def ARRAYsize(self): """Initialisation""" self.QUADCheck1.config(state=tk.NORMAL) self.QUADCheck2.config(state=tk.NORMAL) self.QUADCheck3.config(state=tk.NORMAL) self.QUADCheck4.config(state=tk.NORMAL) self.QUADCheck5.config(state=tk.NORMAL) self.QUADCheck6.config(state=tk.NORMAL) self.QUADCheck7.config(state=tk.NORMAL) self.QUADCheck8.config(state=tk.NORMAL) self.QUADCheck9.config(state=tk.NORMAL) self.QUADCheck10.config(state=tk.NORMAL) self.QUADCheck11.config(state=tk.NORMAL) self.QUADCheck12.config(state=tk.NORMAL) self.QUADCheck13.config(state=tk.NORMAL) self.QUADCheck14.config(state=tk.NORMAL) self.QUADCheck15.config(state=tk.NORMAL) self.QUADCheck16.config(state=tk.NORMAL) """Rows""" if self.arrayRow.get() < 4: self.quad4.set(False) self.QUADCheck4.config(state=tk.DISABLED) self.quad8.set(False) self.QUADCheck8.config(state=tk.DISABLED) self.quad12.set(False) self.QUADCheck12.config(state=tk.DISABLED) self.quad16.set(False) self.QUADCheck16.config(state=tk.DISABLED) if self.arrayRow.get() < 3: self.quad3.set(False) self.QUADCheck3.config(state=tk.DISABLED) self.quad7.set(False) self.QUADCheck7.config(state=tk.DISABLED) self.quad11.set(False) self.QUADCheck11.config(state=tk.DISABLED) self.quad15.set(False) self.QUADCheck15.config(state=tk.DISABLED) if self.arrayRow.get() < 2: self.quad2.set(False) self.QUADCheck2.config(state=tk.DISABLED) self.quad6.set(False) self.QUADCheck6.config(state=tk.DISABLED) self.quad10.set(False) self.QUADCheck10.config(state=tk.DISABLED) self.quad14.set(False) self.QUADCheck14.config(state=tk.DISABLED) if self.arrayRow.get() < 1: self.quad1.set(False) self.QUADCheck1.config(state=tk.DISABLED) self.quad5.set(False) self.QUADCheck5.config(state=tk.DISABLED) self.quad9.set(False) self.QUADCheck9.config(state=tk.DISABLED) self.quad13.set(False) self.QUADCheck13.config(state=tk.DISABLED) """Columns""" if self.arrayColumn.get() < 4: self.quad13.set(False) self.QUADCheck13.config(state=tk.DISABLED) self.quad14.set(False) self.QUADCheck14.config(state=tk.DISABLED) self.quad15.set(False) self.QUADCheck15.config(state=tk.DISABLED) self.quad16.set(False) self.QUADCheck16.config(state=tk.DISABLED) if self.arrayColumn.get() < 3: self.quad9.set(False) self.QUADCheck9.config(state=tk.DISABLED) self.quad10.set(False) self.QUADCheck10.config(state=tk.DISABLED) self.quad11.set(False) self.QUADCheck11.config(state=tk.DISABLED) self.quad12.set(False) self.QUADCheck12.config(state=tk.DISABLED) if self.arrayColumn.get() < 2: self.quad5.set(False) self.QUADCheck5.config(state=tk.DISABLED) self.quad6.set(False) self.QUADCheck6.config(state=tk.DISABLED) self.quad7.set(False) self.QUADCheck7.config(state=tk.DISABLED) self.quad8.set(False) self.QUADCheck8.config(state=tk.DISABLED) if self.arrayColumn.get() < 1: self.quad1.set(False) self.QUADCheck1.config(state=tk.DISABLED) self.quad2.set(False) self.QUADCheck2.config(state=tk.DISABLED) self.quad3.set(False) self.QUADCheck3.config(state=tk.DISABLED) self.quad4.set(False) self.QUADCheck4.config(state=tk.DISABLED) """Maximum Permutations""" self.deviceNumber.set(self.arrayRow.get() * self.arrayColumn.get()) self.switchKey.set(pow(self.arrayRow.get(),self.arrayColumn.get())) self.perStep.set(100/self.switchKey.get()) print(self.switchKey.get()) def QUADserialAuto(self,permutation): quadValue = "" colA = 0 colB = 0 colC = 0 colD = 0 columnA = "" columnB = "" columnC = "" columnD = "" if self.arrayColumn.get() > 3: colD = int(permutation / pow(self.arrayRow.get(),3)) permutation = permutation - (colD * pow(self.arrayRow.get(),3)) columnD = "D" + str(colD) if self.arrayColumn.get() > 2: colC = int(permutation / pow(self.arrayRow.get(),2)) permutation = permutation - (colC * pow(self.arrayRow.get(),2)) columnC = "C" + str(colC) if self.arrayColumn.get() > 1: colB = int(permutation / pow(self.arrayRow.get(),1)) permutation = permutation - (colB * pow(self.arrayRow.get(),1)) columnB = "B" + str(colB) if self.arrayColumn.get() > 0: colA = int(permutation / 1) columnA = "A" + str(colA) quadValue = columnA + columnB + columnC + columnD quadCode = 'Z' + quadValue print(quadValue) self.ser1.write(quadCode.encode()) def QUADserial(self): quadValue = "" self.quadState.set(0) if self.quad1.get(): quadValue = quadValue +"A0" if self.quad2.get(): quadValue = quadValue + "A1" if self.quad3.get(): quadValue = quadValue + "A2" if self.quad4.get(): quadValue = quadValue + "A3" if self.quad5.get(): quadValue = quadValue + "B0" if self.quad6.get(): quadValue = quadValue + "B1" if self.quad7.get(): quadValue = quadValue + "B2" if self.quad8.get(): quadValue = quadValue + "B3" if self.quad9.get(): quadValue = quadValue + "C0" if self.quad10.get(): quadValue = quadValue + "C1" if self.quad11.get(): quadValue = quadValue + "C2" if self.quad12.get(): quadValue = quadValue + "C3" if self.quad13.get(): quadValue = quadValue + "D0" if self.quad14.get(): quadValue = quadValue + "D1" if self.quad15.get(): quadValue = quadValue + "D2" if self.quad16.get(): quadValue = quadValue + "D3" quadCode = 'Z' + quadValue print(quadValue) self.ser1.write(quadCode.encode()) def go(self): self.loopStep.set(100/self.loops.get()) self.perStep.set(100/self.switchKey.get()) self.perComplete.set(0) self.configSweep() if self.holdMode.get() == 0: self.a.hold(False) elif self.holdMode.get() == 1: self.a.hold(True) if self.QUADmode.get() == 0: op=self.loopSweeps() self.exportFile(op) self.filenamenumber.set(1 + self.filenamenumber.get()) self.setfilename() elif self.QUADmode.get() == 1: for p in range(0, self.switchKey.get()): self.a.hold(False) print(p) self.QUADserialAuto(p) time.sleep(5) #Enough time for Bilateral switches to active in the correct order op=self.loopSweeps1() print("Sweep Complete") self.perComplete.set(self.perComplete.get() + self.perStep.get()) self.perCompleteInt.set(int(self.perComplete.get())) self.filenamenumber.set(p) self.setfilename() self.exportFile(op) plt.ion() app = Application() app.master.title('Keithley 2400 Sweeper') app.mainloop()
Report a bug