Implementing Custom Device Drivers
Implementing custom device drivers is straight forward. The following sections
will guide you through several use cases. We will implement a driver for an
imaginary device, extending it’s interface step-by-step, showing more and more
functionality and tricks.
Note
When developing new device drivers, it is useful to enable logging. See
Logging for more information.
First Steps
Let’s assume we’ve got a simple device supporting the following commands:
- ‘ENABLED <on/off>’ – Enables/disables the control loop of the device.
<on/off> is either 0 or 1.
- ‘ENABLED?’ – returns <on/off>
A possible implementation could look like this:
from slave.core import Command, InstrumentBase
from slave.types import Boolean
class Device(InstrumentBase):
def __init__(self, transport):
super(Device, self).__init__(transport)
self.enabled = Command('ENABLED?', 'ENABLED', Boolean())
Now let’s try it. We’re using a SimulatedTransport here (see
Simulating a transport for a detailed explanation):
>>> from slave.core import SimulatedTransport
>>> device = Device(SimulatedTransport())
>>> device.enabled = False
>>> device.enabled
False
It looks as if an instance variable with the name ‘enabled’ and a value of
False was created. But this is not the case. We can check it with the
following line:
>>> type(device.__dict__['enabled'])
<class 'slave.core.Command'>
The assignment did not overwrite the Command attribute. Instead, the
InstrumentBase base class forwarded the False to the
write() method of the Command. The
write() method then created the command message
‘ENABLED 0’, using the Boolean type to convert the
False and passed it to the transport’s
write() method. Likewise the read call was
forwarded to the Command‘s query method.
The IEC60488-2 standard
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 inherit from it and implement the
device specific commands, e.g:
from slave.core import Command
from slave.iec60488 import IEC60488
class CustomDevice(IEC60488):
pass
This is everything you need to do to implement the required IEC 60488-2
command interface.
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.core import Command
from slave.iec60488 import IEC60488, PowerOn
class CustomDevice(IEC60488, PowerOn):
pass