class PrologixUSB(_prologix_base): """ Interface to a Prologix GPIB-USB controller. To instantiate, specify the virtual serial port where the controller is plugged in: >>> plx = prologix.prologix_USB('/dev/ttyUSBgpib') On Windows, you could use something like >>> plx = prologix.prologix_USB('COM1') """ def __init__(self, port='/dev/ttyUSBgpib', log=False): # create a serial port object self.bus = Serial(port, baudrate=115200, rtscts=1, log=log) # if this doesn't work, try settin rtscts=0 # flush whatever is hanging out in the buffer self.bus.readall() # don't save settings (to avoid wearing out EEPROM) self.savecfg = False # do common startup routines super(PrologixUSB, self).__init__() def write(self, command, lag=0.1): self.bus.write("%s\r" % command) sleep(lag) def readall(self): resp = self.bus.readall() return resp.rstrip() def ask(self, query, *args, **kwargs): """ Write to the bus, then read response. """ #TODO: if bus doesn't have a logger self.bus.logger.debug('clearing buffer - expect no result') self.readall() # clear the buffer self.write(query, *args, **kwargs) return self.readall()
class Capture(object): """Class to capture samples from Tektronix TDS 3054B""" def __init__(self, port='/dev/ttyS0', baud=38400): """@todo: to be defined1 :port: Serial port :baud: Baud rate (max 38400) """ self.port = port self.baud = baud self.bus = Serial(port, baudrate=baud, rtscts=True, term_chars='\n') self.init() def init(self): """@todo: Docstring for init :arg1: @todo :returns: @todo """ self.bus.write('HDR OFF') self.bus.write('DATA:STOP 10000') self.bus.write('WFMPRE:NR_P 10000') self.scope = TDS3000(self.bus) def capture(self,channels=None): """Capture samples from the Tektronix TDS 3054B :channels: An array of the channels to retrieve :returns: Captured data array with each channel as column """ if channels is None: channels = range(1,5) #allch = np.array([self.scope.get_wfm('CH%d' % i)[1] for i in channels]).T allch = [self.scope.get_wfm('CH%d' % i)[1] for i in channels] return np.array(allch).T def capsave(self, file_path, vthresh=1.5): """Capture, convert to OLS format and save to file Assumes a voltage threshold of 1.5 :file_path: output file path :returns: None """ allch = self.capture() out = ols.to_ols(allch, vthresh) open(file_path, 'w').write(out)
class spex750m(object): """ A class implementing standard Jobin-Yvon serial commands for simple spectrometers like the SPEX 750M. By default, this class is configured to look for the 750M plugged into ``/dev/ttyUSB0`` (the first port on the USB-serial adapter, when run under linux). """ def __init__(self, addr=None): """ Connect to the spectrometer and initialize its hardware. :param addr: the serial interface where the spectrometer is found. Default: ``/dev/ttyUSB0`` """ if addr is None: addr = self._default_location self.bus = Serial(addr, timeout=10, baudrate=19200) try: self.init_hardware() # try to initialize hardware. except InstrumentError as err: print("%s, rebooting once..." % err) self.reboot() # in case of trouble, reboot self.init_hardware() # and try again. # 750M specific data _steps_per_nm = 4000 _default_location = '/dev/ttyUSB0' def __str__(self): return 'Spex 750M' def boot_status_check(self): """Check the boot status of the controller. - \* : Just Autobauded - B : Boot Acknowledged - F : Just Flashed """ self.bus.readall() resp = self.bus.ask(' ') # send autobaud character if len(resp) == 0: raise InstrumentError("750M did not give a boot status") elif resp[0] in ("*", "F", "B"): return resp[0] else: raise InstrumentError("Unknown 750M boot status: %s" % resp) def reboot(self): """Reboot the controller if it's not responding""" return self.bus.ask("\xDE") def _hi_iq(self): """Send the HI IQ character to the controller. (Duplicates functionality of F7-247.vi.) Returns True if it's ok to flash the controller afterward. """ self.bus.readall() resp = self.bus.ask("\xF7") if resp[0] == "=": return True else: raise InstrumentError("750M HI IQ command failed") def _flash(self): """Flash the controller by sending the O2000<null> string to it. """ return self.bus.ask("O2000\x00") def init_hardware(self): """Initialize 750M hardware. I don't know why this works, I just copied Yan's LabView routine. """ status = self.boot_status_check() if status == "*": self._hi_iq() # * -> B self._flash() # B -> F status = self.boot_status_check() if status == "F": return True else: raise InstrumentError("750M hardware init failed.") def wait_for_ok(self, expected_bytes=1): """ Wait indefinitely for the 'o' status byte. This function waits until a certain number of bytes (usually just one) are present on the bus. When that data arrives, the first bye is read and checked to make sure it's the "okay" status. """ while self.bus.inWaiting() < expected_bytes: # as long as the buffer is empty, hang out sleep(0.050) # read the status byte when it arrives resp = self.bus.read() if resp != 'o': raise InstrumentError("750M operation failed: %s" % resp) def calibrate(self, wl_value): """Read the current wavelength from the window and pass it to this method (units of nm) to recalibrate the 750M. """ self.bus.readall() cmd = "G0,%d\r" % (wl_value * self._steps_per_nm) self.bus.write(cmd) self.wait_for_ok() _busyCodes = {"q": True, "z": False} def is_busy(self): """Check if the motors are busy. """ self.bus.write("E") self.wait_for_ok() resp = self.bus.readall() return self._busyCodes[resp] def rel_move(self, distance_to_move): """Move the grating by the given number of nanometers.""" self.bus.readall() cmd = "F0,%d\r" % (distance_to_move * self._steps_per_nm) self.bus.write(cmd) self.wait_for_ok() while self.is_busy(): # wait for the motors to rest sleep(0.050) def get_wavelength(self): """Query the current wavelength """ self.bus.readall() self.bus.write("HO\r") self.wait_for_ok() resp = self.bus.readall(term_chars='\r') # convert to wavelength units wl = int(resp) / float(self._steps_per_nm) return wl def set_wavelength(self, wl): """Move to the wavelength value specified. contingent on proper calibration, of course. """ if wl < 0 or wl > 1500: raise InstrumentError("Out of Range") distance_to_move = wl - self.get_wavelength() self.rel_move(distance_to_move) wavelength = property(get_wavelength, set_wavelength) # abbreviate 'wavelength' to 'wl' get_wl = get_wavelength set_wl = set_wavelength wl = wavelength
class spex750m(object): """ A class implementing standard Jobin-Yvon serial commands for simple spectrometers like the SPEX 750M. By default, this class is configured to look for the 750M plugged into ``/dev/ttyUSB0`` (the first port on the USB-serial adapter, when run under linux). """ def __init__(self, addr=None): """ Connect to the spectrometer and initialize its hardware. :param addr: the serial interface where the spectrometer is found. Default: ``/dev/ttyUSB0`` """ if addr is None: addr = self._default_location self.bus = Serial(addr, timeout=10, baudrate=19200) try: self.init_hardware() # try to initialize hardware. except InstrumentError as err: print "%s, rebooting once..." % err self.reboot() # in case of trouble, reboot self.init_hardware() # and try again. # 750M specific data _steps_per_nm = 4000 _default_location = "/dev/ttyUSB0" def __str__(self): return "Spex 750M" def boot_status_check(self): """Check the boot status of the controller. - \* : Just Autobauded - B : Boot Acknowledged - F : Just Flashed """ self.bus.readall() resp = self.bus.ask(" ") # send autobaud character if len(resp) == 0: raise InstrumentError("750M did not give a boot status") elif resp[0] in ("*", "F", "B"): return resp[0] else: raise InstrumentError("Unknown 750M boot status: %s" % resp) def reboot(self): """Reboot the controller if it's not responding""" return self.bus.ask("\xDE") def _hi_iq(self): """Send the HI IQ character to the controller. (Duplicates functionality of F7-247.vi.) Returns True if it's ok to flash the controller afterward. """ self.bus.readall() resp = self.bus.ask("\xF7") if resp[0] == "=": return True else: raise InstrumentError("750M HI IQ command failed") def _flash(self): """Flash the controller by sending the O2000<null> string to it. """ return self.bus.ask("O2000\x00") def init_hardware(self): """Initialize 750M hardware. I don't know why this works, I just copied Yan's LabView routine. """ status = self.boot_status_check() if status == "*": self._hi_iq() # * -> B self._flash() # B -> F status = self.boot_status_check() if status == "F": return True else: raise InstrumentError("750M hardware init failed.") def wait_for_ok(self, expected_bytes=1): """ Wait indefinitely for the 'o' status byte. This function waits until a certain number of bytes (usually just one) are present on the bus. When that data arrives, the first bye is read and checked to make sure it's the "okay" status. """ while self.bus.inWaiting() < expected_bytes: # as long as the buffer is empty, hang out sleep(0.050) # read the status byte when it arrives resp = self.bus.read() if resp != "o": raise InstrumentError("750M operation failed: %s" % resp) def calibrate(self, wl_value): """Read the current wavelength from the window and pass it to this method (units of nm) to recalibrate the 750M. """ self.bus.readall() cmd = "G0,%d\r" % (wl_value * self._steps_per_nm) self.bus.write(cmd) self.wait_for_ok() _busyCodes = {"q": True, "z": False} def is_busy(self): """Check if the motors are busy. """ self.bus.write("E") self.wait_for_ok() resp = self.bus.readall() return self._busyCodes[resp] def rel_move(self, distance_to_move): """Move the grating by the given number of nanometers.""" self.bus.readall() cmd = "F0,%d\r" % (distance_to_move * self._steps_per_nm) self.bus.write(cmd) self.wait_for_ok() while self.is_busy(): # wait for the motors to rest sleep(0.050) def get_wavelength(self): """Query the current wavelength """ self.bus.readall() self.bus.write("HO\r") self.wait_for_ok() resp = self.bus.readall(term_chars="\r") # convert to wavelength units wl = int(resp) / float(self._steps_per_nm) return wl def set_wavelength(self, wl): """Move to the wavelength value specified. contingent on proper calibration, of course. """ if wl < 0 or wl > 1500: raise InstrumentError("Out of Range") distance_to_move = wl - self.get_wavelength() self.rel_move(distance_to_move) wavelength = property(get_wavelength, set_wavelength) # abbreviate 'wavelength' to 'wl' get_wl = get_wavelength set_wl = set_wavelength wl = wavelength