├── .gitignore ├── anim.py ├── animtest2.py ├── oceanoptics_gui.ui ├── ui_oceanoptics.py ├── gui.py ├── oceanoptics.py ├── Untitled0.ipynb └── Driver.ipynb /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | 3 | -------------------------------------------------------------------------------- /anim.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from galry import * 3 | from oceanoptics import USB4000 4 | 5 | dev = USB4000() 6 | 7 | dev.set_integration_time(50000) 8 | int16 = np.dtype(' 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 770 10 | 590 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | 21 | 500 22 | 500 23 | 24 | 25 | 26 | USB4000 GUI 27 | 28 | 29 | 30 | 31 | 0 32 | 0 33 | 34 | 35 | 36 | 37 | 3000 38 | 3000 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 0 50 | 200 51 | 52 | 53 | 54 | Settings 55 | 56 | 57 | false 58 | 59 | 60 | false 61 | 62 | 63 | 64 | 65 | 66 | QLayout::SetMinAndMaxSize 67 | 68 | 69 | QFormLayout::FieldsStayAtSizeHint 70 | 71 | 72 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 73 | 74 | 75 | 30 76 | 77 | 78 | 30 79 | 80 | 81 | 82 | 83 | Integration time 84 | 85 | 86 | false 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 0 95 | 0 96 | 97 | 98 | 99 | 100 | 100 101 | 0 102 | 103 | 104 | 105 | 10 106 | 107 | 108 | 109 | 110 | 111 | 112 | Temperature 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 0 121 | 0 122 | 123 | 124 | 125 | 126 | 100 127 | 0 128 | 129 | 130 | 131 | true 132 | 133 | 134 | 4 135 | 136 | 137 | 4 138 | 139 | 140 | QLCDNumber::Flat 141 | 142 | 143 | 25.000000000000000 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 0 152 | 0 153 | 154 | 155 | 156 | 157 | 100 158 | 0 159 | 160 | 161 | 162 | 1 163 | 164 | 165 | 10 166 | 167 | 168 | 169 | 170 | 171 | 172 | Persistence 173 | 174 | 175 | 176 | 177 | 178 | 179 | Wavelength 180 | 181 | 182 | 183 | 184 | 185 | 186 | 0 nm 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 0 200 | 0 201 | 202 | 203 | 204 | QFrame::NoFrame 205 | 206 | 207 | QFrame::Plain 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 0 217 | 0 218 | 770 219 | 22 220 | 221 | 222 | 223 | 224 | 225 | 226 | PlotWidget 227 | QGraphicsView 228 |
pyqtgraph
229 |
230 | 231 | SpinBox 232 | QSpinBox 233 |
pyqtgraph
234 |
235 |
236 | 237 | 238 |
239 | -------------------------------------------------------------------------------- /ui_oceanoptics.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'oceanoptics_gui.ui' 4 | # 5 | # Created: Sat Feb 1 12:50:02 2014 6 | # by: PyQt4 UI code generator 4.10.3 7 | # 8 | # WARNING! All changes made in this file will be lost! 9 | 10 | from PyQt4 import QtCore, QtGui 11 | 12 | try: 13 | _fromUtf8 = QtCore.QString.fromUtf8 14 | except AttributeError: 15 | def _fromUtf8(s): 16 | return s 17 | 18 | try: 19 | _encoding = QtGui.QApplication.UnicodeUTF8 20 | def _translate(context, text, disambig): 21 | return QtGui.QApplication.translate(context, text, disambig, _encoding) 22 | except AttributeError: 23 | def _translate(context, text, disambig): 24 | return QtGui.QApplication.translate(context, text, disambig) 25 | 26 | class Ui_MainWindow(object): 27 | def setupUi(self, MainWindow): 28 | MainWindow.setObjectName(_fromUtf8("MainWindow")) 29 | MainWindow.resize(770, 590) 30 | sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) 31 | sizePolicy.setHorizontalStretch(0) 32 | sizePolicy.setVerticalStretch(0) 33 | sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth()) 34 | MainWindow.setSizePolicy(sizePolicy) 35 | MainWindow.setMinimumSize(QtCore.QSize(500, 500)) 36 | self.centralwidget = QtGui.QWidget(MainWindow) 37 | sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) 38 | sizePolicy.setHorizontalStretch(0) 39 | sizePolicy.setVerticalStretch(0) 40 | sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth()) 41 | self.centralwidget.setSizePolicy(sizePolicy) 42 | self.centralwidget.setMaximumSize(QtCore.QSize(3000, 3000)) 43 | self.centralwidget.setObjectName(_fromUtf8("centralwidget")) 44 | self.gridLayout = QtGui.QGridLayout(self.centralwidget) 45 | self.gridLayout.setObjectName(_fromUtf8("gridLayout")) 46 | self.graphicsView = PlotWidget(self.centralwidget) 47 | self.graphicsView.setObjectName(_fromUtf8("graphicsView")) 48 | self.gridLayout.addWidget(self.graphicsView, 0, 0, 1, 2) 49 | self.groupBox = QtGui.QGroupBox(self.centralwidget) 50 | self.groupBox.setMinimumSize(QtCore.QSize(0, 200)) 51 | self.groupBox.setFlat(False) 52 | self.groupBox.setCheckable(False) 53 | self.groupBox.setObjectName(_fromUtf8("groupBox")) 54 | self.horizontalLayout = QtGui.QHBoxLayout(self.groupBox) 55 | self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) 56 | self.formLayout = QtGui.QFormLayout() 57 | self.formLayout.setSizeConstraint(QtGui.QLayout.SetMinAndMaxSize) 58 | self.formLayout.setFieldGrowthPolicy(QtGui.QFormLayout.FieldsStayAtSizeHint) 59 | self.formLayout.setLabelAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter) 60 | self.formLayout.setSpacing(30) 61 | self.formLayout.setObjectName(_fromUtf8("formLayout")) 62 | self.label = QtGui.QLabel(self.groupBox) 63 | self.label.setScaledContents(False) 64 | self.label.setObjectName(_fromUtf8("label")) 65 | self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.label) 66 | self.spinBox = SpinBox(self.groupBox) 67 | sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) 68 | sizePolicy.setHorizontalStretch(0) 69 | sizePolicy.setVerticalStretch(0) 70 | sizePolicy.setHeightForWidth(self.spinBox.sizePolicy().hasHeightForWidth()) 71 | self.spinBox.setSizePolicy(sizePolicy) 72 | self.spinBox.setMinimumSize(QtCore.QSize(100, 0)) 73 | self.spinBox.setProperty("value", 10) 74 | self.spinBox.setObjectName(_fromUtf8("spinBox")) 75 | self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.spinBox) 76 | self.label_3 = QtGui.QLabel(self.groupBox) 77 | self.label_3.setObjectName(_fromUtf8("label_3")) 78 | self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.label_3) 79 | self.lcdNumber = QtGui.QLCDNumber(self.groupBox) 80 | sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum) 81 | sizePolicy.setHorizontalStretch(0) 82 | sizePolicy.setVerticalStretch(0) 83 | sizePolicy.setHeightForWidth(self.lcdNumber.sizePolicy().hasHeightForWidth()) 84 | self.lcdNumber.setSizePolicy(sizePolicy) 85 | self.lcdNumber.setMinimumSize(QtCore.QSize(100, 0)) 86 | self.lcdNumber.setSmallDecimalPoint(True) 87 | self.lcdNumber.setNumDigits(4) 88 | self.lcdNumber.setDigitCount(4) 89 | self.lcdNumber.setSegmentStyle(QtGui.QLCDNumber.Flat) 90 | self.lcdNumber.setProperty("value", 25.0) 91 | self.lcdNumber.setObjectName(_fromUtf8("lcdNumber")) 92 | self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.lcdNumber) 93 | self.persistenceBox = QtGui.QSpinBox(self.groupBox) 94 | sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed) 95 | sizePolicy.setHorizontalStretch(0) 96 | sizePolicy.setVerticalStretch(0) 97 | sizePolicy.setHeightForWidth(self.persistenceBox.sizePolicy().hasHeightForWidth()) 98 | self.persistenceBox.setSizePolicy(sizePolicy) 99 | self.persistenceBox.setMinimumSize(QtCore.QSize(100, 0)) 100 | self.persistenceBox.setMinimum(1) 101 | self.persistenceBox.setMaximum(10) 102 | self.persistenceBox.setObjectName(_fromUtf8("persistenceBox")) 103 | self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.persistenceBox) 104 | self.label_4 = QtGui.QLabel(self.groupBox) 105 | self.label_4.setObjectName(_fromUtf8("label_4")) 106 | self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.label_4) 107 | self.label_2 = QtGui.QLabel(self.groupBox) 108 | self.label_2.setObjectName(_fromUtf8("label_2")) 109 | self.formLayout.setWidget(3, QtGui.QFormLayout.LabelRole, self.label_2) 110 | self.wavelength_label = QtGui.QLabel(self.groupBox) 111 | self.wavelength_label.setObjectName(_fromUtf8("wavelength_label")) 112 | self.formLayout.setWidget(3, QtGui.QFormLayout.FieldRole, self.wavelength_label) 113 | self.horizontalLayout.addLayout(self.formLayout) 114 | self.gridLayout.addWidget(self.groupBox, 1, 0, 1, 1) 115 | self.frame = QtGui.QFrame(self.centralwidget) 116 | sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) 117 | sizePolicy.setHorizontalStretch(0) 118 | sizePolicy.setVerticalStretch(0) 119 | sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth()) 120 | self.frame.setSizePolicy(sizePolicy) 121 | self.frame.setFrameShape(QtGui.QFrame.NoFrame) 122 | self.frame.setFrameShadow(QtGui.QFrame.Plain) 123 | self.frame.setObjectName(_fromUtf8("frame")) 124 | self.gridLayout.addWidget(self.frame, 1, 1, 1, 1) 125 | MainWindow.setCentralWidget(self.centralwidget) 126 | self.menubar = QtGui.QMenuBar(MainWindow) 127 | self.menubar.setGeometry(QtCore.QRect(0, 0, 770, 22)) 128 | self.menubar.setObjectName(_fromUtf8("menubar")) 129 | MainWindow.setMenuBar(self.menubar) 130 | 131 | self.retranslateUi(MainWindow) 132 | QtCore.QMetaObject.connectSlotsByName(MainWindow) 133 | 134 | def retranslateUi(self, MainWindow): 135 | MainWindow.setWindowTitle(_translate("MainWindow", "USB4000 GUI", None)) 136 | self.groupBox.setTitle(_translate("MainWindow", "Settings", None)) 137 | self.label.setText(_translate("MainWindow", "Integration time", None)) 138 | self.label_3.setText(_translate("MainWindow", "Temperature", None)) 139 | self.label_4.setText(_translate("MainWindow", "Persistence", None)) 140 | self.label_2.setText(_translate("MainWindow", "Wavelength", None)) 141 | self.wavelength_label.setText(_translate("MainWindow", "0 nm", None)) 142 | 143 | from pyqtgraph import SpinBox, PlotWidget 144 | -------------------------------------------------------------------------------- /gui.py: -------------------------------------------------------------------------------- 1 | import time 2 | import threading 3 | import sys 4 | from collections import deque 5 | 6 | from PySide import QtGui 7 | from PySide.QtCore import QTimer 8 | from PySide.QtGui import QMainWindow, QGroupBox, QWidget, QHBoxLayout, QFormLayout 9 | import pyqtgraph as pg 10 | 11 | from oceanoptics import USB4000 12 | import logging 13 | 14 | import numpy as np 15 | 16 | np.seterr(divide='ignore') 17 | 18 | log = logging.getLogger('oceanoptics.gui') 19 | 20 | log.setLevel(logging.CRITICAL) 21 | 22 | class SpectrometerWindow(QMainWindow): 23 | def __init__(self, parent=None): 24 | # Set up everything 25 | QMainWindow.__init__(self, parent) 26 | self.setWindowTitle("USB4000 Control") 27 | 28 | self.make_main_frame() 29 | 30 | self.spectra_timer = QTimer() 31 | self.spectra_timer.timeout.connect(self.update_spectrum) 32 | 33 | self.temp_timer = QTimer() 34 | self.temp_timer.timeout.connect(self.update_temp) 35 | 36 | self.worker = Usb4000Thread() 37 | self.wavelength_mapping = self.worker.dev.get_wavelength_mapping() 38 | 39 | self.curves = [] 40 | self.persistence_sb.valueChanged.connect(self.change_persistence) 41 | self.change_persistence() 42 | 43 | self.background = 1 44 | self.bg_min = 0 45 | 46 | self.use_background = False 47 | 48 | self.abs645 = pg.InfiniteLine(angle=90, movable=False) 49 | self.abs663 = pg.InfiniteLine(angle=90, movable=False) 50 | 51 | self.plot.addItem(self.abs645, ignoreBounds=True) 52 | self.plot.addItem(self.abs663, ignoreBounds=True) 53 | 54 | self.abs645.setPos(645) 55 | self.abs663.setPos(663) 56 | 57 | self.conc_deque = deque(maxlen=20) 58 | 59 | def make_main_frame(self): 60 | self.main_frame = QWidget() 61 | win = pg.GraphicsWindow() 62 | self.crosshair_lb = pg.LabelItem(justify='right') 63 | win.addItem(self.crosshair_lb) 64 | self.plot = win.addPlot(row=1, col=0) 65 | self.plot.showGrid(x=True, y=True) 66 | self.right_panel = QGroupBox("Spectrometer Settings") 67 | 68 | hbox = QHBoxLayout() 69 | for w in [win, self.right_panel]: 70 | hbox.addWidget(w) 71 | 72 | form = QFormLayout() 73 | 74 | self.integration_sb = pg.SpinBox(value=0.001, bounds=(10*1e-6, 6553500*1e-6), suffix='s', siPrefix=True, \ 75 | dec=True, step=1) 76 | self.integration_sb.valueChanged.connect(self.change_integration_time) 77 | 78 | self.persistence_sb = QtGui.QSpinBox() 79 | self.persistence_sb.setValue(7) 80 | self.persistence_sb.setRange(1,10) 81 | self.persistence_sb.valueChanged.connect(self.change_persistence) 82 | 83 | self.take_background_btn = QtGui.QPushButton('Take background') 84 | self.take_background_btn.clicked.connect(self.on_take_background) 85 | self.conc_lb = pg.ValueLabel() 86 | 87 | self.spec_temp_lb = pg.ValueLabel() 88 | 89 | self.use_background_cb = QtGui.QCheckBox("enabled") 90 | self.use_background_cb.stateChanged.connect(self.on_use_background) 91 | 92 | form.addRow("Integration time", self.integration_sb) 93 | form.addRow("Persistence", self.persistence_sb) 94 | 95 | form.addRow("Background", self.take_background_btn) 96 | form.addRow("Use background", self.use_background_cb) 97 | self.right_panel.setLayout(form) 98 | self.main_frame.setLayout(hbox) 99 | self.setCentralWidget(self.main_frame) 100 | 101 | def on_use_background(self): 102 | if self.use_background_cb.isChecked(): 103 | self.spectra_timer.stop() 104 | self.spectra_timer.start(500) 105 | self.persistence_sb.setValue(1) 106 | self.change_persistence() 107 | self.use_background = True 108 | else: 109 | self.spectra_timer.stop() 110 | self.spectra_timer.start(25) 111 | self.use_background = False 112 | 113 | def process_spectrum(self, data): 114 | if self.use_background: 115 | res = np.log10(self.background) - np.log10(np.array(data, dtype='float')) 116 | self.conc_deque.append((res[1455]*20.2 + res[1539]*8.02)*0.2) 117 | self.crosshair_lb.setText("Abs645=%0.3f, Abs663=%0.3f, Conc=%0.3f" % (res[1455],res[1539], np.mean(np.array(self.conc_deque)))) 118 | return res 119 | else: 120 | return np.array(data, dtype='float') 121 | 122 | def update_spectrum(self): 123 | self.data_stack.append(self.worker.get_spectrum()) 124 | 125 | for i in xrange(len(self.data_stack)): 126 | d = self.data_stack[i] 127 | if d != None: 128 | log.debug('plotting curve %d', i) 129 | if i == len(self.data_stack)-1: 130 | self.curves[i].setPen(color=(0, 255, 0, 255)) 131 | else: 132 | self.curves[i].setPen(color=(0, 255, 0, 50)) 133 | self.curves[i].setData(self.wavelength_mapping, self.process_spectrum(d)) 134 | 135 | def update_temp(self): 136 | res = self.worker.get_temp() 137 | 138 | if res != None: 139 | self.spec_temp_lb.setText("value") 140 | 141 | def change_integration_time(self): 142 | self.worker.set_integration_time(int(self.integration_sb.value()*1e6)) 143 | 144 | def change_persistence(self): 145 | self.spectra_timer.stop() 146 | log.info('persistence changed') 147 | # remove all curves 148 | for i in self.curves: self.plot.removeItem(i) 149 | 150 | self.curves = [] 151 | # add new curves 152 | val = self.persistence_sb.value() 153 | 154 | for i in xrange(val): 155 | log.info('added %d item', i) 156 | self.curves.append(self.plot.plot()) 157 | 158 | self.data_stack = deque(maxlen=val) 159 | log.info('maxlen is %d', val) 160 | self.spectra_timer.start(25) 161 | 162 | def on_take_background(self): 163 | self.spectra_timer.stop() 164 | self.data_stack.clear() 165 | 166 | bg = self.worker.get_spectrum() 167 | self.bg_min = np.amin(bg) 168 | self.background = np.array(bg, dtype='float') 169 | self.spectra_timer.start(25) 170 | 171 | def close(self): 172 | self.worker.join() 173 | 174 | def show(self): 175 | self.temp_timer.start(1000) 176 | self.spectra_timer.start(25) 177 | self.worker.start() 178 | super(QMainWindow, self).show() 179 | 180 | def closeEvent(self, event): 181 | super(QMainWindow, self).closeEvent(event) 182 | 183 | class Usb4000Thread(threading.Thread): 184 | def __init__(self): 185 | super(Usb4000Thread, self).__init__() 186 | 187 | self.dev = USB4000() 188 | self.cmd_q = deque(maxlen=100) 189 | 190 | self.data = None 191 | self.temp = None 192 | 193 | self.is_active = threading.Event() 194 | 195 | def get_spectrum(self): 196 | # add spectrum to queue 197 | self.cmd_q.append((self._spectrum, [])) 198 | 199 | # and return a dataset 200 | return self.data 201 | 202 | def _spectrum(self): 203 | try: 204 | self.data = self.dev.request_spectra() 205 | except Exception as e: 206 | log.error('could not request spectrum') 207 | log.error(repr(e)) 208 | 209 | def get_temp(self): 210 | #self.cmd_q.clear() 211 | self.cmd_q.append((self._temp, [])) 212 | 213 | return self.temp 214 | 215 | def _temp(self): 216 | self.temp = self.dev.read_temp() 217 | 218 | def set_integration_time(self, val): 219 | self.cmd_q.clear() 220 | self.cmd_q.append((self._integration_time, [val])) 221 | 222 | def _integration_time(self, val): 223 | try: 224 | self.dev.set_integration_time(val) 225 | except Exception as e: 226 | log.error('could not set integration time') 227 | log.error(repr(e)) 228 | 229 | def run(self): 230 | self.is_active.set() 231 | 232 | while self.is_active.is_set(): 233 | try: 234 | cmd, args = self.cmd_q.popleft() 235 | cmd(*args) 236 | log.debug('executed command {}'.format(repr(cmd))) 237 | except IndexError: 238 | time.sleep(0.05) 239 | 240 | def join(self): 241 | self.is_active.clear() 242 | 243 | # Try to create a worker thread that polls device 244 | app = QtGui.QApplication(sys.argv) 245 | 246 | try: 247 | ex = SpectrometerWindow() 248 | ex.show() 249 | app.exec_() 250 | except RuntimeError as e: 251 | print e 252 | 253 | -------------------------------------------------------------------------------- /oceanoptics.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import usb.core 3 | import usb.util 4 | import struct 5 | import numpy 6 | 7 | logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') 8 | log = logging.getLogger('oceanoptics.hardware') 9 | 10 | log.setLevel(logging.INFO) 11 | __all__ = ['USB4000'] 12 | 13 | commands = { \ 14 | 0x01: ('init', 'initialize USB4000'), 15 | 0x02: ('set_i', 'set integration time in uS'), 16 | 0x03: ('set_strobe', 'set strobe enable status'), 17 | 0x05: ('ask', 'query information'), 18 | 0x06: ('write', 'write information'), 19 | 0x09: ('get_spectra', 'request spectra'), 20 | \ 21 | 0x0A: ('set_trigger', 'set trigger mode'), 22 | 0x0B: ('num_plugins', 'query number of plug-in accessories present'), 23 | 0x0C: ('plugin_ids', 'query plug-in identifiers'), 24 | 0x0D: ('detect_plugins', 'detect plug-ins'), 25 | \ 26 | 0x60: ('read_i2c', 'general I2C read'), 27 | 0x61: ('write_i2c', 'general I2C write'), 28 | 0x62: ('spi_io', 'general spi I/O'), 29 | 0x68: ('read_psoc', 'PSOC read'), 30 | 0x69: ('write_psoc', 'PSOC write'), 31 | 0x6A: ('write_reg', 'write register information'), 32 | 0x6B: ('read_reg', 'read register information'), 33 | 0x6C: ('read_temp', 'read PCB temperature'), 34 | 0x6D: ('read_calib', 'read irradiance calibration factors'), 35 | 0x6E: ('write_calib', 'write irradiance calibration factors'), 36 | \ 37 | 0xFE: ('ask_2', 'query information') 38 | } 39 | 40 | config_regs = {\ 41 | 0: 'serial_number', 42 | 1: '0_order_wavelength_coeff', 43 | 2: '1_order_wavelength_coeff', 44 | 3: '2_order_wavelength_coeff', 45 | 4: '3_order_wavelength_coeff', 46 | 5: 'stray_light_constant', 47 | 6: '0_order_nonlinear_coeff', 48 | 7: '1_order_nonlinear_coeff', 49 | 8: '2_order_nonlinear_coeff', 50 | 9: '3_order_nonlinear_coeff', 51 | 10: '4_order_nonlinear_coeff', 52 | 11: '5_order_nonlinear_coeff', 53 | 12: '6_order_nonlinear_coeff', 54 | 13: '7_order_nonlinear_coeff', 55 | 14: 'polynomial_order', 56 | 15: 'bench_configuration', 57 | 16: 'USB4000_config', 58 | 17: 'autonull', 59 | 18: 'baud_rate' \ 60 | } 61 | 62 | class USB4000(object): 63 | '''Class representing Ocean Optics spectrometer''' 64 | 65 | idVendor = 0x2457 66 | idProduct = 0x1022 67 | 68 | def __new__(cls, id=0): 69 | avail = usb.core.find(idVendor=cls.idVendor, idProduct=cls.idProduct) 70 | 71 | if avail is None: 72 | raise RuntimeError('no ocean optics devices found') 73 | 74 | if isinstance(avail, list): 75 | print 'Got {:d} devices, taking {:d}'.format(len(avail), id) 76 | avail = avail[id] 77 | obj = super(USB4000, cls).__new__(cls) 78 | obj._device = avail 79 | return obj 80 | 81 | def __init__(self): 82 | log.debug('In init!') 83 | 84 | try: 85 | if self._device.is_kernel_driver_active(0): 86 | self._device.detach_kernel_driver(0) 87 | except (usb.core.USBError, NotImplementedError) as e: 88 | log.error(repr(e)) 89 | 90 | try: 91 | self._device.set_configuration() # There is only one configuration 92 | #self._device.reset() 93 | except usb.core.USBError as e: 94 | log.fatal("could not set configuration") 95 | raise RuntimeError('failed to set configuration') 96 | 97 | cfg = self._device.get_active_configuration() 98 | 99 | self._cmd_w = usb.util.find_descriptor(cfg[(0,0)], bEndpointAddress=0x01) 100 | self._spec_hi = usb.util.find_descriptor(cfg[(0,0)], bEndpointAddress=0x82) 101 | self._spec_lo = usb.util.find_descriptor(cfg[(0,0)], bEndpointAddress=0x86) 102 | self._cmd_r = usb.util.find_descriptor(cfg[(0,0)], bEndpointAddress=0x81) 103 | 104 | # initialize spectrometer 105 | self.init() 106 | 107 | def init(self): 108 | '''sends the initialization command to the USB4000 spectrometer 109 | 110 | This command initializes certain parameters on the USB4000 and sets internal variables 111 | based on the USB communication speed. This command is called at object instantiation. 112 | ''' 113 | self._cmd_w.write(struct.pack(' 65535000: # largest value of 32 bit unsigned int 128 | log.warning('integration time {:d} too high, setting to maximum of 65,535,000 us'.format(dt)) 129 | dt = 65535000 # can't integrate for less than 10 us 130 | 131 | cmd = struct.pack('H', resp[1:3])[0] 190 | log.info('firmware is {:d}'.format(vers)) 191 | return vers 192 | 193 | def set_trigger_mode(self, mode=0): 194 | log.debug('setting {} for the trigger mode'.format(repr(mode))) 195 | if isinstance(mode, int): 196 | cmd = struct.pack(']" 132 | ] 133 | }, 134 | { 135 | "output_type": "display_data", 136 | "png": "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\nnzH3328P3h0d0Z3Y449HQ0F7e/TAadszOnjr+OlP2/t1dfagd9tt9vl//EdjJk2KbV9v3t703s7c\nCxqSPYB5Qcor+/WvY5ftlT32mK1/5/Jp04x54gnb5jt32vl7B/3Fi6PL9g4Mr71my/76VzttMGjM\nL38Zu010dNhw/8Ybxtx5pw1CXrnUPaxmZhrz4x/bspwce5uREdsWd9xhy0tKosv5l3+x9WlttcN7\n78W2V3Jy7Lo+80xsW544YYNs57qEw3Z79lxyiQ1a27cbc9ddxvzP/2nHf+gh+xp+/vP28Z499qD/\n3nvGHDkSuw0sWGDMf/2XbbOOjugHma5De3vP5V/+cs/lpxoyMoz5zW+ij9essbdLl9rbf/1XW7cd\nO+zOfNKkaGCXbPgPBKLTt7TYbaPzMrz17jocOmTMxInG5OXZ12TKlJ4PeqNH2+V861t2updesh8S\nOs/rT3+ybfLTn9rH9fV2nt5+wu+Pjnv0qG1fLwgfOhR9buFCu8zHHrP7ps7bSGe7dxvzH/9hA0tx\nsTGPPmrMH/8YW6e1a+3tr34VncewYdHg/9RT0bDhTZOebutqTPQDmffcb35jHweDpxc+vOn+6Z/s\ne/mvf7XrlZ5uy+fONebWW2OnefZZ+5rfeqsdx/sg09Ji67tvX3Tea9ca8+1v24Dleffd7h+on3nG\nvsc9f/tbtG6LFtmyn/3MmIcfNubcc6Pr9sQTxjQ1Rdu7qio63b59tv3vvdfuD7wPXj/9qQ0tn/mM\nbT/vg7T3YcUY+wG0oSFan44OYy691NbdGPsh3pvOU1ER/SDrjbN1q93Xee/FEyfscef+++0Hgq6v\n0eHDdhuX7Hb5/vux7/+eXHKJMTNn2g81Xlt1tn+/vX37bdtencfJzrb17OzPf47dj3nb7Pnn223E\n8/77dh+1Y4d9vGWLrf9NN/UcyjsfUzs67Pje8a2lxQ7vvmvX25jouH/8o338gx8Yk5JizPDh9j3i\nTeuN5+3LjbGB9G9/s/e99fNOSLzwgt0uv/jF6HbotbG3bGPstvy979lpbr65+7rs3m3vP/igbf+u\ntm6NZhOv/u+/b/f13n5j1Sr7uvzzP0ene+cd2zbG2G3Fywc97Wfa220uqa62beetq9fW3nFWMmbG\nDLu/+6Dtaaj7yAbtl1+ObiR1dXZj/s1v7MF27177xv74x3sOAN6G+uij9vaOO6IH08REe3vZZbHT\n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\nAAAASUVORK5CYII=\n", 137 | "text": [ 138 | "" 139 | ] 140 | } 141 | ], 142 | "prompt_number": 6 143 | }, 144 | { 145 | "cell_type": "code", 146 | "collapsed": false, 147 | "input": [ 148 | "dev.reset()" 149 | ], 150 | "language": "python", 151 | "metadata": {}, 152 | "outputs": [ 153 | { 154 | "output_type": "stream", 155 | "stream": "stderr", 156 | "text": [ 157 | "2013-05-15 22:54:40,639 - DEBUG - resetting device\n" 158 | ] 159 | } 160 | ], 161 | "prompt_number": 65 162 | }, 163 | { 164 | "cell_type": "code", 165 | "collapsed": false, 166 | "input": [ 167 | "dev.get_status()" 168 | ], 169 | "language": "python", 170 | "metadata": {}, 171 | "outputs": [ 172 | { 173 | "output_type": "stream", 174 | "stream": "stderr", 175 | "text": [ 176 | "2013-05-15 22:55:26,242 - DEBUG - getting status parameters\n" 177 | ] 178 | }, 179 | { 180 | "output_type": "stream", 181 | "stream": "stderr", 182 | "text": [ 183 | "2013-05-15 22:55:26,242 - DEBUG - Sending '\\xfe'\n" 184 | ] 185 | }, 186 | { 187 | "output_type": "stream", 188 | "stream": "stderr", 189 | "text": [ 190 | "2013-05-15 22:55:26,244 - DEBUG - status is bytearray(b\"\\x00\\x0f\\x10\\'\\x00\\x00\\x00\\x00\\x00\\x0f\\x00\\x00\\x00\\x00\\x80U\")\n" 191 | ] 192 | }, 193 | { 194 | "output_type": "pyout", 195 | "prompt_number": 70, 196 | "text": [ 197 | "{'acq_status': 0,\n", 198 | " 'integration_time': 10000,\n", 199 | " 'lamp_enable': False,\n", 200 | " 'num_pixels': 3840,\n", 201 | " 'packet_count': 0,\n", 202 | " 'packets_in_spectra': 15,\n", 203 | " 'power_down': False,\n", 204 | " 'trigger_mode': 0,\n", 205 | " 'usb_speed': 128}" 206 | ] 207 | } 208 | ], 209 | "prompt_number": 70 210 | }, 211 | { 212 | "cell_type": "code", 213 | "collapsed": false, 214 | "input": [], 215 | "language": "python", 216 | "metadata": {}, 217 | "outputs": [] 218 | } 219 | ], 220 | "metadata": {} 221 | } 222 | ] 223 | } -------------------------------------------------------------------------------- /Driver.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "Driver" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "code", 12 | "collapsed": false, 13 | "input": [ 14 | "import logging\n", 15 | "logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')\n", 16 | "logging.debug('This is a log message.')" 17 | ], 18 | "language": "python", 19 | "metadata": {}, 20 | "outputs": [ 21 | { 22 | "output_type": "stream", 23 | "stream": "stderr", 24 | "text": [ 25 | "2013-05-15 20:10:08,090 - DEBUG - This is a log message.\n" 26 | ] 27 | } 28 | ], 29 | "prompt_number": 2 30 | }, 31 | { 32 | "cell_type": "code", 33 | "collapsed": false, 34 | "input": [ 35 | "import usb.core\n", 36 | "import usb.util\n", 37 | "import struct\n", 38 | "import time\n", 39 | "\n", 40 | "commands = { \\\n", 41 | " 0x01: ('init', 'initialize USB4000'), \n", 42 | " 0x02: ('set_i', 'set integration time in uS'), \n", 43 | " 0x03: ('set_strobe', 'set strobe enable status'), \n", 44 | " 0x05: ('ask', 'query information'), \n", 45 | " 0x06: ('write', 'write information'), \n", 46 | " 0x09: ('get_spectra', 'request spectra'), \n", 47 | " \\\n", 48 | " 0x0A: ('set_trigger', 'set trigger mode'),\n", 49 | " 0x0B: ('num_plugins', 'query number of plug-in accessories present'),\n", 50 | " 0x0C: ('plugin_ids', 'query plug-in identifiers'),\n", 51 | " 0x0D: ('detect_plugins', 'detect plug-ins'),\n", 52 | " \\\n", 53 | " 0x60: ('read_i2c', 'general I2C read'),\n", 54 | " 0x61: ('write_i2c', 'general I2C write'),\n", 55 | " 0x62: ('spi_io', 'general spi I/O'),\n", 56 | " 0x68: ('read_psoc', 'PSOC read'),\n", 57 | " 0x69: ('write_psoc', 'PSOC write'),\n", 58 | " 0x6A: ('write_reg', 'write register information'),\n", 59 | " 0x6B: ('read_reg', 'read register information'),\n", 60 | " 0x6C: ('read_temp', 'read PCB temperature'),\n", 61 | " 0x6D: ('read_calib', 'read irradiance calibration factors'),\n", 62 | " 0x6E: ('write_calib', 'write irradiance calibration factors'),\n", 63 | " \\\n", 64 | " 0xFE: ('ask_2', 'query information')\n", 65 | "}\n", 66 | "\n", 67 | "config_regs = {\\\n", 68 | " 0: 'serial_number',\n", 69 | " 1: '0_order_wavelength_coeff',\n", 70 | " 2: '1_order_wavelength_coeff',\n", 71 | " 3: '2_order_wavelength_coeff',\n", 72 | " 4: '3_order_wavelength_coeff',\n", 73 | " 5: 'stray_light_constant',\n", 74 | " 6: '0_order_nonlinear_coeff',\n", 75 | " 7: '1_order_nonlinear_coeff',\n", 76 | " 8: '2_order_nonlinear_coeff',\n", 77 | " 9: '3_order_nonlinear_coeff',\n", 78 | " 10: '4_order_nonlinear_coeff',\n", 79 | " 11: '5_order_nonlinear_coeff',\n", 80 | " 12: '6_order_nonlinear_coeff',\n", 81 | " 13: '7_order_nonlinear_coeff',\n", 82 | " 14: 'polynomial_order',\n", 83 | " 15: 'bench_configuration',\n", 84 | " 16: 'USB4000_config',\n", 85 | " 17: 'autonull',\n", 86 | " 18: 'baud_rate' \\\n", 87 | "} \n", 88 | "\n", 89 | "class USB4000(object):\n", 90 | " '''Class representing Ocean Optics spectrometer'''\n", 91 | " \n", 92 | " idVendor = 0x2457\n", 93 | " idProduct = 0x1022\n", 94 | " \n", 95 | " def __new__(cls, id=0):\n", 96 | " avail = usb.core.find(idVendor=cls.idVendor, idProduct=cls.idProduct)\n", 97 | " if avail is None:\n", 98 | " raise RuntimeError('no ocean optics devices found')\n", 99 | " \n", 100 | " if isinstance(avail, list):\n", 101 | " print 'Got {:d} devices, taking {:d}'.format(len(avail), id)\n", 102 | " avail = avail[id]\n", 103 | " obj = super(USB4000, cls).__new__(cls)\n", 104 | " obj._device = avail\n", 105 | " return obj\n", 106 | " \n", 107 | " def __init__(self, debug=False):\n", 108 | " logging.debug('In init!')\n", 109 | " \n", 110 | " if self._device.is_kernel_driver_active(0):\n", 111 | " try:\n", 112 | " self._device.detach_kernel_driver(0)\n", 113 | " except usb.core.USBError as e:\n", 114 | " logging.fatal(\"Could not detatch kernel driver: %s\" % str(e))\n", 115 | " raise e\n", 116 | " \n", 117 | " try:\n", 118 | " self._device.set_configuration() # There is only one configuration\n", 119 | " self._device.reset()\n", 120 | " except usb.core.USBError as e:\n", 121 | " logging.fatal(\"could not set configuration\" % str(e))\n", 122 | " raise e\n", 123 | " \n", 124 | " cfg = self._device.get_active_configuration()\n", 125 | " \n", 126 | " self._cmd_w = usb.util.find_descriptor(cfg[(0,0)], bEndpointAddress=0x01)\n", 127 | " self._spec_lo = usb.util.find_descriptor(cfg[(0,0)], bEndpointAddress=0x82)\n", 128 | " self._spec_hi = usb.util.find_descriptor(cfg[(0,0)], bEndpointAddress=0x86)\n", 129 | " self._cmd_r = usb.util.find_descriptor(cfg[(0,0)], bEndpointAddress=0x81)\n", 130 | " \n", 131 | " # initialize spectrometer\n", 132 | " self.init()\n", 133 | " \n", 134 | " def init(self):\n", 135 | " '''sends the initialization command to the USB4000 spectrometer\n", 136 | " \n", 137 | " This command initializes certain parameters on the USB4000 and sets internal variables\n", 138 | " based on the USB communication speed. This command is called at object instantiation.\n", 139 | " '''\n", 140 | " self._cmd_w.write(struct.pack(' 65535000: # largest value of 32 bit unsigned int\n", 155 | " logging.warning('integration time {:d} too high, setting to maximum of 65,535,000 us'.format(dt))\n", 156 | " dt = 65535000 # can't integrate for less than 10 us\n", 157 | " \n", 158 | " cmd = struct.pack('H', resp[1:3])[0]\n", 217 | " logging.info('firmware is {:d}'.format(vers))\n", 218 | " return vers\n", 219 | " \n", 220 | " def set_trigger_mode(self, mode=0):\n", 221 | " logging.debug('setting {} for the trigger mode'.format(repr(mode)))\n", 222 | " if isinstance(mode, int):\n", 223 | " cmd = struct.pack('\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdev\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mquery_config\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 378 | "\u001b[0;32m\u001b[0m in \u001b[0;36mquery_config\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 136\u001b[0m \u001b[0mcmd\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mstruct\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpack\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'<2B'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0x05\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 137\u001b[0m \u001b[0mlogging\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdebug\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Sending {:s}'\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrepr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcmd\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 138\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_cmd_w\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcmd\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 139\u001b[0m \u001b[0mresp\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mbytearray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_cmd_r\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m64\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1000\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 140\u001b[0m \u001b[0mlogging\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdebug\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'config {:d} is {:s}'\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrepr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresp\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 379 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/core.pyc\u001b[0m in \u001b[0;36mwrite\u001b[0;34m(self, data, timeout)\u001b[0m\n\u001b[1;32m 286\u001b[0m \u001b[0mFor\u001b[0m \u001b[0mdetails\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msee\u001b[0m \u001b[0mthe\u001b[0m \u001b[0mDevice\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 287\u001b[0m \"\"\"\n\u001b[0;32m--> 288\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbEndpointAddress\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minterface\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 289\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 290\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msize\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 380 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/core.pyc\u001b[0m in \u001b[0;36mwrite\u001b[0;34m(self, endpoint, data, interface, timeout)\u001b[0m\n\u001b[1;32m 624\u001b[0m \u001b[0mintf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbInterfaceNumber\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 625\u001b[0m \u001b[0m_interop\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mas_array\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 626\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__get_timeout\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtimeout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 627\u001b[0m )\n\u001b[1;32m 628\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 381 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/backend/libusb1.pyc\u001b[0m in \u001b[0;36mbulk_write\u001b[0;34m(self, dev_handle, ep, intf, data, timeout)\u001b[0m\n\u001b[1;32m 530\u001b[0m \u001b[0mintf\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 531\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 532\u001b[0;31m timeout)\n\u001b[0m\u001b[1;32m 533\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 534\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mmethodtrace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_logger\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 382 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/backend/libusb1.pyc\u001b[0m in \u001b[0;36m__write\u001b[0;34m(self, fn, dev_handle, ep, intf, data, timeout)\u001b[0m\n\u001b[1;32m 629\u001b[0m \u001b[0;31m# do not assume LIBUSB_ERROR_TIMEOUT means no I/O.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 630\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mtransferred\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mretval\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mLIBUSB_ERROR_TIMEOUT\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 631\u001b[0;31m \u001b[0m_check\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mretval\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 632\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 633\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mtransferred\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 383 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/backend/libusb1.pyc\u001b[0m in \u001b[0;36m_check\u001b[0;34m(retval)\u001b[0m\n\u001b[1;32m 401\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0musb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcore\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mUSBError\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 402\u001b[0m \u001b[0mret\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mretval\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 403\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mUSBError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_str_error\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mret\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mret\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_libusb_errno\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mret\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 404\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mretval\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 405\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 384 | "\u001b[0;31mUSBError\u001b[0m: [Errno 60] Operation timed out" 385 | ] 386 | } 387 | ], 388 | "prompt_number": 20 389 | }, 390 | { 391 | "cell_type": "code", 392 | "collapsed": false, 393 | "input": [ 394 | "dev.request_spectra()" 395 | ], 396 | "language": "python", 397 | "metadata": {}, 398 | "outputs": [ 399 | { 400 | "output_type": "stream", 401 | "stream": "stderr", 402 | "text": [ 403 | "2013-05-15 20:15:46,995 - DEBUG - Requesting spectra\n" 404 | ] 405 | }, 406 | { 407 | "output_type": "stream", 408 | "stream": "stderr", 409 | "text": [ 410 | "2013-05-15 20:15:46,995 - DEBUG - Sending '\\t'\n" 411 | ] 412 | }, 413 | { 414 | "ename": "USBError", 415 | "evalue": "[Errno 60] Operation timed out", 416 | "output_type": "pyerr", 417 | "traceback": [ 418 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mUSBError\u001b[0m Traceback (most recent call last)", 419 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdev\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrequest_spectra\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 420 | "\u001b[0;32m\u001b[0m in \u001b[0;36mrequest_spectra\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 196\u001b[0m \u001b[0mlogging\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdebug\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Requesting spectra'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 197\u001b[0m \u001b[0mlogging\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdebug\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Sending {:s}'\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrepr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcmd\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 198\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_cmd_w\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcmd\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 199\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 200\u001b[0m \u001b[0mpackets\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 421 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/core.pyc\u001b[0m in \u001b[0;36mwrite\u001b[0;34m(self, data, timeout)\u001b[0m\n\u001b[1;32m 286\u001b[0m \u001b[0mFor\u001b[0m \u001b[0mdetails\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msee\u001b[0m \u001b[0mthe\u001b[0m \u001b[0mDevice\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 287\u001b[0m \"\"\"\n\u001b[0;32m--> 288\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbEndpointAddress\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minterface\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 289\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 290\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msize\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 422 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/core.pyc\u001b[0m in \u001b[0;36mwrite\u001b[0;34m(self, endpoint, data, interface, timeout)\u001b[0m\n\u001b[1;32m 624\u001b[0m \u001b[0mintf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbInterfaceNumber\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 625\u001b[0m \u001b[0m_interop\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mas_array\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 626\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__get_timeout\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtimeout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 627\u001b[0m )\n\u001b[1;32m 628\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 423 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/backend/libusb1.pyc\u001b[0m in \u001b[0;36mbulk_write\u001b[0;34m(self, dev_handle, ep, intf, data, timeout)\u001b[0m\n\u001b[1;32m 530\u001b[0m \u001b[0mintf\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 531\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 532\u001b[0;31m timeout)\n\u001b[0m\u001b[1;32m 533\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 534\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mmethodtrace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_logger\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 424 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/backend/libusb1.pyc\u001b[0m in \u001b[0;36m__write\u001b[0;34m(self, fn, dev_handle, ep, intf, data, timeout)\u001b[0m\n\u001b[1;32m 629\u001b[0m \u001b[0;31m# do not assume LIBUSB_ERROR_TIMEOUT means no I/O.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 630\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mtransferred\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mretval\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mLIBUSB_ERROR_TIMEOUT\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 631\u001b[0;31m \u001b[0m_check\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mretval\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 632\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 633\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mtransferred\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 425 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/backend/libusb1.pyc\u001b[0m in \u001b[0;36m_check\u001b[0;34m(retval)\u001b[0m\n\u001b[1;32m 401\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0musb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcore\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mUSBError\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 402\u001b[0m \u001b[0mret\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mretval\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 403\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mUSBError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_str_error\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mret\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mret\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_libusb_errno\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mret\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 404\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mretval\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 405\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 426 | "\u001b[0;31mUSBError\u001b[0m: [Errno 60] Operation timed out" 427 | ] 428 | } 429 | ], 430 | "prompt_number": 19 431 | }, 432 | { 433 | "cell_type": "code", 434 | "collapsed": false, 435 | "input": [ 436 | "dev.firmware_version()" 437 | ], 438 | "language": "python", 439 | "metadata": {}, 440 | "outputs": [ 441 | { 442 | "output_type": "stream", 443 | "stream": "stderr", 444 | "text": [ 445 | "2013-05-15 20:10:37,631 - DEBUG - getting firmware version\n" 446 | ] 447 | }, 448 | { 449 | "output_type": "stream", 450 | "stream": "stderr", 451 | "text": [ 452 | "2013-05-15 20:10:37,631 - DEBUG - sending 'k\\x04'\n" 453 | ] 454 | }, 455 | { 456 | "output_type": "stream", 457 | "stream": "stderr", 458 | "text": [ 459 | "2013-05-15 20:10:37,634 - DEBUG - got bytearray(b'\\x000\\x10')\n" 460 | ] 461 | }, 462 | { 463 | "output_type": "stream", 464 | "stream": "stderr", 465 | "text": [ 466 | "2013-05-15 20:10:37,635 - INFO - firmware is 12304\n" 467 | ] 468 | }, 469 | { 470 | "output_type": "pyout", 471 | "prompt_number": 7, 472 | "text": [ 473 | "12304" 474 | ] 475 | } 476 | ], 477 | "prompt_number": 7 478 | }, 479 | { 480 | "cell_type": "code", 481 | "collapsed": false, 482 | "input": [ 483 | "dev.read_temp()" 484 | ], 485 | "language": "python", 486 | "metadata": {}, 487 | "outputs": [ 488 | { 489 | "output_type": "stream", 490 | "stream": "stderr", 491 | "text": [ 492 | "2013-05-15 20:13:54,268 - DEBUG - getting pcb temperature\n" 493 | ] 494 | }, 495 | { 496 | "ename": "USBError", 497 | "evalue": "[Errno 60] Operation timed out", 498 | "output_type": "pyerr", 499 | "traceback": [ 500 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mUSBError\u001b[0m Traceback (most recent call last)", 501 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdev\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread_temp\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 502 | "\u001b[0;32m\u001b[0m in \u001b[0;36mread_temp\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 154\u001b[0m \u001b[0mlogging\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdebug\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'getting pcb temperature'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 155\u001b[0m \u001b[0mcmd\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mstruct\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpack\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m' 156\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_cmd_w\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcmd\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 157\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 158\u001b[0m \u001b[0mlogging\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdebug\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'sending {:s}'\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrepr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcmd\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 503 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/core.pyc\u001b[0m in \u001b[0;36mwrite\u001b[0;34m(self, data, timeout)\u001b[0m\n\u001b[1;32m 286\u001b[0m \u001b[0mFor\u001b[0m \u001b[0mdetails\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msee\u001b[0m \u001b[0mthe\u001b[0m \u001b[0mDevice\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 287\u001b[0m \"\"\"\n\u001b[0;32m--> 288\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbEndpointAddress\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minterface\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 289\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 290\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msize\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 504 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/core.pyc\u001b[0m in \u001b[0;36mwrite\u001b[0;34m(self, endpoint, data, interface, timeout)\u001b[0m\n\u001b[1;32m 624\u001b[0m \u001b[0mintf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbInterfaceNumber\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 625\u001b[0m \u001b[0m_interop\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mas_array\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 626\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__get_timeout\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtimeout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 627\u001b[0m )\n\u001b[1;32m 628\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 505 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/backend/libusb1.pyc\u001b[0m in \u001b[0;36mbulk_write\u001b[0;34m(self, dev_handle, ep, intf, data, timeout)\u001b[0m\n\u001b[1;32m 530\u001b[0m \u001b[0mintf\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 531\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 532\u001b[0;31m timeout)\n\u001b[0m\u001b[1;32m 533\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 534\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mmethodtrace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_logger\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 506 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/backend/libusb1.pyc\u001b[0m in \u001b[0;36m__write\u001b[0;34m(self, fn, dev_handle, ep, intf, data, timeout)\u001b[0m\n\u001b[1;32m 629\u001b[0m \u001b[0;31m# do not assume LIBUSB_ERROR_TIMEOUT means no I/O.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 630\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mtransferred\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mretval\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mLIBUSB_ERROR_TIMEOUT\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 631\u001b[0;31m \u001b[0m_check\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mretval\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 632\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 633\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mtransferred\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 507 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/backend/libusb1.pyc\u001b[0m in \u001b[0;36m_check\u001b[0;34m(retval)\u001b[0m\n\u001b[1;32m 401\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0musb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcore\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mUSBError\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 402\u001b[0m \u001b[0mret\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mretval\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 403\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mUSBError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_str_error\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mret\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mret\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_libusb_errno\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mret\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 404\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mretval\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 405\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 508 | "\u001b[0;31mUSBError\u001b[0m: [Errno 60] Operation timed out" 509 | ] 510 | } 511 | ], 512 | "prompt_number": 18 513 | }, 514 | { 515 | "cell_type": "code", 516 | "collapsed": false, 517 | "input": [ 518 | "dev.reset()" 519 | ], 520 | "language": "python", 521 | "metadata": {}, 522 | "outputs": [ 523 | { 524 | "output_type": "stream", 525 | "stream": "stderr", 526 | "text": [ 527 | "2013-05-15 20:08:25,088 - DEBUG - resetting device\n" 528 | ] 529 | } 530 | ], 531 | "prompt_number": 39 532 | }, 533 | { 534 | "cell_type": "code", 535 | "collapsed": false, 536 | "input": [ 537 | "dev.status" 538 | ], 539 | "language": "python", 540 | "metadata": {}, 541 | "outputs": [ 542 | { 543 | "output_type": "stream", 544 | "stream": "stderr", 545 | "text": [ 546 | "2013-05-15 20:13:13,072 - DEBUG - getting status parameters\n" 547 | ] 548 | }, 549 | { 550 | "output_type": "stream", 551 | "stream": "stderr", 552 | "text": [ 553 | "2013-05-15 20:13:13,073 - DEBUG - Sending '\\xfe'\n" 554 | ] 555 | }, 556 | { 557 | "ename": "USBError", 558 | "evalue": "[Errno 60] Operation timed out", 559 | "output_type": "pyerr", 560 | "traceback": [ 561 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mUSBError\u001b[0m Traceback (most recent call last)", 562 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdev\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstatus\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 563 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 239\u001b[0m \u001b[0musb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mutil\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdispose_resources\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_device\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 240\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 241\u001b[0;31m \u001b[0mstatus\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mproperty\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mlambda\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_status\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 564 | "\u001b[0;32m\u001b[0m in \u001b[0;36mget_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 219\u001b[0m \u001b[0mlogging\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdebug\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Sending {:s}'\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrepr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcmd\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 220\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_cmd_w\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcmd\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 221\u001b[0;31m \u001b[0mresp\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mbytearray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_cmd_r\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m16\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1000\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 222\u001b[0m \u001b[0mlogging\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdebug\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'status is {:s}'\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrepr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresp\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 223\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 565 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/core.pyc\u001b[0m in \u001b[0;36mread\u001b[0;34m(self, size, timeout)\u001b[0m\n\u001b[1;32m 299\u001b[0m \u001b[0mFor\u001b[0m \u001b[0mdetails\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msee\u001b[0m \u001b[0mthe\u001b[0m \u001b[0mDevice\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0mmethod\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 300\u001b[0m \"\"\"\n\u001b[0;32m--> 301\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdevice\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbEndpointAddress\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msize\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minterface\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 302\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 303\u001b[0m \u001b[0;32mclass\u001b[0m \u001b[0mInterface\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobject\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 566 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/core.pyc\u001b[0m in \u001b[0;36mread\u001b[0;34m(self, endpoint, size, interface, timeout)\u001b[0m\n\u001b[1;32m 659\u001b[0m \u001b[0mintf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbInterfaceNumber\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 660\u001b[0m \u001b[0msize\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 661\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__get_timeout\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtimeout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 662\u001b[0m )\n\u001b[1;32m 663\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 567 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/backend/libusb1.pyc\u001b[0m in \u001b[0;36mbulk_read\u001b[0;34m(self, dev_handle, ep, intf, size, timeout)\u001b[0m\n\u001b[1;32m 539\u001b[0m \u001b[0mintf\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 540\u001b[0m \u001b[0msize\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 541\u001b[0;31m timeout)\n\u001b[0m\u001b[1;32m 542\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 543\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mmethodtrace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_logger\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 568 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/backend/libusb1.pyc\u001b[0m in \u001b[0;36m__read\u001b[0;34m(self, fn, dev_handle, ep, intf, size, timeout)\u001b[0m\n\u001b[1;32m 646\u001b[0m \u001b[0;31m# do not assume LIBUSB_ERROR_TIMEOUT means no I/O.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 647\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mtransferred\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mretval\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mLIBUSB_ERROR_TIMEOUT\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 648\u001b[0;31m \u001b[0m_check\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mretval\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 649\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0mtransferred\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 650\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 569 | "\u001b[0;32m/usr/local/lib/python2.7/site-packages/usb/backend/libusb1.pyc\u001b[0m in \u001b[0;36m_check\u001b[0;34m(retval)\u001b[0m\n\u001b[1;32m 401\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0musb\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcore\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mUSBError\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 402\u001b[0m \u001b[0mret\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mretval\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 403\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mUSBError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_str_error\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mret\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mret\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_libusb_errno\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mret\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 404\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mretval\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 405\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 570 | "\u001b[0;31mUSBError\u001b[0m: [Errno 60] Operation timed out" 571 | ] 572 | } 573 | ], 574 | "prompt_number": 17 575 | }, 576 | { 577 | "cell_type": "code", 578 | "collapsed": false, 579 | "input": [ 580 | "dev.set_trigger_mode(0)" 581 | ], 582 | "language": "python", 583 | "metadata": {}, 584 | "outputs": [ 585 | { 586 | "output_type": "stream", 587 | "stream": "stderr", 588 | "text": [ 589 | "2013-05-15 20:12:54,441 - DEBUG - setting 0 for the trigger mode\n" 590 | ] 591 | }, 592 | { 593 | "output_type": "stream", 594 | "stream": "stderr", 595 | "text": [ 596 | "2013-05-15 20:12:54,442 - DEBUG - Sending '\\n\\x00\\x00'\n" 597 | ] 598 | }, 599 | { 600 | "output_type": "pyout", 601 | "prompt_number": 15, 602 | "text": [ 603 | "3" 604 | ] 605 | } 606 | ], 607 | "prompt_number": 15 608 | }, 609 | { 610 | "cell_type": "code", 611 | "collapsed": false, 612 | "input": [], 613 | "language": "python", 614 | "metadata": {}, 615 | "outputs": [] 616 | } 617 | ], 618 | "metadata": {} 619 | } 620 | ] 621 | } --------------------------------------------------------------------------------