Open-Source SCPI / IEEE 488.2 Parser library

SCPI parser is a C library that adds SCPI and IEEE 488.2 command handling to the instrument side: a power supply, a multimeter or any other device you build yourself. You define each command by its pattern, e.g. MEASure:VOLTage[:DC]?, and a callback. The library does the parsing, parameter conversion, error queue and the mandatory commands.

Why it exists

At the Department of Measurement (CTU in Prague), I supervised several bachelor and master students. Many of them built an instrument and then needed SCPI support for it, and each of them started to write their own parser from scratch. Nothing usable existed at that time, so I wrote this library and gave it to them. They could then work on their thesis and not on routine string parsing.

Since then, more than 20 people have contributed to the library.

Features

  • Based on SCPI-99 and IEEE 488.2-2004, tries to be SCPI-99 compliant as much as possible.
  • One line per command: pattern and callback, no duplicate information.
  • Implementation of the IEEE 488.2 mandatory commands (*CLS, *ESE, *IDN?, *OPC, *RST, *SRE, *STB?, *TST?, *WAI, …) and of the SCPI mandatory commands (SYSTem:ERRor[:NEXT]?, STATus:QUEStionable…, …).
  • Error queue, status registers and service request (SRQ) support.
  • Units and special numbers (MIN, MAX, DEF, INF, …).
  • Header tree traversal: CONF:VOLT:DC 1; AC 2 works the same as CONF:VOLT:DC 1; CONF:VOLT:AC 2.
  • Portable C with no OS dependency. It compiles as C89, C99 and C++ and runs from small MCUs to PCs. It is also available as a PlatformIO library and a Zephyr module.
  • Unit tests and integration tests cover more than 93 % of the core library.

Command patterns

Feature Pattern example
Short and long form MEASure means MEAS or MEASURE
Common command *CLS
Compound command CONFigure:VOLTage
Query command MEASure:VOLTage?, *IDN?
Optional keywords MEASure:VOLTage[:DC]?
Numeric keyword suffix (multiple identical capabilities) OUTput#:FREQuency matches OUT:FREQ, OUT2:FREQ, …

Parameter types

Type Example
Decimal 10, 10.5
Decimal with suffix -5.5 V, 1.5 KOHM
Hexadecimal, octal, binary #HFF, #Q77, #B11
String "text", 'text'
Arbitrary block #12AB
Program expression (1)
Numeric list (1,2:50,80)
Channel list (@1!2:3!4,5!6)
Character data MINimum, DEFault, INFinity

Example

Each command is a pattern and a callback. The callback reads parameters and writes results:

static scpi_result_t SRC_Voltage(scpi_t * context) {
    double value;

    /* mandatory parameter, error -109 "Missing parameter" if not present */
    if (!SCPI_ParamDouble(context, &value, TRUE)) {
        return SCPI_RES_ERR;
    }

    set_output_voltage(value);
    return SCPI_RES_OK;
}

static scpi_result_t SRC_VoltageQ(scpi_t * context) {
    SCPI_ResultDouble(context, get_output_voltage());
    return SCPI_RES_OK;
}

const scpi_command_t scpi_commands[] = {
    { .pattern = "*IDN?", .callback = SCPI_CoreIdnQ,},
    { .pattern = "*RST", .callback = SCPI_CoreRst,},
    { .pattern = "SYSTem:ERRor[:NEXT]?", .callback = SCPI_SystemErrorNextQ,},
    { .pattern = "SOURce:VOLTage[:LEVel]", .callback = SRC_Voltage,},
    { .pattern = "SOURce:VOLTage[:LEVel]?", .callback = SRC_VoltageQ,},
    SCPI_CMD_LIST_END
};

The application provides a write callback for the output, initializes the context with SCPI_Init and feeds received characters from UART, USB or TCP to SCPI_Input. The input does not need to contain whole commands. The library buffers it and parses each command when it is complete. The whole setup is described in Basic instrument.

The repository also contains examples: an interactive command line demo, a TCP server on port 5025 with and without SRQ, a VXI-11 server, an LwIP netconn example and a LabWindows/CVI example.

History

  • v1.0 (2013): basic command pattern matching and basic data types.
  • v2.0 (2015): parser rewritten to be more compliant with SCPI-99, all parameter types from the specification, arbitrary block data, optional keywords, header tree traversal and multiple identical capabilities.
  • v2.1 (2015): full list of SCPI error messages, LabWindows/CVI example, support for more compilers.
  • v2.2 (2018): bug fixes and improvements.
  • v2.3 (2024): builds as C89, C99 and C++, PlatformIO library, CI with GitHub Actions.

More details are in the version history and in the migration guide from v1 to v2.

Severovýchod