예제 #1
0
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
예제 #2
0
파일: spex750m.py 프로젝트: thoo/wanglib
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