Basic Concepts
slave uses three layers of abstraction. The transport layer resides at the
lowest level. It’s responsibility is sending and receiving raw bytes. It has no
knowledge of their meaning. The protocol layer on the next higher level is
responsible for creating and parsing messages. The driver layer is at the
highest level. It knows which commands are supported and maps them to python
representations.
Transport Layer
The slave.transport
module implements the lowest level abstraction
layer of the slave library.
The transport is responsible for sending and receiving raw bytes. It interfaces
with the hardware, but has no knowledge of the semantic meaning of the
transfered bytes.
The Transport
class defines a common api used in higher abstraction
layers. Custom transports should subclass slave.Transport
and implement
the __read__() and __write__() methods.
The following transports are already available:
Serial
- A wrapper of the pyserial library
Socket
- A wrapper around the standard socket library.
LinuxGpib
- A wrapper of the linux-gpib library
Visa
- A wrapper of the pyvisa library. (Supports pyvisa 1.4 - 1.5).
Protocol Layer
The slave.protocol
module implements the intermediate abstraction
layer of the slave library.
The protocol knows how to create command messages and how to parse responses.
It has no knowledge of which commands are actually supported by the device and
does not care what kind of connection (e.g. ethernet, gpib, serial, ...) is used
to communicate with the device.
The common protocol api is defined by the slave.Protocol
class. Custom
protocols must implement the query()
and
write()
methods.
The following protocols are already implemented and ready to use:
Driver Layer
The core module contains several helper classes to ease instrument control.
Implementing an instrument interface is pretty straight forward. A simple
implementation might look like:
from slave.driver import Driver, Command
from slave.types import Integer
class MyInstrument(Driver):
def __init__(self, transport):
super(MyInstrument, self).__init__(transport)
# A simple query and writeable command, which takes and writes an
# Integer.
self.my_cmd = Command('QRY?', 'WRT', Integer)
# A query and writeable command that converts a string parameter to
# int and vice versa.
self.my_cmd2 = Command('QRY2?', 'WRT2', Enum('first', 'second'))
IEC60488 Compliant Drivers
The slave.iec60488
module implements a IEC 60488-2:2004(E) compliant
interface.
The IEC 60488-2 describes a standard digital interface for programmable
instrumentation. It is used by devices connected via the IEEE 488.1 bus,
commonly known as GPIB. It is an adoption of the IEEE std. 488.2-1992
standard.
The IEC 60488-2 requires the existence of several commands which are
logically grouped.
- Reporting Commands
- *CLS - Clears the data status structure .
- *ESE - Write the event status enable register .
- *ESE? - Query the event status enable register .
- *ESR? - Query the standard event status register .
- *SRE - Write the status enable register .
- *SRE? - Query the status enable register .
- *STB - Query the status register .
- Internal operation commands
- *IDN? - Identification query .
- *RST - Perform a device reset .
- *TST? - Perform internal self-test .
- Synchronization commands
- *OPC - Set operation complete flag high .
- *OPC? - Query operation complete flag .
- *WAI - Wait to continue .
To ease development, these are implemented in the
IEC60488
base class. To implement a IEC 60488-2
compliant device driver, you only have to subclass it and implement the
device specific commands, e.g:
from slave.driver import Command
from slave.iec60488 import IEC60488
class CustomDevice(IEC60488):
pass
Optional Commands
Despite the required commands, there are several optional command groups
defined. The standard requires that if one command is used, it’s complete
group must be implemented. These are
- Power on common commands
- *PSC - Set the power-on status clear bit .
- *PSC? - Query the power-on status clear bit .
- Parallel poll common commands
- *IST? - Query the individual status message bit .
- *PRE - Set the parallel poll enable register .
- *PRE? - Query the parallel poll enable register .
- Resource description common commands
- *RDT - Store the resource description in the device .
- *RDT? - Query the stored resource description .
- Protected user data commands
- *PUD - Store protected user data in the device .
- *PUD? - Query the protected user data .
- Calibration command
- *CAL? - Perform internal self calibration .
- Trigger command
- *TRG - Execute trigger command .
- Trigger macro commands
- *DDT - Define device trigger .
- *DDT? - Define device trigger query .
- Macro Commands
- *DMC - Define device trigger .
- *EMC - Define device trigger query .
- *EMC? - Define device trigger .
- *GMC? - Define device trigger query .
- *LMC? - Define device trigger .
- *PMC - Define device trigger query .
- Option Identification command
- *OPT? - Option identification query .
- Stored settings commands
- *RCL - Restore device settings from local memory .
- *SAV - Store current settings of the device in local memory .
- Learn command
- *LRN? - Learn device setup query .
- System configuration commands
- *AAD - Accept address command .
- *DLF - Disable listener function command .
- Passing control command
- *PCB - Pass control back .
The optional command groups are implemented as Mix-in classes. A device
supporting required IEC 60488-2 commands as well as the optional Power-on
commands is implemented as follows:
from slave.driver import Command
from slave.iec60488 import IEC60488, PowerOn
class CustomDevice(IEC60488, PowerOn):
pass
Reference: