Writing New Drivers

Create the Core Structure

Driver Builder

The easiest way to create a new instrument driver for any kind of instrument is to open CAMELS and navigate to Tools > Driver builder. After filling out the desired fields the driver builder creates all required files and the folder structure needed for a basic instrument driver. Additional functionality can then be added to the driver by modifying the files manually.

Basic Driver Settings

At the top of the driver builder enter the Name of the instrument, this should be lowercase and describe the instrument unambiguously. For example, you could name the Keithley Series 2400 SourceMeter : keithley_2400.

If you communicate with the instrument via a serial connection check the VISA button and enter the correct baud rate and read and write terminators. This is not relevant, if you communicate with the device via other ways such as .dlls, sockets, or ethernet connections.

Instrument Channels

Channels are a key part of CAMELS. When you create a measurement protocol you can set and read the channels of the instruments. Each channel typically corresponds to a single property or functionality of the instrument. Channels are the core functionality of your instrument. Channels can be thought of like methods of a class that can be called to perform various tasks.

You now have the option to add four different types of channels to your instrument.

For Read Channels and Set Channels you can individually set if the channel should directly communicate with the instrument via the serial connection or if the channel should execute some other custom function. To do this check the VISA button of the channel you are adding. The custom function is typically used if you want to set/read values where you do not want to actually send any commands to the physical instrument.

  • Read Channels: Communicate with the instrument and read/return the value/data that you want to save in the final measurement data file. This channel type is used for values that can only be read from the instrument, e.g. a measured resistance. They can be used in measurements protocols by using a Read Channels step.
    If you for example have a simple instrument using VISA communication that returns a voltage measurement when you send VOLT? to the device you would simply enter VOLT? in to the Query-String field.

  • Set Channels: These channels can set/output a value defined by the user, e.g. a voltage. These channels typically communicate with the instruments and write to the instrument. It is assumed that the state of instrument is modified in some way or that the value is later used to modify its state. If no return parser is set the message is simply written and nothing is read from the instrument. They can be used in measurements protocols by using a Set Channels step. In most cases it is not assumed that a Set Channel would return/save any data/information from the instrument.

Read Channels and Set Channels can be used in measurement protocols (or manual controls) to read and set instruments. They are only executed when explicitly called in a protocol.

  • Config Channels - Read Only: These may be used for values that are read only once from the instrument at the beginning of the measurement, but do not change its current state, e.g. the instrument identifier, as a response from the *IDN? command.\

  • Config Channels: These values are set at the beginning of a protocol and can be configured in the instrument management (Manage Instruments) window.

    These should be values, that are typically not changed during a measurement run, like the current and voltage compliance, exposure time or whether the instrument is used as a voltage or current source.

Note

Config Channels are always run once at the beginning of a measurement when the instrument is used.
You can change instrument config channels during measurements, but the idea behind configs are settings that do not change within a single measurement. The value of the config channels are saved as metadata to the instrument at the beginning of the measurement. So take care when changing this during the measurement.

Channel Fields

These four channels have several fields that you can fill out while creating your driver. They define what exactly is done when a channel is set or read.

If you require complicated functionality you can simply fill out the fields that are relevant and then add the functionality in the driver after it was generated by the builder.

  • Name: This will be the name of the channel, as it is also displayed in CAMELS.

  • Query-String: (Only for Read Channels) The string sent to the instrument for querying some value (Input only, examples: *IDN?, VOLT?). This is useful for query commands that do not change.

  • Write-Format-String: (Only for Set Channels) A string that formats the input value so that the instrument understands the set command. The value (that you entered in the measurement protocol) is passed to the string with {value}, i.e. for example: "VOLT {value}" where “{value}” will be replaced with the input value. So in the end if you set the value in the protocol to 1 the string that the instrument receives would be for example "VOLT 1".

  • Return-Parser: A regular expression which parses the string returned from the instrument. The regex must contain a capture group, so parenthesis around the value you want to extract. The first capture group from the regex will become the value. The actual code executed looks like this re.match(parse, val).group(1), where parse is the regex string and val is the initial string read from the instrument.
    If this is None, for a set-channel, the instrument will only be written to, if it is not None a query is performed.

  • Return-Type: The type to which the returned value from the “Return-Parser” should be converted. Supported are str, float, int and bool.

  • Unit: The physical unit of the channel’s measurement / output.

  • Description: A description for the channel, making it clear in the metadata and for the user, what this channel does. It is displayed in the measurement protocol when hovering over the channel.

  • Input-Type: This determines the input for a config-channel in the config window. Supporter are str, float (or any number-type) and bool.

Build Driver

When you are finished click Build Driver and select a folder where you want to save the driver.

This will automatically create the basic folder structure and files so that you can immediately use the driver in CAMELS.

The basic folder structure of a driver is quite simple. For an instrument named driver_name it looks as follows.

<driver_name>
└─> nomad_camels_driver_<driver_name> (contains the actual device communication files)
    └─> <driver_name>.py
    └─> <driver_name>_ophyd.py
└─> LICENSE.txt
└─> pyproject.toml
└─> README.md

The <driver_name>.py file contains code regarding the configuration settings you find in the Manage Instruments window and sets up the instrument. Here the Config Channels are implemented.

The <driver_name>_ophyd.py file contains code that describes how exactly you communicate with the instrument and defines the available channels. This file contains all commands that are sent to the instrument and specifies how the read data is treated.

Adding New Driver to CAMELS

CAMELS loads locally created drivers on start-up from the directory specified in File > Settings and then Drivers > Local drivers path.
You can add a driver you just built by placing the nomad_camels_driver_* folder in the directory specified above.

Note

If you place the folder there while CAMELS is running you must restart CAMELS to be able to use the instrument.


Head to the next page to learn how to modify your driver after it was automatically generated by the driver builder.


If you want to share your driver with others all you need to do is upload your driver to PyPI or create a pull request on our driver GitHub repository. For more information on how to do this look here.