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 [1] .
  • *ESE - Write the event status enable register [2] .
  • *ESE? - Query the event status enable register [3] .
  • *ESR? - Query the standard event status register [4] .
  • *SRE - Write the status enable register [5] .
  • *SRE? - Query the status enable register [6] .
  • *STB - Query the status register [7] .
Internal operation commands
  • *IDN? - Identification query [8] .
  • *RST - Perform a device reset [9] .
  • *TST? - Perform internal self-test [10] .
Synchronization commands
  • *OPC - Set operation complete flag high [11] .
  • *OPC? - Query operation complete flag [12] .
  • *WAI - Wait to continue [13] .

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 [14] .
  • *PSC? - Query the power-on status clear bit [15] .
Parallel poll common commands
  • *IST? - Query the individual status message bit [16] .
  • *PRE - Set the parallel poll enable register [17] .
  • *PRE? - Query the parallel poll enable register [18] .
Resource description common commands
  • *RDT - Store the resource description in the device [19] .
  • *RDT? - Query the stored resource description [20] .
Protected user data commands
  • *PUD - Store protected user data in the device [21] .
  • *PUD? - Query the protected user data [22] .
Calibration command
  • *CAL? - Perform internal self calibration [23] .
Trigger command
  • *TRG - Execute trigger command [24] .
Trigger macro commands
  • *DDT - Define device trigger [25] .
  • *DDT? - Define device trigger query [26] .
Macro Commands
  • *DMC - Define device trigger [27] .
  • *EMC - Define device trigger query [28] .
  • *EMC? - Define device trigger [29] .
  • *GMC? - Define device trigger query [30] .
  • *LMC? - Define device trigger [31] .
  • *PMC - Define device trigger query [32] .
Option Identification command
  • *OPT? - Option identification query [33] .
Stored settings commands
  • *RCL - Restore device settings from local memory [34] .
  • *SAV - Store current settings of the device in local memory [35] .
Learn command
  • *LRN? - Learn device setup query [36] .
System configuration commands
  • *AAD - Accept address command [37] .
  • *DLF - Disable listener function command [38] .
Passing control command
  • *PCB - Pass control back [39] .

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

[1]IEC 60488-2:2004(E) section 10.3
[2]IEC 60488-2:2004(E) section 10.10
[3]IEC 60488-2:2004(E) section 10.11
[4]IEC 60488-2:2004(E) section 10.12
[5]IEC 60488-2:2004(E) section 10.34
[6]IEC 60488-2:2004(E) section 10.35
[7]IEC 60488-2:2004(E) section 10.36
[8]IEC 60488-2:2004(E) section 10.14
[9]IEC 60488-2:2004(E) section 10.32
[10]IEC 60488-2:2004(E) section 10.38
[11]IEC 60488-2:2004(E) section 10.18
[12]IEC 60488-2:2004(E) section 10.19
[13]IEC 60488-2:2004(E) section 10.39
[14]IEC 60488-2:2004(E) section 10.25
[15]IEC 60488-2:2004(E) section 10.26
[16]IEC 60488-2:2004(E) section 10.15
[17]IEC 60488-2:2004(E) section 10.23
[18]IEC 60488-2:2004(E) section 10.24
[19]IEC 60488-2:2004(E) section 10.30
[20]IEC 60488-2:2004(E) section 10.31
[21]IEC 60488-2:2004(E) section 10.27
[22]IEC 60488-2:2004(E) section 10.28
[23]IEC 60488-2:2004(E) section 10.2
[24]IEC 60488-2:2004(E) section 10.37
[25]IEC 60488-2:2004(E) section 10.4
[26]IEC 60488-2:2004(E) section 10.5
[27]IEC 60488-2:2004(E) section 10.7
[28]IEC 60488-2:2004(E) section 10.8
[29]IEC 60488-2:2004(E) section 10.9
[30]IEC 60488-2:2004(E) section 10.13
[31]IEC 60488-2:2004(E) section 10.16
[32]IEC 60488-2:2004(E) section 10.22
[33]IEC 60488-2:2004(E) section 10.20
[34]IEC 60488-2:2004(E) section 10.29
[35]IEC 60488-2:2004(E) section 10.33
[36]IEC 60488-2:2004(E) section 10.17
[37]IEC 60488-2:2004(E) section 10.1
[38]IEC 60488-2:2004(E) section 10.6
[39]IEC 60488-2:2004(E) section 10.21