prologix.py

Fri, 25 Jan 2008 20:49:28 +0100

author
David Douard <david.douard@logilab.fr>
date
Fri, 25 Jan 2008 20:49:28 +0100
changeset 29
558a7d3fb123
parent 14
07e2cbf140df
child 35
3b7a38af5c42
permissions
-rw-r--r--

oops, forgot icon files

"""
prologix
========

Module defining a communication object to talk to Prologix USB-GPIB controler.

"""
import serial
import time

import gpib
from gpib import ConnectionError

GPIB_CONTROLLER = 1
GPIB_DEVICE = 0

class GPIB(object):
    _retries = 15
    def __init__(self, device="/dev/ttyUSB0", baudrate=115200, timeout=0.1,
                    address=0, mode=1):        
        """
        Create a new GPIB controller for the Prologix USB-GPIB device
        located on serial device 'device'.        
        """
        self._cnx = serial.Serial(port=device, baudrate=baudrate, timeout=timeout)
        self._timeout = timeout
        
        self.set_mode(mode)
        self.set_address(address)
        
    def set_address(self, address):
        """
        Set the address of the GPIB device:
        
        - if the device is the Controller In Charge, this is the
          address of the device commands are sent to,

        - if the device is in GPIB_DEVICE mode, this is its address.
        """
        self._set_cmd('addr', address)
        self._adress = address
        
    def set_mode(self, mode):
        """
        Set GPIB device mode to 'mode':
        
        - GPIB_CONTROLLER: set the device as the Controller In Charge
          on the GPIB bus

        - GPIB_DEVICE: set the device as a standard GPIB device on the
          bus.
        """
        self._set_cmd('mode', mode)
        self._mode = mode

    def set_controller(self):
        """
        Set GPIB device the Controller In Charge on the GPIB bus.
        """
        self.set_mode(1)

    def set_device(self):
        """
        Set the GPIB device as a simple device on the GPIB bus.        
        """
        self.set_mode(0)

    def send_command(self, cmd):
        """
        Send the specified GPIB command on the bus (must be the CIC),
        and read the answer.
        """
        assert self._mode == 1
        self._cnx.write(cmd+'\r')
        time.sleep(self._timeout) # required?
        ret = self._cnx.readlines()
        return ''.join(ret)

    def check_srq(self):
        """
        Check the SRQ line
        """
        assert self._mode == 1, "must be the Controller In Charge"
        self._cnx.write('++srq\r')
        ret = self._cnx.readline().strip()
        if ret:
            return bool(int(ret))
        return None

    def poll(self):
        """
        Poll every address, and return a dictionnary
         {add: status, ...}        
        """
        assert self._mode == 1, "must be the Controller In Charge"
        dico = {}
        for add in range(31):
            self._cnx.write('++spoll %d\r'%i)
            ret = self._cnx.readline().strip()
            if ret:
                dico[i] = int(ret)
        return dico
    
    def _read(self):
        for i in range(self._retries):
            rdata = self._cnx.readline()
            if rdata.strip() != "":
                break
            time.sleep(self._timeout)
        return rdata

    def _set_cmd(self, cmd, value):
        self._cnx.write('++%s %d\r'%(cmd, value))
        self._cnx.write('++%s\r'%(cmd))
        rval = self._read().strip()
        if not rval.isdigit() or int(rval) != value:
            raise ConnectionError("Can't set GPIB %s to %s [ret=%s]"%(cmd, value, repr(rval)))

mercurial