def __init__(self, parent=None): super(ControlMainWindow, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # Config Slots self.ui.dcRadioButton.toggled.connect(self.switchSweepType) #self.ui.pulseRadioButton.toggled.connect(self.switchSweepType) # Measurement slots self.ui.measurementButton.clicked.connect(self.doSweep) self.ui.saveButton.clicked.connect(self.saveSweep) self.ui.clearDataButton.clicked.connect(self.clearSweep) # Port Magic self.keithleyPort = serial.Serial() self.keithleyPort.baudrate = 9600 self.keithleyPort.port = "COM2" self.keithleyPort.timeout = 0.1 self.keithley = Keithley() self.ui.keithleyPortOpenButton.clicked.connect(self.openKeithleyPort) self.ui.keithleyPortCloseButton.clicked.connect(self.closeKeithleyPort) self.fuckedUp = False self.data = []
def __init__(self, parent=None): # Создаём класс (главное окно) super(ControlMainWindow, self).__init__(parent) self.ui = Ui_MainWindow() # Загружаем информацию о расположениее кнопочек - mainwindow.py, файл создаётся # "автоматически" после редактирования интерфейса внешней программой qtDesigner self.ui.setupUi(self) # Config Slots # Подключаем функции пограммы к кнопкам интерфейса self.ui.dcRadioButton.toggled.connect(self.switchSweepType) #self.ui.pulseRadioButton.toggled.connect(self.switchSweepType) #self.filePath = os.getcwd() self.filePath = "e:\Documents\\" # Measurement slots self.ui.measurementButton.clicked.connect(self.doSweep) self.ui.saveButton.clicked.connect(self.saveSweep) self.ui.clearDataButton.clicked.connect(self.clearSweep) # Port Magic # Задаём дефолтные настройки порта self.keithleyPort = serial.Serial() self.keithleyPort.baudrate = 9600 self.keithleyPort.port = "COM2" self.keithleyPort.timeout = 0.1 self.keithley = Keithley() self.ui.keithleyPortOpenButton.clicked.connect(self.openKeithleyPort) # Подключаем функции пограммы к кнопкам интерфейса self.ui.keithleyPortCloseButton.clicked.connect(self.closeKeithleyPort) self.fuckedUp = False # Пара внутренних переменных для работы с данными self.data = []
def setUp(): """Set up power supply and turn on Also put a message on the PSU LCD to warn operator""" global psu #goop #assert False, "STOP ME" #raise Exception('kdfksdhfks') if debug: print 'setUp: **initialising**' psu = Keithley.PSU2303() psu.setCurrent(0.35) psu.setVoltage(3.876) psu.powerOn() if debug: psu.settings() psu.measure() psu.message('Test in progress Do NOT Touch ')
def setUp(): """Set up power supply and turn on Also put a message on the PSU LCD to warn operator""" global psu, dmm if debug: print 'setUp: **initialising**' dmm = Agilent.DMM34401A(22) dmm.setVoltageDC() psu = Keithley.PSU2303(7) psu.setCurrent(0.25) psu.setVoltage(0) psu.powerOn() if debug: psu.settings() psu.measure() psu.message('Test in progress Do NOT Touch ')
def setUp(): """Set up power supply and turn on Also put a message on the PSU LCD to warn operator""" global debug, psu, dvm, relay info('setUp: **initialising**') relay = RelayBoard.PIC16F873A(port=RELAY_SERIAL) dvm = Agilent.DMM34401A() dvm.setVoltageDC() psu = Keithley.PSU2303() psu.setCurrent(SUPPLY_CURRENT_LIMIT) psu.setVoltage(SUPPLY_STANDARD_VOLTAGE) psu.powerOff() if debug: psu.settings() psu.measure() psu.message('Test in progress Do NOT Touch ') relay.on(RELAY_VBATT)
# LED Power supply: ps_voltage = 2.513 # V, for single voltage #for sweep ps_vmin = 2.54 ps_vmax = 2.55 ps_vstep = -0.005 ####################################### if not os.path.isdir(savepath): os.makedirs(savepath) # Open Device : Ps = MulticompPro() Sm = Keithley() Mux = ArdunioMux() Cam = Zyla(cam_exposure_time, cam_bit_depth, cam_shutter_mode) def exposure_maker(nominal_v): return 10 ''' LOOPS AVALIABLE: * Format = cam[index]sm[index]ps[index] * Indicies are permutation + combination of the following: * Camera (cam): * 0 = Off * 1 = On
#current = 1e-7 current_range = 1e-3 current_compliance = current_range #Current = numpy.arange(10e-7,200e-7,10e-7) Current = numpy.arange(-20e-6,10e-6,1e-6) #Current = numpy.arange(-5e-6,1e-6,0.1e-6) #Current = numpy.arange(0.1e-6,2e-6,0.1e-6) #Current = numpy.arange(1e-7,20e-7,1e-7) #Current = numpy.array([1e-6,5e-6,10e-6]) print("Current scan:",Current[0]*10**6,'-',Current[-1]*10**6,'uA') Voltage = [] keithley = Keithley.Keithley(channel_GPIB) for current in Current: keithley.set_current_source(current,current_range) keithley.set_voltage_measurement(voltage_range, voltage_compliance) keithley.output_on() time.sleep(10) print("Time: ",time.time()-t0) voltage = keithley.read() Voltage.append(voltage)
sm_vmin = 0 sm_vmax = 1.1 sm_vstep = 0.01 # LED Power supply: ps_voltage = 2.711 # V, for single voltage #for sweep ps_vmin = 2.54 ps_vmax = 2.55 ps_vstep = -0.005 ####################################### # Open Device : Ps = MulticompPro() Sm = Keithley() Mux = ArdunioMux() Cam = Zyla(cam_exposure_time, cam_bit_depth, cam_shutter_mode) ''' LOOPS AVALIABLE: * Format = cam[index]sm[index]ps[index] * Indicies are permutation + combination of the following: * Camera (cam): * 0 = Off * 1 = On * Source meter (sm): * 1 = Short circuit * 2 = Open circuit * 3 = Apply set voltage * 4 = Apply set current * 5 = Voltage sweep
class ControlMainWindow(QtGui.QMainWindow): # Класс главного окна def __del__(self): # Уничтожение класса, на всякий случай закрываем порт, чтоб он не повис self.keithleyPort.close() def __init__(self, parent=None): # Создаём класс (главное окно) super(ControlMainWindow, self).__init__(parent) self.ui = Ui_MainWindow() # Загружаем информацию о расположениее кнопочек - mainwindow.py, файл создаётся # "автоматически" после редактирования интерфейса внешней программой qtDesigner self.ui.setupUi(self) # Config Slots # Подключаем функции пограммы к кнопкам интерфейса self.ui.dcRadioButton.toggled.connect(self.switchSweepType) #self.ui.pulseRadioButton.toggled.connect(self.switchSweepType) #self.filePath = os.getcwd() self.filePath = "e:\Documents\\" # Measurement slots self.ui.measurementButton.clicked.connect(self.doSweep) self.ui.saveButton.clicked.connect(self.saveSweep) self.ui.clearDataButton.clicked.connect(self.clearSweep) # Port Magic # Задаём дефолтные настройки порта self.keithleyPort = serial.Serial() self.keithleyPort.baudrate = 9600 self.keithleyPort.port = "COM2" self.keithleyPort.timeout = 0.1 self.keithley = Keithley() self.ui.keithleyPortOpenButton.clicked.connect(self.openKeithleyPort) # Подключаем функции пограммы к кнопкам интерфейса self.ui.keithleyPortCloseButton.clicked.connect(self.closeKeithleyPort) self.fuckedUp = False # Пара внутренних переменных для работы с данными self.data = [] # # Config Slots # @pyqtSlot(bool) def switchSweepType(self, x): # Вроде выбираем между импульсным режимиом или режимом постоянного тока if x: # Панелька в низу интерфейса меняется когда выбирашь другой режим self.ui.stackedWidget.setCurrentIndex(0) else: self.ui.stackedWidget.setCurrentIndex(1) @pyqtSlot() def doSweep(self): # Измеряй, сохраняй властвуй! #We're ready to sweep if self.keithley.port.isOpen(): #Бесполезные сторчки self.ui.progressBar.setRange(0, 0) #Legacy just in case if self.ui.legacySweepCheckbox.isChecked() or self.keithley.type == '2635A': # Если запрашиваем "старый режим работы" или же у нас прибор 2635А, self.doLegacySweep() # Измеряем по старинке. #Full speed ahead =\ else: # Нет? Страдаем новыми приблудами. #DC Sweep self.fuckedUp = True # Априори считаем, что всё сломалось пока не узнали обратное if self.ui.dcRadioButton.isChecked(): # Если работаем в режиме постоянного тока, пытаемся настроить прибор для работы в этом режиме if self.keithley.armDCMeasurements(remoteSensing=self.ui.fourWireRadio.isChecked(), # Задаем 2х или 4х проводную схему autorange=self.ui.autoRangeCheckBox.isChecked(), # Включаем или выключаем режим автопобора диапаозона range=self.ui.currentRangeSpinBox.value(), # Если выключен автопобор, работаем в этом диапазоне limit=self.ui.currentLimitSpinBox.value()): # Макисмальный ток который можно пропускать через образец self.fuckedUp = False # Мы смогли всё хорошо else: QMessageBox.error(self, "Error", "Couldn't arm DC Measurement") # Не смогли, ругаемся #Pulse Sweep else: # Нет, хотим импульсный if self.keithley.armPulseMeasurements(remoteSensing=self.ui.fourWireRadio.isChecked(), # 4х проводная? range=self.ui.currentRangeSpinBox.value(), # диапазон измерений? limit=self.ui.currentLimitSpinBox.value(), # ограничение по току? pulseWidth=self.ui.pulseWidthSpinEdit.value()/1000.0, # ширина импульса pulseDelay=self.ui.pulseDelaySpinEdit.value()/1000.0): # задержка между импульсами self.fuckedUp = False # получилось else: QMessageBox.error(self, "Error", "Couldn't arm Pulse Measurement") # не получилось #Lets measure and read some points! if not self.fuckedUp: # ух ты, смогли, давайте данные получать! #Linear Sweep if self.ui.LinearRadioButton.isChecked(): # линейный шаг? start = self.ui.sweepStartVSpinEdit.value() # начальное напряжение num = self.ui.NumPointsSpinBox.value() # сколько точек? step = (self.ui.sweepEndSpinEdit.value() - start)/(num - 1) # шаг по напряжению self.data = [] # обнуляем данные for i in range(0, num): # для каждой точки #self.ui.progressBar.setValue(i/num) app.processEvents() # не вешаем интерфейс self.data.append(self.keithley.getPoint(voltage=(start + i*step), repeats=self.ui.numberOfSamplesSpinBox.value())) # Получаем ток при заданном напряжении, усреднённый по N измерениям print(str(i) + ": (" + str(self.data[i][0]) + ", " + str(self.data[i][1]) + ")") # Выводим в консоль QMessageBox.about(self, "Info", "Measurement complete!") # ух ты получилось #Log Sweep else: QMessageBox.about(self, "Info", "Log sweep not yet implemented!") # А логарифмическую шкалу пока не сделал, всё равно не использовали ни разу... self.ui.progressBar.setRange(0, 1) @pyqtSlot() def doLegacySweep(self): # Если вдруг захотелось получить данные по старинке if self.keithley.port.isOpen(): self.keithley.doLegacySweep(startV=self.ui.sweepStartVSpinEdit.value(), # начальное напряжение? endV=self.ui.sweepEndSpinEdit.value(), # конечное напряжение? numberOfPoints=self.ui.NumPointsSpinBox.value(), # сколько точек? remoteSensing=self.ui.fourWireRadio.isChecked(), # 4х проводная схема? logSteps=self.ui.LogRadioButton.isChecked(), # логарифмические шаги autorange=self.ui.autoRangeCheckBox.isChecked(), # автодиапазон range=self.ui.currentRangeSpinBox.value(), # диапазон токов // по измерениям // точность измерения limit=self.ui.currentLimitSpinBox.value(), # ограничение тока pulseSweep=self.ui.pulseRadioButton.isChecked(), # импульсный режим? pulseWidth=self.ui.pulseWidthSpinEdit.value()/1000.0, # ширина импульса pulseDelay=self.ui.pulseDelaySpinEdit.value()/1000.0) # задержка между импульсами QMessageBox.about(self, "Info", "Press Ok when measurement is complete") self.data = self.keithley.legacyReadDataPoints(self.ui.NumPointsSpinBox.value()) # Читаем данные по старинке else: QMessageBox.about(self, "Error", "Port Not Open") @pyqtSlot() def saveSweep(self): # Сохраняем данные с файл fname = QtGui.QFileDialog.getSaveFileName(self, caption="Save file", directory=self.filePath, # Получаем имя файла filter="Text Files (*.txt *.dat *.csv)") self.filePath = os.path.dirname(fname) f = open(fname, 'w') for point in self.data: # Пишем точки. "Напряжение, Ток" f.write(str(point[0]) + ", " + str(point[1]) + "\n") f.close() @pyqtSlot() def clearSweep(self): # Ощичаем внутренее хранилище данных self.data = [] # # Port Magic # @pyqtSlot() def openKeithleyPort(self): # Открываем порт self.keithleyPort.port = self.ui.keithleyPortEdit.text() # Название порта берём из текстового поля self.keithleyPort.close() # Закрываем, если вдруг открыт - не хотим всё повесить print("Trying to open port... ", self.keithleyPort) self.keithleyPort.open() # А теперь открываем! string = "" if self.keithleyPort.isOpen(): # Если получаилось, self.keithleyPort.write(b"*IDN?\n") ## Пишем в прибор запрос на идентификатор string = self.keithleyPort.read(128) ## Читаем идентификатор string = str(string, "windows-1252") ## Читаем с правильной кодировкой self.ui.keithleyPortLabel.setText(string) ## Пишем в интерфейс идентификатор print(string) ## и в консоль тоже пришем else: # Не получилось, print("Failed to do something") ## Ноем в консоль self.ui.keithleyPortLabel.setText("Failed to read ID string") ## Ноем в интерфейс self.keithleyPport.close() ## Закрываем if self.keithleyPort.isOpen(): # Вроде пока всё получается, #Toggle ui self.ui.keithleyPortCloseButton.setEnabled(True) ## Подрубаем интерфейс разговаривающий с прибором self.ui.measureTab.setEnabled(True) #Create Keithley class self.keithleyPort.close() ## Зачем-то закрываем порта self.keithley = Keithley.factory(string, self.keithleyPort) ## Создаём объект прибора if not self.keithley.port.isOpen(): ## Если чё, опять открываем порт. self.keithley.port.open() @pyqtSlot() def closeKeithleyPort(self): # Закрываем порт #Close Keithley port self.keithley.port.close() # Закрыли порт self.ui.keithleyPortLabel.setText("Port Closed") #Toggle ui self.ui.keithleyPortCloseButton.setEnabled(False) # Отключили элементы интерфейса, работающие с прибором self.ui.measureTab.setEnabled(False)
def runTest(self): """main test routine""" auto = self.autoSave.get_active() if auto: try: gtk.gdk.threads_enter() start = self.buffer.get_start_iter() end = self.buffer.get_end_iter() self.buffer.delete(start, end) finally: gtk.gdk.threads_leave() try: s = None program = None psu = None s = SerialPort() serialNumber = self.serialNumber.get_text().strip() versionNumber = self.versionNumber.get_text().strip() if '' == serialNumber: raise StopTestException('Serial number invalid') program = ProgramPin() psu = Keithley.PSU2303() psu.setCurrent(SUPPLY_CURRENT_LIMIT) psu.setVoltage(SUPPLY_STANDARD_VOLTAGE) psu.powerOn() self.write('\n*** Start of Test for device SN: %s ***\n\n' % (serialNumber)) t = time.time() self.write( '*** Press device power on button to begin test ***\n\n') starting = True run = True current_version = 'NONE' while run: line = '' while not self.testStop: c = s.readChar() if '\n' == c: break if '' == c or ' ' > c: if starting: i = psu.current self.write( 'INFO: starting, current = %7.3f mA @ %5.1f V\n' % (1000 * i, psu.voltage)) if MINIMUM_ON_CURRENT < i: starting = False s.resetHigh() s.write(' ') time.sleep(0.02) s.write(' ') continue line = line + c if 'menu?' == line: s.write(' ') self.write('Menu detected\n') if self.testStop: raise StopTestException('Stop button pressed') self.write(line) self.write('\n') # verify the serial number if line.startswith('S/N:'): psn = line.split(' ')[-1] if serialNumber == psn: self.write('PASS: Programmed S/N matches\n', 'pass-text') else: self.write( 'FAIL: FLASH S/N(%s) != %s\n' % (psn, serialNumber), 'fail-text') raise StopTestException('Serial Number mismatch') elif line.upper().startswith('VERSION') or (line + 'X')[0].isdigit(): current_version = line.split(' ')[-1] if '. Boot Test Program' == line[1:]: s.write(line[0:1]) elif '*SUSPEND*' == line: samples = 30 total = 0 for j in range(samples): i = psu.current total = total + i self.write( 'INFO: suspend current = %7.3f mA @ %5.1f V\n' % (1000 * i, psu.voltage)) time.sleep(0.1) average_suspend_current = total / samples self.write( 'INFO: average suspend current = %7.3f mA @ %5.1f V\n' % (1000 * average_suspend_current, psu.voltage)) if abs(average_suspend_current) > MAXIMUM_SUSPEND_CURRENT: s.write('N') else: s.write('Y') elif '*VERSION*' == line: self.write('INFO: check "%s" against "%s"\n' % (current_version, versionNumber)) if current_version.lower() == versionNumber.lower(): s.write('Y') else: s.write('N') raise StopTestException('Version Number mismatch') else: i = psu.current self.write('INFO: current = %7.3f mA @ %5.1f V\n' % (1000 * i, psu.voltage)) if abs(i) > MAXIMUM_ON_CURRENT: raise StopTestException( 'Device overcurrent: %7.3f mA' % (1000 * i)) if '*END-TEST*' == line: run = False t = time.time() - t self.write('\n*** End of Test [%7.3f seconds] ***\n' % (t)) except StopTestException, e: # no save on manual abort auto = False self.write('\n*** Test stop exception ***\n') self.write('FAIL: %s\n' % str(e))
class ControlMainWindow(QtGui.QMainWindow): def __del__(self): self.keithleyPort.close() def __init__(self, parent=None): super(ControlMainWindow, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # Config Slots self.ui.dcRadioButton.toggled.connect(self.switchSweepType) #self.ui.pulseRadioButton.toggled.connect(self.switchSweepType) # Measurement slots self.ui.measurementButton.clicked.connect(self.doSweep) self.ui.saveButton.clicked.connect(self.saveSweep) self.ui.clearDataButton.clicked.connect(self.clearSweep) # Port Magic self.keithleyPort = serial.Serial() self.keithleyPort.baudrate = 9600 self.keithleyPort.port = "COM2" self.keithleyPort.timeout = 0.1 self.keithley = Keithley() self.ui.keithleyPortOpenButton.clicked.connect(self.openKeithleyPort) self.ui.keithleyPortCloseButton.clicked.connect(self.closeKeithleyPort) self.fuckedUp = False self.data = [] # # Config Slots # @pyqtSlot(bool) def switchSweepType(self, x): if x: self.ui.stackedWidget.setCurrentIndex(0) else: self.ui.stackedWidget.setCurrentIndex(1) # # Legacy Measurement slots # @pyqtSlot() def doSweep(self): #We're ready to sweep if self.keithley.port.isOpen(): self.ui.progressBar.setRange(0, 0) #Legacy just in case if self.ui.legacySweepCheckbox.isChecked(): self.doLegacySweep() #Full speed ahead =\ else: #DC Sweep self.fuckedUp = True if self.ui.dcRadioButton.isChecked(): if self.keithley.armDCMeasurements(remoteSensing=self.ui.fourWireRadio.isChecked(), autorange=self.ui.autoRangeCheckBox.isChecked(), range=self.ui.currentRangeSpinBox.value(), limit=self.ui.currentLimitSpinBox.value()): self.fuckedUp = False else: QMessageBox.error(self, "Error", "Couldn't arm DC Measurement") #Pulse Sweep else: if self.keithley.armPulseMeasurements(remoteSensing=self.ui.fourWireRadio.isChecked(), range=self.ui.currentRangeSpinBox.value(), limit=self.ui.currentLimitSpinBox.value(), pulseWidth=self.ui.pulseWidthSpinEdit.value()/1000.0, pulseDelay=self.ui.pulseDelaySpinEdit.value()/1000.0): self.fuckedUp = False else: QMessageBox.error(self, "Error", "Couldn't arm Pulse Measurement") #Lets measure and read some points! if not self.fuckedUp: #Linear Sweep if self.ui.LinearRadioButton.isChecked(): start = self.ui.sweepStartVSpinEdit.value() num = self.ui.NumPointsSpinBox.value() step = (self.ui.sweepEndSpinEdit.value() - start)/(num - 1) self.data = [] for i in range(0, num): #self.ui.progressBar.setValue(i/num) app.processEvents() self.data.append(self.keithley.getPoint(voltage=(start + i*step), repeats=self.ui.numberOfSamplesSpinBox.value())) print(str(i) + ": (" + str(self.data[i][0]) + ", " + str(self.data[i][1]) + ")") QMessageBox.about(self, "Info", "Measurement complete!") #Log Sweep else: QMessageBox.about(self, "Info", "Log sweep not yet implemented!") self.ui.progressBar.setRange(0, 1) @pyqtSlot() def doLegacySweep(self): if self.keithley.port.isOpen(): self.keithley.doLegacySweep(startV=self.ui.sweepStartVSpinEdit.value(), endV=self.ui.sweepEndSpinEdit.value(), numberOfPoints=self.ui.NumPointsSpinBox.value(), remoteSensing=self.ui.fourWireRadio.isChecked(), logSteps=self.ui.LogRadioButton.isChecked(), autorange=self.ui.autoRangeCheckBox.isChecked(), range=self.ui.currentRangeSpinBox.value(), limit=self.ui.currentLimitSpinBox.value(), pulseSweep=self.ui.pulseRadioButton.isChecked(), pulseWidth=self.ui.pulseWidthSpinEdit.value()/1000.0, pulseDelay=self.ui.pulseDelaySpinEdit.value()/1000.0) QMessageBox.about(self, "Info", "Press Ok when measurement is complete") self.data = self.keithley.legacyReadDataPoints(self.ui.NumPointsSpinBox.value()) else: QMessageBox.about(self, "Error", "Port Not Open") @pyqtSlot() def saveSweep(self): fname = QtGui.QFileDialog.getSaveFileName(self, caption="Save file", directory=os.getcwd(), filter="Text Files (*.txt *.dat *.csv)") f = open(fname, 'w') for point in self.data: f.write(str(point[0]) + ", " + str(point[1]) + "\n") f.close() @pyqtSlot() def clearSweep(self): self.data = [] # # Port Magic # @pyqtSlot() def openKeithleyPort(self): self.keithleyPort.port = self.ui.keithleyPortEdit.text() self.keithleyPort.close() print("Trying to open port... ", self.keithleyPort) self.keithleyPort.open() string = "" if self.keithleyPort.isOpen(): self.keithleyPort.write(b"*IDN?\n") string = self.keithleyPort.read(128) string = str(string, "windows-1252") self.ui.keithleyPortLabel.setText(string) print(string) else: print("Failed to do something") self.ui.keithleyPortLabel.setText("Failed to read ID string") self.keithleyPport.close() if self.keithleyPort.isOpen(): #Toggle ui self.ui.keithleyPortCloseButton.setEnabled(True) self.ui.measureTab.setEnabled(True) #Create Keithley class self.keithleyPort.close() self.keithley = Keithley.factory(string, self.keithleyPort) if not self.keithley.port.isOpen(): self.keithley.port.open() @pyqtSlot() def closeKeithleyPort(self): #Close Keithley port self.keithley.port.close() self.ui.keithleyPortLabel.setText("Port Closed") #Toggle ui self.ui.keithleyPortCloseButton.setEnabled(False) self.ui.measureTab.setEnabled(False)