fenugrec
2025-02-21 c0d5572cf7b622df0a30972ceaabe183a2c50f76
README.md
@@ -1,73 +1,61 @@
SCPI parser library
SCPI parser library v2
===========
[SCPI](http://en.wikipedia.org/wiki/Standard_Commands_for_Programmable_Instruments) Parser library aims to provide parsing ability of SCPI commands on instrument side. All commands are defined by its patterns eg: "STATus:QUEStionable:EVENt?".
![Build status](https://github.com/j123b567/scpi-parser/actions/workflows/main.yml/badge.svg) [![Coverage Status](https://coveralls.io/repos/j123b567/scpi-parser/badge.svg?branch=master&service=github)](https://coveralls.io/github/j123b567/scpi-parser?branch=master)
Source codes are devided into few files to provide better portability to other systems.
Documentation
--------
Documentation is available at [http://j123b567.github.io/scpi-parser](http://j123b567.github.io/scpi-parser).
- *scpi.c* - provides the core parser library
- *scpi_error.c* - provides basic error handling (error queue of the instrument)
- *scpi_ieee488.c* - provides basic implementation of IEEE488.2 mandatory commands
- *scpi_minimal.c* - provides basic implementation of SCPI mandatory commands
- *scpi_utils.c* - provides string handling routines and conversion routines
Examples
--------
Library contains several [examples](https://github.com/j123b567/scpi-parser/tree/master/examples) of usage but please note, that this code is just for educational purpose and not production ready.
Examples are from several contributors and they are not tested and it is also not known, if they really work or can compile at all.
- *test-parser.c* - is the basic non-interactive demo of the parser
The core library itself is well tested and has more then 93% of the code covered by unit tests and integration tests and tries to be SCPI-99 compliant as much as possible.
Implementation to your instrument
-------------
First of all you need to fill structure of SCPI command definitions
   scpi_command_t scpi_commands[] = {
      { .pattern = "*IDN?", .callback = SCPI_CoreIdnQ,},
      { .pattern = "*RST", .callback = SCPI_CoreRst,},
      SCPI_CMD_LIST_END
   };
About
--------
Than you need to initialize interface callbacks structure. If you don't want to provide some callbacks, just initialize it as NULL. write callback is mandatory and is used to output data from the library.
[SCPI](http://en.wikipedia.org/wiki/Standard_Commands_for_Programmable_Instruments) Parser library aims to provide parsing ability of SCPI commands on **instrument side**. All commands are defined by its patterns eg: `"STATus:QUEStionable:EVENt?"`.
   scpi_interface_t scpi_interface = {
      .write = myWrite,
      .error = NULL,
      .reset = NULL,
      .test = NULL,
   };
Source codes are published with open source BSD 2-Clause License.
Important thing is command buffer. Maximum size is up to you and it should be larger than any possible largest command.
SCPI parser library is based on these standards
   #define SCPI_BUFFER_LENGTH 256
   char myBuffer[SCPI_BUFFER_LENGTH];
   scpi_buffer_t scpi_buffer = {
      .length = SCPI_BUFFER_LENGTH,
      .data = myBuffer,
   };
The last structure is scpi context used in parser library.
   scpi_context_t scpi_context;
All these structures should be global variables of the c file or allocated by function like malloc. It is common mistake to create these structures inside a function as local variables of this function. This will not work. If you don't know why, you should read something about [function stack.](http://stackoverflow.com/questions/4824342/returning-a-local-variable-from-function-in-c).
* [SCPI-99](https://www.ivifoundation.org/downloads/SCPI/scpi-99.pdf)
* [IEEE 488.2-2004](http://dx.doi.org/10.1109/IEEESTD.2004.95390)
Now we are ready to connect everything together
   SCPI_Init(&scpi_context, scpi_commands, &scpi_buffer, &scpi_interface);
Test implementation of function myWrite, which outputs everything to stdout, can be
   size_t myWrite(scpi_context_t * context, const char * data, size_t len) {
      (void) context;
      return fwrite(data, 1, len, stdout);
   }
Interactive demo can beimplemented using this loop
   #define SMALL_BUFFER_LEN
   char smbuffer[SMALL_BUFFER_LEN];
   while(1) {
      fgets(smbuffer, SMALL_BUFFER_LEN, stdin);
      SCPI_Input(&scpi_context, smbuffer, strlen(smbuffer));
   }
**SCPI version compliance**
<table>
<tr><td>SCPI version<td>v1999.0</tr>
</table>
**Supported command patterns**
<table>
<tr><th>Feature<th>Pattern example</tr>
<tr><td>Short and long form<td><code>MEASure</code> means <code>MEAS</code> or <code>MEASURE</code> command</tr>
<tr><td>Common command<td><code>*CLS</code></td>
<tr><td>Compound command<td><code>CONFigure:VOLTage</code><tr>
<tr><td>Query command<td><code>MEASure:VOLTage?</code>, <code>*IDN?</code></tr>
<tr><td>Optional keywords<td><code>MEASure:VOLTage[:DC]?</code></tr>
<tr><td>Numeric keyword suffix<br>Multiple identical capabilities<td><code>OUTput#:FREQuency</code></tr>
</table>
**Supported parameter types**
<table>
<tr><th>Type<th>Example</tr>
<tr><td>Decimal<td><code>10</code>, <code>10.5</code></tr>
<tr><td>Decimal with suffix<td><code>-5.5 V</code>, <code>1.5 KOHM</code></tr>
<tr><td>Hexadecimal<td><code>#HFF</code></tr>
<tr><td>Octal<td><code>#Q77</code></tr>
<tr><td>Binary<td><code>#B11</code></tr>
<tr><td>String<td><code>"text"</code>, <code>'text'</code></tr>
<tr><td>Arbitrary block<td><code>#12AB</code></tr>
<tr><td>Program expression<td><code>(1)</code></tr>
<tr><td>Numeric list<td><code>(1,2:50,80)</code></tr>
<tr><td>Channel list<td><code>(@1!2:3!4,5!6)</code></tr>
<tr><td>Character data<td><code>MINimum</code>, <code>DEFault</code>, <code>INFinity</code></tr>
</table>