diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0d20b64 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/apps/AppGlobalSettings.pyc b/apps/AppGlobalSettings.pyc deleted file mode 100644 index 5e69e42..0000000 Binary files a/apps/AppGlobalSettings.pyc and /dev/null differ diff --git a/apps/Preferences.pyc b/apps/Preferences.pyc deleted file mode 100644 index bcbe9e2..0000000 Binary files a/apps/Preferences.pyc and /dev/null differ diff --git a/apps/app_menubar.pyc b/apps/app_menubar.pyc deleted file mode 100644 index d703bf4..0000000 Binary files a/apps/app_menubar.pyc and /dev/null differ diff --git a/apps/app_toolbar.pyc b/apps/app_toolbar.pyc deleted file mode 100644 index 9015cf4..0000000 Binary files a/apps/app_toolbar.pyc and /dev/null differ diff --git a/apps/menubar.pyc b/apps/menubar.pyc deleted file mode 100644 index b0ef33c..0000000 Binary files a/apps/menubar.pyc and /dev/null differ diff --git a/apps/toolbar.pyc b/apps/toolbar.pyc deleted file mode 100644 index 8c3128f..0000000 Binary files a/apps/toolbar.pyc and /dev/null differ diff --git a/apps/widgets/XWidget.pyc b/apps/widgets/XWidget.pyc deleted file mode 100644 index c525fcc..0000000 Binary files a/apps/widgets/XWidget.pyc and /dev/null differ diff --git a/lib/Plot2D.pyc b/lib/Plot2D.pyc deleted file mode 100644 index af051f4..0000000 Binary files a/lib/Plot2D.pyc and /dev/null differ diff --git a/lib/XDict.pyc b/lib/XDict.pyc deleted file mode 100644 index e544258..0000000 Binary files a/lib/XDict.pyc and /dev/null differ diff --git a/lib/XMethod.pyc b/lib/XMethod.pyc deleted file mode 100644 index d5cc7ab..0000000 Binary files a/lib/XMethod.pyc and /dev/null differ diff --git a/lib/XThread.pyc b/lib/XThread.pyc deleted file mode 100644 index 47f84c3..0000000 Binary files a/lib/XThread.pyc and /dev/null differ diff --git a/lib/tkValidatingEntry.pyc b/lib/tkValidatingEntry.pyc deleted file mode 100644 index 27193e7..0000000 Binary files a/lib/tkValidatingEntry.pyc and /dev/null differ diff --git a/modules/Cryostat/Cryostat.pyc b/modules/Cryostat/Cryostat.pyc deleted file mode 100644 index 2bc4269..0000000 Binary files a/modules/Cryostat/Cryostat.pyc and /dev/null differ diff --git a/modules/Cryostat/Cryostat_Constants.pyc b/modules/Cryostat/Cryostat_Constants.pyc deleted file mode 100644 index 16e9b86..0000000 Binary files a/modules/Cryostat/Cryostat_Constants.pyc and /dev/null differ diff --git a/modules/Cryostat/Cryostat_Method.pyc b/modules/Cryostat/Cryostat_Method.pyc deleted file mode 100644 index c0c52ba..0000000 Binary files a/modules/Cryostat/Cryostat_Method.pyc and /dev/null differ diff --git a/modules/Cryostat/Cryostat_UI.pyc b/modules/Cryostat/Cryostat_UI.pyc deleted file mode 100644 index 615bd04..0000000 Binary files a/modules/Cryostat/Cryostat_UI.pyc and /dev/null differ diff --git a/modules/app_modules.pyc b/modules/app_modules.pyc deleted file mode 100644 index 12f2b94..0000000 Binary files a/modules/app_modules.pyc and /dev/null differ diff --git a/modules/mgps/MGPS_Banner.pyc b/modules/mgps/MGPS_Banner.pyc deleted file mode 100644 index 9b0d977..0000000 Binary files a/modules/mgps/MGPS_Banner.pyc and /dev/null differ diff --git a/modules/mgps/MGPS_Constants.pyc b/modules/mgps/MGPS_Constants.pyc deleted file mode 100644 index 96949da..0000000 Binary files a/modules/mgps/MGPS_Constants.pyc and /dev/null differ diff --git a/modules/mgps/MGPS_DataType.pyc b/modules/mgps/MGPS_DataType.pyc deleted file mode 100644 index 56cd27b..0000000 Binary files a/modules/mgps/MGPS_DataType.pyc and /dev/null differ diff --git a/modules/mgps/MGPS_Method.pyc b/modules/mgps/MGPS_Method.pyc deleted file mode 100644 index 726e703..0000000 Binary files a/modules/mgps/MGPS_Method.pyc and /dev/null differ diff --git a/modules/mgps/app_mgps.pyc b/modules/mgps/app_mgps.pyc deleted file mode 100644 index fed89e2..0000000 Binary files a/modules/mgps/app_mgps.pyc and /dev/null differ diff --git a/modules/mgps/mgps.pyc b/modules/mgps/mgps.pyc deleted file mode 100644 index 6bed3d7..0000000 Binary files a/modules/mgps/mgps.pyc and /dev/null differ diff --git a/modules/modules.pyc b/modules/modules.pyc deleted file mode 100644 index d11dbc5..0000000 Binary files a/modules/modules.pyc and /dev/null differ diff --git a/modules/modules_constants.pyc b/modules/modules_constants.pyc deleted file mode 100644 index 90c247d..0000000 Binary files a/modules/modules_constants.pyc and /dev/null differ diff --git a/modules/xhires/XHIRES_Banner.pyc b/modules/xhires/XHIRES_Banner.pyc deleted file mode 100644 index 04c87b2..0000000 Binary files a/modules/xhires/XHIRES_Banner.pyc and /dev/null differ diff --git a/modules/xhires/XHIRES_Constants.pyc b/modules/xhires/XHIRES_Constants.pyc deleted file mode 100644 index 28ead71..0000000 Binary files a/modules/xhires/XHIRES_Constants.pyc and /dev/null differ diff --git a/modules/xhires/XHIRES_DataType.pyc b/modules/xhires/XHIRES_DataType.pyc deleted file mode 100644 index fe95b0c..0000000 Binary files a/modules/xhires/XHIRES_DataType.pyc and /dev/null differ diff --git a/modules/xhires/XHIRES_Method.pyc b/modules/xhires/XHIRES_Method.pyc deleted file mode 100644 index d93b426..0000000 Binary files a/modules/xhires/XHIRES_Method.pyc and /dev/null differ diff --git a/modules/xhires/app_xhires.pyc b/modules/xhires/app_xhires.pyc deleted file mode 100644 index a4c1b88..0000000 Binary files a/modules/xhires/app_xhires.pyc and /dev/null differ diff --git a/modules/xhires/xhires.pyc b/modules/xhires/xhires.pyc deleted file mode 100644 index 5bcf788..0000000 Binary files a/modules/xhires/xhires.pyc and /dev/null differ diff --git a/modules/xlia/XLIA_Banner.pyc b/modules/xlia/XLIA_Banner.pyc deleted file mode 100644 index 0ce3480..0000000 Binary files a/modules/xlia/XLIA_Banner.pyc and /dev/null differ diff --git a/modules/xlia/XLIA_Constants.pyc b/modules/xlia/XLIA_Constants.pyc deleted file mode 100644 index 222b9a4..0000000 Binary files a/modules/xlia/XLIA_Constants.pyc and /dev/null differ diff --git a/modules/xlia/XLIA_DataType.pyc b/modules/xlia/XLIA_DataType.pyc deleted file mode 100644 index a0c0da6..0000000 Binary files a/modules/xlia/XLIA_DataType.pyc and /dev/null differ diff --git a/modules/xlia/XLIA_Method.pyc b/modules/xlia/XLIA_Method.pyc deleted file mode 100644 index f0c5ff3..0000000 Binary files a/modules/xlia/XLIA_Method.pyc and /dev/null differ diff --git a/modules/xlia/app_xlia.pyc b/modules/xlia/app_xlia.pyc deleted file mode 100644 index 02db95a..0000000 Binary files a/modules/xlia/app_xlia.pyc and /dev/null differ diff --git a/modules/xlia/xlia.pyc b/modules/xlia/xlia.pyc deleted file mode 100644 index 93fd083..0000000 Binary files a/modules/xlia/xlia.pyc and /dev/null differ diff --git a/modules/xmc/XMC.pyc b/modules/xmc/XMC.pyc deleted file mode 100644 index 4fb4a31..0000000 Binary files a/modules/xmc/XMC.pyc and /dev/null differ diff --git a/modules/xmc/XMC_Banner.pyc b/modules/xmc/XMC_Banner.pyc deleted file mode 100644 index fd350cf..0000000 Binary files a/modules/xmc/XMC_Banner.pyc and /dev/null differ diff --git a/modules/xmc/XMC_Constants.pyc b/modules/xmc/XMC_Constants.pyc deleted file mode 100644 index ef9a3dc..0000000 Binary files a/modules/xmc/XMC_Constants.pyc and /dev/null differ diff --git a/modules/xmc/XMC_DataType.pyc b/modules/xmc/XMC_DataType.pyc deleted file mode 100644 index 3cbad41..0000000 Binary files a/modules/xmc/XMC_DataType.pyc and /dev/null differ diff --git a/modules/xmc/appXMC.pyc b/modules/xmc/appXMC.pyc deleted file mode 100644 index d8ef110..0000000 Binary files a/modules/xmc/appXMC.pyc and /dev/null differ diff --git a/modules/xsmu/XSMU_Banner.pyc b/modules/xsmu/XSMU_Banner.pyc deleted file mode 100644 index f00583a..0000000 Binary files a/modules/xsmu/XSMU_Banner.pyc and /dev/null differ diff --git a/modules/xsmu/XSMU_Constants.py b/modules/xsmu/XSMU_Constants.py index 6caf3cf..82faab8 100644 --- a/modules/xsmu/XSMU_Constants.py +++ b/modules/xsmu/XSMU_Constants.py @@ -17,6 +17,7 @@ RUN_MODE_VTime = C = C + 1 RUN_MODE_IV = C = C + 1 RUN_MODE_RTime = C = C + 1 +RUN_MODE_IV_TIME_RESOLVED = C = C + 1 START_RUN = C = C + 1 FINISH_RUN = C = C + 1 @@ -31,6 +32,7 @@ METER_SETTINGS_DIALOG = C = C + 1 ACQUISITION_SETTINGS_DIALOG = C = C + 1 IV_RAMP_SETTINGS_DIALOG = C = C + 1 +IV_TIME_RESOLVED_RAMP_SETTINGS_DIALOG = C = C + 1 OHMMETER_SETTINGS_DIALOG = C = C + 1 APPLY = C = C + 1 diff --git a/modules/xsmu/XSMU_Constants.pyc b/modules/xsmu/XSMU_Constants.pyc deleted file mode 100644 index bdfeb9d..0000000 Binary files a/modules/xsmu/XSMU_Constants.pyc and /dev/null differ diff --git a/modules/xsmu/XSMU_DataType.pyc b/modules/xsmu/XSMU_DataType.pyc deleted file mode 100644 index 085fad7..0000000 Binary files a/modules/xsmu/XSMU_DataType.pyc and /dev/null differ diff --git a/modules/xsmu/XSMU_Method.py b/modules/xsmu/XSMU_Method.py index 7c63b05..a10d7e8 100644 --- a/modules/xsmu/XSMU_Method.py +++ b/modules/xsmu/XSMU_Method.py @@ -71,6 +71,21 @@ def set_IV_RampSettings (self, finalCurrent, finalVoltage, maxPower, } # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + def set_IV_TimeResolvedRampSettings (self, finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode): + + self['IV_RampSettings'] = { + 'finalCurrent' : finalCurrent, + 'finalVoltage' : finalVoltage, + 'maxPower' : maxPower, + 'currentStep' : currentStep, + 'voltageStep' : voltageStep, + 'bipolar' : bipolar, + 'resTrackMode' : resTrackMode + } + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ def setOhmmeterSettings (self, maxCurrent, maxVoltage, maxPower, bipolar, resTrackMode): @@ -172,6 +187,33 @@ def get_IV_RampSettings (self, currentStep, voltageStep, bipolar, resTrackMode) # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + def get_IV_TimeResolvedRampSettings (self, + finalCurrent = None, + finalVoltage = None, + maxPower = None, + currentStep = None, + voltageStep = None, + bipolar = None, + resTrackMode = None): + + try: + settings = self['IV_RampSettings'] + finalCurrent = settings.get ('finalCurrent' , finalCurrent) + finalVoltage = settings.get ('finalVoltage' , finalVoltage) + maxPower = settings.get ('maxPower' , maxPower ) + currentStep = settings.get ('currentStep' , currentStep ) + voltageStep = settings.get ('voltageStep' , voltageStep ) + bipolar = settings.get ('bipolar' , bipolar ) + resTrackMode = settings.get ('resTrackMode' , resTrackMode) + + except KeyError : pass + + return ( + finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode) + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ def getOhmmeterSettings (self, maxCurrent = None, diff --git a/modules/xsmu/XSMU_Method.pyc b/modules/xsmu/XSMU_Method.pyc deleted file mode 100644 index c15ea9b..0000000 Binary files a/modules/xsmu/XSMU_Method.pyc and /dev/null differ diff --git a/modules/xsmu/app_xsmu.py b/modules/xsmu/app_xsmu.py index bd49f1c..71fc75a 100644 --- a/modules/xsmu/app_xsmu.py +++ b/modules/xsmu/app_xsmu.py @@ -15,10 +15,11 @@ class GUI: run_modes = { - RUN_MODE_ITime : 'I-Time', - RUN_MODE_VTime : 'V-Time', - RUN_MODE_IV : 'I-V', - RUN_MODE_RTime : 'R-Time' + RUN_MODE_ITime : 'I-Time', + RUN_MODE_VTime : 'V-Time', + RUN_MODE_IV : 'I-V', + RUN_MODE_IV_TIME_RESOLVED : 'I-V Time Resolved', + RUN_MODE_RTime : 'R-Time' } methodFileTypes = [ @@ -111,6 +112,10 @@ def populateMenu (self, master): self.utilmenu.add_command ( label = 'I-V measurement settings', command = self.wIVRampSettingsCB) + + self.utilmenu.add_command ( + label = 'I-V Time Resolved measurement settings', + command = self.wIVTimeResolvedRampSettingsCB) self.utilmenu.add_command ( label = 'Resistance measurement settings', @@ -170,6 +175,9 @@ def populateDisplayPanel (self, master): self.wIVRampSettings = \ GUI_IVRampSettingsDisplay (master = Frame (master)) + + self.wIVTimeResolvedRampSettings = \ + GUI_IVTimeResolvedRampSettingsDisplay (master = Frame (master)) self.grid_OhmmeterSettings = (row, col) @@ -412,6 +420,9 @@ def getRunMode (self): def wIVRampSettingsCB (self, *args): self.do_callback (OPEN_DIALOG, IV_RAMP_SETTINGS_DIALOG) + + def wIVTimeResolvedRampSettingsCB (self, *args): + self.do_callback (OPEN_DIALOG, IV_TIME_RESOLVED_RAMP_SETTINGS_DIALOG) def wOhmmeterSettingsCB (self, *args): self.do_callback (OPEN_DIALOG, OHMMETER_SETTINGS_DIALOG) @@ -533,15 +544,18 @@ def setRunMode (self, run_mode): self.run_mode.set (self.run_modes.get (run_mode)) - for w in (self.wIVRampSettings, self.wOhmmeterSettings): + for w in (self.wIVRampSettings, self.wIVTimeResolvedRampSettings, self.wOhmmeterSettings): w.master.grid_forget() options = { - RUN_MODE_IV : ( + RUN_MODE_IV : ( + self.grid_IVRampSettings, self.wIVRampSettings), + + RUN_MODE_IV_TIME_RESOLVED : ( self.grid_IVRampSettings, self.wIVRampSettings), - RUN_MODE_RTime : ( + RUN_MODE_RTime : ( self.grid_OhmmeterSettings, self.wOhmmeterSettings) } @@ -745,6 +759,14 @@ def setIVRampSettings ( self.wIVRampSettings.set ( finalCurrent, finalVoltage, maxPower, currentStep, voltageStep, bipolar, resTrackMode) + + def setIVTimeResolvedRampSettings ( + self, finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode): + + self.wIVTimeResolvedRampSettings.set ( + finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode) def setOhmmeterSettings ( self, maxCurrent, maxVoltage, @@ -2030,6 +2052,495 @@ def blank_parameters (self): # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +class GUI_IVTimeResolvedRampSettings: + + bipolarMenuItems = { + True : 'Yes', + False : 'No' + } + + resTrackMenuItems = { + R_TRACK_V_I : u'V/I', + R_TRACK_dV_dI : u'ΔV/ΔI' + } + + def __init__ ( + self, master, finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode): + + self.master = master + self.master.title ('I-V Time Resolved ramp settings') + self.createWidgets (master) + self.set (finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode) + + def callback (self, cb): + self._callback = cb + + def do_callback (self, context, *args): + if hasattr (self, '_callback'): + self._callback (context, *args) + + def createWidgets (self, master): + + self.mainmenu = Menu (self.master) + self.mainmenu.config (borderwidth = 1) + self.master.config (menu = self.mainmenu) + + self.filemenu = Menu (self.mainmenu) + self.filemenu.config (tearoff = 0) + self.mainmenu.add_cascade ( + label = 'File', menu = self.filemenu, underline = 0) + + self.filemenu.add_command (label = 'Done', command = self.wApplyCB) + self.filemenu.add_command (label = 'Cancel', command = self.wCancelCB) + + # +++++++++++++++++++++++++++++++ + + master.grid_columnconfigure (0, weight = 1) + + # +++++++++++++++++++++++++++++++ + + row = 0; col = 0 + w = LabelFrame (master, text = 'Limits') + w.grid (row = row, column = col, + sticky = NSEW, padx = 5, pady = 5) + + self.populateLimits (w) + + # +++++++++++++++++++++++++++++++ + + row += 1 + w = LabelFrame (master, text = 'Step size') + w.grid (row = row, column = col, + sticky = NSEW, padx = 5, pady = 5) + + self.populateStepSize (w) + + # +++++++++++++++++++++++++++++++ + + row += 1 + w = LabelFrame (master, text = 'Options') + w.grid (row = row, column = col, + sticky = NSEW, padx = 5, pady = 5) + + self.populateOptions (w) + + # +++++++++++++++++++++++++++++++ + + def populateLimits (self, master): + master.grid_columnconfigure (0, weight = 1) + master.grid_columnconfigure (1, weight = 1) + + col_widths = [20, 10] + + # +++++++++++++++++++++++++++++++ + + row = 0; col = 0 + w = Label (master, text = 'Current (μA)', + width = col_widths[col], anchor = W) + + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + + col += 1 + w = self.wFinalCurrent = \ + XFloatEntry (master, width = col_widths[col]) + + w.enable_color (False) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + # +++++++++++++++++++++++++++++++ + + row += 1; col = 0 + w = Label (master, text = 'Voltage (mV)', + width = col_widths[col], anchor = W) + + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + + col += 1 + w = self.wFinalVoltage = \ + XFloatEntry (master, width = col_widths[col]) + + w.enable_color (False) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + # +++++++++++++++++++++++++++++++ + + row += 1; col = 0 + w = Label (master, text = 'Power (mW)', + width = col_widths[col], anchor = W) + + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + + col += 1 + w = self.wMaxPower = \ + XFloatEntry (master, width = col_widths[col]) + + w.enable_color (False) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + # +++++++++++++++++++++++++++++++ + + row += 1; col = 0 + w = Label (master, text = 'Whichever happens first', + width = col_widths[col], anchor = E) + + w.grid (row = row, column = col, columnspan = 2, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + + def populateStepSize (self, master): + master.grid_columnconfigure (0, weight = 1) + master.grid_columnconfigure (1, weight = 1) + + col_widths = [20, 10] + + # +++++++++++++++++++++++++++++++ + + row = 0; col = 0 + w = Label (master, text = 'Current (μA)', + width = col_widths[col], anchor = W) + + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + + col += 1 + w = self.wCurrentStep = \ + XFloatEntry (master, width = col_widths[col]) + + w.enable_color (False) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + # +++++++++++++++++++++++++++++++ + + row += 1; col = 0 + w = Label (master, text = 'Voltage (mV)', + width = col_widths[col], anchor = W) + + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + + col += 1 + w = self.wVoltageStep = \ + XFloatEntry (master, width = col_widths[col]) + + w.enable_color (False) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + # +++++++++++++++++++++++++++++++ + + def populateOptions (self, master): + master.grid_columnconfigure (0, weight = 1, minsize = 20) + master.grid_columnconfigure (1, weight = 1, minsize = 10) + + # +++++++++++++++++++++++++++++++ + + row = 0; col = 0 + w = Label (master, text = 'Bipolar', anchor = W) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + + col += 1 + var = self.bipolar = StringVar() + options = self.bipolarMenuItems.values() + w = self.wBipolarOptions = OptionMenu (master, var, *options) + w.config (anchor = W) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + # +++++++++++++++++++++++++++++++ + + #row += 1; col = 0 + w = Label (master, text = 'Tracking mode', anchor = W) + #w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + + #col += 1 + options = self.resTrackMenuItems.values() + var = self.resTrackMode = StringVar() + w = self.wResTrackOptions = OptionMenu (master, var, *options) + w.config (anchor = W) + #w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + # +++++++++++++++++++++++++++++++ + + def wApplyCB (self): + + bipolarModes = {v : k for (k, v) in self.bipolarMenuItems.items()} + resTrackModes = {v : k for (k, v) in self.resTrackMenuItems.items()} + + self.do_callback (APPLY, + uA_to_A * self.wFinalCurrent.get(), + mV_to_V * self.wFinalVoltage.get(), + mW_to_W * self.wMaxPower.get(), + uA_to_A * self.wCurrentStep.get(), + mV_to_V * self.wVoltageStep.get(), + bipolarModes.get (self.bipolar.get()), + resTrackModes.get (self.resTrackMode.get())) + + def wCancelCB (self): + self.do_callback (CANCEL) + + # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + def set (self, finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode): + + self.wFinalCurrent.set (A_to_uA * finalCurrent) + self.wFinalVoltage.set (V_to_mV * finalVoltage) + self.wMaxPower.set (W_to_mW * maxPower) + self.wCurrentStep.set (A_to_uA * currentStep) + self.wVoltageStep.set (V_to_mV * voltageStep) + self.bipolar.set (self.bipolarMenuItems.get (bipolar)) + self.resTrackMode.set (self.resTrackMenuItems.get (resTrackMode)) + + # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +class GUI_IVTimeResolvedRampSettingsDisplay: + + bipolarMenuItems = { + True : 'Yes', + False : 'No' + } + + resTrackMenuItems = { + R_TRACK_V_I : u'V/I', + R_TRACK_dV_dI : u'ΔV/ΔI' + } + + instances = [] + + def __init__ (self, master): + self.master = master + self.createWidgets (master) + self.synchronize() + + def close (self): + self.instances.remove (self) + + def createWidgets (self, master): + + master.grid_columnconfigure (0, weight = 1) + + # +++++++++++++++++++++++++++++++ + + row = 0; col = 0 + w = LabelFrame (master, text = 'Limits') + w.grid (row = row, column = col, + sticky = NSEW, padx = 5, pady = 5) + + self.populateLimits (w) + + # +++++++++++++++++++++++++++++++ + + row += 1 + w = LabelFrame (master, text = 'Step size') + w.grid (row = row, column = col, + sticky = NSEW, padx = 5, pady = 5) + + self.populateStepSize (w) + + # +++++++++++++++++++++++++++++++ + + row += 1 + w = LabelFrame (master, text = 'Options') + w.grid (row = row, column = col, + sticky = NSEW, padx = 5, pady = 5) + + self.populateOptions (w) + + # +++++++++++++++++++++++++++++++ + + def populateLimits (self, master): + master.grid_columnconfigure (0, weight = 1, minsize = 20) + master.grid_columnconfigure (1, weight = 1, minsize = 10) + + # +++++++++++++++++++++++++++++++ + + row = 0; col = 0 + w = Label (master, text = 'Current (μA)', anchor = W) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + + col += 1 + w = self.wFinalCurrent = Label (master, anchor = E) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + # +++++++++++++++++++++++++++++++ + + row += 1; col = 0 + w = Label (master, text = 'Voltage (mV)', anchor = W) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + + col += 1 + w = self.wFinalVoltage = Label (master, anchor = E) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + # +++++++++++++++++++++++++++++++ + + row += 1; col = 0 + w = Label (master, text = 'Power (mW)', anchor = W) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + + col += 1 + w = self.wMaxPower = Label (master, anchor = E) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + # +++++++++++++++++++++++++++++++ + + row += 1; col = 0 + w = Label (master, text = 'Whichever happens first', anchor = E) + w.grid (row = row, column = col, columnspan = 2, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + + def populateStepSize (self, master): + master.grid_columnconfigure (0, weight = 1) + master.grid_columnconfigure (1, weight = 1) + + col_widths = [20, 10] + + # +++++++++++++++++++++++++++++++ + + row = 0; col = 0 + w = Label (master, text = 'Current (μA)', anchor = W) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + + col += 1 + w = self.wCurrentStep = Label (master, anchor = E) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + # +++++++++++++++++++++++++++++++ + + row += 1; col = 0 + w = Label (master, text = 'Voltage (mV)', anchor = W) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + + col += 1 + w = self.wVoltageStep = Label (master, anchor = E) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + # +++++++++++++++++++++++++++++++ + + def populateOptions (self, master): + + master.grid_columnconfigure (0, weight = 1, minsize = 200) + master.grid_columnconfigure (1, weight = 1, minsize = 100) + + # +++++++++++++++++++++++++++++++ + # +++++++++++++++++++++++++++++++ + + row = 0; col = 0 + w = Label (master, text = 'Bipolar', anchor = W) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + + col += 1 + w = self.wBipolar = Label (master, anchor = E) + w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + # +++++++++++++++++++++++++++++++ + + # row += 1; col = 0 + w = Label (master, text = 'R track mode', anchor = W) + # w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + + # col += 1 + w = self.wResTrackMode = Label (master, anchor = E) + # w.grid (row = row, column = col, sticky = NSEW) + + # +++++++++++++++++++++++++++++++ + # +++++++++++++++++++++++++++++++ + + def synchronize (self): + + if len (self.instances) == 0: + self._blank_parameters() + + else: + first = self.instances[0] + self.wFinalCurrent ['text'] = first.wFinalCurrent ['text'] + self.wFinalVoltage ['text'] = first.wFinalVoltage ['text'] + self.wMaxPower ['text'] = first.wMaxPower ['text'] + self.wCurrentStep ['text'] = first.wCurrentStep ['text'] + self.wVoltageStep ['text'] = first.wVoltageStep ['text'] + self.wBipolar ['text'] = first.wBipolar ['text'] + self.wResTrackMode ['text'] = first.wResTrackMode ['text'] + + self.instances.append (self) + + # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + def _set (self, finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode): + + self.wFinalCurrent ['text'] = str (A_to_uA * finalCurrent) + self.wFinalVoltage ['text'] = str (V_to_mV * finalVoltage) + self.wMaxPower ['text'] = str (W_to_mW * maxPower) + self.wCurrentStep ['text'] = str (A_to_uA * currentStep) + self.wVoltageStep ['text'] = str (V_to_mV * voltageStep) + self.wBipolar ['text'] = self.bipolarMenuItems.get (bipolar) + self.wResTrackMode ['text'] = self.resTrackMenuItems.get (resTrackMode) + + def set (self, finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode): + + for instance in self.instances: + instance._set (finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode) + + # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + def _blank_parameters (self): + self.wFinalCurrent ['text'] = '...' + self.wFinalVoltage ['text'] = '...' + self.wMaxPower ['text'] = '...' + self.wCurrentStep ['text'] = '...' + self.wVoltageStep ['text'] = '...' + self.wBipolar ['text'] = '...' + self.wResTrackMode ['text'] = '...' + + def blank_parameters (self): + for instance in self.instances: + instance._blank_parameters() + +# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + class GUI_OhmmeterSettings: bipolarMenuItems = { diff --git a/modules/xsmu/app_xsmu.pyc b/modules/xsmu/app_xsmu.pyc deleted file mode 100644 index b82bfaa..0000000 Binary files a/modules/xsmu/app_xsmu.pyc and /dev/null differ diff --git a/modules/xsmu/xsmu.py b/modules/xsmu/xsmu.py index da94de6..834e427 100644 --- a/modules/xsmu/xsmu.py +++ b/modules/xsmu/xsmu.py @@ -1,11 +1,13 @@ # coding: utf-8 import libxsmu +import time from app_xsmu import GUI from app_xsmu import GUI_SourceParameters from app_xsmu import GUI_MeterParameters from app_xsmu import GUI_AcquisitionSettings from app_xsmu import GUI_IVRampSettings +from app_xsmu import GUI_IVTimeResolvedRampSettings from app_xsmu import GUI_OhmmeterSettings from XSMU_DataType import DataPoint, DataSet @@ -23,6 +25,7 @@ from math import copysign, sqrt from XSMU_Constants import * +INDEX = 0 def Driver(): @@ -167,7 +170,7 @@ def _CS_setCurrent (self, value): self.check_timeout (timeout, 'Set current') self.cs_value = value - return value + return set_value def _VS_setVoltage (self, value): @@ -178,7 +181,7 @@ def _VS_setVoltage (self, value): self.check_timeout (timeout, 'Set voltage') self.vs_value = value - return value + return set_value def _CM_setRange (self, range): @@ -443,13 +446,16 @@ def CM_setRange (self, autorange, range): # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ def CM_getReading (self, filterLength = 128): - + + self.check_connected() - + + if self.src_mode != SOURCE_MODE_CS and self.cm_autorange: range = self._CM_doAutoRange() self.do_callback (CM_RANGE_CHANGED, self.cm_autorange, range) - + + timeout = COMM_TIMEOUT_INTERVAL if (libxsmu.firmware_version (self.deviceID) @@ -459,11 +465,13 @@ def CM_getReading (self, filterLength = 128): else: timeout += filterLength * 0.01 - + + (current, timeout) = \ libxsmu.CM_getReading (self.deviceID, filterLength, timeout) - + self.check_timeout (timeout, 'Get ammeter reading') + return current # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -678,6 +686,18 @@ def setIVRampSettings ( self.oXSMU.ivRampSettings.set ( finalCurrent, finalVoltage, maxPower, currentStep, voltageStep, bipolar, resTrackMode) + + def setIVTimeResolvedRampSettings ( + self, finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode): + + self.oXSMU.oApp.setIVTimeResolvedRampSettings ( + finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode) + + self.oXSMU.ivTimeResolvedRampSettings.set ( + finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode) # +++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -1091,6 +1111,35 @@ def get (self): self.bipolar, self.resTrackMode) +class IVTimeResolvedRampSettings: + + def __init__ (self, finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode): + + self.set (finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode) + + def set (self, finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode): + + self.finalCurrent = finalCurrent + self.finalVoltage = finalVoltage + self.maxPower = maxPower + self.currentStep = currentStep + self.voltageStep = voltageStep + self.bipolar = bipolar + self.resTrackMode = resTrackMode + + def get (self): + return ( + self.finalCurrent, + self.finalVoltage, + self.maxPower, + self.currentStep, + self.voltageStep, + self.bipolar, + self.resTrackMode) + # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ class OhmmeterSettings: @@ -1159,6 +1208,15 @@ def __init__ (self, oApp, sample): voltageStep = 1.0, bipolar = True, resTrackMode = R_TRACK_dV_dI) + + self.ivTimeResolvedRampSettings = IVTimeResolvedRampSettings ( + finalCurrent = 10e-3, + finalVoltage = 10.0, + maxPower = 100e-3, + currentStep = 1e-3, + voltageStep = 1.0, + bipolar = True, + resTrackMode = R_TRACK_V_I) self.ohmmeterSettings = OhmmeterSettings ( maxCurrent = 10e-3, @@ -1203,6 +1261,16 @@ def __init__ (self, oApp, sample): self.ivRampSettings.voltageStep, self.ivRampSettings.bipolar, self.ivRampSettings.resTrackMode) + + oApplet.schedule_task ( + oApplet.setIVTimeResolvedRampSettings, + self.ivTimeResolvedRampSettings.finalCurrent, + self.ivTimeResolvedRampSettings.finalVoltage, + self.ivTimeResolvedRampSettings.maxPower, + self.ivTimeResolvedRampSettings.currentStep, + self.ivTimeResolvedRampSettings.voltageStep, + self.ivTimeResolvedRampSettings.bipolar, + self.ivTimeResolvedRampSettings.resTrackMode) oApplet.schedule_task ( oApplet.setOhmmeterSettings, @@ -1334,7 +1402,7 @@ def oAppCB (self, context, *args): else: raise ValueError (context) - # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # ++++++++++++++++++++++++++++++++++++++++'NoneType+++++++++++++++++++ def startRun (self, mode): @@ -1389,6 +1457,21 @@ def prepareModule (self, master, mode): self.ivRampSettings.voltageStep, self.ivRampSettings.bipolar, self.ivRampSettings.resTrackMode) + + elif mode == RUN_MODE_IV_TIME_RESOLVED: + module = _IVTimeResolvedModule (master, self) + module.initAcquisitionSettings ( + self.acquisitionSettings.delay, + self.acquisitionSettings.filterLength) + + module.initIVTimeResolvedRampSettings ( + self.ivTimeResolvedRampSettings.finalCurrent, + self.ivTimeResolvedRampSettings.finalVoltage, + self.ivTimeResolvedRampSettings.maxPower, + self.ivTimeResolvedRampSettings.currentStep, + self.ivTimeResolvedRampSettings.voltageStep, + self.ivTimeResolvedRampSettings.bipolar, + self.ivTimeResolvedRampSettings.resTrackMode) elif mode == RUN_MODE_RTime: module = _RTimeModule (master, self) @@ -1440,6 +1523,9 @@ def prepareAcquisition (self, mode): elif mode == RUN_MODE_IV: thread = _IVAcquisitionThread (module) + + elif mode == RUN_MODE_IV_TIME_RESOLVED: + thread = _IVTimeResolvedAcquisitionThread (module) elif mode == RUN_MODE_RTime: thread = _RTimeAcquisitionThread (module) @@ -1485,6 +1571,9 @@ def openDialog (self, dialog): elif dialog == IV_RAMP_SETTINGS_DIALOG: self.openIVRampDialog() + + elif dialog == IV_TIME_RESOLVED_RAMP_SETTINGS_DIALOG: + self.openIVTimeResolvedRampDialog() elif dialog == OHMMETER_SETTINGS_DIALOG: self.openOhmmeterDialog() @@ -1651,6 +1740,28 @@ def openIVRampDialog (self): w.master.grab_set() w.master.wm_attributes("-topmost", 1) w.master.transient (parent) + + def openIVTimeResolvedRampDialog (self): + + w = self.dialog = GUI_IVTimeResolvedRampSettings ( + Toplevel (takefocus = True), + self.ivTimeResolvedRampSettings.finalCurrent, + self.ivTimeResolvedRampSettings.finalVoltage, + self.ivTimeResolvedRampSettings.maxPower, + self.ivTimeResolvedRampSettings.currentStep, + self.ivTimeResolvedRampSettings.voltageStep, + self.ivTimeResolvedRampSettings.bipolar, + self.ivTimeResolvedRampSettings.resTrackMode) + + w.callback (self.ivTimeResolvedRampDialogCB) + + # Makes it modal + parent = self.oApp.master.focus_displayof().winfo_toplevel() + parent.lift() + w.master.focus_set() + w.master.grab_set() + w.master.wm_attributes("-topmost", 1) + w.master.transient (parent) def ivRampDialogCB (self, context, *args): @@ -1672,6 +1783,27 @@ def ivRampDialogCB (self, context, *args): self.dialog = None else: raise ValueError (context) + + def ivTimeResolvedRampDialogCB (self, context, *args): + + oApplet = self.oApplet + oModule = self.oModule + + if context == APPLY: + + oApplet.schedule_task (oApplet.setIVTimeResolvedRampSettings, *args) + + if oModule and isinstance (oModule, _IVModule): + oModule.schedule_task (oModule.setIVTimeResolvedRampSettings, *args) + + self.dialog.master.destroy() + self.dialog = None + + elif context == CANCEL: + self.dialog.master.destroy() + self.dialog = None + + else: raise ValueError (context) # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -2058,11 +2190,12 @@ def measureR ( def getMethod (self): method = Method() - method.setSourceParameters (*self.sourceParameters.get()) - method.setMeterParameters (*self.meterParameters.get()) - method.setAcquisitionSettings (*self.acquisitionSettings.get()) - method.set_IV_RampSettings (*self.ivRampSettings.get()) - method.setOhmmeterSettings (*self.ohmmeterSettings.get()) + method.setSourceParameters (*self.sourceParameters.get()) + method.setMeterParameters (*self.meterParameters.get()) + method.setAcquisitionSettings (*self.acquisitionSettings.get()) + method.set_IV_RampSettings (*self.ivRampSettings.get()) + method.set_IV_TimeResolvedRampSettings (*self.ivTimeResolvedRampSettings.get()) + method.setOhmmeterSettings (*self.ohmmeterSettings.get()) return method def applyMethod (self, method): @@ -2118,6 +2251,16 @@ def applyMethod (self, method): oModule.setIVRampSettings, *settings) # ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + settings = method.get_IV_TimeResolvedRampSettings (*self.ivRampSettings.get()) + + oApplet.schedule_task (oApplet.setIVTimeResolvedRampSettings, *settings) + + if oModule and isinstance (oModule, _IVModule): + oModule.schedule_task ( + oModule.setIVTimeResolvedRampSettings, *settings) + + # ++++++++++++++++++++++++++++++++++++++++++++++++++++++ settings = method.getOhmmeterSettings (*self.ohmmeterSettings.get()) @@ -2704,6 +2847,7 @@ def excite_n_plot (self, bg_task = None, *bg_tasks): if not self.complete(): self.sleep (self.delay, self.do_tasks, bg_task, *bg_tasks) + datapoint = self.acquire (self.do_tasks, bg_task, *bg_tasks) self.update_log (datapoint) @@ -2923,6 +3067,442 @@ def thread (self): # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +class _IVTimeResolvedModule (_Module): + + def __init__ (self, master, oXSMU): + _Module.__init__ (self, master, oXSMU) + self.excitationVoltage = None + self.excitationCurrent = None + self.scan_mode = None + self.power_limited = False + self._complete = False + + def run_type (self): + return 'IV-Time-Resolved' + + def xlabel (self): + return 'Voltage (V)' + + def ylabel (self): + return 'Current (A)' + + def init (self): + _Module.init (self) + + oXSMU = self.oXSMU + oApplet = oXSMU.oApplet + oApplet.schedule_task (oApplet.setRunMode, RUN_MODE_IV_TIME_RESOLVED) + + self.excitationVoltage = None + self.excitationCurrent = None + self.scan_mode = None + self.power_limited = False + self._complete = False + + def initIVTimeResolvedRampSettings ( + self, finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode): + + self.finalCurrent = finalCurrent + self.finalVoltage = finalVoltage + self.maxPower = maxPower + self.currentStep = currentStep + self.voltageStep = voltageStep + self.bipolar = bipolar + self.resTrackMode = resTrackMode + + def setIVTimeResolvedRampSettings ( + self, finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode): + + self.initIVTimeResolvedRampSettings ( + finalCurrent, finalVoltage, maxPower, + currentStep, voltageStep, bipolar, resTrackMode) + + text = 'IV Time Resolved settings updated' + oApplet = self.oXSMU.oApplet + oApplet.schedule_task (oApplet.set_status, text) + + def acquire (self, bg_task = None, *bg_tasks): + + oXSMU = self.oXSMU + t = systime() - self.t0 + self.do_tasks (bg_task, *bg_tasks) + + try: + oXSMU.acquire_lock() + (current, voltage, vsrc) = oXSMU.measureIVV2 (self.filterLength) + + finally: + oXSMU.release_lock() + + return DataPoint ( + time = t, + current = current, + voltage = voltage, + vsrc = vsrc) + + def breakPlot (self): + + oApplet = self.oXSMU.oApplet + + blank_datapoint = DataPoint ( + time = None, + current = None, + voltage = None, + vsrc = None) + + self.dataset.append (blank_datapoint) + + oApplet.schedule_task ( + oApplet.updatePlot, self, + blank_datapoint.voltage, blank_datapoint.current) + + return blank_datapoint + + def excite_n_plot (self, bg_task = None, *bg_tasks): + + oApplet = self.oXSMU.oApplet + self.do_tasks (bg_task, *bg_tasks) + + try: + + breakPlot = self.applySameExcitation() + if breakPlot: self.breakPlot() + + if not self.complete(): + + self.sleep (self.delay, self.do_tasks, bg_task, *bg_tasks) + datapoint = self.acquire (self.do_tasks, bg_task, *bg_tasks) + + self.update_log (datapoint) + self.dataset.append (datapoint) + + oApplet.schedule_task ( + oApplet.updatePlot, self, + datapoint.voltage, datapoint.current) + + + else: + datapoint = None + + except (CommError, LinkError) as e: + oApplet.schedule_task (oApplet.set_status, str (e)) + raise + + except (IOError, OSError) as e: + text = e.strerror + ' on ' + e.filename + oApplet.schedule_task (oApplet.set_status, text) + raise + + return datapoint, breakPlot + + def applySameExcitation (self): + + oXSMU = self.oXSMU + + ''' + Find excitation + ''' + + breakPlot = NO_BREAKPLOT + + if self.scan_mode == None: + self.scan_mode = SCAN_MODE_POSITIVE + + if self.scan_mode == SCAN_MODE_POSITIVE: + breakPlot = self.keepSameExcitation (breakPlot) + + if self.scan_mode == SCAN_MODE_NEGATIVE: + breakPlot = self.keepSameExcitation (breakPlot) + + if not self.complete(): + + try: + oXSMU.acquire_lock() + + current = ( + self.excitationCurrent if self.currentStep != 0.0 + else copysign (self.finalCurrent, self.excitationVoltage)) + + voltage = ( + self.excitationVoltage if self.voltageStep != 0.0 + else copysign (self.finalVoltage, self.excitationCurrent)) + + if current == 0.0 or voltage == 0.0: + oXSMU.output_off() + + else: + oXSMU.setExcitationLimits (current, voltage, self.maxPower) + + (src_mode, value, self.power_limited) = ( + oXSMU.doExcitationAutoTune ( + track_mode = self.resTrackMode)) + + finally: + oXSMU.release_lock() + + return breakPlot + + def keepSameExcitation (self, breakPlot): + + oXSMU = self.oXSMU + + if (self.excitationCurrent == None + or self.excitationVoltage == None): + + self.excitationCurrent = 0.0 + self.excitationVoltage = 0.0 + self.power_limited = False + + elif (not self.power_limited + and abs (self.excitationCurrent) < self.finalCurrent + and abs (self.excitationVoltage) < self.finalVoltage): + + # Estimating next current + + if oXSMU.sourceParameters.mode == SOURCE_MODE_CS: + nextCurrent = ( + oXSMU.sourceParameters.value()) + + else: + nextCurrent = ( + self.dataset[-1].current) + + try: + self.excitationCurrent = self.currentStep * round ( + nextCurrent / self.currentStep) + + except ZeroDivisionError: + self.excitationCurrent = nextCurrent + + # Estimating next voltage + + if oXSMU.sourceParameters.mode == SOURCE_MODE_VS: + nextVoltage = ( + oXSMU.sourceParameters.value()) + + else: + nextVoltage = ( + self.dataset[-1].vsrc) + + try: + self.excitationVoltage = self.voltageStep * round ( + nextVoltage / self.voltageStep) + + except ZeroDivisionError: + self.excitationVoltage = nextVoltage + + else: + self.excitationCurrent = None + self.excitationVoltage = None + + if self.bipolar: + breakPlot = DO_BREAKPLOT + self.scan_mode = SCAN_MODE_NEGATIVE + + else: + self.scan_mode = None + self._complete = True + + return breakPlot + + def applyNextExcitation (self): + + oXSMU = self.oXSMU + + ''' + Find excitation + ''' + + breakPlot = NO_BREAKPLOT + + if self.scan_mode == None: + self.scan_mode = SCAN_MODE_POSITIVE + + if self.scan_mode == SCAN_MODE_POSITIVE: + breakPlot = self.findNextPositiveExcitation (breakPlot) + + if self.scan_mode == SCAN_MODE_NEGATIVE: + breakPlot = self.findNextNegativeExcitation (breakPlot) + + if not self.complete(): + + try: + oXSMU.acquire_lock() + + current = ( + self.excitationCurrent if self.currentStep != 0.0 + else copysign (self.finalCurrent, self.excitationVoltage)) + + voltage = ( + self.excitationVoltage if self.voltageStep != 0.0 + else copysign (self.finalVoltage, self.excitationCurrent)) + + if current == 0.0 or voltage == 0.0: + oXSMU.output_off() + + else: + oXSMU.setExcitationLimits (current, voltage, self.maxPower) + + (src_mode, value, self.power_limited) = ( + oXSMU.doExcitationAutoTune ( + track_mode = self.resTrackMode)) + + finally: + oXSMU.release_lock() + + return breakPlot + + def findNextPositiveExcitation (self, breakPlot): + + oXSMU = self.oXSMU + + if (self.excitationCurrent == None + or self.excitationVoltage == None): + + self.excitationCurrent = 0.0 + self.excitationVoltage = 0.0 + self.power_limited = False + + elif (not self.power_limited + and abs (self.excitationCurrent) < self.finalCurrent + and abs (self.excitationVoltage) < self.finalVoltage): + + # Estimating next current + + if oXSMU.sourceParameters.mode == SOURCE_MODE_CS: + nextCurrent = ( + oXSMU.sourceParameters.value() + self.currentStep) + + else: + nextCurrent = ( + self.dataset[-1].current + self.currentStep) + + try: + self.excitationCurrent = self.currentStep * round ( + nextCurrent / self.currentStep) + + except ZeroDivisionError: + self.excitationCurrent = nextCurrent + + # Estimating next voltage + + if oXSMU.sourceParameters.mode == SOURCE_MODE_VS: + nextVoltage = ( + oXSMU.sourceParameters.value() + self.voltageStep) + + else: + nextVoltage = ( + self.dataset[-1].vsrc + self.voltageStep) + + try: + self.excitationVoltage = self.voltageStep * round ( + nextVoltage / self.voltageStep) + + except ZeroDivisionError: + self.excitationVoltage = nextVoltage + + else: + self.excitationCurrent = None + self.excitationVoltage = None + + if self.bipolar: + breakPlot = DO_BREAKPLOT + self.scan_mode = SCAN_MODE_NEGATIVE + + else: + self.scan_mode = None + self._complete = True + + return breakPlot + + def findNextNegativeExcitation (self, breakPlot): + + oXSMU = self.oXSMU + + if (self.excitationCurrent == None + or self.excitationVoltage == None): + + self.excitationCurrent = 0.0 + self.excitationVoltage = 0.0 + self.power_limited = False + + elif (not self.power_limited + and abs (self.excitationCurrent) < self.finalCurrent + and abs (self.excitationVoltage) < self.finalVoltage): + + # Estimating next current + + if oXSMU.sourceParameters.mode == SOURCE_MODE_CS: + nextCurrent = ( + oXSMU.sourceParameters.value() - self.currentStep) + + else: + nextCurrent = ( + self.dataset[-1].current - self.currentStep) + + try: + self.excitationCurrent = self.currentStep * round ( + nextCurrent / self.currentStep) + + except ZeroDivisionError: + self.excitationCurrent = nextCurrent + + # Estimating next voltage + + if oXSMU.sourceParameters.mode == SOURCE_MODE_VS: + nextVoltage = ( + oXSMU.sourceParameters.value() - self.voltageStep) + + else: + nextVoltage = ( + self.dataset[-1].vsrc - self.voltageStep) + + try: + self.excitationVoltage = self.voltageStep * round ( + nextVoltage / self.voltageStep) + + except ZeroDivisionError: + self.excitationVoltage = nextVoltage + + else: + self.scan_mode = None + self.excitationCurrent = None + self.excitationVoltage = None + self._complete = True + + return breakPlot + + def complete (self): + return True if self._complete else False + +# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +class _IVTimeResolvedAcquisitionThread (_AcquisitionThread): + + def __init__ (self, module): + _AcquisitionThread.__init__ (self, module) + + def thread (self): + + try: + self.module.init() + + while True: + self.do_tasks() + self.module.excite_n_plot (self.do_tasks) + if self.module.complete(): break + + except (CommError, LinkError) : pass + except (IOError, OSError) : pass + except XTerminate : pass + + self.module.atexit() + +# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +# +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + class _RTimeModule (_Module): def __init__ (self, master, oXSMU): diff --git a/modules/xsmu/xsmu.pyc b/modules/xsmu/xsmu.pyc deleted file mode 100644 index 6147417..0000000 Binary files a/modules/xsmu/xsmu.pyc and /dev/null differ diff --git a/modules/xtcon/TCON_Banner.pyc b/modules/xtcon/TCON_Banner.pyc deleted file mode 100644 index 6aed67e..0000000 Binary files a/modules/xtcon/TCON_Banner.pyc and /dev/null differ diff --git a/modules/xtcon/TCON_Constants.pyc b/modules/xtcon/TCON_Constants.pyc deleted file mode 100644 index 6c0332e..0000000 Binary files a/modules/xtcon/TCON_Constants.pyc and /dev/null differ diff --git a/modules/xtcon/TCON_DataType.pyc b/modules/xtcon/TCON_DataType.pyc deleted file mode 100644 index e0f2867..0000000 Binary files a/modules/xtcon/TCON_DataType.pyc and /dev/null differ diff --git a/modules/xtcon/TCON_Method.pyc b/modules/xtcon/TCON_Method.pyc deleted file mode 100644 index 436ed5b..0000000 Binary files a/modules/xtcon/TCON_Method.pyc and /dev/null differ diff --git a/modules/xtcon/app_tcon.pyc b/modules/xtcon/app_tcon.pyc deleted file mode 100644 index 89c8bfd..0000000 Binary files a/modules/xtcon/app_tcon.pyc and /dev/null differ diff --git a/modules/xtcon/tcon.pyc b/modules/xtcon/tcon.pyc deleted file mode 100644 index a7adbba..0000000 Binary files a/modules/xtcon/tcon.pyc and /dev/null differ diff --git a/ppsel/app_ppsel.pyc b/ppsel/app_ppsel.pyc deleted file mode 100644 index c3dcc02..0000000 Binary files a/ppsel/app_ppsel.pyc and /dev/null differ diff --git a/ppsel/capacitance/IV_sweep.py b/ppsel/capacitance/IV_sweep.py new file mode 100644 index 0000000..486b212 --- /dev/null +++ b/ppsel/capacitance/IV_sweep.py @@ -0,0 +1,417 @@ +#------------------------------------------------------------------------------------------------- +#------------------------------------------------------------------------------------------------ +# +# ALGORITHM FOR IV MEASUREMENTS +# +# Set voltage source to 0 +# Call function to measure IV +# Print out the (voltage, current, time) values +# Change voltage source to (value + step_size) +# +# measure current, if (current_new - current_old) > current_step -> switch mode to current +# Set current source to (last measured current value + current_step) +# Call function to measure current +# Call function to measure voltage +# Loop over the measuring functions +# Print out the (voltage, current, time) values +# +# measure current, if (current_new - current_old) < current_step -> keep the new voltage value +# Call function to measure current +# Call function to measure voltage +# Loop over the measuring functions +# Print out the (voltage, current, time) values +# +#------------------------------------------------------------------------------------------------- +#------------------------------------------------------------------------------------------------- + +import sys, time +import libxsmu +import csv +import numpy as np + +logfile = open("histogram_data.txt", "w") +logfile.close () + +def set_DC_voltage (deviceID, value): + + ############################ + # Set VS range + + timeout = 1.0 + voltageSourceRange = 0 # 0: 10V, 1: 100V + + print \ + "voltageSourceRange :", voltageSourceRange, "\n" \ + "Remaining time :", timeout, "sec", "\n" + + voltageSourceRange, timeout = \ + libxsmu.VS_setRange (deviceID, voltageSourceRange, timeout) + + if (timeout == 0.0): + print 'Communication timeout in VS_setRange.' + exit (-2) + + ############################ + # Set VS voltage + + timeout = 1.0 + voltage = value + voltage, timeout = libxsmu.VS_setVoltage (deviceID, voltage, timeout) + print \ + "Voltage: ", voltage, "\n" \ + "Timeout: ", timeout + + if (timeout == 0.0): + print 'Communication timeout in VS_setVoltage' + exit (-2) + + ############################ + time.sleep(1) + + +def set_DC_current (deviceID, value): + + ############################ + # Set CS range + + currentSourceRange = 3 # 0: 10uA, 1: 100uA, 2: 1mA, 3: 10mA, 4: 100mA + timeout = 1.0 + + if (np.abs(value) < 0.0001): + currentSourceRange = 1 + + elif (np.abs(value) < 0.001): + currentSourceRange = 2 + + elif (np.abs(value) < 0.01): + currentSourceRange = 3 + + currentSourceRange, timeout = \ + libxsmu.CS_setRange (deviceID, currentSourceRange, timeout) + + print \ + "currentSourceRange :", currentSourceRange, "\n" \ + "Remaining time :", timeout, "sec", "\n" + + if (timeout == 0.0): + print 'Communication timeout in CS_setRange.' + exit (-2) + + + ############################ + # Set CS current + + timeout = 1.0 + current = value + current, timeout = libxsmu.CS_setCurrent (deviceID, current, timeout) + + print \ + "Current: ", current, "\n" \ + "Timeout: ", timeout + + if (timeout == 0.0): + print 'Communication timeout in CS_setCurrent' + exit (-2) + + ############################ + time.sleep(1) + +def set_CM_Range(deviceID, range): + + ############################ + # Set CM range + + timeout = 1.0 + currentMeterRange = range # 0: 10uA, 1: 100uA, 2: 1mA, 3: 10mA, 4: 100mA + + currentMeterRange, timeout = \ + libxsmu.CM_setRange (deviceID, currentMeterRange, timeout) + + print \ + "currentMeterRange :", currentMeterRange, "\n" \ + "Remaining time :", timeout, "sec", "\n" + + if (timeout == 0.0): + print 'Communication timeout in CM_setRange.' + exit (-2) + +def measureI (deviceID, filterLength): + + ############################ + # Set CM Range to 10mA + set_CM_Range(deviceID, 3) + + ############################ + # Get CM Current + + filter_length = filterLength + timeout = 1 + 0.022 * filter_length + + current, timeout = libxsmu.CM_getReading (deviceID, filter_length, timeout) + + print '**** Current : ' + str(current) + ' ****' + + if (timeout == 0.0): + print 'Communication timeout in CM_getReading.' + exit (-2) + + ############################ + + if (np.abs(current) < 0.0001): + # Set CM Range to 100uA + set_CM_Range(deviceID, 1) + print 'Range : 100 uA' + + elif (np.abs(current) < 0.001): + # Set CM Range to 1mA + set_CM_Range(deviceID, 2) + print 'Range : 1 mA' + + elif (np.abs(current) < 0.01): + print 'Range : 10 mA' + + else : + print 'Out of Range' + + ############################ + + timeout = 1 + 0.022 * filter_length + current, timeout = libxsmu.CM_getReading (deviceID, filter_length, timeout) + + print \ + "current :", current, "\n" \ + "Remaining time :", timeout, "sec", "\n" + + if (timeout == 0.0): + print 'Communication timeout in CM_getReading.' + exit (-2) + + return current + + +def set_VM_Range(deviceID, range): + + ############################ + # Set VM range + + timeout = 1.0 + voltageMeterRange = range # 0: 1mV, 1: 10mV, 2: 100mV, 3: 1V, 4: 10V, 5: 100V + + voltageMeterRange, timeout = \ + libxsmu.VM2_setRange (deviceID, voltageMeterRange, timeout) + print \ + "voltageMeterRange :", voltageMeterRange, "\n" \ + "Remaining time :", timeout, "sec", "\n" + + if (timeout == 0.0): + print 'Communication timeout in VM_setRange.' + exit (-2) + + +def measureV (deviceID, filterLength): + + ############################ + # Set VM Range to 10V + + set_VM_Range(deviceID, 4) + + ############################ + # Get VM Voltage + + filter_length = filterLength + timeout = 1 + 0.03 * filter_length + + voltage, timeout = libxsmu.VM2_getReading (deviceID, filter_length, timeout) + + print '**** Voltage : ' + str(voltage) + ' ****' + + if (timeout == 0.0): + print 'Communication timeout in VM_getReading.' + exit (-2) + + ############################ + + if (np.abs(voltage) < 0.01): + ############################ + # Set VM Range to 100mV + set_VM_Range(deviceID, 2) + print 'VM Range : 100 mV' + + elif (np.abs(voltage) < 1): + ############################ + # Set VM Range to 1V + set_VM_Range(deviceID, 3) + print 'VM Range : 1 V' + + elif (np.abs(voltage < 10)): + print 'VM Range : 10 V' + + else : + print 'Out of Range' + + ############################ + + timeout = 1 + 0.03 * filter_length + + voltage, timeout = libxsmu.VM2_getReading (deviceID, filter_length, timeout) + + print \ + "voltage :", voltage, "\n" \ + "Remaining time :", timeout, "sec", "\n" + + if (timeout == 0.0): + print 'Communication timeout in VM_getReading.' + exit (-2) + + return voltage + + +def measure_IV (deviceID, iteration, mode, filterLength): + + logfile = open("histogram_data.txt", "a") + + for index in range(iteration): + + current = measureI(deviceID, filterLength) + voltage = measureV(deviceID, filterLength) + + logfile.write(str(voltage) + "," + str(current) + "," + str(time.time()) + "," + mode + "\n") + + + logfile.write ('Next Source Value...\n') + logfile.close () + + print current, voltage + + return current, voltage + +def sourceMode (deviceID, mode): + + timeout = 10.0 + sourceMode, timeout = libxsmu.setSourceMode (deviceID, mode, timeout) + print \ + "sourceMode :", sourceMode, "\n" \ + "Remaining time:", timeout, "sec", "\n" + + if (timeout == 0.0): + print 'Communication timeout in setSourceMode.' + exit (-2) + + +def sourceSwitching (deviceID, voltage, current, voltage_step, current_step, mode, filterLength): + + if (mode == "VOLTAGE"): + + set_DC_voltage (deviceID, (voltage + voltage_step)) + current_new = measureI(deviceID, filterLength) + set_DC_voltage (deviceID, voltage) + + if (np.abs(current_new - current) >= current_step): + sourceMode (deviceID, 1) # source mode : 0 = Voltage, 1 = Current + return "CURRENT" + + else: + return "VOLTAGE" + + else : + set_DC_current (deviceID, current + current_step) + voltage_new = measureV(deviceID, filterLength) + set_DC_current (deviceID, current) + + if (np.abs(voltage_new - voltage) >= voltage_step): + sourceMode (deviceID, 0) # source mode : 0 = Voltage, 1 = Current + return "VOLTAGE" + + else: + return "CURRENT" + + +def main(): + + + ########################################################################## + # Scans USB bus for Xplore SMU. + + N = libxsmu.scan() + print "Total device:", N + + if N == 0: + print 'No Xplore SMU device found.' + exit (-1) + + ########################################################################## + # Queries serial number of the first device. + # This should be sufficient if only a single device is present. + + serialNo = 'XSMU012A' + print "Serial number:", serialNo + + timeout = 1.0 + deviceID, goodID, timeout = libxsmu.open_device (serialNo, timeout) + print \ + "Device ID :", deviceID, "\n" \ + "goodID :", goodID, "\n" \ + "Remaining time:", timeout, "sec", "\n" + + if (timeout == 0.0) or (not goodID): + print 'Communication timeout in open_device.' + exit (-2) + + ########################################################################## + # User input parameters + + Voltage_Range = float (raw_input ("Enter Voltage Range (V) : ")) # V + Current_Range = float (raw_input ("Enter Current Range (A) : ")) # I + Voltage_Step = float (raw_input ("Enter Voltage Step Size (V) : ")) # Delta_V + Current_Step = float (raw_input ("Enter Current Step Size (A) : ")) # Delta_V + iteration = int (raw_input ("Enter number of iterations : ")) # no. of measurements at each (I,V) point + + ########################################################################## + #Intelligent Switching algorithm + + voltage = 0.0 + current = 0.0 + mode = "VOLTAGE" + + filterLength = 1 + + set_DC_voltage(deviceID, voltage) + + while ((voltage <= Voltage_Range) and (current <= Current_Range)): + + if (mode == "VOLTAGE"): + + set_DC_voltage (deviceID, voltage) + current, voltage = measure_IV (deviceID, iteration, mode, filterLength) + mode = sourceSwitching (deviceID, voltage, current, Voltage_Step, Current_Step, mode, filterLength) + + if (mode == "VOLTAGE"): + voltage = voltage + Voltage_Step + + else: + current = current + Current_Step + + elif (mode == "CURRENT"): + + set_DC_current (deviceID, current) + current, voltage = measure_IV (deviceID, iteration, mode, filterLength) + mode = sourceSwitching (deviceID, voltage, current, Voltage_Step, Current_Step, mode, filterLength) + + if (mode == "VOLTAGE"): + voltage = voltage + Voltage_Step + + else: + current = current + Current_Step + + print mode + + set_DC_voltage (deviceID, 0.0) + + raw_input ("Run Finished. Press Enter to Exit\n") + + ########################################################################## + # closes the device. + + libxsmu.close_device(deviceID) + +main() diff --git a/ppsel/curr/current_measurement.py b/ppsel/curr/current_measurement.py new file mode 100644 index 0000000..cfbcfdb --- /dev/null +++ b/ppsel/curr/current_measurement.py @@ -0,0 +1,139 @@ +#------------------------------------------------------------------------------------------------- +#------------------------------------------------------------------------------------------------ +# +# ALGORITHM FOR IV MEASUREMENTS +# +# Set voltage source to 0 +# Call function to measure IV +# Print out the (voltage, current, time) values +# Change voltage source to (value + step_size) +# +# measure current, if (current_new - current_old) > current_step -> switch mode to current +# Set current source to (last measured current value + current_step) +# Call function to measure current +# Call function to measure voltage +# Loop over the measuring functions +# Print out the (voltage, current, time) values +# +# measure current, if (current_new - current_old) < current_step -> keep the new voltage value +# Call function to measure current +# Call function to measure voltage +# Loop over the measuring functions +# Print out the (voltage, current, time) values +# +#------------------------------------------------------------------------------------------------- +#------------------------------------------------------------------------------------------------- + +import sys, time + +sys.path.insert(0,"../../modules/xsmu") +sys.path.insert(0,"../../apps") +sys.path.insert(0,"../../apps/widgets") +sys.path.insert(0,"../../lib") + +import xsmu +import csv +import numpy as np +import multiprocessing as mp +from XSMU_Constants import * + +filename = open("histogram_data.txt", "w") +filename.close () + +def set_DC_voltage (xsmu_driver, value): + + # mode = SOURCE_MODE_VS + xsmu_driver._VS_setVoltage(value) # autorange = AUTORANGE_ON + # range = VS_RANGE_10V + # xsmu_driver.setSourceParameters (mode, autorange, range, value) + +def set_DC_current (xsmu_driver, value): + + # mode = SOURCE_MODE_CS + # autorange = AUTORANGE_ON + xsmu_driver._CS_setCurrent(value) + xsmu_driver._CM_setRange(CM_RANGE_MAX) # range = VS_RANGE_10V + # xsmu_driver.setSourceParameters (mode, autorange, range, value) + + +def measure_IV (xsmu_driver, iteration, mode): + + filename = open("histogram_data.txt", "a") + for index in range(iteration): + current = xsmu_driver.CM_getReading (filterLength = 1) + voltage = xsmu_driver.VM_getReading (filterLength = 1) + filename.write (str(voltage) + "," + str(current) + "," + str(time.time()) + "," + mode + "\n") + + + filename.write ('Next Source Value\n') + filename.close () + print current, voltage + return current, voltage + + + +def setMode (xsmu_driver, voltage, current, voltage_step_size, current_step_size, mode): + + if (mode == "VOLTAGE"): + + set_DC_voltage (xsmu_driver, voltage + voltage_step_size) + current_new = xsmu_driver.CM_getReading (filterLength = 1) + set_DC_voltage (xsmu_driver, voltage) + if (np.abs(current_new - current) >= current_step_size): + xsmu_driver._setSourceMode(SOURCE_MODE_CS) + return "CURRENT" + else: + return "VOLTAGE" + + else : + set_DC_current (xsmu_driver, current + current_step_size) + voltage_new = xsmu_driver.VM_getReading (filterLength = 1) + set_DC_current (xsmu_driver, current) + if (np.abs(voltage_new - voltage) >= voltage_step_size): + xsmu_driver._setSourceMode(SOURCE_MODE_VS) + return "VOLTAGE" + else: + return "CURRENT" + + +def main(): + + xsmu_driver = xsmu .Driver() + xsmu_devices = xsmu_driver.scan () + xsmu_driver.open (xsmu_devices[0]) + + DC_Voltage_Amplitude = float (raw_input ("Enter DC Voltage Max (V) : ")) # V + DC_Current_Amplitude = float (raw_input ("Enter DC Current Max (V) : ")) # I + DC_Voltage_StepSize = float (raw_input ("Enter DC Voltage Step Size (V) : ")) # Delta_V + DC_Current_StepSize = float (raw_input ("Enter DC Current Step Size (V) : ")) # Delta_V + iteration = int (raw_input ("Enter no of iterations : " )) # no of measurements + voltage = 0.0 + current = 0.0 + mode = "VOLTAGE" + set_DC_voltage (xsmu_driver, voltage) + + while ((voltage <= DC_Voltage_Amplitude) and (current <= DC_Current_Amplitude)): + if (mode == "VOLTAGE"): + set_DC_voltage (xsmu_driver, voltage) + current,voltage = measure_IV (xsmu_driver, iteration, mode) + mode = setMode (xsmu_driver, voltage, current, DC_Voltage_StepSize, DC_Current_StepSize, mode) + if (mode == "VOLTAGE"): + voltage = voltage + DC_Voltage_StepSize + else: + current = current + DC_Current_StepSize + else : + set_DC_current (xsmu_driver, current) + current,voltage = measure_IV (xsmu_driver, iteration, mode) + mode = setMode (xsmu_driver, voltage, current, DC_Voltage_StepSize, DC_Current_StepSize, mode) + if (mode == "VOLTAGE"): + voltage = voltage + DC_Voltage_StepSize + else: + current = current + DC_Current_StepSize + print mode + + raw_input ("Press enter after observing signals") + + set_DC_voltage (xsmu_driver, 0.0) + xsmu_driver.close () + +main() diff --git a/ppsel/curr/current_measurement.py~ b/ppsel/curr/current_measurement.py~ new file mode 100644 index 0000000..d940d1b --- /dev/null +++ b/ppsel/curr/current_measurement.py~ @@ -0,0 +1,37 @@ +import sys, time + +sys.path.insert(0,"../../modules/xlia") +sys.path.insert(0,"../../apps") +sys.path.insert(0,"../../apps/widgets") +sys.path.insert(0,"../../lib") + +import math +import xsmu +from XSMU_Constants import * + +# Set voltage source to some value +# Call function to measure current +# Loop over the measuring function +# Print out the current values + +def set_DC_voltage (xsmu_driver, value): + + mode = SOURCE_MODE_VS + autorange = AUTORANGE_ON + range = VS_RANGE_10V + + xsmu_driver.setSourceParameters (mode, autorange, range, values) + +def measure_current(): + + for index in range(100): + current = CM_getReading() + print ("The value of current is " + current + " and the time is " + time.strftime('%H:%M:%S') + '\n') + + +mode = _setSourceMode(RUN_MODE_VS) +voltage = _VS_setVoltage(10) +current = CM_getReading(1) + +set_DC_voltage( +# Print out the current values diff --git a/ppsel/hires/HIRES_Constants.pyc b/ppsel/hires/HIRES_Constants.pyc deleted file mode 100644 index 97cefcc..0000000 Binary files a/ppsel/hires/HIRES_Constants.pyc and /dev/null differ diff --git a/ppsel/hires/HIRES_DataType.pyc b/ppsel/hires/HIRES_DataType.pyc deleted file mode 100644 index bbed091..0000000 Binary files a/ppsel/hires/HIRES_DataType.pyc and /dev/null differ diff --git a/ppsel/hires/HIRES_Method.pyc b/ppsel/hires/HIRES_Method.pyc deleted file mode 100644 index 381746c..0000000 Binary files a/ppsel/hires/HIRES_Method.pyc and /dev/null differ diff --git a/ppsel/hires/app_hires.pyc b/ppsel/hires/app_hires.pyc deleted file mode 100644 index 76d871d..0000000 Binary files a/ppsel/hires/app_hires.pyc and /dev/null differ diff --git a/ppsel/hires/hires.pyc b/ppsel/hires/hires.pyc deleted file mode 100644 index aa34f09..0000000 Binary files a/ppsel/hires/hires.pyc and /dev/null differ diff --git a/ppsel/ppsel.pyc b/ppsel/ppsel.pyc deleted file mode 100644 index a4f7d9e..0000000 Binary files a/ppsel/ppsel.pyc and /dev/null differ diff --git a/ppsel/ppsel_constants.pyc b/ppsel/ppsel_constants.pyc deleted file mode 100644 index f9d236c..0000000 Binary files a/ppsel/ppsel_constants.pyc and /dev/null differ diff --git a/ppsel/res/RES_Constants.pyc b/ppsel/res/RES_Constants.pyc deleted file mode 100644 index bb74fda..0000000 Binary files a/ppsel/res/RES_Constants.pyc and /dev/null differ diff --git a/ppsel/res/RES_DataType.pyc b/ppsel/res/RES_DataType.pyc deleted file mode 100644 index 4a84838..0000000 Binary files a/ppsel/res/RES_DataType.pyc and /dev/null differ diff --git a/ppsel/res/RES_Method.pyc b/ppsel/res/RES_Method.pyc deleted file mode 100644 index ae3558b..0000000 Binary files a/ppsel/res/RES_Method.pyc and /dev/null differ diff --git a/ppsel/res/app_res.pyc b/ppsel/res/app_res.pyc deleted file mode 100644 index fc9c7fc..0000000 Binary files a/ppsel/res/app_res.pyc and /dev/null differ diff --git a/ppsel/res/res.pyc b/ppsel/res/res.pyc deleted file mode 100644 index 597afab..0000000 Binary files a/ppsel/res/res.pyc and /dev/null differ diff --git a/ppsel/sus/SUS_Constants.pyc b/ppsel/sus/SUS_Constants.pyc deleted file mode 100644 index bbac1ed..0000000 Binary files a/ppsel/sus/SUS_Constants.pyc and /dev/null differ diff --git a/ppsel/sus/SUS_DataType.pyc b/ppsel/sus/SUS_DataType.pyc deleted file mode 100644 index 3853dcc..0000000 Binary files a/ppsel/sus/SUS_DataType.pyc and /dev/null differ diff --git a/ppsel/sus/SUS_Method.pyc b/ppsel/sus/SUS_Method.pyc deleted file mode 100644 index bb19127..0000000 Binary files a/ppsel/sus/SUS_Method.pyc and /dev/null differ diff --git a/ppsel/sus/app_sus.pyc b/ppsel/sus/app_sus.pyc deleted file mode 100644 index 7a85e05..0000000 Binary files a/ppsel/sus/app_sus.pyc and /dev/null differ diff --git a/ppsel/sus/sus.pyc b/ppsel/sus/sus.pyc deleted file mode 100644 index 9b3c191..0000000 Binary files a/ppsel/sus/sus.pyc and /dev/null differ diff --git a/user_scripts/IV_sweep.py b/user_scripts/IV_sweep.py new file mode 100644 index 0000000..486b212 --- /dev/null +++ b/user_scripts/IV_sweep.py @@ -0,0 +1,417 @@ +#------------------------------------------------------------------------------------------------- +#------------------------------------------------------------------------------------------------ +# +# ALGORITHM FOR IV MEASUREMENTS +# +# Set voltage source to 0 +# Call function to measure IV +# Print out the (voltage, current, time) values +# Change voltage source to (value + step_size) +# +# measure current, if (current_new - current_old) > current_step -> switch mode to current +# Set current source to (last measured current value + current_step) +# Call function to measure current +# Call function to measure voltage +# Loop over the measuring functions +# Print out the (voltage, current, time) values +# +# measure current, if (current_new - current_old) < current_step -> keep the new voltage value +# Call function to measure current +# Call function to measure voltage +# Loop over the measuring functions +# Print out the (voltage, current, time) values +# +#------------------------------------------------------------------------------------------------- +#------------------------------------------------------------------------------------------------- + +import sys, time +import libxsmu +import csv +import numpy as np + +logfile = open("histogram_data.txt", "w") +logfile.close () + +def set_DC_voltage (deviceID, value): + + ############################ + # Set VS range + + timeout = 1.0 + voltageSourceRange = 0 # 0: 10V, 1: 100V + + print \ + "voltageSourceRange :", voltageSourceRange, "\n" \ + "Remaining time :", timeout, "sec", "\n" + + voltageSourceRange, timeout = \ + libxsmu.VS_setRange (deviceID, voltageSourceRange, timeout) + + if (timeout == 0.0): + print 'Communication timeout in VS_setRange.' + exit (-2) + + ############################ + # Set VS voltage + + timeout = 1.0 + voltage = value + voltage, timeout = libxsmu.VS_setVoltage (deviceID, voltage, timeout) + print \ + "Voltage: ", voltage, "\n" \ + "Timeout: ", timeout + + if (timeout == 0.0): + print 'Communication timeout in VS_setVoltage' + exit (-2) + + ############################ + time.sleep(1) + + +def set_DC_current (deviceID, value): + + ############################ + # Set CS range + + currentSourceRange = 3 # 0: 10uA, 1: 100uA, 2: 1mA, 3: 10mA, 4: 100mA + timeout = 1.0 + + if (np.abs(value) < 0.0001): + currentSourceRange = 1 + + elif (np.abs(value) < 0.001): + currentSourceRange = 2 + + elif (np.abs(value) < 0.01): + currentSourceRange = 3 + + currentSourceRange, timeout = \ + libxsmu.CS_setRange (deviceID, currentSourceRange, timeout) + + print \ + "currentSourceRange :", currentSourceRange, "\n" \ + "Remaining time :", timeout, "sec", "\n" + + if (timeout == 0.0): + print 'Communication timeout in CS_setRange.' + exit (-2) + + + ############################ + # Set CS current + + timeout = 1.0 + current = value + current, timeout = libxsmu.CS_setCurrent (deviceID, current, timeout) + + print \ + "Current: ", current, "\n" \ + "Timeout: ", timeout + + if (timeout == 0.0): + print 'Communication timeout in CS_setCurrent' + exit (-2) + + ############################ + time.sleep(1) + +def set_CM_Range(deviceID, range): + + ############################ + # Set CM range + + timeout = 1.0 + currentMeterRange = range # 0: 10uA, 1: 100uA, 2: 1mA, 3: 10mA, 4: 100mA + + currentMeterRange, timeout = \ + libxsmu.CM_setRange (deviceID, currentMeterRange, timeout) + + print \ + "currentMeterRange :", currentMeterRange, "\n" \ + "Remaining time :", timeout, "sec", "\n" + + if (timeout == 0.0): + print 'Communication timeout in CM_setRange.' + exit (-2) + +def measureI (deviceID, filterLength): + + ############################ + # Set CM Range to 10mA + set_CM_Range(deviceID, 3) + + ############################ + # Get CM Current + + filter_length = filterLength + timeout = 1 + 0.022 * filter_length + + current, timeout = libxsmu.CM_getReading (deviceID, filter_length, timeout) + + print '**** Current : ' + str(current) + ' ****' + + if (timeout == 0.0): + print 'Communication timeout in CM_getReading.' + exit (-2) + + ############################ + + if (np.abs(current) < 0.0001): + # Set CM Range to 100uA + set_CM_Range(deviceID, 1) + print 'Range : 100 uA' + + elif (np.abs(current) < 0.001): + # Set CM Range to 1mA + set_CM_Range(deviceID, 2) + print 'Range : 1 mA' + + elif (np.abs(current) < 0.01): + print 'Range : 10 mA' + + else : + print 'Out of Range' + + ############################ + + timeout = 1 + 0.022 * filter_length + current, timeout = libxsmu.CM_getReading (deviceID, filter_length, timeout) + + print \ + "current :", current, "\n" \ + "Remaining time :", timeout, "sec", "\n" + + if (timeout == 0.0): + print 'Communication timeout in CM_getReading.' + exit (-2) + + return current + + +def set_VM_Range(deviceID, range): + + ############################ + # Set VM range + + timeout = 1.0 + voltageMeterRange = range # 0: 1mV, 1: 10mV, 2: 100mV, 3: 1V, 4: 10V, 5: 100V + + voltageMeterRange, timeout = \ + libxsmu.VM2_setRange (deviceID, voltageMeterRange, timeout) + print \ + "voltageMeterRange :", voltageMeterRange, "\n" \ + "Remaining time :", timeout, "sec", "\n" + + if (timeout == 0.0): + print 'Communication timeout in VM_setRange.' + exit (-2) + + +def measureV (deviceID, filterLength): + + ############################ + # Set VM Range to 10V + + set_VM_Range(deviceID, 4) + + ############################ + # Get VM Voltage + + filter_length = filterLength + timeout = 1 + 0.03 * filter_length + + voltage, timeout = libxsmu.VM2_getReading (deviceID, filter_length, timeout) + + print '**** Voltage : ' + str(voltage) + ' ****' + + if (timeout == 0.0): + print 'Communication timeout in VM_getReading.' + exit (-2) + + ############################ + + if (np.abs(voltage) < 0.01): + ############################ + # Set VM Range to 100mV + set_VM_Range(deviceID, 2) + print 'VM Range : 100 mV' + + elif (np.abs(voltage) < 1): + ############################ + # Set VM Range to 1V + set_VM_Range(deviceID, 3) + print 'VM Range : 1 V' + + elif (np.abs(voltage < 10)): + print 'VM Range : 10 V' + + else : + print 'Out of Range' + + ############################ + + timeout = 1 + 0.03 * filter_length + + voltage, timeout = libxsmu.VM2_getReading (deviceID, filter_length, timeout) + + print \ + "voltage :", voltage, "\n" \ + "Remaining time :", timeout, "sec", "\n" + + if (timeout == 0.0): + print 'Communication timeout in VM_getReading.' + exit (-2) + + return voltage + + +def measure_IV (deviceID, iteration, mode, filterLength): + + logfile = open("histogram_data.txt", "a") + + for index in range(iteration): + + current = measureI(deviceID, filterLength) + voltage = measureV(deviceID, filterLength) + + logfile.write(str(voltage) + "," + str(current) + "," + str(time.time()) + "," + mode + "\n") + + + logfile.write ('Next Source Value...\n') + logfile.close () + + print current, voltage + + return current, voltage + +def sourceMode (deviceID, mode): + + timeout = 10.0 + sourceMode, timeout = libxsmu.setSourceMode (deviceID, mode, timeout) + print \ + "sourceMode :", sourceMode, "\n" \ + "Remaining time:", timeout, "sec", "\n" + + if (timeout == 0.0): + print 'Communication timeout in setSourceMode.' + exit (-2) + + +def sourceSwitching (deviceID, voltage, current, voltage_step, current_step, mode, filterLength): + + if (mode == "VOLTAGE"): + + set_DC_voltage (deviceID, (voltage + voltage_step)) + current_new = measureI(deviceID, filterLength) + set_DC_voltage (deviceID, voltage) + + if (np.abs(current_new - current) >= current_step): + sourceMode (deviceID, 1) # source mode : 0 = Voltage, 1 = Current + return "CURRENT" + + else: + return "VOLTAGE" + + else : + set_DC_current (deviceID, current + current_step) + voltage_new = measureV(deviceID, filterLength) + set_DC_current (deviceID, current) + + if (np.abs(voltage_new - voltage) >= voltage_step): + sourceMode (deviceID, 0) # source mode : 0 = Voltage, 1 = Current + return "VOLTAGE" + + else: + return "CURRENT" + + +def main(): + + + ########################################################################## + # Scans USB bus for Xplore SMU. + + N = libxsmu.scan() + print "Total device:", N + + if N == 0: + print 'No Xplore SMU device found.' + exit (-1) + + ########################################################################## + # Queries serial number of the first device. + # This should be sufficient if only a single device is present. + + serialNo = 'XSMU012A' + print "Serial number:", serialNo + + timeout = 1.0 + deviceID, goodID, timeout = libxsmu.open_device (serialNo, timeout) + print \ + "Device ID :", deviceID, "\n" \ + "goodID :", goodID, "\n" \ + "Remaining time:", timeout, "sec", "\n" + + if (timeout == 0.0) or (not goodID): + print 'Communication timeout in open_device.' + exit (-2) + + ########################################################################## + # User input parameters + + Voltage_Range = float (raw_input ("Enter Voltage Range (V) : ")) # V + Current_Range = float (raw_input ("Enter Current Range (A) : ")) # I + Voltage_Step = float (raw_input ("Enter Voltage Step Size (V) : ")) # Delta_V + Current_Step = float (raw_input ("Enter Current Step Size (A) : ")) # Delta_V + iteration = int (raw_input ("Enter number of iterations : ")) # no. of measurements at each (I,V) point + + ########################################################################## + #Intelligent Switching algorithm + + voltage = 0.0 + current = 0.0 + mode = "VOLTAGE" + + filterLength = 1 + + set_DC_voltage(deviceID, voltage) + + while ((voltage <= Voltage_Range) and (current <= Current_Range)): + + if (mode == "VOLTAGE"): + + set_DC_voltage (deviceID, voltage) + current, voltage = measure_IV (deviceID, iteration, mode, filterLength) + mode = sourceSwitching (deviceID, voltage, current, Voltage_Step, Current_Step, mode, filterLength) + + if (mode == "VOLTAGE"): + voltage = voltage + Voltage_Step + + else: + current = current + Current_Step + + elif (mode == "CURRENT"): + + set_DC_current (deviceID, current) + current, voltage = measure_IV (deviceID, iteration, mode, filterLength) + mode = sourceSwitching (deviceID, voltage, current, Voltage_Step, Current_Step, mode, filterLength) + + if (mode == "VOLTAGE"): + voltage = voltage + Voltage_Step + + else: + current = current + Current_Step + + print mode + + set_DC_voltage (deviceID, 0.0) + + raw_input ("Run Finished. Press Enter to Exit\n") + + ########################################################################## + # closes the device. + + libxsmu.close_device(deviceID) + +main() diff --git a/user_scripts/multiple_temperatures_IV.py b/user_scripts/multiple_temperatures_IV.py new file mode 100644 index 0000000..4d2928d --- /dev/null +++ b/user_scripts/multiple_temperatures_IV.py @@ -0,0 +1,122 @@ +import sys, time + +sys.path.insert(0,"../modules/xsmu") +sys.path.insert(0,"../modules/xtcon") +sys.path.insert(0,"../apps") +sys.path.insert(0,"../apps/widgets") +sys.path.insert(0,"../lib") + +import xsmu +import tcon +import numpy as np +from XSMU_Constants import * + +f = open("I-T-Data.txt", "w") +f.close() + +# Set voltage source to some value +# Call function to measure current +# Loop over the measuring function +# Print out the current values + +def set_DC_voltage (xsmu_driver, value): + + mode = SOURCE_MODE_VS + autorange = AUTORANGE_ON + range = VS_RANGE_10V + + xsmu_driver.setSourceParameters (mode, autorange, range, value) + +def measure_current(xsmu_driver, xtcon_driver, iterations): + + f = open("I-Data.txt", "a") + for index in range(iterations): + current = xsmu_driver.CM_getReading( filterLength = 1 ) + temperature = xtcon_driver.getSampleTemperature() + f.write(str(current) + "," + str(temperature) + '\n') + f.close() + +def stabilize_temp (xtcon_driver, tolerance, monitoring_period): + + history = [] + + print ("Stabilizing .. \n") + + while True : + history.append(xtcon_driver.getSampleTemperature()) + + if (len(history)