Spike Software Documentation
Loading...
Searching...
No Matches
SCPI Programming

Introduction

SCPI (Standard Commands for Programmable Instruments) is a standard which covers the set of commands used to program various instruments. The standard covers the syntax, form, behavior, etc. of these commands in attempt to reduce development time for the user.

For the purposes of Signal Hound and the Spike software, a user can send SCPI commands to Spike to control and make measurements using the Spike software in an automatic fashion. SCPI commands are sent to instruments over many interfaces, commonly GPIB, VXI, USB, Ethernet, etc. The Spike software accepts commands over a network socket. The Spike software will accept a single network connection in which it can receive SCPI commands and send responses.

This document will cover the basics of SCPI commands, how to get started programming the Spike software, and will cover the full SCPI command set implemented by the Spike software.

Command Basics

This section contains a quick overview of the SCPI command syntax and usage to the extent that is relevant to the Spike software. Spike does not utilize all functionality in the SCPI standard and as such said functionality will not be covered here.

Commands

A SCPI command is comprised of a series of keywords separated by colons. A command may be followed by a ‘?’ to represent a query, a series of parameters separated by spaces, or both.

:SENSE:FREQUENCY:CENTER 1GHz (Example command for setting the center frequency to 1GHz)

:sense:frequency:center? (Example command for querying the current center frequency)

Commands are case insensitive. Each keyword in a command can have a short and long form. Both can be used interchangeably.

:SENSe:FREQuency:CENTer is a command with three keywords. Each keyword has a short and long form. The short form is denoted by the uppercase characters and the long form is the full keyword including the upper and lower-case characters. For example, FREQ is the short form of FREQUENCY. When constructing a command, the short and long form can be interchanged. For example, you could construct the command as such, :SENS:FREQUENCY:CENT where SENSE and CENTER are sent as short form and FREQUENCY as longform.

Some commands are options and are denoted as such by the ‘[]’ characters.

[:SENSe]:FREQuency:CENTer is a command where the first keyword is optional. This command can be sent as FREQ:CENT and still be interpreted correctly.

Commands are terminated with a newline character. For example

:SENS:FREQ:CENT 1GHZ\n

Spike will begin processing the commands once a newline is reached. Additionally, a newline will reset the current keyword path.

Multiple Commands

Multiple commands can be sent to the device at once using the semi colon character separating each command.

:SENS:FREQ:CENT 1GHz; :SENS:FREQ:SPAN 10MHz\n

This is an example of sending two commands at once. Additionally, when sending multiple commands, you don’t need to repeat all keywords leading up to the final keyword for commands after the first.

:SENS:FREQ:CENT 1GHz; SPAN 10MHz\n

Here SPAN retains the :SENS:FREQ: keywords from the previous command. To prevent this from happening use the colon character leading the second command. For example

:SENS:FREQ:CENT 1GHz; :SPAN 10MHz\n

This is an invalid series of commands, since span is prefixed with a colon command which reset the previous keywords.

Parameters

There are several types of parameters that can be sent in commands.

Parameter Type Description
Boolean ON, OFF, 0, 1
Keyword
<bool>
Character specific strings for a given command. These keywords can also have short and long form.
Numeric
<integer>
<double>
Numeric parameters take either the form of integer or decimal values. Examples include
1
1.23
9
3.14
Frequency
<freq>
These are numeric parameters with a frequency suffix. Possible frequency suffixes include
HZ, KHZ, MHZ, GHZ
The suffixes are case insensitive. If a suffix is not present, Hz is the default unit. Examples include
1kHz
20MHz
12GHz
Any function that returns a frequency will return the frequency in Hz with no suffix present.
Amplitude
<amplitude>
These are numeric parameters with an amplitude suffix. Possible amplitude suffixes include
DBM, DBMV, DBUV, MV
The suffixes are case insensitive. A suffix must be present unless indicated otherwise. Examples include
-20DBM
60dbuv
If a function returns an amplitude, it will return the amplitude in the current software units without a suffix.

Return Values

Values returned from the Spike software (as a result of sending a query command) are separated by a semi-colon if multiple query commands are sent in one string and are terminated by a newline. For example, sending

“CALC:MARK:MAX; X?; Y?\n”

results in a return string of

“1000000;-20\n”

The command sent performs a peak search and queries the X and Y positions of the marker. The return is the X and Y positions separated by a semicolon and terminated with a newline.

Special Characters

This section describes the numerous special characters that are present in the commands in this document.

Character Description Example
Vertical stroke between parameters indicates multiple choices FLATtopGAUSsian
[] Square brackets indicate an optional keyword :SYSTem:ERRor[:NEXT]?
Next is an optional keyword and the command could also be composed as
:SYSTem:ERRor?
<> Angle brackets around a parameter indicate a type and angle brackets should not be included in the user command. *RCL <int>
<int> is the type of parameter and an example of using this command would be
*RCL 1
Notice the angle brackets are not included.

Getting Started

See the SCPI examples found in the SDK download on any of the Signal Hound product download pages. The examples use the C programming language and a common VISA library implementation.

Instrument control is performed by connecting to the Spike software on TCP/IP port 5025. On this port, a user can send and receive raw SCPI commands. It is not necessary to use a I/O library like VISA to communicate with the Spike software but it can simplify several operations. It is possible to communicate directly over the socket with socket programming. The computer that is communicating with the Spike software does not have to be the same computer running the Spike software and does not have to be a Windows platform.

It is recommended to use a VISA library if available. Several implementations of VISA exist. Commonly used ones include Keysight’s I/O libraries, and NI’s VISA libraries. You can also use VISA implementations that exist in other languages/environments such as MATLAB, LabVIEW, and Python.

Connecting to the socket interface using VISA looks like this

viOpen(rm, “TCPIP::localhost::5025::SOCKET”, VI_NULL, VI_NULL, &inst);

Additionally, when using a VISA library, it is necessary to set the VI_ATTR_TERMCHAR_EN attribute to true. This will terminate the read operation when the termination character is received. The termination character should be set to the newline (‘
’) character if it is not set by default. The code for this is below.

viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);

viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');

Only one connection to the Spike software can be active at a time. The connection can be terminated by either closing the socket connection, either through the socket library you are using, the viClose function if you are using a VISA library, or by closing your application. Spike will immediately begin waiting for another socket connection when the previous one is ended.

Functionality Provided Through SCPI

The table below lists what features can be automated with SCPI.

Feature Implemented
Swept Analysis – Sweep Settings Yes
Swept Analysis – Trace controls Yes
Swept Analysis – Marker controls Yes
Swept Analysis – Channel power, occupied bandwidth Yes
Swept Analysis – Peak table Yes
Swept Analysis – Sweep recording/playback Yes
Path Loss Tables Yes
Limit Lines Yes
Spectrogram/Waterfall plot controls No
Persistence display controls No
Real-Time Partial
Zero-Span Partial
Harmonic Measurements Yes
Scalar Network Analysis Yes
Phase Noise Measurements Yes
Digital Modulation Analysis Yes
EMC Precompliance No
Analog Demodulation Yes
Interference Hunting No
Spectrum Emission Mask Yes
Noise Figure Yes
SUN-OFDM No
BLE Analysis Yes
WLAN Modulation Analysis Yes
LTE Yes
VCO Characterization Yes

Commands

Display

:DISPlay:HIDE <bool>

When set to true, hides the Spike application. The application will be hidden in the taskbar but will continue to be visible in the task manager. The SCPI lockout dialog, device connecting progress dialog, no device connected alert dialog and multiple devices connected alert dialog will be hidden, overriding related settings in the preferences menu.

:DISPlay:HIDE?

Returns true if hidden mode is enabled.

:DISPlay:ANNotation:TITLe <string>

Set the measurement title.

:DISPlay:ANNotation:TITLe?

Returns the current measurement title.

:DISPlay:ANNotation:CLEar

Remove the title. Has the same effect as setting the title with an empty string.

Common Commands

*IDN?

Query the serial number and name of the device.

*OPC

Wait for the current operation to complete before processing the next command. See the Mode/Measurements section for more information on the OPC command.

*OPC?

Wait for the current operation to complete before processing the next command. Returns 1 when the operation completes. See the Mode/Measurements section for more information on the OPC command.

*RCL <int>

Load preset [1-9]

*SAV <int>

Save preset [1-9]

*RST

Same as PREset.

Format

:FORMat:TRACe[:DATA] ASCii|REAL

Specify the format of the returned trace data from the TRACe[:DATA]? command.

:FORMat:TRACe[:DATA]?

Returns the current trace data format.

:FORMat:IQ[:DATA] ASCii|BINary

Specify the format of the returned IQ data from the FETCH:ZS? 1 command.

:FORMat:IQ[:DATA]?

Returns the current IQ data format.

Format Descriptions

Ascii Trace Format

When the ascii format is specified, traces are returned as an ascii string of the form

<ascii value 1>,<ascii value 2>,...,<ascii value N>

An example of this is

-89.324,-102.784,-27.641,…,-112.882<NL>

Real Trace Format

When the real format is specified, traces are returned in a block data transfer. A block data transfer is of the form

#NBBBBDDDDD…D<NL>

Where

  • # - Leading character of a block data transfer. Always present.
  • N – Number of decimal digits in the total byte count.
  • BBBB – The total byte count of the payload of the block data transfer. More specifically, the number of bytes that follow the byte count. This number must be N decimal digits long.
  • DDDD…D – The binary data.

An example block data transfer is below

#212ABCDEFGHIJKL<NL>

The 2 following the # denotes that the byte count is 2 decimal digits. The ‘12’ following this is the byte count. Note it is 2 decimal digits long. Note: The ‘#’ ‘2’ and ‘12’ should be read as ascii characters. ‘ABC…JKL’ is the data. The data in this example is 12 bytes long. The data should be read as bytes and not ascii.

Trace data is sent in little endian order, or least significant bytes first. Trace data is sent as successive 32-bit floating point values.

Ascii I/Q Format

See Ascii Trace Format.

Binary I/Q Format

See Real Trace Format. I/Q data is sent as successive 16-bit integer values.

System Functions

The following commands are used to perform system level software actions and query information about the system.

:SYSTem:CLOSe

Disconnect any active device and closes the Spike software. It is not possible to reopen the software using SCPI commands. This will also terminate the socket connection with the Spike software.

:SYSTem:PRESet

Presets the active device. This will power cycled the active device and return the software to the initial power on state. This process can take between 6-20 seconds depending on the device type.

:SYSTem:PRESet?

Presets the active device. This will close and reopen the active device. This process can take between 6-20 seconds depending on the device type. Returns 0 or 1 depending on success. (1 for success)

:SYSTem:PRESet[:USER]:SAVE <filename>

Save a preset with the given file name. The file name should have extension “.ini”.

:SYSTem:PRESet[:USER]:LOAD <filename>

Load the preset given by the file name. If the preset does not exist, nothing occurs. The file name should have extension “.ini”.

:SYSTem:VERsion?

Returns the Spike software version number.

:SYSTem:COMMunicate:GTLocal

Puts Spike in local mode.

:SYSTem:IMAGe:SAVe <filename>

Save an image with the specified filename.

:SYSTem:IMAGe:SAVe:QUICk

Quick save image. Same functionality as the Image quick save file menu option.

:SYSTem:PRINt

Print with the default system print settings.

:SYSTem:TEMPerature?

Returns the current internal temperature of the active device, in degrees celsius.

:SYSTem:VOLTage?

Returns the measured voltage of the active device, in volts.

:SYSTem:CURRent?

Returns the measured current of the active device, in amps. Devices which don't report current will return zero instead.

:SYSTem:OVERflow?

This will return true if the hardware reported A/D overflow during the last measurement. This value is overwritten on each measurement. If you need the overflow status of each measurement, it is recommended to operate Spike in single trigger mode.

Device Management

The functions below allow you to manage the connected device in the Spike software. This is useful for error recovery in the event a device disconnect occurs due, or if one is managing multiple Signal Hound devices on one PC.

Connecting Signal Hound devices can take between 3-20 seconds depending on the type of device and the state of the device prior to interfacing it. If the VISA timeout is shorter than the time it takes to connect the device in the Spike software, you will need to loop on timeout until you receive the connect status return.

:SYSTem:DEVice:ACTive?

Returns whether or not a device is currently connected and active in the software. Look at the *IDN? function to request information about the device.

:SYSTem:DEVice:COUNt?

Returns the number of devices connected to the PC. No device may be active when this function is called. IE, you must call DISConnect? before calling this function. Any networked device that have been configured will be counted in the returned value.

:SYSTem:DEVice:LIST?

Returns the connection strings for all devices available to connect in the Spike software. To determine how many devices are present, use the COUNt? function. For USB devices, this is serial numbers returned as ascii integers and comma separated. If any networked devices have been configured they will be returned in the list with the following format

SOCKET::IP::PORT example, SOCKET::192.168.1.1::12345

This entire string can be sent to the connect function to connect to a networked device.

:SYSTem:DEVice:CURRent?

Returns the currently active device’s connection string. See LIST? for format.

:SYSTem:DEVice:CONnect? <int>

Connect a device in the Spike software. For USB devices, you need to provide the serial number of the device to connect. For networked devices, send a string with format

SOCKET::IP::PORT example, SOCKET::192.168.1.1::12345

Returns 0 or 1 depending on if the device successfully opened.

:SYSTem:DEVice:DISConnect?

Disconnects any device actively connected in Spike. Returns 1 when finished.

Errors

The Spike software maintains a list of system errors available to the user. Errors are stored with a unique ID, name, and description. The types of issues represented in the error list are settings conflicts, SCPI issues such as invalid parameter types or instructions, file I/O errors, etc.

See the SCPI examples to see how to poll Spike for any present errors.

The errors are returned in the form

“ID,description;error information”

ID is a unique integer for the error. The description is an ascii text description for the error, and error information is any additional context information for the error generated. An example error message is below.

“-2,Invalid Parameter;Expected frequency parameter”

This error indicates the SCPI parser was expecting a frequency parameter and was either unable to find it or was unable to parse it as a frequency.

Once the error queue is empty, the software will return the ‘no error’ error when the next system error is requested. ‘No error’ has an ID of 0.

:SYSTem:ERRor:COUNt?

Returns the number of errors in the error queue.

:SYSTem:ERRor[:NEXT]?

Returns the next error in the queue, and removing it from the queue.

:SYSTem:ERRor:CLEAr

Remove all errors from the queue, returns nothing.

Mode/Measurements

Instrument (Mode)

These commands control the measurement mode of the Spike software.

:INSTrument[:SELect] SA|RTSA|ZS|HARMonics|NA|PNoise|DDEMod|EMI|ADEMod|IH|SEMask|NFIGure|WLAN|BLE|LTE

Determines the current measurement mode.

:INSTrument[:SELect]?

Returns the current measurement mode.

:INSTrument:RECALibrate

Perform a device recalibration.

Initiate (Single/Continuous)

The commands are used to control when measurements are performed in the application. For automated measurements, it is common/recommended to disable CONTinuous measurement and control when the software performs the next measurement (sweep/IQ acquisition/etc) with the INIT:IMM command.

:INITiate:CONTinuous ON|OFF|0|1

Enable/Disable continuous measurement operation. This state is global and will affect all measurements. When enabled, measurements are automatically triggered after the previous measurement is finished. When disabled, measurements are triggered only on the IMMediate command.

:INITiate:CONTinuous?

Returns whether continuous measurement operation is enabled.

:INIT[:IMMediate]

Trigger a measurement. Has no effect if CONTinuous is enabled.

Limit Lines

These commands control the limit lines which are available in sweep, real-time, and network analysis measurement modes. If no numeric suffix is provided to specify a limit line, the last used suffix is assumed. The last used suffix defaults to 1.

:CALCulate:LLINe[1|2|3|4|5|6]:STATe ON|OFF|0|1

Enable or disable testing of this limit line. If there are not at least 2 points in the limit line, testing doesn’t occur despite being enabled.

:CALCulate:LLINe[1|2|3|4|5|6]:STATe?

Returns whether testing of this limit line is enabled.

:CALCulate:LLINe[1|2|3|4|5|6]:TITLe

Specify the name of the limit line.

:CALCulate:LLINe[1|2|3|4|5|6]:TITLe?

Returns the name of the limit line.

:CALCulate:LLINe[1|2|3|4|5|6]:TRACe <int>

Specify which trace is tested against this limit line.

:CALCulate:LLINe[1|2|3|4|5|6]:TRACe?

Returns which trace is tested against this limit line.

:CALCulate:LLINe[1|2|3|4|5|6]:TYPE UPPer|LOWer

Specify whether the limit line is tested as an upper bound or lower bound.

:CALCulate:LLINe[1|2|3|4|5|6]:TYPE?

Returns whether the limit line is tested as an upper bound or lower bound.

:CALCulate:LLINe[1|2|3|4|5|6]:REFerence FIXed|RELative

Specify whether the limit line values are fixed/absolute or relative to the center frequency and ref level.

:CALCulate:LLINe[1|2|3|4|5|6]:REFerence?

Returns whether the limit line values are fixed/absolute or relative.

:CALCulate:LLINe[1|2|3|4|5|6]:REFerence:TRANsform

Convert the limit line reference type between fixed and relative by recalculating points based on the current configuration.

:CALCulate:LLINe[1|2|3|4|5|6]:INTerpolate LINear|LOGarithmic

Specify whether the limit line uses linear or logarithmic interpolation.

:CALCulate:LLINe[1|2|3|4|5|6]:INTerpolate?

Returns whether the limit line uses linear or logarithmic interpolation.

:CALCulate:LLINe[1|2|3|4|5|6]:PAUSe[:STATe] ON|OFF|0|1

When enabled, a failure of this limit will pause the sweep update.

:CALCulate:LLINe[1|2|3|4|5|6]:PAUSe[:STATe]?

Returns whether a failure of this limit will pause the sweep update.

:CALCulate:LLINe[1|2|3|4|5|6]:DISPlay:LINE[:STATe]

When enabled, the limit line will be visible on the graticule.

:CALCulate:LLINe[1|2|3|4|5|6]:DISPlay:LINE[:STATe]?

Returns whether the limit line is visible on the graticule.

:CALCulate:LLINe[1|2|3|4|5|6]:DISPlay:RESult[:STATe]

When enabled, the limit line pass/fail result will be visible on the graticule.

:CALCulate:LLINe[1|2|3|4|5|6]:DISPlay:RESult[:STATe]?

Returns whether the limit line pass/fail result is visible on the graticule.

:CALCulate:LLINe[1|2|3|4|5|6]:OFFSet:Y <double>

Specify a dB offset to the limit line.

:CALCulate:LLINe[1|2|3|4|5|6]:OFFSet:Y?

Returns the dB offset of the limit line.

:CALCulate:LLINe[1|2|3|4|5|6]:BUILD:POINts <int>

Specify how many points to use when building limit line from trace.

:CALCulate:LLINe[1|2|3|4|5|6]:BUILD:POINts?

Returns how many points to use when building limit line from trace.

:CALCulate:LLINe[1|2|3|4|5|6]:BUILD

Build limit line points from trace, max holding across frequency sections.

:CALCulate:LLINe[1|2|3|4|5|6]:POINts?

Returns the number of points in the limit line as an integer.

:CALCulate:LLINe[1|2|3|4|5|6]:DATA <freq1>, <ampl1>, …

Specify the points in the limit line, will override any existing points. Points are specified as freq/amplitude pairs where the amplitude is specified as dBm.

:CALCulate:LLINe[1|2|3|4|5|6]:DATA?

Returns the points in the limit line. Points are returned as freq/amplitude pairs where the frequencies are specified as Hz and the amplitudes as dBm.

:CALCulate:LLINe[1|2|3|4|5|6]:FAIL?

Returns 1 when the limit test has failed, 0 if passed.

:CALCulate:LLINe[1|2|3|4|5|6]:CLEAr

Resets the selected limit line. Removes all points stored.

:CALCulate:LLINe:ALL:CLEAr

Resets all limit lines.

Path Loss Tables

These commands control the path loss tables which are available in sweep, real-time, zero-span, harmonics, digital modulation analysis, EMC precompliance, analog demod, and interference hunting measurement modes. If no numeric suffix is provided to specify a path loss table, the last used suffix is assumed. The last used suffix defaults to 1.

:SENSe:CORRection:PATHloss[1-8]:STATe ON|OFF|0|1

Enable or disable application of this path loss table.

:SENSe:CORRection:PATHloss[1-8]:STATe?

Returns whether application of this path loss table is enabled.

:SENSe:CORRection:PATHloss[1-8]:DESCription <string>

Specify the name/description of this path loss table.

:SENSe:CORRection:PATHloss[1-8]:DESCription?

Returns the name/description of this path loss table.

:SENSe:CORRection:PATHloss[1-8]:POINts?

Returns the number of points in the path loss table as an integer.

:SENSe:CORRection:PATHloss[1-8]:DATA <freq1>, <offset1>, …

Specify the points in the path loss table, will override any existing points. Points are specified as freq/offset pairs where the offset is specified as dB.

:SENSe:CORRection:PATHloss[1-8]:DATA?

Returns the points in the path loss table. Points are returned as freq/offset pairs where the frequencies are specified as Hz and the offsets as dB.

:SENSe:CORRection:PATHloss[1-8]:CLEAr

Resets the selected path loss table. Removes all points stored.

:SENSe:CORRection:PATHloss:ALL:CLEAr

Resets all path loss tables.

Reference

These commands control the reference oscillator settings the of the spectrum analyzer.

[:SENSe]:ROSCillator:SOURce INTernal|EXTernal|OUTput

Configure the reference clock of the instrument.

This modifies the settings in the Reference dialog of the Settings menu.

The exact behavior of this command is device dependent. This table maps the SCPI command to the Spike reference dialog settings for each device:

Device INTernal EXTernal OUTput
SM200/SM435 Use internal reference Use external reference + internal out enabled to false Use internal reference + internal out enabled to true
SP145 Use internal reference Use external reference No change
BB60D Use internal reference Use external reference No change
BB60C Use internal reference Use external reference (AC) Reference out
SA124B Not set, use internal reference Use external reference Internal reference out
SA44B Not set, use internal reference Use external reference No change

Conflicts that normally result in user dialogs will not appear when using this SCPI command. To verify the correct value has been set and accepted, use the query command.

[:SENSe]:ROSCillator:SOURce?

Returns the current reference clock source.

Spectrum Analysis

Sweep Configuration

These commands control the receiver configuration in the swept analysis mode.

Frequency

These commands control the frequency range of the sweeps in swept analysis mode.

[:SENSe]:FREQuency:CENTer <freq>|UP|DOWN

Set the measurement center frequency. This can cause the start or stop frequency to change if the device is unable to maintain the current span with the new center frequency. This can have the side effect of changing the span/start/stop frequencies.

[:SENSe]:FREQuency:CENTer? [MIN|MAX]

Query the current center frequency. Returned as Hz. By passing the MIN or MAX arguments, the user can query the upper and lower frequency limits for a sweep.

[:SENSe]:FREQuency:STARt <freq>

Change the sweep start frequency. The lower bound for the start frequency is determined with the CENT? MIN command.

[:SENSe]:FREQuency:STARt?

Query the current measurement start frequency in Hz.

[:SENSe]:FREQuency:STOP <freq>

Set the sweep stop frequency. The upper bound for the stop frequency is determined with the CENT? MAX command.

[:SENSe]:FREQuency:STOP?

Query the current measurement stop frequency in Hz.

[:SENSe]:FREQuency:CENTer:STEP[:INCRement] <freq>

Set the step amount the center frequency changes by when using the UP or DOWN parameters on the CENTer command.

[:SENSe]:FREQuency:CENTer:STEP[:INCRement]?

Query the center frequency step size in Hz.

[:SENSe]:FREQuency:SPAN <freq>|UP|DOWN

Set the sweep span. This will change the start/stop and potentially center frequency of the sweep in attempt to meet the span requested.

[:SENSe]:FREQuency:SPAN?

Query the span in Hz.

Power

These commands affect the RF front end of the device. Not all settings are available for each Signal Hound spectrum analyzer. It is recommended to leave attenuation/gain/preamp set to auto and control the RF leveling with reference level.

[:SENSe]:POWer[:RF]:RLEVel <amplitude>|UP|DOWN

Set the reference level. If UP or DOWN is specified, the reference level is increased or decreased by the div amount (when reference level is a logarithmic unit).

[:SENSe]:POWer[:RF]:RLEVel?

Return the current reference level as dBM.

[:SENSe]:POWer[:RF]:RLEVel:UNIT?

Return the current amplitude unit used to express reference level.

[:SENSe]:POWer[:RF]:RLEVel:OFFSet <double>

Set the reference level offset in dB.

[:SENSe]:POWer[:RF]:RLEVel:OFFSet?

Return the current reference level offset in dB.

[:SENSe]:POWer[:RF]:PDIVision <double>

specify the plot vertical division (1/10th of the plot height) as dB. Logarithmic scale only.

[:SENSe]:POWer[:RF]:PDIVision?

Query the plot vertical division as dB.

[:SENSe]:POWer[:RF]:ATTenuation <int>

Specify the attenuation index. It is recommended to leave attenuation set to auto and set the reference level instead.

[:SENSe]:POWer[:RF]:ATTenuation?

Query the attenuation index.

[:SENSe]:POWer[:RF]:ATTenuation:AUTO <bool>

Specify whether attenuation is automatically selected.

[:SENSe]:POWer[:RF]:ATTenuation:AUTO?

Query whether attenuation is automatically selected.

[:SENSe]:POWer[:RF]:GAIN <int>

Specify the gain index. It is recommended to leave gain set to auto and set the reference level instead.

[:SENSe]:POWer[:RF]:GAIN?

Query the gain index.

[:SENSe]:POWer[:RF]:GAIN:AUTO <bool>

Specify whether gain is automatically selected.

[:SENSe]:POWer[:RF]:GAIN:AUTO?

Query whether gain is automatically selected.

[:SENSe]:POWer[:RF]:PREAMP <int>

Specify whether the preamp is on/off. Only valid for the SA devices. It is recommended to leave preamp set to auto and set the reference level instead.

[:SENSe]:POWer[:RF]:PREAMP?

Query the preamp state.

[:SENSe]:POWer[:RF]:PREAMP:AUTO <bool>

Specify whether the preamp is automatically selected.

[:SENSe]:POWer[:RF]:PREAMP:AUTO?

Query whether the preamp is automatically selected.

[:SENSe]:POWer[:RF]:MW:PRESelector[:STATe] <bool>

SM200A only. Set the preselector state on or off. The preselector filters affected by this setting are below 650MHz.

[:SENSe]:POWer[:RF]:MW:PRESelector[:STATe]?

Query the preselector state.

[:SENSe]:POWer[:RF]:SPURReject <bool>

Enable/Disable the software spur reject algorithm.

[:SENSe]:POWer[:RF]:SPURReject?

Query whether the software spur reject algorithm is enabled.

Bandwidth

These commands control the FFT processing for the receivers. These settings are highly coupled with the frequency range and sweep time. Additionally, there are several RBW/VBW restrictions present based on device type and span.

[:SENSe]:BANDwidth[:RESolution] <freq>|UP|DOWN

Specify the RBW. If UP or DOWN is specified, the RBW is stepped in a 1/3/10 sequence.

[:SENSe]:BANDwidth[:RESolution]?

Query the RBW in Hz.

[:SENSe]:BANDwidth[:RESolution]:AUTO ON|OFF|0|1

Specify whether the RBW is automatically selected.

[:SENSe]:BANDwidth[:RESolution]:AUTO?

Query whether the RBW is automatically selected.

[:SENSe]:BANDwidth:VIDeo <freq>|UP|DOWN

Specify the VBW. If UP or DOWN is specified, the VBW is stepped in a 1/3/10 sequence.

[:SENSe]:BANDwidth:VIDeo?

Query the VBW in Hz.

[:SENSe]:BANDwidth:VIDeo:AUTO ON|OFF|0|1

Specify whether the VBW is automatically selected.

[:SENSe]:BANDwidth:VIDeo:AUTO?

Query whether the VBW is automatically selected.

[:SENSe]:BANDwidth:SHAPe FLATtop|NUTTall|GAUSsian

Specify the FFT window function.

[:SENSe]:BANDwidth:SHAPe?

Query the FFT window function.

Sweep

The sweep commands control additional FFT settings of the receiver.

[:SENSe]:SWEep:TIME <double>

Specified as seconds. Controls the overall acquisition length for the sweep. If the sweep time is smaller than is needed for the current RBW/VBW settings, then sweep time is ignored. If sweep time is longer than necessary for the current RBW/VBW settings, then VBW is lowered to meet the requested sweep time. The VBW is lowered internally and won’t be represented in the VBW settings.

[:SENSe]:SWEep:TIME?

Query the sweep time in seconds.

[:SENSe]:SWEep:DETector:FUNCtion AVERage|MINMAX|MIN|MAX

Controls how the VBW processing is performed. If average, overlapping FFTs are averaged together. If MIN/MAX, overlapping FFTs are min/max held. MIN or MAX is the same processing as min/max but only returns one of the resulting arrays.

[:SENSe]:SWEep:DETector:FUNCtion?

Query the detector function.

[:SENSe]:SWEep:DETector:UNITs POWer|SAMPle|VOLTage|LOG

Controls the units in which the detector function is performed in.

[:SENSe]:SWEep:DETector:UNITs?

Query the detector units.

Traces

The trace commands control the user configurable traces for sweep mode. At any point there is an active trace that is selected with the TRACe:SELect command. All other commands operate on the current selected trace.

It may be necessary to request the entire selected sweep from the software. To do this, use the DATA? command. The sweep data will be returned as comma separated ascii floating point values. For example,

-107.12,-88.4,-30.72,-91.94,-111.6,…

To determine the frequency of any given point in the sweep, use the XSTARt? and XINCrement? commands. The frequency of a given point is given by the equation,

Frequency of j’th point = XSTART + j * XINCREMENT

where j is a zero based index into the array of sweep points.

:TRACe:SELect <int>

Specify a trace index [1,6]. All future operations occur on this trace.

:TRACe:SELect?

Query the active trace index.

:TRACe:TYPE OFF|WRITe|AVERage|MAXhold|MINhold|MINMAX

Specify the behavior of the trace.

:TRACe:AVERage:COUNt <int>

Specify the number of traces that are averaged together to create the final sweep.

:TRACe:AVERage:COUNt?

Query the number of traces that are averaged together.

:TRACe:AVERage:CURRent?

Retrieve the current number of traces that have been averaged together to create the final sweep.

:TRACe:COPY <int>

Copy the currently selected trace to the trace specified by the supplied parameter. The supplied parameter should be between the value [1,6] and should not equal the currently selected trace. If the destination trace type is off, the trace type is set to clear and write. Update is set to off and display is set to on for the destination trace.

:TRACe:UPDate[:STATe] ON|OFF|0|1

Specify if the trace updates when a new sweep is acquired from the device.

:TRACe:UPDate[:STATe]?

Query whether the trace updates when a new sweep is acquired.

:TRACe:DISPlay[:STATe] ON|OFF|0|1

Specify if the trace is hidden.

:TRACe:DISPlay[:STATe]?

Query whether the trace is displayed.

:TRACe:CLEar

Clear the selected trace. For example, if the current sweep is a max hold, sweep, and is cleared, the trace will be replaced with the next sweep from the device.

:TRACe:CLEar:ALL

Clear all the traces.

:TRACe:XSTARt?

Retrieve the frequency of the first point in the sweep as Hz. Useful for calculating the frequency of each point in the trace data returned from the :TRACe:DATA? command.

:TRACe:XINCrement?

Retrieve the frequency step between two points in the trace data as Hz. Useful for calculating the frequency of each point in the trace data.

:TRACe:POINts?

Returns the number of points in the trace data.

:TRACe[:DATA]?

Returns the trace data.

Markers

The marker commands control the Spike sweep markers. Select the active marker with the MARKer:SELect command. All marker commands will operate on the active marker.

Several commands operate on peaks. Peaks must meet the peak criteria which can be set with the EXCursion and THReshold commands.

:CALCulate:MARKer:SELect <int>

Select the active marker.

:CALCulate:MARKer:SELect?

Query the active marker index.

:CALCulate:MARKer:STATe ON|OFF|0|1

Turn the marker on/off.

:CALCulate:MARKer:STATe?

Query whether the marker is on.

:CALCulate:MARKer:TRACe <int>

Specify which trace to place the marker on. The trace must also be active to be able to retrieve marker measurements.

:CALCulate:MARKer:TRACe?

Query which trace the marker is placed on.

:CALCulate:MARKer:MODE POSition|NOISE|CHPower|NDB

Switch between positional and noise marker.

:CALCulate:MARKer:MODE?

Query the marker mode.

:CALCulate:MARKer:UPDate ON|OFF|0|1

When update is disabled, the marker will hold its current position and will not update on future sweep updates.

:CALCulate:MARKer:UPDate?

Query whether marker update is enabled.

:CALCulate:MARKer:DELTa ON|OFF|0|1

When delta is enabled, the delta reference takes the current marker position and the marker measurement returns the delta frequency and amplitude between the current marker position and the delta reference.

:CALCulate:MARKer:DELTa?

Query whether delta is enabled.

:CALCulate:MARKer:PKTRack ON|OFF|0|1

When enabled, the marker performs a peak search on each new trace update.

:CALCulate:MARKer:PKTRack?

Query whether peak tracking is enabled.

:CALCulate:MARKer:X <freq>

Move the marker position to the specified frequency.

:CALCulate:MARKer:X?

Retrieve the marker position frequency as Hz.

:CALCulate:MARKer:Y?

Retrieve the marker position amplitude according to marker type. Position and channel power markers return dBm, and noise markers return dBm/Hz. N dB markers also return the amplitude at their position in dBm. N dB results are retrieved using the N dB commands.

:CALCulate:MARKer:MAXimum

Perform a peak search.

:CALCulate:MARKer:MAXimum:NEXT

Move the marker to the next highest peak. Only peaks that meet the peak criteria are considered.

:CALCulate:MARKer:MAXimum:LEFT

Move the marker to the next peak to the left of its current position. Only peaks that meet the peak criteria are considered.

:CALCulate:MARKer:MAXimum:RIGHt

Move the marker to the next peak to the right of its current position (higher frequency). Only peaks that meet the peak criteria are considered.

:CALCulate:MARKer:MINimum

Perform a minimum peak search.

:CALCulate:MARKer:PEAK:EXCursion <double>

Specify the peak excursion in dB. How many dB above surrounding points the point must be before being considered a peak.

:CALCulate:MARKer:PEAK:EXCursion?

Query the peak excursion in dB.

:CALCulate:MARKer:PEAK:THReshold <amplitude>

Specify the peak threshold. A point must exceed this amount before being considered as a peak. Once the threshold test is met, then the excursion test is ran. If it meets both, then a point is considered a peak.

:CALCulate:MARKer:PEAK:THReshold?

Returns the current threshold as dBm.

:CALCulate:MARKer:CHPower:WIDth <freq>

Specify the width of the channel power marker measurement as a frequency.

:CALCulate:MARKer:CHPower:WIDth?

Query the width of the channel power marker measurement.

:CALCulate:MARKer:NDB[:OFFset] <double>

Specify the offset of the N dB marker measurement in dB.

:CALCulate:MARKer:NDB[:OFFset]?

Query the offset of the N dB marker measurement.

:CALCulate:MARKer:NDB:BANDwidth?

Retrieve the width of the N dB band.

:CALCulate:MARKer:NDB:RLEFt?

Retrieve the left edge frequency of the N dB band.

:CALCulate:MARKer:NDB:RRIGht?

Retrieve the right edge frequency of the N dB band.

:CALCulate:MARKer[:SET]:CENTer

Set the sweep center frequency to the current marker frequency.

:CALCulate:MARKer[:SET]:RLEVel

Set the sweep reference level to the current marker amplitude.

:CALCulate:MARKer:AOFF

Disables all markers. All other configuration parameters of the markers remain the same.

Trace Math

For more information on trace math, see the Spike user manual.

:CALCulate:MATH[:STATe] <bool>

Enabled or disable the trace math function.

:CALCulate:MATH[:STATe]?

Query whether the trace math function is enabled.

:CALCulate:MATH:FIRST <int>

Specify the first operand trace in the selected trace math function. Valid values are [1,6].

:CALCulate:MATH:FIRST?

Query the first operand trace.

:CALCulate:MATH:SECond <int>

Specify the second operand trace in the selected trace math function. Valid values are [1,6].

:CALCulate:MATH:SECond?

Query the second operand trace.

:CALCulate:MATH:RESult <int>

Specify the result trace in the selected trace math function. Valid values are [1,6].

:CALCulate:MATH:RESult?

Query the result trace.

:CALCulate:MATH:OP PDIFF|PSUM|LOFFset|LDIFF

Specify the trace math function.

:CALCulate:MATH:OP?

Query the trace math function.

:CALCulate:MATH:OFFSet <double>

Specify the offset to use in the logarithm trace math functions.

:CALCulate:MATH:OFFSet?

Query the offset used in the logarithm trace math functions.

Channel Power

These commands control the channel power measurement in the Spike software. Through these commands you can configure a main channel and up to 5 adjacent channels and simultaneously measure channel and adjacent channel power.

[:SENSe]:CHPower:STATe ON|OFF|0|1

Enables/disables the channel power measurement.

[:SENSe]:CHPower:STATe?

Query whether the channel power measurement is enabled.

[:SENSe]:CHPower:TRACe <int>

Selects which trace the channel power measurement is performed on.

[:SENSe]:CHPower:TRACe?

Query which trace the channel power measurement is performed on.

[:SENSe]:CHPower:WIDth <freq>

Specifies the width of the main channel power measurement as a frequency.

[:SENSe]:CHPower:WIDth?

Query the width of the main channel power measurement.

[:SENSe]:CHPower:CHANnel:STATe <int>,ON|OFF|0|1

Enables/disables the measurement of an adjacent channel.*

[:SENSe]:CHPower:CHANnel:STATe? <int>

Query whether the measurement of an adjacent channel is enabled.*

[:SENSe]:CHPower:CHANnel:OFFSet <int>,<freq>

Specifies the offset from center of an adjacent channel.*

[:SENSe]:CHPower:CHANnel:OFFSet? <int>

Query the offset from center of an adjacent channel.*

[:SENSe]:CHPower:CHANnel:WIDth <int>,<freq>

Specifies the width of an adjacent channel.*

[:SENSe]:CHPower:CHANnel:WIDth? <int>

Query the width of an adjacent channel.*

[:SENSe]:CHPower:CHPower?

Returns the channel power of the main channel. The value has units equal to the units currently selected in reference level. No unit string is returned.

[:SENSe]:CHPower:CHPower:LOWer? <int>

Returns the lower channel power of an adjacent channel as dBm.*

[:SENSe]:CHPower:CHPower:UPPer? <int>

Returns the upper channel power of an adjacent channel as dBm.*

[:SENSe]:CHPower:ACPower:LOWer? <int>

Returns the lower adjacent power† of an adjacent channel as dBc.*

[:SENSe]:CHPower:ACPower:UPPer? <int>

Returns the upper adjacent power† of an adjacent channel as dBc.*

  • Read the notes on how to specify a channel. † This is the power of the center channel minus the power of the channel specified.

Occupied Bandwidth

These commands allow you to configure the occupied bandwidth measurement in the Spike software.

[:SENSe]:OBWidth:STATe ON|OFF|0|1

Enable or disable the occupied bandwidth measurement.

[:SENSe]:OBWidth:STATe?

Query whether the occupied bandwidth measurement is enabled.

[:SENSe]:OBWidth:TRACe <int>

Specify which trace the occupied bandwidth measurement is performed on.

[:SENSe]:OBWidth:TRACe?

Query which trace the occupied bandwidth measurement is performed on.

[:SENSe]:OBWidth:PERCent <double>

The occupied bandwidth measurement must contain N% of the total energy of the sweep. Specified as a percent.

[:SENSe]:OBWidth:PERCent?

Query the occupied bandwidth percent.

[:SENSe]:OBWidth:OBWidth?

Returns the bandwidth of the occupied bandwidth measurement as Hz.

[:SENSe]:OBWidth:CENTer?

Returns the center frequency of the occupied bandwidth measurement as Hz.

[:SENSe]:OBWidth:POWer?

Returns the power of the occupied bandwidth measurement.

Intermodulation Distortion

These commands allow you to configure the intermodulation distortion measurement in the Spike software.

[:SENSe]:IMD:STATe ON|OFF|0|1

Enable or disable the intermodulation distortion measurement.

[:SENSe]:IMD:STATe?

Query whether the intermodulation distortion measurement is enabled.

[:SENSe]:IMD:FREQuency? F1|F2|IM3L|IM3U

Returns the frequency of the specified intermodulation product: f1, f2, lower third order product (2f1 – f2), or upper third order product (2f2 – f1).

[:SENSe]:IMD:TPOWer? F1|F2|IM3L|IM3U

Returns the tonal power in dBm of the specified intermodulation product.

[:SENSe]:IMD:TPOWer:DIFF? IM3L|IM3U

Returns the tonal power difference in dBc between the specified third order product and its corresponding first order product.

[:SENSe]:IMD:TOI? IM3L|IM3U

Returns the third-order intercept in dBm of the specified third order product.

Peak Table

These commands control the Peak Table display panel in Swept Analysis mode.

[:SENSe]:PEAK:TABLe:STATe ON|OFF|0|1

Enables/disables the Peak Table panel.

[:SENSe]:PEAK:TABLe:STATe?

Query whether the Peak Table panel is enabled.

[:SENSe]:PEAK:TABLe:TRACe <int>

Selects which trace the peak measurements are performed on.

[:SENSe]:PEAK:TABLe:TRACe?

Query which trace the peak measurements are performed on.

[:SENSe]:PEAK:TABLe:THReshold <double>

Specify the peak threshold in dBm. A point must exceed this amount before being considered as a peak. Once the threshold test is met, then the excursion test is ran. If it meets both, then a point is considered a peak.

[:SENSe]:PEAK:TABLe:THReshold?

Query the peak threshold in dBm.

[:SENSe]:PEAK:TABLe:EXCursion <double>

Specify the peak excursion in dB. How many dB above surrounding points the point must be before being considered a peak.

[:SENSe]:PEAK:TABLe:EXCursion?

Query the peak excursion in dB.

[:SENSe]:PEAK:TABLe:SORT FREQuency|AMPLitude

Specifies the sort order of the table. Peaks can be sorted by frequency or amplitude. Frequency is ascending; amplitude is descending.

[:SENSe]:PEAK:TABLe:SORT?

Query the sort order of the table.

[:SENSe]:PEAK:TABLe:COUNt?

Returns the number of peaks in the table. This is the number of peaks that have met the criteria specified. This value can change after each sweep.

[:SENSe]:PEAK:TABLe:MAX <int>

Specify the maximum number of peaks that can appear in the table. This value must be between [0, 99].

[:SENSe]:PEAK:TABLe:MAX?

Query the maximum number of peaks that can appear in the table.

[:SENSe]:PEAK:TABLe:FREQuency? <int>

Returns the frequency of the specified peak.*

[:SENSe]:PEAK:TABLe:AMPLitude? <int>

Returns the amplitude of the specified peak.*

[:SENSe]:PEAK:TABLe:FREQuency:DELTa? <int>

Returns the frequency difference between the specified peak and the first peak in the list.*

[:SENSe]:PEAK:TABLe:AMPLitude:DELTa? <int>

Returns the amplitude difference between the specified peak and the first peak in the list.*

  • Read the notes on how to specify a peak.

Sweep Recording

These commands control the Sweep Recording control panel in Swept Analysis mode.

[:SENSe]:RECord:SWEep:DECimate:TYPE TIME|COUNT

Selects the decimation type.

[:SENSe]:RECord:SWEep:DECimate:TYPE?

Query the decimation type.

[:SENSe]:RECord:SWEep:DECimate:TIME <double>

Specifies the amount of time by which to decimate.

[:SENSe]:RECord:SWEep:DECimate:TIME?

Query the amount of time by which to decimate.

[:SENSe]:RECord:SWEep:DECimate:COUNt <int>

Specifies the number of sweeps by which to decimate.

[:SENSe]:RECord:SWEep:DECimate:COUNt?

Query the number of sweeps by which to decimate.

[:SENSe]:RECord:SWEep:DECimate:DETector AVERage|MAX

Selects the decimation detector.

[:SENSe]:RECord:SWEep:DECimate:DETector?

Query the decimation detector.

[:SENSe]:RECord:SWEep:CHANnelizer:STATe ON|OFF|0|1

Toggles decimation in frequency with the channelizer.

[:SENSe]:RECord:SWEep:CHANnelizer:STATe?

Query whether the channelizer is enabled.

[:SENSe]:RECord:SWEep:CHANnelizer:CENTer <freq>

Specifies the center frequency of the channel.

[:SENSe]:RECord:SWEep:CHANnelizer:CENTer?

Query the center frequency of the channel.

[:SENSe]:RECord:SWEep:CHANnelizer:SPACing <freq>

Specifies the channel width.

[:SENSe]:RECord:SWEep:CHANnelizer:SPACing?

Query the channel width.

[:SENSe]:RECord:SWEep:CHANnelizer:UNITs DBM|DBMHZ

Selects the output units of the channel power measurement.

[:SENSe]:RECord:SWEep:CHANnelizer:UNITs?

Query the output units of the channel power measurement.

[:SENSe]:RECord:SWEep:PROGress?

Returns the progress of the current decimation in time as a floating point percentage between 0 and 100.

[:SENSe]:RECord:SWEep:COUNt?

Returns the integer number of sweeps saved so far.

[:SENSe]:RECord:SWEep:FILE:SIZE?

Returns the size of the file in bytes as a floating point number.

[:SENSe]:RECord:SWEep:FILE:COUNt?

Returns the integer number of files saved so far.

[:SENSe]:RECord:SWEep:FILE:SIZE:MAX <int>

Specifies the maximum file size in gigabytes as an integer.

[:SENSe]:RECord:SWEep:FILE:SIZE:MAX?

Query the maximum file size in gigabytes.

[:SENSe]:RECord:SWEep:FILE:COUNt:MAX <int>

Specifies the maximum number of files to save.

[:SENSe]:RECord:SWEep:FILE:COUNt:MAX?

Query the maximum number of files to save.

[:SENSe]:RECord:SWEep:FILE:PREfix <string>

Specifies the file prefix.

[:SENSe]:RECord:SWEep:FILE:PREfix?

Query the file prefix.

[:SENSe]:RECord:SWEep:FILE:DIRectory <string>

Specifies the directory in which to save recordings. If the specified directory does not exist, then no change is made.

[:SENSe]:RECord:SWEep:FILE:DIRectory?

Query the directory in which recordings are saved.

[:SENSe]:RECord:SWEep:STARt

Start recording.

[:SENSe]:RECord:SWEep:STOP

Stop recording.

[:SENSe]:RECord:SWEep:STATus?

Returns true if actively recording.

Zero-Span

Configuration

These commands control the receiver configuration in zero-span mode.

Capture Settings

These commands control the configuration of the capture in zero-span mode.

[:SENSe]:ZS:CAPture:RLEVel <amplitude>

Set the reference level.

[:SENSe]:ZS:CAPture:RLEVel?

Return the current reference level as dBm.

[:SENSe]:ZS:CAPture:CENTer <freq>|UP|DOWN

Set the measurement center frequency.

[:SENSe]:ZS:CAPture:CENTer? [MIN|MAX]

Query the current center frequency. Returned as Hz. By passing the MIN or MAX arguments, the user can query the upper and lower frequency limits for a capture.

[:SENSe]:ZS:CAPture:CENTer:STEP[:INCRement] <freq>

Set the step amount the center frequency changes by when using the UP or DOWN parameters on the CENTer command.

[:SENSe]:ZS:CAPture:CENTer:STEP[:INCRement]?

Query the center frequency step size in Hz.

[:SENSe]:ZS:CAPture:SRATe <freq>

Specify the sample rate of the capture. This determines how much decimation will be applied to the full signal.

[:SENSe]:ZS:CAPture:SRATe?

Query the sample rate of the capture.

[:SENSe]:ZS:CAPture:IFBWidth <freq>

Specify the IF bandwidth, only active when AUTO is set to false.

[:SENSe]:ZS:CAPture:IFBWidth?

Query the IF bandwidth.

[:SENSe]:ZS:CAPture:IFBWidth:AUTO ON|OFF|0|1

When enabled, the Spike software will automatically choose an appropriate IF bandwidth for the measurement.

[:SENSe]:ZS:CAPture:IFBWidth:AUTO?

Query whether the IF bandwidth is automatically selected.

[:SENSe]:ZS:CAPture:SWEep:TIME <double>

Specified as seconds. Controls the overall acquisition length of the capture.

[:SENSe]:ZS:CAPture:SWEep:TIME?

Query the sweep time in seconds.

Trigger Settings

:TRIGger:ZS:SOURce IMMediate|IF|EXTernal|FMT

Specify the trigger type.

:TRIGger:ZS:SOURce?

Query the trigger type.

:TRIGger:ZS:SLOPe POSitive|NEGative

Specify rising edge (positive) or falling edge.

:TRIGger:ZS:SLOPe?

Query the trigger slope.

:TRIGger:ZS:IF:LEVel <amplitude>

Specify the trigger level of the IF trigger.

:TRIGger:ZS:IF:LEVel?

Query the trigger level of the IF trigger.

:TRIGger:ZS:POSition <double>

Specify the trigger delay of the IF or ext trigger, the percentage of samples of the capture displayed before the trigger.

:TRIGger:ZS:POSition?

Query the trigger position.

I/Q Data

A zero-span capture consists of a sequence of complex I/Q points. The number of points is determined by the sample rate and sweep time. Usually, points = sample rate * sweep time.

Each complex point has an in-phase and quadrature component, each of which is represented as a 32-bit floating point number. Data is returned as an array of values where the complex components are interleaved. For example,

I1, Q1, I2, Q2,…

The I/Q data can be represented in ASCII or binary format. If ASCII is chosen, the data will be returned as a comma separated list of ASCII floating point values. For example,

-0.08213204145, 0.04985508695, -0.08225408942, 0.05008481443,…

In binary format, the values are scaled to 16-bit integers. The current reference level is used as scaler. To retrieve the floating point values, use the following equation:

float=short/32768 √reflevel

where reflevel is represented in mW.

For large captures, binary format is faster and more efficient. Format is set using the :FORMat:IQ[:DATA] command.

Fetch Results

These functions are used to retrieve the measurement results. Fetch commands do not perform any measurement. The measurement must be performed with the INIT command when in single trigger mode or can be retrieved at any time in continuous measurement mode.

:FETCh:ZS? <int>

Fetch I/Q data and other measurement parameters. The integer parameter specifies which to retrieve.

Value Description
1 I/Q data in ASCII or binary format (see “I/Q Data” section above)
2 Length of I/Q data. This is the number of complex I/Q data points (eg. (I1, Q1) is a single point).
10 Average power as reported on the AM vs Time plot. Returned as dBm.

Scalar Network Analysis

These commands control Spike in the Scalar Network Analysis measurement mode. Several commands are shared with standard spectrum analysis.

Frequency Configuration

Note that the commands shared with sweep measurement mode are listed here again.

[:SENSe]:FREQuency:CENTer <freq>|UP|DOWN

Set the measurement center frequency. This can cause the start or stop frequency to change if the device is unable to maintain the current span with the new center frequency. This can have the side effect of changing the span/start/stop frequencies.

[:SENSe]:FREQuency:CENTer? [MIN|MAX]

Query the current center frequency. Returned as Hz. By passing the MIN or MAX arguments, the user can query the upper and lower frequency limits for a sweep.

[:SENSe]:FREQuency:STARt <freq>

Change the sweep start frequency. The lower bound for the start frequency is determined with the CENT? MIN command.

[:SENSe]:FREQuency:STARt?

Query the current measurement start frequency in Hz.

[:SENSe]:FREQuency:STOP <freq>

Set the sweep stop frequency. The upper bound for the stop frequency is determined with the CENT? MAX command.

[:SENSe]:FREQuency:STOP?

Query the current measurement stop frequency in Hz.

[:SENSe]:FREQuency:CENTer:STEP[:INCRement] <freq>

Set the step amount the center frequency changes by when using the UP or DOWN parameters on the CENTer command.

[:SENSe]:FREQuency:CENTer:STEP[:INCRement]?

Query the center frequency step size in Hz.

[:SENSe]:FREQuency:SPAN <freq>|UP|DOWN

Set the sweep span. This will change the start/stop and potentially center frequency of the sweep in attempt to meet the span requested.

[:SENSe]:FREQuency:SPAN?

Query the span in Hz.

Sweep Configuration

[:SENSe]:NA:SWEep:POINts <int>

Specify a suggested sweep size. The final sweep size takes this setting into consideration as well as hardware limitations when determining the final sweep size.

[:SENSe]:NA:SWEep:POINts?

Query the sweep size.

[:SENSe]:NA:SWEep:TYPE PASSive|ACTive

Specify whether an active or passive device is being measured. This will affect the attenuation and gain used during the sweep. Failure to properly set this value may result in reduced dynamic range or IF overload.

[:SENSe]:NA:SWEep:TYPE?

Query the sweep type.

[:SENSe]:NA:SWEep:HRANge ON|OFF|0|1

If high range is enabled, the software will optimize the sweep for dynamic range when a 20dB pad store through is performed. Sweep speed will decrease when selected.

[:SENSe]:NA:SWEep:HRANge?

Query whether high range is enabled.

[:SENSe]:NA:VIEW:SCALe LOG|VSWR

Specify whether the plot is in log or VSWR units. A unique reference level and div are stored for both scale types.

[:SENSe]:NA:VIEW:SCALe?

Query the plot scale.

[:SENSe]:NA:VIEW:RLEVel <double>

Specify the reference level. When log scale is selected, the rlevel is specified as dBm, when VSWR is selected, rlevel is specified as SWR directly. Do not specify units.

[:SENSe]:NA:VIEW:RLEVel?

Query the reference level.

[:SENSe]:NA:VIEW:DIV <double>

Specify the plot vertical scale as either dB or SWR (depending on what scale is currently selected). Do not specify units. In each case, the div is 1/10th the vertical scale of the plot.

[:SENSe]:NA:VIEW:DIV?

Query the plot vertical scale.

[:SENSe]:CORRection:NA:STORe:THRU

Perform a store through calibration.

[:SENSe]:CORRection:NA:STORe:THRU:HIGH

Perform a store through high range calibration.

[:SENSe]:CORRection:NA:STORe:THRU:ACTive?

Returns true when a calibration is active.(The store through has been performed for the current sweep settings.)

Traces

See Traces

Markers

See Markers

Phase Noise Measurements

These commands control Spike in the Phase Noise measurement mode. Phase noise measurements are only available for certain Signal Hound devices (SA and SM series spectrum analyzers).

Sweep Configuration

Configure the carrier search and phase noise measurement parameters.

[:SENSe]:PNoise:CARRier:SEARch[:STATe] ON|OFF|0|1

Enable the signal search functionality.

[:SENSe]:PNoise:CARRier:SEARch[:STATe]?

Query whether the signal search functionality is enabled.

[:SENSe]:PNoise:CARRier:SEARch:STARt <frequency>

Set the signal search frequency range.

[:SENSe]:PNoise:CARRier:SEARch:STARt?

Query the signal search start frequency.

[:SENSe]:PNoise:CARRier:SEARch:STOP <frequency>

Set the signal search frequency range.

[:SENSe]:PNoise:CARRier:SEARch:STOP?

Query the signal search stop frequency.

[:SENSe]:PNoise:CARRier:SEARch:PERForm

Forces a new signal search.

[:SENSe]:PNoise:CARRier:THReshold:MINimum <double>

Specify the minimum amplitude required in dBm (do not include units) needed for a signal to be detected as a carrier.

[:SENSe]:PNoise:CARRier:THReshold:MINimum?

Query the minimum carrier amplitude threshold.

[:SENSe]:PNoise:CARRier:VALid?

Returns whether a carrier was detected.

[:SENSe]:PNoise:CARRier:FREQuency?

Returns the detected frequency of the carrier in Hz.

[:SENSe]:PNoise:CARRier:AMPLitude?

Returns the detected amplitude of the carrier as dBm.

[:SENSe]:PNoise:VIEW:RLEVel <double>

Specify the plot reference level as dBc/Hz.

[:SENSe]:PNoise:VIEW:RLEVel?

Query the plot reference level.

[:SENSe]:PNoise:VIEW:PDIVision <double>

Specify the plot division height as a floating point value.

[:SENSe]:PNoise:VIEW:PDIVision?

Query the plot division height.

[:SENSe]:PNoise:VIEW:PNUMDIVisions <int>

Specify the number of divisions on the phase noise plot.

[:SENSe]:PNoise:VIEW:PNUMDIVisions?

Query the number of divisions on the phase noise plot.

[:SENSe]:PNoise:FREQuency:CENTer <frequency>

Specify the carrier search frequency window. A search window with 200kHz span centered at the specified frequency is used for detecting a carrier.

[:SENSe]:PNoise:FREQuency:CENTer?

Query the carrier search center frequency.

[:SENSe]:PNoise:FREQuency:OFFSet:STARt <frequency>

Specify the start frequency of the phase noise sweep as an offset from the detected carrier center frequency in Hz. Values must be between 10Hz and 10kHz and will be clamped to the closest value from the list [10Hz, 100Hz, 1kHz, 10kHz].

[:SENSe]:PNoise:FREQuency:OFFSet:STARt?

Query the phase noise sweep start offset.

[:SENSe]:PNoise:FREQuency:OFFSet:STOP <frequency>

Specify the stop frequency of the phase noise sweep as an offset from the detected carrier center frequency in Hz. Values must be between 1kHz and 10MHz and will be clamped to the closest value from the list [1kHz, 10kHz, 100kHz, 1MHz, 10MHz]

[:SENSe]:PNoise:FREQuency:OFFSet:STOP?

Query the phase noise sweep stop offset.

[:SENSe]:PNoise:PKTRack ON|OFF|0|1

Enable peak tracking.

[:SENSe]:PNoise:PKTRack?

Query whether peak tracking is enabled.

[:SENSe]:PNoise:TYPE PN|PNPAM|AM

Set the measurement type, select between, AM noise, Phase noise, or both.

[:SENSe]:PNoise:TYPE?

Query the measurement type.

Cross Correlation

These commands control the settings for cross correlation measurements

[:SENSe]:PNoise:XCORr:DEVice:ACTive?

Returns true if second SM device is connected.

[:SENSe]:PNoise:XCORr:DEVice:COUNt?

Returns the number of devices available for cross correlation.

[:SENSe]:PNoise:XCORr:DEVice:LIST?

Returns a list of all SM devices that can be used as the second analyzer for cross correlation measurements.

[:SENSe]:PNoise:XCORr:DEVice:CURRent?

Returns the name of the second analyzer, if active.

[:SENSe]:PNoise:XCORr:DEVice:CONnect?

Connects the second analyzer. Must be one of the names returned from the LIST? Command.

[:SENSe]:PNoise:XCORr:DEVice:DISConnect?

Disconnects the second analyzer.

[:SENSe]:PNoise:XCORr[:STATe] ON|OFF|0|1

Enable cross correlation. Both the PN400 and a second SM device should be connected prior to enabling cross correlation.

[:SENSe]:PNoise:XCORr[:STATe]?

Query whether cross correlation is enabled.

[:SENSe]:PNoise:XCORr:REFerence INTernal|EXTernal|RF

Set the timebase reference of the cross correlation measurement system.

[:SENSe]:PNoise:XCORr:REFerence?

Query the timebase reference.

[:SENSe]:PNoise:XCORr:FACTor <int>

Set the cross correlation factor.

[:SENSe]:PNoise:XCORr:FACTor?

Query the cross correlation factor.

DISPlay:PNoise:XCORr:GINdicator[:STATe] ON|OFF|0|1

Show/hide the gain indicator.

DISPlay:PNoise:XCORr:GINdicator[:STATe]?

Query whether the gain indicator is shown.

DISPlay:PNoise:XCORr:COUNt[:STATe] ON|OFF|0|1

show/hide the cross correlation counts.

DISPlay:PNoise:XCORr:COUNt[:STATe]?

Query whether the cross correlation counts are shown.

[:SENSe]:PNoise:XCORr:MEAS:RESTart

Restarts a cross correlation measurement.

[:SENSe]:PNoise:XCORr:MEAS:PROGress?

Tracks the progress of the cross correlation measurement. If cross correlation is enabled, this will return a value between [0,XCorr factor]. Once the value reaches the factor, the measurement is complete. If this command returns -1, then cross correlation is not enabled. There is a small period after enabling cross correlation where this function will return -1.

VCO Control

These commands allow connecting to and controlling the PN400.

[:SENSe]:PNoise:VCO:ACTive?

Returns whether the PN400 is connected in the software.

[:SENSe]:PNoise:VCO:CONnect?

Connects the PN400 and returns true if successful. If the PN400 is already connected, then returns true immediately.

[:SENSe]:PNoise:VCO:VOLTage[:STATe]

Enable/disable the supply and tune output voltages.

[:SENSe]:PNoise:VCO:VOLTage[:STATe]?

Query whether the supply and tune output voltages are enabled.

[:SENSe]:PNoise:VCO:VOLTage:SUPply:MIN <float>

Set the minimum supply voltage.

[:SENSe]:PNoise:VCO:VOLTage:SUPply:MIN?

Query the minimum supply voltage.

[:SENSe]:PNoise:VCO:VOLTage:SUPply:MAX <float>

Set the maximum supply voltage.

[:SENSe]:PNoise:VCO:VOLTage:SUPply:MAX?

Query the maximum supply voltage.

[:SENSe]:PNoise:VCO:VOLTage:SUPply <float>

Set the supply voltage.

[:SENSe]:PNoise:VCO:VOLTage:SUPply?

Query the supply voltage.

[:SENSe]:PNoise:VCO:VOLTage:TUNE:MIN <float>

Set the minimum tune voltage.

[:SENSe]:PNoise:VCO:VOLTage:TUNE:MIN?

Query the minimum tune voltage.

[:SENSe]:PNoise:VCO:VOLTage:TUNE:MAX <float>

Set the maximum tune voltage.

[:SENSe]:PNoise:VCO:VOLTage:TUNE:MAX?

Query the maximum tune voltage.

[:SENSe]:PNoise:VCO:VOLTage:TUNE <float>

Set the tune voltage.

[:SENSe]:PNoise:VCO:VOLTage:TUNE?

Query the tune voltage.

Traces

There are 6 user configurable traces for phase noise measurements. Any active user traces are updated after each phase noise sweep.

:TRACe:PNoise:SELect 1|2|3|4|5|6

Specify the active trace index. All future operations will occur on this trace.

:TRACe:PNoise:SELect?

Query the active trace index.

:TRACe:PNoise:TYPE OFF|NORMal|AVERage|REFerence|MINhold|MAXhold

Specify the trace type. AVERage:COUNt sweeps and REFerence stops the trace from updating (effectively holding the current values.

:TRACe:PNoise:TYPE?

Query the trace type.

:TRACe:PNoise:AVERage:COUNt <int>

Specify the number of sweeps that will be averaged together when trace is set to average type.

:TRACe:PNoise:AVERage:COUNt?

Query the average count.

:TRACe:PNoise:UPDate[:STATe] ON|OFF|0|1

Specify if the trace updates when a new sweep is acquired from the device.

:TRACe:PNoise:UPDate[:STATe]?

Query whether the trace updates.

:TRACe:PNoise:HIDE[:STATe] ON|OFF|0|1

hides/shows the trace.

:TRACe:PNoise:HIDE[:STATe]?

Query whether the trace is hidden.

:TRACe:PNoise:SMOothing[:STATe] ON|OFF|0|1

Enable/disable smoothing.

:TRACe:PNoise:SMOothing[:STATe]?

Query whether smoothing is enabled.

:TRACe:PNoise:SMOothing:APERture <float>

Specify the trace smoothing aperture as a %.

:TRACe:PNoise:SMOothing:APERture?

Query the trace smoothing aperture.

:TRACe:PNoise:SPURReject[:STATe] ON|OFF|0|1

Enable/disable trace spur rejection.

:TRACe:PNoise:SPURReject[:STATe]?

Query whether trace spur rejection is enabled.

:TRACe:PNoise:SPURReject:THRESHold <float>

Specify the spur reject threshold in dB.

:TRACe:PNoise:SPURReject:THRESHold?

Query the spur reject threshold.

:TRACe:PNoise:OFFSet <float>

Specify an offset in dB. Immediately applies to the trace.

:TRACe:PNoise:OFFSet?

Query the trace offset.

:TRACe:PNoise:TO 1|2|3|4|5|6

Move the current trace to the selected trace. The selected trace type will be set to reference.

:TRACe:PNoise:CLEar

Clear the current average accumulation.

:TRACe:PNoise[:DATA][:Y]?

Returns the trace data amplitudes. The number of values returned is the number of decades in the sweep times 100.

:TRACe:PNoise[:DATA]:X?

Returns the trace data frequencies. The number of values returned is the number of decades in the sweep times 100.

Markers

There are 6 user configurable markers for phase noise measurements. Each marker can be placed on one of the 3 user configurable traces. Delta measurements can be enabled. A reference marker is placed at the current marker location when the delta measurement is enabled.

:CALCulate:PNoise:MARKer:SELect 1|2|3|4|5|6

Specify the active marker index. All future operations will occur on this marker.

:CALCulate:PNoise:MARKer:SELect?

Query the active marker index.

:CALCulate:PNoise:MARKer[:STATe] ON|OFF|0|1

Enable/disable the marker

:CALCulate:PNoise:MARKer[:STATe]?

Query whether the marker is enabled.

:CALCulate:PNoise:MARKer:TRACe 1|2|3

Select which trace the marker is placed on. The marker is updated immediately.

:CALCulate:PNoise:MARKer:TRACe?

Query which trace the marker is placed on.

:CALCulate:PNoise:MARKer:DELTa ON|OFF|0|1

Enable/disable the delta marker. A reference marker is created when the delta functionality is enabled. It is possible to update the reference marker on an already active delta marker simply by enabling delta again.

:CALCulate:PNoise:MARKer:DELTa?

Query whether the delta marker is enabled.

:CALCulate:PNoise:MARKer:X <frequency>

Set the marker frequency as an offset from the carrier frequency.

:CALCulate:PNoise:MARKer:X?

Query the frequency of the marker as a frequency offset from the carrier. If the reference marker is active, the frequency returned is the difference between the reference marker and the current position.

:CALCulate:PNoise:MARKer:Y?

Query the amplitude of the marker as dBc/Hz. If the ref. marker is active, the value returned is the dB difference between the ref. marker and the current position.

Jitter Configuration

Perform a jitter measurement on any of the 3 user traces.

:CALCulate:PNoise:JITTer[:STATe] ON|OFF|0|1

Enable/disable the jitter measurement.

:CALCulate:PNoise:JITTer[:STATe]?

Query whether the jitter measurement is enabled.

:CALCulate:PNoise:JITTer:TRACe 1|2|3

Specify the target trace of the jitter measurement.

:CALCulate:PNoise:JITTer:TRACe?

Query the target trace of the jitter measurement.

:CALCulate:PNoise:JITTer:STARt <frequency>

Specify the start frequency of the jitter measurement as an offset from the carrier frequency.

:CALCulate:PNoise:JITTer:STARt?

Query the jitter measurement start frequency.

:CALCulate:PNoise:JITTer:STOP <frequency>

Specify the stop frequency of the jitter measurement as an offset from the carrier frequency.

:CALCulate:PNoise:JITTer:STOP?

Query the jitter measurement stop frequency.

:CALCulate:PNoise:JITTer:RMS?

Query the RMS Jitter of the measurement in seconds.

:CALCulate:PNoise:JITTer:PHASe?

Query the Phase Jitter of the measurement in radians.

Harmonic Measurements

Configuration

These commands configure the harmonic measurement.

[:SENSe]:HARMonics:NUMBer <int>

Specify the number of harmonics to be measured and displayed on screen.

[:SENSe]:HARMonics:NUMBer?

Query the number of harmonics.

[:SENSe]:HARMonics:TRACKing[:STATe] ON|OFF|0|1

When enabled the fundamental frequency is tracked. When peak measurement mode is selected, the frequency of the peak is used, when channel power measurement mode is selected, the center of the occupied bandwidth is tracked. With tracking enabled, the harmonics are measured at multiples of the measured fundamental and the fundamental is always drawn centered on the measured frequency.

[:SENSe]:HARMonics:TRACKing[:STATe]?

Query whether fundamental tracking is enabled.

[:SENSe]:HARMonics:MODE PEAK | CHPower

Specify the measurement mode for a harmonics peak amplitude. When peak is selected, a peak search algorithm is performed on the measured span. When channel power is selected over the entire measured harmonic span.

[:SENSe]:HARMonics:MODE?

Query the measurement mode.

[:SENSe]:HARMonics:FREQuency:FUNDamental <freq>|UP|DOWN

Specify the center frequency of the 1st harmonic or fundamental.

[:SENSe]:HARMonics:FREQuency:FUNDamental?

Query the fundamental frequency.

[:SENSe]:HARMonics:FREQuency:STEP[:INCRement] <freq>

Specify the step frequency. Used to step the fundamental frequency.

[:SENSe]:HARMonics:FREQuency:STEP[:INCRement]?

Query the step frequency.

[:SENSe]:HARMonics:FREQuency:SPAN <freq>

Specify the span of each measurement window at each harmonic.

[:SENSe]:HARMonics:FREQuency:SPAN?

Query the span of each measurement window.

[:SENSe]:HARMonics:BANDwidth[:RESolution] <freq>

Specify the RBW of the measurement at each harmonic.

[:SENSe]:HARMonics:BANDwidth[:RESolution]?

Query the RBW.

[:SENSe]:HARMonics:BANDwidth:VIDeo <freq>

Specify the VBW of the measurement at each harmonic.

[:SENSe]:HARMonics:BANDwidth:VIDEO?

Query the VBW.

[:SENSe]:HARMonics:POWer[:RF]:RLEVel <double>

Specify the measurement reference level as dBm. This value should be greater than the expected input power to prevent IF/ADC overload.

[:SENSe]:HARMonics:POWer[:RF]:RLEVel?

Query the measurement reference level.

[:SENSe]:HARMonics:VIEW:RLEVel <double>

Specify the plot reference level as dBm. This affects only the plot y-axis.

[:SENSe]:HARMonics:VIEW:RLEVel?

Query the plot reference level.

[:SENSe]:HARMonics:VIEW:PDIVision <double>

Specify the division height of the plot in dB. The division height is 1/10th of the plot height.

[:SENSe]:HARMonics:VIEW:PDIVision?

Query the plot division height.

[:SENSe]:HARMonics:TRACe:TYPE WRITe|MAXhold

Specify the trace behavior.

[:SENSe]:HARMonics:TRACe:TYPE?

Query the trace type.

Fetch Results

These commands retrieve the measurement results of the harmonic measurement. These commands do not issue a resweeps nor wait for a completed measurement. It is recommended to configure the software for single triggered measurements and using the INIT and *OPC? commands to initiate and wait for a measurement to complete before fetching measurement results.

[:SENSe]:FETCh:HARMonics:FREQuency? <int>

Fetch the specified harmonics peak frequency.

[:SENSe]:FETCh:HARMonics:AMPLitude? <int>

Fetch the specified harmonics amplitude in dBm.

[:SENSe]:FETCh:HARMonics:DISTortion?

Fetch the measured total harmonic distortion in %

Analog Demodulation

Configuration

[:SENSe]:ADEMod:FREQuency:CENTer <freq>|UP|DOWN

Specify the measurement center frequency.

[:SENSe]:ADEMod:FREQuency:CENTer?

Query the measurement center frequency.

[:SENSe]:ADEMod:FREQuency:CENTer:STEP[:INCRement] <freq>

Specify the center frequency step amount when using the UP|DOWN parameters.

[:SENSe]:ADEMod:FREQuency:CENTer:STEP[:INCRement]?

Query the center frequency step amount.

[:SENSe]:ADEMod:POWer[:RF]:RLEVel <amplitude>

Specify the measurement reference level. This should be large than the highest expected input power.

[:SENSe]:ADEMod:POWer[:RF]:RLEVel?

Query the measurement reference level.

[:SENSe]:ADEMod:LPFilter <freq>

Specify the analog low pass filter cutoff frequency.

[:SENSe]:ADEMod:LPFilter?

Query the analog low pass filter cutoff frequency.

Fetch Results

:FETCh:ADEMod:AM? <int>

Fetch AM demodulation metrics. The integer parameter specifies the metric to retrieve. Possible integer values are below. Can specify a list of metrics to request as comma separated list. The metrics will be returned as a comma separated list in the order they were requested.

Value Description
1 Returns carrier frequency in Hz
2 Returns carrier power in dBm
3 Returns AM modulation rate in Hz
4 Returns AM Depth (RMS) as %
5 Returns AM Depth (Peak+) as %
6 Returns AM Depth (Peak-) as %
7 Returns AM SINAD as dB
8 Returns AM THD as %

:FETCh:ADEMod:FM? <int>

Fetch FM demodulation metrics. The integer provided specifies the metric to retrieve. Possible integer values are below. Can specify a list of metrics to request as comma separated list. The metrics will be returned as a comma separated list in the order they were requested.

Value Description
1 Returns carrier frequency in Hz
2 Returns carrier power in dBm
3 Returns FM modulation rate in Hz
4 Returns FM Depth (RMS) in Hz
5 Returns FM Depth (Peak+) in Hz
6 Returns FM Depth (Peak-) in Hz
7 Returns FM SINAD as dB
8 Returns FM THD as %

Digital Demodulation

Configuration

Measurement

These commands modify the digital demod measurement parameters.

[:SENSe]:DDEMod:FREQuency:CENTer <freq>|UP|DOWN

Set the center frequency of the measurement.

[:SENSe]:DDEMod:FREQuency:CENTer?

Query the center frequency.

[:SENSe]:DDEMod:FREQuency:CENTer:STEP[:INCRement] <freq>

Set the center frequency step amount.

[:SENSe]:DDEMod:FREQuency:CENTer:STEP[:INCRement]?

Query the center frequency step amount.

[:SENSe]:DDEMod:POWer[:RF]:RLEVel <amplitude>

Set the reference level of the measurement. This value should be higher than the expected peak power of the input signal. Setting it closer to the actual peak input will optimize for dynamic range.

[:SENSe]:DDEMod:POWer[:RF]:RLEVel?

Query the reference level.

[:SENSe]:DDEMod:SRATe <freq>

Specify the sample rate of the input modulated signal.

[:SENSe]:DDEMod:SRATe?

Query the sample rate.

[:SENSe]:DDEMod:MODulation BPSK|DBPSK|QPSK|DQPSK|OQPSK|PI4QPSK|8PSK|D8PSK|QAM16|QAM32|QAM64|QAM256|QAM1024|FSK2|FSK4|FSK8|FSK16|ASK2|CUSTom

Specify the modulation type of the input signal.

[:SENSe]:DDEMod:MODulation?

Query the modulation type.

[:SENSe]:DDEMod:RLENgth <int>

Specify the measurement window length in symbols.

[:SENSe]:DDEMod:RLENgth?

Query the measurement window length.

[:SENSe]:DDEMod:FILTer NYQuist|RNYQuist|GAUSsian|RECTangle

Specify the measurement and reference filter.

[:SENSe]:DDEMod:FILTer?

Query the measurement and reference filter.

[:SENSe]:DDEMod:FILTer:ABT <double>

Specify the filter alpha/beta coefficient.

[:SENSe]:DDEMod:FILTer:ABT?

Query the filter alpha/beta coefficient.

[:SENSe]:DDEMod:IFBWidth:AUTO ON|OFF|0|1

When enabled, the Spike software will automatically choose an appropriate IF bandwidth for the measurement, (usually 2x the sample rate)

[:SENSe]:DDEMod:IFBWidth:AUTO?

Query whether the IF bandwidth is automatically selected.

[:SENSe]:DDEMod:IFBWidth <freq>

Specify the IF bandwidth, only active when AUTO is set to false.

[:SENSe]:DDEMod:IFBWidth?

Query the IF bandwidth.

[:SENSe]:DDEMod:AVERage[:STATe] ON|OFF|0|1

Enable measurement averaging.

[:SENSe]:DDEMod:AVERage[:STATe]?

Query whether measurement averaging is enabled.

[:SENSe]:DDEMod:AVERage:COUNt <int>

Specify the average count.

[:SENSe]:DDEMod:AVERage:COUNt?

Query the average count.

[:SENSe]:DDEMod:WCE[:STATe] ON|OFF|0|1

Enable wide carrier estimation.

[:SENSe]:DDEMod:WCE[:STATe]?

Query whether wide carrier estimation is enabled.

[:SENSe]:DDEMod:WCE:RANge <freq>

Set the wide carrier estimation range.

[:SENSe]:DDEMod:WCE:RANge?

Query the wide carrier estimation range.

Custom Modulation

[:SENSe]:DDEMod:CUSTom:IQ:VALid?

Returns 1 when the custom constellation is valid.

[:SENSe]:DDEMod:CUSTom:IQ:LENGth?

Returns the number of symbols in the custom constellation.

[:SENSe]:DDEMod:CUSTom:IQ:DATA <float>,<float>,…,<float>

Specify the constellation symbols as IQ values. IQ values are specified as comma separated real numbers, alternating IQ values. If an odd number of real values are provided the last value is ignored. If any value is an invalid real number, the command fails and throws a system error. While not strictly necessary, it is suggested to scale the constellation so that the maximum symbol magnitude is 1. See the example below.

[:SENSe]:DDEMod:CUSTom:IQ:DATA?

Returns the constellation symbols as a comma separated list of alternating IQ values.

Trigger

:TRIGger:DDEMod:SOURce IMMediate|IF|EXTernal

Specify the trigger type.

:TRIGger:DDEMod:SOURce?

Query the trigger type.

:TRIGger:DDEMod:IF:LEVel <amplitude>

Specify the trigger level of the IF trigger.

:TRIGger:DDEMod:IF:LEVel?

Query the trigger level of the IF trigger.

:TRIGger:DDEMod:DELay <int>

Specify the trigger delay of the IF or ext trigger, the number of symbols after the trigger to start the measurement.

:TRIGger:DDEMod:DELay?

Query the trigger delay.

Sync Search

These commands affect the sync pattern search.

[:SENSe]:DDEMod:SYNC[:STATe] ON|OFF|0|1

Enable/disable sync search.

[:SENSe]:DDemod:SYNC[:STATe]?

Query whether sync search is enabled.

[:SENSe]:DDEMod:SYNC:SWORd:PATTern <hex string>

The pattern to trigger on for the trigger pattern. Patterns will be converted to uppercase when provided otherwise.

[:SENSe]:DDEMod:SYNC:SWORd:PATTern?

Query the sync pattern.

[:SENSe]:DDEMod:SYNC:SWORd:LENGth <int>

The length in symbols of the pattern trigger. The pattern length is not necessarily the same length as the pattern itself. A shorter length uses only a portion of the pattern and a longer length pads the pattern with ‘zeros’

[:SENSe]:DDEMod:SYNC:SWORd:LENGth?

Query the pattern length.

[:SENSe]:DDEMod:SYNC:SLENgth <int>

Search length for the pattern trigger.

[:SENSe]:DDEMod:SYNC:SLENgth?

Query the search length.

[:SENSe]:DDEMod:SYNC:OFFSet <int>

Offsets the measurement from the beginning of a successful sync search. Can be negative.

[:SENSe]:DDEMod:SYNC:OFFSet?

Query the sync offset.

Compensation

These commands determine what type of compensations are performed on the measurement. When the compensations are active, they are performed before error metrics are measured.

[:SENSe]:DDEMod:COMPensate:IQINVersion[:STATe] ON|OFF|0|1

Enabled or disable IQ swap

[:SENSe]:DDEMod:COMPensate:IQINVersion[:STATe]?

Query whether IQ inversion is enabled.

[:SENSe]:DDEMod:COMPensate:IQOFFset[:STATe] ON|OFF|0|1

When enabled, IQ offset is removed from the signal.

[:SENSe]:DDEMod:COMPensate:IQOFFset[:STATe]?

Query whether IQ offset compensation is enabled.

[:SENSe]:DDEMod:COMPensate:ADRoop[:STATe] ON|OFF|0|1

When enabled, linear amplitude errors are corrected for in the signal.

[:SENSe]:DDEMod:COMPensate:ADRoop[:STATe]?

Query whether amplitude droop compensation is enabled.

Equalization

These commands affect the adaptive equalizer.

[:SENSe]:DDEMod:EQUalization[:STATe] ON|OFF|0|1

Enabled or disable equalization.

[:SENSe]:DDEMod:EQUalization[:STATe]?

Query whether equalization is enabled.

[:SENSe]:DDEMod:EQUalization:LENGth <int>

Length of the equalization filter in symbols. Must be odd.

[:SENSe]:DDEMod:EQUalization:LENGth?

Query the equalization filter length.

[:SENSe]:DDEMod:EQUalization:CONVergence <double>

Adaptive rate. Higher number adapt faster but are more unstable.

[:SENSe]:DDEMod:EQUalization:CONVergence?

Query the convergence rate.

[:SENSe]:DDEMod:EQUalization:HOLD[:STATe] ON|OFF|0|1

When enabled, adaptation step is bypassed but equalization is still applied.

[:SENSe]:DDEMod:EQUalization:HOLD[:STATe]?

Query whether hold is enabled.

[:SENSe]:DDEMod:EQUalization:RESet

Resets the equalization filter to the unit impulse response (pass through).

Sweep

These functions are used to retrieve spectrum data from the digital demodulation measurement mode.

[:SENSe]:DDEMod:TRACe:SWEep:XSTARt?

Get the frequency value associated with the first sample in the returned data.

[:SENSe]:DDEMod:TRACe:SWEep:XINCrement?

Get the frequency spacing for the samples in the returned data.

[:SENSe]:DDEMod:TRACe:SWEep:POINts?

Get the number of points returned by the DATA function.

[:SENSe]:DDEMod:TRACe:SWEep:DATA?

Get the spectrum trace.

Fetch Results

These functions are used to retrieve the measurement results. Fetch commands do not perform any measurement. The measurement must be performed with the INIT command when in single trigger mode or can be retrieved at any time in continuous measurement mode.

:FETCh:DDEMod? <int>

Fetch digital demodulation metrics. The integer parameter specifies the metric to retrieve. Possible integer values are below. Can specify a list of metrics to request as comma separated list. The metrics will be returned as a comma separated list in the order they were requested.

Value Description
1 RMS EVM average as %
2 RMS EVM peak as %
3 RMS mag error average as %
4 RMS mag error peak as %
5 RMS phase error average as %
6 RMS phase error peak as %
7 IQ offset average as dB
8 IQ offset peak as dB
9 Frequency error average as Hz
10 Frequency error peak as Hz
11 RF power average as dBm
12 RF power peak as dBm
13 SNR average as dB
14 SNR peak as dB
15 RMS FSK error average as %
16 RMS FSK error peak as %
17 FSK deviation avg as Hz
18 FSK deviation peak as Hz
29 Current average count
30 Demod bits as binary string
40 Constellation result length (see 41). Length in complex samples for PSK/QAM demodulations, or frequency samples for FSK demodulations.
41 Constellation results. This returns the I/Q values displayed on the constellation plot. When PSK/QAM demodulation is active, this is an array of complex values, and when FSK is selected, this is an array of scaled frequency values. This array is equal in length to the value returned in 40. This length is the symbol count times the oversample rate. For instance, with a symbol count of 128 and oversample rate of 16, this array should be 2048 samples (either complex or real). In this example, every 16th sample is the sampled symbol, with the transitions in-between. If FSK is selected, a real array is returned. The FSK frequency array returned should be scaled by the average frequency deviation returned in 17 (i.e. multiply every value in the returned array by the FSK avg dev). For complex constellation results, it is recommended to return to set :FORMAT:IQ to ascii (default), otherwise the I/Q data will be scaled to full scale 16-bit binary.

Spectrum Emission Mask

Configuration

These commands control the receiver and measurement configuration in the spectrum emission mask mode.

Frequency

These commands control the frequency range of the sweeps in spectrum emission mask mode.

[:SENSe]:SEMask:FREQuency:CENTer <freq>|UP|DOWN

Set the center frequency of the measurement.

[:SENSe]:SEMask:FREQuency:CENTer?

Query the center frequency.

[:SENSe]:SEMask:FREQuency:CENTer:STEP[:INCRement] <freq>

Set the center frequency step amount.

[:SENSe]:SEMask:FREQuency:CENTer:STEP[:INCRement]

Query the center frequency step amount.

[:SENSe]:SEMask:FREQuency:SPAN <freq>

Set the sweep span.

[:SENSe]:SEMask:FREQuency:SPAN?

Query the sweep span.

Bandwidth

These commands control the FFT processing for the receivers. These settings are highly coupled with the frequency range. Additionally, there are several RBW/VBW restrictions present based on device type and span.

[:SENSe]:SEMask:BANDwidth[:RESolution] <freq>|UP|DOWN

Specify the RBW. If UP or DOWN is specified, the RBW is stepped in a 1/3/10 sequence.

[:SENSe]:SEMask:BANDwidth[:RESolution]?

Query the RBW in Hz.

[:SENSe]:SEMask:BANDwidth[:RESolution]:AUTO ON|OFF|0|1

Specify whether the RBW is automatically selected.

[:SENSe]:SEMask:BANDwidth[:RESolution]:AUTO?

Query whether the RBW is automatically selected.

[:SENSe]:SEMask:BANDwidth:VIDeo <freq>|UP|DOWN

Specify the VBW. If UP or DOWN is specified, the VBW is stepped in a 1/3/10 sequence.

[:SENSe]:SEMask:BANDwidth:VIDeo?

Query the VBW in Hz.

[:SENSe]:SEMask:BANDwidth:VIDeo:AUTO ON|OFF|0|1

Specify whether the VBW is automatically selected.

[:SENSe]:SEMask:BANDwidth:VIDeo:AUTO?

Query whether the VBW is automatically selected.

Amplitude

These commands affect the RF front end of the device.

[:SENSe]:POWer[:RF]:RLEVel <double>

Set the reference level in dBm.

[:SENSe]:POWer[:RF]:RLEVel?

Query the reference level.

[:SENSe]:POWer[:RF]:PDIVision <double>

specify the plot vertical division (1/10th of the plot height) as dB. Logarithmic scale only.

[:SENSe]:POWer[:RF]:PDIVision?

Query the plot vertical division as dB.

Detector / Trace

These commands control the detector and trace settings of the receiver.

[:SENSe]:SEMask:SWEep:DETector:FUNCtion AVERage|MINMAX

Controls how the VBW processing is performed. If average, overlapping FFTs are averaged together. If min/max, overlapping FFTs are min/max held.

[:SENSe]:SEMask:SWEep:DETector:FUNCtion?

Query the detector function.

[:SENSe]:SEMask:SWEep:DETector:UNITs POWer|SAMPle|VOLTage|LOG

Controls the units in which the detector function is performed in.

[:SENSe]:SEMask:SWEep:DETector:UNITs?

Query the detector units.

:TRACe:SEMask:TYPE WRITe|MAXhold

Specify the trace type. Select WRITE for the standard clear/write operation, and MAXHOLD to persist the maximum amplitudes at each frequency bin.

:TRACe:SEMask:TYPE?

Query the trace type.

Measurement Reference

These commands control the configuration of the reference used in mask construction.

[:SENSe]SEMask:REF:TYPE PSD|PEAK|DIRect

Controls how the reference measurement is taken. PSD performs a channel power computation, PEAK does a peak search, and DIRECT uses the amplitude value set directly by user.

[:SENSe]SEMask:REF:TYPE?

Query the reference measurement type.

[:SENSe]SEMask:REF:BANDwidth:MODE AUTO|MANual

Controls the mode of setting the width of the measurement band. AUTO chooses a value automatically, MANUAL uses a width entered by user.

[:SENSe]SEMask:REF:BANDwidth:MODE?

Query the reference bandwidth mode.

[:SENSe]SEMask:REF:BANDwidth <freq>

Controls the width of the measurement band in manual mode.

[:SENSe]SEMask:REF:BANDwidth?

Query the width of the measurement band.

[:SENSe]SEMask:REF:LEVEL <double>

Controls the reference amplitude level in direct set mode.

[:SENSe]SEMask:REF:LEVEL?

Query the reference amplitude level.

Offset Table

These functions load data into offset tables in memory and read back offset table defining the current mask.

[:SENSe]SEMask:OFFSet:DATA <enabled1>, <startFreq1>, <stopFreq1>, <startLimit1>, <stopLimit1>, <mode1>, …

Specify the sets of offset parameters in the offset table in memory as the current mask. This will override any existing offsets. Offsets are specified as sets of six parameters:

  • enabled: ON|OFF|0|1
  • startFreq: <freq>
  • startLimit: <freq>
  • stopLimit: <double>
  • startFreq: <double>
  • mode: RELative|ABSolute
[:SENSe]SEMask:OFFSet:DATA?

Returns the offset table defining the current mask.

Measurement

These functions return measurements from spectrum emission mask mode, testing the trace against the current mask defined in the offset table.

[:SENSe]SEMask:CARRier:POWer?

Retrieves the current power used as the reference for the masks.

[:SENSe]SEMask:OFFSet:FAIL?

Returns 1 if mask fails, 0 if passes.

[:SENSe]SEMask:OFFSet[1-16]:FAIL?

Returns 1 if specified offset fails, 0 if it passes.

[:SENSe]SEMask:OFFSet[1-16]:LOWer:FAIL?

Returns 1 if lower range of specified offset fails, 0 if it passes.

[:SENSe]SEMask:OFFSet[1-16]:UPper:FAIL?

Returns 1 if upper range of specified offset fails, 0 if it passes.

[:SENSe]SEMask:OFFSet[1-16]:MARgin?

Retrieves worst margin (limit - peak) of specified offset.

[:SENSe]SEMask:OFFSet[1-16]:MARgin:LOWer?

Retrieves margin (limit - peak) of lower range of specified offset.

[:SENSe]SEMask:OFFSet[1-16]:MARgin:UPper?

Retrieves margin (limit - peak) of upper range of specified offset.

[:SENSe]SEMask:OFFSet[1-16]:PEAK:LEVel:LOWer?

Retrieves peak level of lower range of specified offset.

[:SENSe]SEMask:OFFSet[1-16]:PEAK:LEVel:UPper?

Retrieves peak level of upper range of specified offset.

[:SENSe]SEMask:OFFSet[1-16]:PEAK:FREQuency:LOWer?

Retrieves frequency at peak of lower range of specified offset.

[:SENSe]SEMask:OFFSet[1-16]:PEAK:FREQuency:UPper?

Retrieves frequency at peak of upper range of specified offset.

Marker

The marker commands control the marker in spectrum emission mask mode.

:CALCulate:SEMask:MARKer:STATe ON|OFF|0|1

Turn the marker on/off.

:CALCulate:SEMask:MARKer:STATe?

Query whether the marker is on.

:CALCulate:SEMask:MARKer:DELTa ON|OFF|0|1

When delta is enabled, the delta reference takes the current marker position and the marker measurement returns the delta frequency and amplitude between the current marker position and the delta reference.

:CALCulate:SEMask:MARKer:DELTa?

Query whether delta is enabled.

:CALCulate:SEMask:MARKer:X <freq>

Move the marker position to the specified frequency.

:CALCulate:SEMask:MARKer:X?

Retrieve the marker position frequency as Hz.

:CALCulate:SEMask:MARKer:Y?

Retrieve the marker position amplitude.

:CALCulate:SEMask:MARKer:MAXimum

Perform a peak search.

:CALCulate:SEMask:MARKer:MINimum

Perform a minimum search.

:CALCulate:SEMask:MARKer:NEXT

Move marker to next graph on plot.

:CALCulate:SEMask:MARKer:PREVious

Move marker to previous graph on plot.

Noise Figure

These commands control the receiver and measurement configuration and retrieve measurement results for the Noise Figure measurement mode.

Configuration

Frequency List

These commands control the list of frequency points at which measurements will take place.

[:SENSe]:NFIGure:FREQuency:MODE SWEPt|FIXed

Set how the list of measurement frequencies is determined. In SWEPt, the points are linearly distributed between the Start and Stop frequencies, with Points determining the number of points. In FIXed mode, a single frequency is measured, specified by Fixed Freq.

[:SENSe]:NFIGure:FREQuency:MODE?

Query how the list of measurement frequencies is determined.

[:SENSe]:NFIGure:FREQuency:STARt <freq>

Change the measurement list start frequency in Swept mode. The lower bound for the start frequency is determined with the CENT? MIN command.

[:SENSe]:NFIGure:FREQuency:STARt?

Query the current measurement list start frequency in Hz.

[:SENSe]:NFIGure:FREQuency:STOP <freq>

Set the measurement list stop frequency in Swept mode. The upper bound for the stop frequency is determined with the CENT? MAX command.

[:SENSe]:NFIGure:FREQuency:STOP?

Query the current measurement list stop frequency in Hz.

[:SENSe]:NFIGure:FREQuency:CENTer <freq>

Set the measurement list center frequency in Swept mode.

[:SENSe]:NFIGure:FREQuency:CENTer? [MIN|MAX]

Query the current measurement list center frequency in Hz. By passing the MIN or MAX arguments, the user can query the upper and lower frequency limits for a measurement.

[:SENSe]:NFIGure:FREQuency:SPAN <freq>

Set the measurement list span in Swept mode. This will change the start/stop and potentially center frequency of the measurement list in attempt to meet the span requested.

[:SENSe]:NFIGure:FREQuency:SPAN?

Query the measurement list span in Hz.

[:SENSe]:NFIGure:FREQuency:POINts <int>

Set the number of measurement points distributed across the Span in Swept mode.

[:SENSe]:NFIGure:FREQuency:POINts?

Query the number of measurement points.

[:SENSe]:NFIGure:FREQuency:FIXed <freq>

Set the frequency of the measurement in Fixed mode.

[:SENSe]:NFIGure:FREQuency:FIXed?

Query the frequency of the measurement in Hz.

[:SENSe]:NFIGure:FREQuency:LIST:DATA?

Get the list of measurement frequencies in Hz.

Measurement

[:SENSe]:NFIGure:POWer[:RF]:RLEVel <double>

Specify the reference level of the measurement in dBm.

[:SENSe]:NFIGure:POWer[:RF]:RLEVel?

Query the reference level of the measurement.

[:SENSe]:NFIGure:BANDwidth[:RESolution] <freq>|UP|DOWN

Specify the RBW. If UP or DOWN is specified, the RBW is stepped in a 1/3/10 sequence.

[:SENSe]:NFIGure:BANDwidth[:RESolution]?

Query the RBW in Hz.

[:SENSe]:NFIGure:BANDwidth[:RESolution]:AUTO ON|OFF|0|1

Automatically choose the RBW.

[:SENSe]:NFIGure:BANDwidth[:RESolution]:AUTO?

Query whether the RBW is automatically selected.

[:SENSe]:NFIGure:BANDwidth:VIDeo <freq>|UP|DOWN

Specify the VBW. If UP or DOWN is specified, the VBW is stepped in a 1/3/10 sequence.

[:SENSe]:NFIGure:BANDwidth:VIDeo?

Query the VBW in Hz.

[:SENSe]:NFIGure:BANDwidth:VIDeo:AUTO ON|OFF|0|1

Automatically choose the VBW.

[:SENSe]:NFIGure:BANDwidth:VIDeo:AUTO?

Query whether the VBW is automatically selected.

[:SENSe]:NFIGure[:MEAS]:SPAN <freq>

Specify the span of each sweep.

[:SENSe]:NFIGure[:MEAS]:SPAN?

Query the span of each sweep.

[:SENSe]:NFIGure:AVERage[:STATe] ON|OFF|0|1

Specify whether multiple sweeps are averaged together.

[:SENSe]:NFIGure:AVERage[:STATe]?

Query whether averaging is enabled.

[:SENSe]:NFIGure:AVERage:COUNt <integer>

Specify the number of sweeps that are averaged together.

[:SENSe]:NFIGure:AVERage:COUNt?

Query the number of averaged sweeps.

[:SENSe]:NFIGure:CORRection:TCOLd:VALue <double>

Specify room temperature in Kelvin.

[:SENSe]:NFIGure:CORRection:TCOLd:VALue?

Query room temperature.

[:SENSe]:NFIGure:ALERt[:STATe] ON|OFF|0|1

Specify whether a series of beeps will play when a sweep has finished.

[:SENSe]:NFIGure:ALERt[:STATe]?

Query whether an alert will play on sweep completion.

[:SENSe]:NFIGure:CORRection:ENR:TABLe:COUNt?

Query the count of ENR tables, corresponding to noise sources.

[:SENSe]:NFIGure:CORRection:ENR:TABLe:NEW

Create a new ENR table.

[:SENSe]:NFIGure:CORRection:ENR:TABLe:LOAD[:ID] <integer>

Load an ENR table by ID for programmatic access.

[:SENSe]:NFIGure:CORRection:ENR:TABLe[:ID]?

Query the ID of the currently loaded ENR table.

[:SENSe]:NFIGure:CORRection:ENR:TABLe:TITLe <string>

Set the title of the currently loaded ENR table.

[:SENSe]:NFIGure:CORRection:ENR:TABLe:TITLe?

Query the title of the loaded ENR table.

[:SENSe]:NFIGure:CORRection:ENR:TABLe:POINts?

Query the number of points in the loaded ENR table.

[:SENSe]:NFIGure:CORRection:ENR:TABLe:DATA <freq1>, <enr1>, …

Set the (frequency, enr) points in the loaded ENR table.

[:SENSe]:NFIGure:CORRection:ENR:TABLe:DATA?

Get the list of points in the loaded ENR table.

[:SENSe]:NFIGure:CORRection:ENR:CALibration:TABLe[:ID] <integer>

Specify which ENR table will be used for calibration.

[:SENSe]:NFIGure:CORRection:ENR:CALibration:TABLe[:ID]?

Query the calibration ENR table.

[:SENSe]:NFIGure:CORRection:ENR:MEASurement:TABLe[:ID] <integer>

Specify which ENR table will be used for measurement.

[:SENSe]:NFIGure:CORRection:ENR:MEASurement:TABLe[:ID]?

Query the measurement ENR table.

Calibration and Measurement

[:SENSe]:NFIGure:CALibration:STATe?

Returns the current cal state. Possible values are

  • uncal – There is no valid calibration currently stored. High measurement error is likely unless the DUT has at least 30 dB gain.
  • semical – There is a valid stored calibration, however the measurement accuracy has been reduced due to changes in the configuration since last cal.
  • cal – There is a valid stored calibration whose settings are identical to the current configuration.

[:SENSe]:NFIGure:CALibration:INITiate

Begin calibration process.

[:SENSe]:NFIGure:MEASurement:INITiate

Begin measurement process.

[:SENSe]:NFIGure:CONTinue

Continue calibration or measurement after the next action has been taken.

[:SENSe]:NFIGure:ABORt

Stop any calibration or measurement in progress. Corresponding data is not retained.

:STATus:NFIGure:NEXT?

Query the next action user needs to take before continuing measurement.

:STATus:NFIGure:PROGress?

Query the percentage progress of the current sweep. If there is no sweep currently in progress, this will return 100%. This is a more verbose alternative to simply waiting for sweep to finish with *OPC.

Fetch Results

:FETCh:NFIGure?

Fetch the list of noise figure measurements for each point in the frequency list.

:FETCh:NFIGure:GAIN?

Fetch the list of gain measurements for each point in the frequency list.

Bluetooth® Low Energy Measurements

These commands control the receiver and measurement configuration and retrieve measurement results for the Bluetooth Low Energy measurement mode.

Configuration

Measurement

[:SENSe]:BLE:MEAS DEMOD|IBE

Specify the active Bluetooth measurement, demodulation vs in-band emission testing.

[:SENSe]:BLE:MEAS?

Query the active Bluetooth measurement.

[:SENSe]:BLE:FREQuency:CENTer <freq>

Specify the center frequency of the demodulation measurements.

[:SENSe]:BLE:FREQuency:CENTer?

Query the center frequency of the demodulation measurements.

[:SENSe]:BLE:FREQuency:CENTer:STEP[:INCRement] <freq>

Specify the center frequency step size.

[:SENSe]:BLE:FREQuency:CENTer:STEP[:INCRement]?

Query the center frequency step size.

[:SENSe]:BLE:IFBW <freq>

Specify the measurement bandwidth for demodulation measurements.

[:SENSe]:BLE:IFBW?

Query the measurement bandwidth.

[:SENSe]:BLE:CHANnel:INDex <int>

When auto channel index is false, channel index is used to seed the PDU dewhitening.

[:SENSe]:BLE:CHANnel:INDex?

Query the channel index.

[:SENSe]:BLE:CHANnel:AUTO <bool>

When enabled, channel index is inferred from the center frequency.

[:SENSe]:BLE:CHANnel:AUTO?

Query whether the channel index is automatically inferred.

[:SENSe]:BLE:POW[:RF]:RLEVel <double>

Specify the reference level of the measurement in dBm.

[:SENSe]:BLE:POW[:RF]:RLEVel?

Query the reference level of the measurement.

Trigger

:TRIGger:BLE:SLENgth <time>

Specify the measurement capture length in which to search for a Bluetooth Low Energy packet.

:TRIGger:BLE:SLENgth?

Query the measurement capture length.

Fetch Results

:FETCh:BLE? <int>

Fetch Bluetooth Low Energy demodulation metrics. The integer parameter specifies the metric to retrieve. Possible integer values are below. Can specify a list of metrics to request as comma separated list. The metrics will be returned as a comma separated list in the order they were requested.

Value Description
1 Average count for output power TRM measurements (as int)
2 Total average output power as dBm
3 Max average power as dBm
4 Peak power of last measurement as dBm
5 Avg power of last measurement as dBm
6 Pk – Avg power of last measurement as dBm
100 f1 Avg as Hz
101 f2 Avg as Hz
102 f2 Max ratio as double
103 f2 / f1 as double
200 CFO and drift measurement count as int
201 Preamble CFO as Hz
202 Max CFO as Hz
203 Max drift as Hz
204 Max drift / 50us as Hz
205 Max overall CFO as Hz
206 Max overall drift as Hz
207 Max overall drift / 50us as Hz
300 Pass fail status for in-band emissions (IBE) measurement, false if measurement not performed.
301 IBE tx channel as int, -1 if measurement not performed.
302 IBE peak power as dBm, 0 if measurement not performed.
303 IBE adjacent power lower as dBm, 0 if measurement not performed.
304 IBE adjacent power upper as dBm, 0 if measurement not performed.
305 IBE failed channels as int, -1 if measurement not performed.
400 PDU type as string
401 Access address bits as binary string
402 PDU bits as binary string (de-whitened if applicable)
403 Full packet bits as binary string (not de-whitened or decoded)

WLAN Measurements

These commands control the receiver and measurement configuration in the WLAN measurement mode.

Configuration

Measurement

These commands affect the demodulation and receiver parameters of the measurement.

[:SENSe]:WLAN:STANdard BG | AG | N20 | N40 | AC20 | AC40 | AH | AX20

Select the WLAN modulation standard.

[:SENSe]:WLAN:STANdard?

Query the WLAN modulation standard.

[:SENSe]:WLAN:SYMbols:DSSS <int>

Specify how many DSSS symbols to demodulate/decode.

[:SENSe]:WLAN:SYMbols:DSSS?

Query how many DSSS symbols to demodulate/decode.

[:SENSe]:WLAN:PSDU:DECode <bool>

Enable OFDM PSDU decoding for BCC encoded waveforms.

[:SENSe]:WLAN:PSDU:DECode?

Query whether OFDM PSDU decoding is enabled.

[:SENSe]:WLAN:EQUalizer:MODE PREamble | DATA

Set the equalizer training method.

[:SENSe]:WLAN:EQUalizer:MODE?

Query the equalizer training method.

[:SENSe]:WLAN:PILot:TRACk:AMPLitude <bool>

Enable amplitude tracking using pilot subcarriers.

[:SENSe]:WLAN:PILot:TRACk:AMPLitude?

Query whether amplitude tracking is enabled.

[:SENSe]:WLAN:SYMBol:OFFSet <double>

Specify a GI timing offset between -100 and 0 (%)

[:SENSe]:WLAN:SYMBol:OFFSet?

Query the GI timing offset.

[:SENSe]:WLAN:FREQuency:CENTer <freq>

Specify the center frequency of the WLAN measurement.

[:SENSe]:WLAN:FREQuency:CENTer?

Query the center frequency of the WLAN measurement.

[:SENSe]:WLAN:FREQuency:CENTer:STEP[:INCRement] <freq>

Specify the center frequency step size.

[:SENSe]:WLAN:FREQuency:CENTer:STEP[:INCRement]?

Query the center frequency step size.

[:SENSe]:WLAN:FREQuency:INVert <bool>

Set to true to invert the spectrum. Useful for measuring signals subject to high side mixing.

[:SENSe]:WLAN:FREQuency:INVert?

Query whether the spectrum is inverted.

[:SENSe]:WLAN:IFBW <freq>

Specify the IF bandwidth of the measurement. This is applied as a low pass filter before the WLAN demodulation occurs.

[:SENSe]:WLAN:IFBW?

Query the IF bandwidth of the measurement.

[:SENSe]:WLAN:POWer[:RF]:RLEVel <double>

Specify the reference level of the measurement in dBm. This controls the sensitivity of the measurement.

[:SENSe]:WLAN:POWer[:RF]:RLEVel?

Query the reference level of the measurement.

Trigger

These commands affect the triggering and capturing parameters of the measurement.

:TRIGger:WLAN:SLENgth <time>

Specify the measurement capture length.

:TRIGger:WLAN:SLENgth?

Query the measurement capture length.

:TRIGger:WLAN:IF:THRESHold <double>

Specify the OFDM trigger threshold in dB.

:TRIGger:WLAN:IF:THRESHold?

Query the OFDM trigger threshold.

:TRIGger:WLAN:IF:LEVel <double>

Specify the DSSS video trigger level in dBm.

:TRIGger:WLAN:IF:LEVel?

Query the DSSS video trigger level.

Fetch Results

This command is used to retrieve the results of a WLAN measurement.

:FETCh:WLAN? <int>

Fetch WLAN demodulation metrics. The integer parameter specifies the metric to retrieve. Possible integer values are below. Can specify a list of metrics to request as comma separated list. The metrics will be returned as a comma separated list in the order they were requested.

When the WLAN standard is set to 802.11 a/n/ac/ah, the integers below correspond to the following measurement results.

Value Description
1 Modulation as text
2 Modulation encoding as text
3 Guard interval as text
4 Frequency error as Hz
5 EVM as %
6 EVM as dB
7 Avg Power as dBm
8 Peak Power as dBm
9 Crest factor
10 Initial scrambler state
11 Symbol count
12 Payload bit count
13 Sample rate error as ppm
14 Bandwidth as MHz. For WLAN-AH, this is the detected BW of the measured packet.

When the WLAN standard is set to 802.11 b, the integers below correspond to the following measurement results.

Value Description
1 Modulation as text
2 Preamble as text
3 Payload bit count
4 EVM as %
5 EVM as dB
6 Freq error as Hz
7 Avg power as dBm
8 Peak power as dBm
9 Crest factor

LTE Measurements

Both single frequency and scanning LTE measurements can be performed with the SCPI commands. Configuration of the scan bands themselves cannot be performed via SCPI. For that reason, we recommend configuring a preset with the desired scan bands ahead of time and using SCPI to load that preset. Once the preset is loaded, scans can be manually performed, and the cell search results table can be queried with the FETCH command. Single frequency measurements can be performed, and most demodulation values can be retrieved with the FETCH command.

Configuration

[:SENSe]:LTE:FREQuency:CENTer <freq>

Set the center frequency of the single frequency LTE measurement.

[:SENSe]:LTE:FREQuency:CENTer?

Query the center frequency of the single frequency LTE measurement.

[:SENSe]:LTE:FREQuency:CENTer:STEP[:INCRement] <freq>

Set the frequency step. Stepping not available via SCPI, use FREQ:CENTER directly.

[:SENSe]:LTE:FREQuency:CENTer:STEP[:INCRement]?

Query the frequency step.

[:SENSe]:LTE:CORRelation:THREShold <double>

Set the cell search correlation threshold. Must be between 0 and 1.

[:SENSe]:LTE:CORRelation:THREShold?

Query the cell search correlation threshold.

[:SENSe]:LTE:POW[:RF]:RLEVel <double>

Set the reference level (in dBm) for the single frequency LTE measurement.

[:SENSe]:LTE:POW[:RF]:RLEVel?

Query the reference level for the single frequency LTE measurement.

[:SENSe]:LTE:MEAS:INClude <bool>

When enabled, single frequency measurements are included in the cell search results.

[:SENSe]:LTE:MEAS:INClude?

Query whether single frequency measurements are included in the cell search results.

[:SENSe]:LTE:SCAN:TYPE SINGle|CONTinuous

Set whether the configured scan occurs once or continuously per “start scan”.

[:SENSe]:LTE:SCAN:TYPE?

Query the scan type.

[:SENSe]:LTE:SCAN:RESults:SORT RSSI|FREQuency|TIME

Determines how the cell search result entries are sorted.

[:SENSe]:LTE:SCAN:RESults:SORT?

Query how the cell search result entries are sorted.

[:SENSe]:LTE:SCAN:RESults:KEEP LAST|PEAK

When cell search results are grouped, determines which measurement is displayed for that given grouping.

[:SENSe]:LTE:SCAN:RESults:KEEP?

Query which measurement is displayed for a given grouping.

[:SENSe]:LTE:SCAN:RESults:GROUP <bool>

Enables cell search result grouping.

[:SENSe]:LTE:SCAN:RESults:GROUP?

Query whether cell search result grouping is enabled.

[:SENSe]:LTE:SCAN:RESults:MAX <int>

Determines the maximum number of entries visible in the cell search results window.

[:SENSe]:LTE:SCAN:RESults:MAX?

Query the maximum number of entries visible in the cell search results window.

[:SENSe]:LTE:SCAN:STARt?

Starts the scan, returns 1 once the scan has been started.

[:SENSe]:LTE:SCAN:ACTive?

Returns 1 if the scan is active.

[:SENSe]:LTE:SCAN:STOP?

Stops the scan. Returns 1 when complete.

[:SENSe]:LTE:SCAN:RESults:COUNt?

Returns the number of rows in the cell scan results table.

[:SENSe]:LTE:SCAN:RESults:INDEX <int>

Set the index into the cell scan results table to be used with the FETCH command.

[:SENSe]:LTE:SCAN:RESults:INDEX?

Query the index into the cell scan results table.

[:SENSe]:LTE:SCAN:RESults:CLEar

Clears the cell search results table.

Fetch Results

This function is used to retrieve measurement results from both single frequency and scanning LTE measurements. Fetch commands do not perform the actual measurement, only retrieves the measurement result. We recommend the measurement be in an idle state when querying results. This ensures measurement values are not being updated mid-way through a fetch query.

:FETCh:LTE? <int>

Fetch LTE measurement value. The integer parameter specifies the value to retrieve. Possible integer values are below. Can specify a list of metrics to request as comma separated list. The metrics will be returned as a comma separated list in the order they were requested.

The following parameters retrieve measurements from the single frequency LTE result.

Value Description
1 Frequency of measurement
2 Channel power as dBm
3 Peak power
4 Peak to average power ratio
5 RSSI
6 RSRP
7 RSRQ
8 Freq error
9 Correlation result
10 PSS EVM
11 PBCH EVM
50 GPS Latitude
51 GPS Longitude
100 Phy. Cell ID
101 Phy. Group ID
102 Phy. Sector ID
103 Bandwidth
104 Duplex Mode
105 Cyclic Prefix
106 Number of ports
107 PHICH
108 Ng
109 Frame number
150 MIB bits
200 SIB1 Valid
201 EARFCN
202 TAC
203 Cell ID
204 Cell Barred
210 PLMN Count
211 MCC #1
212 MNC #1
213 Country String #1
214 Network String #1
215 MCC #2
216 MNC #2
217 Country String #2
218 Network String #2
219 MCC #3
220 MNC #3
221 Country String #3
222 Network String #3
223 MCC #4
224 MNC #4
225 Country String #4
226 Network String #4
250 SIB1 bits

The following parameters retrieve measurements from the cell search results table. Which row the results are retrieved from are determined by the index specified with the LTE:SCAN:RESULTS:INDEX command.

Value Description
301 Frequency
302 EARFCN
303 RSSI
304 RSRP
305 RSRQ
306 Cell ID
307 Phy. Cell ID
308 Bandwidth
309 Duplex Mode
310 # of ports
311 PLMN Count
312 MCC #1
313 MNC #1
314 Country String #1
315 Network String #1
316 Time as milliseconds since epoch
319 GPS Latitude
320 GPS Longitude

VCO Characterization

Configuration

These commands control the configuration of the measurement in VCO Characterization mode.

Sweep

[:SENSe]:VCO:SWEep:SOURce?

Query the sweep source.

[:SENSe]:VCO:SWEep:STARt <double>

Set the starting voltage for the sweep in volts.

[:SENSe]:VCO:SWEep:STARt?

Query the starting voltage for the sweep.

[:SENSe]:VCO:SWEep:STOP <double>

Set the stopping voltage for the sweep in volts.

[:SENSe]:VCO:SWEep:STOP?

Query the stopping voltage for the sweep.

[:SENSe]:VCO:SWEep:POINts <int>

Set the number of points to measure.

[:SENSe]:VCO:SWEep:POINts?

Query the number of points to measure.

[:SENSe]:VCO:SWEep[:RF]:RLEVel <double>

Set the reference level as dBm.

[:SENSe]:VCO:SWEep[:RF]:RLEVel?

Query the reference level.

[:SENSe]:VCO:SWEep:FREQuency:BAND:AUTO ON|OFF|0|1

Set whether the frequency band search range is automaticaly configured.

[:SENSe]:VCO:SWEep:FREQuency:BAND:AUTO?

Query whether the frequency band search range is automatically configured.

[:SENSe]:VCO:SWEep:FREQuency:BAND:STARt <freq>

Set the start frequency of the search range.

[:SENSe]:VCO:SWEep:FREQuency:BAND:STARt?

Query the start frequency of the search range.

[:SENSe]:VCO:SWEep:FREQuency:BAND:STOP <freq>

Set the stop frequency of the search range.

[:SENSe]:VCO:SWEep:FREQuency:BAND:STOP?

Query the stop frequency of the search range.

[:SENSe]:VCO:SWEep:FCOunter:RESolution <freq>

Set the frequency resolution of each measurement. This is effectively the RBW of the measurement sweep performed at each point.

[:SENSe]:VCO:SWEep:FCOunter:RESolution?

Query the frequency resolution of each measurement.

[:SENSe]:VCO:SWEep:CHPower:WIDth <freq>

Set the width of the channel for power and harmonics measurements..

[:SENSe]:VCO:SWEep:CHPower:WIDth?

Query the width of the channel for power and harmonics measurements.

[:SENSe]:VCO:SWEep:DELay <double>

Set the dwell time for each measurement, or the pause between setting PN400 voltage and measuring VCO output.

[:SENSe]:VCO:SWEep:DELay?

Query the dwell time for each measurement.

DC Source

[:SENSe]:VCO:SOURce:VOLTage[:STATe] ON|OFF|0|1

Enable or disable overall DC power.

[:SENSe]:VCO:SOURce:VOLTage[:STATe]?

Query whether overall DC power is enabled.

[:SENSe]:VCO:SOURce:VOLTage:FIXed[:LEVel] <double>

Set the output level of the fixed power source in volts.

[:SENSe]:VCO:SOURce:VOLTage:FIXed[:LEVel]?

Query the output level of the fixed power source.

[:SENSe]:VCO:SOURce:VOLTage:VTUNe[:LEVel]:LIMit:LOW <double>

Set the minimum output level of the V Tune port in volts.

[:SENSe]:VCO:SOURce:VOLTage:VTUNe[:LEVel]:LIMit:LOW?

Query the minimum output level of the V Tune port.

[:SENSe]:VCO:SOURce:VOLTage:VTUNe[:LEVel]:LIMit:HIGH <double>

Set the maximum output level of the V Tune port in volts.

[:SENSe]:VCO:SOURce:VOLTage:VTUNe[:LEVel]:LIMit:HIGH?

Query the maximum output level of the V Tune port.

[:SENSe]:VCO:SOURce:VOLTage:VSUPply[:LEVel]:LIMit:LOW <double>

Set the minimum output level of the V Supply port in volts.

[:SENSe]:VCO:SOURce:VOLTage:VSUPply[:LEVel]:LIMit:LOW?

Query the minimum output level of the V Supply port.

[:SENSe]:VCO:SOURce:VOLTage:VSUPply[:LEVel]:LIMit:HIGH <double>

Set the maximum output level of the V Supply port in volts.

[:SENSe]:VCO:SOURce:VOLTage:VSUPply[:LEVel]:LIMit:HIGH?

Query the maximum output level of the V Supply port.

Fetch Results

This function is used to retrieve measurement results from VCO characterization measurements. Fetch commands do not perform the actual measurement, only retrieves the measurement result. We recommend the measurement be in an idle state when querying results. This ensures measurement values are not being updated mid-way through a fetch query.

These commands all return sweep data as a list of comma separated ascii floating point values.

For example,

-107.12,-88.4,-30.72,-91.94,-111.6,…

To determine the voltage of any given point in the sweep, use the SWEEP:START?, SWEEP:STOP?, and SWEEP:POINTS? commands. The frequency of a given point is given by the equation,

Frequency of j’th point = START + j * (STOP - START) / POINTS

where j is a zero based index into the array of sweep points.

:FETCh:VCO:FREQuency?

Fetch the frequency vs. voltage measurement data.

:FETCh:VCO:SENSitivity?

Fetch the frequency delta vs. voltage delta measurement data.

:FETCh:VCO:POWer?

Fetch the amplitude vs. voltage measurement data.

:FETCh:VCO:CURRent?

Fetch the current vs. voltage measurement data.

:FETCh:VCO:HARMonics? <int>

Fetch the harmonic amplitude vs. voltage measurement data. The integer parameter specifies the harmonic to retrieve. Possible integer values are 1 – 6.

Audio Player

These commands control the audio player utility in Spike. The audio player can be started and stopped using these commands. The demodulation parameters can also be adjusted.

Configuration

[:SENSe]:AUDio:STARt

Open the audio player. If the audio player is already open, does nothing.

[:SENSe]:AUDio:STOP

Closes the audio player. If the audio player is already closed, does nothing.

[:SENSe]:AUDio:FREQuency:CENTer <frequency>

Set the center frequency of the audio player.

[:SENSe]:AUDio:FREQuency:CENTer?

Query the center frequency of the audio player.

[:SENSe]:AUDio:MOD AM|FM|LSB|USB|CW

Set the audio demodulation type.

[:SENSe]:AUDio:MOD?

Query the audio demodulation type.

[:SENSe]:AUDio:BANDwidth:IF <frequency>

Set the IF bandwidth of the audio player. This is the filter applied before audio demodulation.

[:SENSe]:AUDio:BANDwidth:IF?

Query the IF bandwidth of the audio player.

[:SENSe]:AUDio:BANDwidth:LOW <frequency>

Set the audio low pass filter.

[:SENSe]:AUDio:BANDwidth:LOW?

Query the audio low pass filter.

[:SENSe]:AUDio:BANDwidth:HIGH <frequency>

Set the audio high pass filter.

[:SENSe]:AUDio:BANDwidth:HIGH?

Query the audio high pass filter.

[:SENSe]:AUDio:FM:DEEMphasis <double>

Set the FM deemphasis in us.

[:SENSe]:AUDio:FM:DEEMphasis?

Query the FM deemphasis.

Examples

Connecting a Device

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates using VISA to connect to the Spike software
// using the SOCKET protocol and query the IDN string.
void scpi_simple_connect()
{
ViSession rm, inst;
ViStatus rmStatus;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Query the active device
char idn[256];
viPrintf(inst, "*IDN?\n");
viScanf(inst, "%s", idn);
// Print the IDN response
printf("*IDN? Response: %s\n", idn);
// Done
viClose(inst);
}

Error Query

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// It is recommended the user periodically query/flush all errors present in the
// Spike error queue. This ensures that the user is aware of any issues due to the
// SCPI command programming of the Spike software.
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Query the number of errors in the queue
// 3. Query each error and print it to the console
void scpi_error_query()
{
ViSession rm, inst;
ViStatus rmStatus;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Lets create a couple errors by sending invalid commands
for(int i = 0; i < 20; i++) {
viPrintf(inst, "SENSE:INVALID:COMMAND\n");
}
// Query the number of errors present
int errorCount = 0;
viQueryf(inst, "SYSTEM:ERROR:COUNT?\n", "%d", &errorCount);
printf("Error count %d\n", errorCount);
// For each error, query the error string, print it out in the console
char errBuf[256];
for(int i = 0; i < errorCount; i++) {
viQueryf(inst, "SYST:ERR:NEXT?\n", "%[^\n]", errBuf);
printf("Error: %s\n", errBuf);
}
// Done
viClose(inst);
}

Performing a Sweep

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Put the device into non-continuous mode
// 4. Perform and wait for a sweep to complete
void scpi_simple_sweep()
{
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to sweep
viPrintf(inst, "INSTRUMENT:SELECT SA\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
// Configure a 20MHz span sweep at 1GHz
// Set the RBW/VBW to auto
viPrintf(inst, "SENS:BAND:RES:AUTO ON; :BAND:VID:AUTO ON; :BAND:SHAPE FLATTOP\n");
// Center/span
viPrintf(inst, "SENS:FREQ:SPAN 20MHZ; CENT 1GHZ\n");
// Reference level/Div
viPrintf(inst, "SENS:POW:RF:RLEV -20DBM; PDIV 10\n");
// Peak detector
viPrintf(inst, "SENS:SWE:DET:FUNC MINMAX; UNIT POWER\n");
// Configure the trace. Ensures trace 1 is active and enabled for clear-and-write.
// These commands are not required to be sent everytime, this is for illustrative purposes only.
viPrintf(inst, "TRAC:SEL 1\n"); // Select trace 1
viPrintf(inst, "TRAC:TYPE WRITE\n"); // Set clear and write mode
viPrintf(inst, "TRAC:UPD ON\n"); // Set update state to on
viPrintf(inst, "TRAC:DISP ON\n"); // Set un-hidden
// Trigger a sweep, and wait for it to complete
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
// Done
viClose(inst);
}

Averaging Multiple Traces

#include <cassert>
#include <cstdio>
#include <vector>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Configuring an average trace
// 3. Performing several sweeps to generate the avg trace
// 4. Querying the trace data
// 5. Manual peak search on the trace data and determine freq,ampl of peak
// Intended input signal is 1GHz less than -20dBm
void scpi_trace_average()
{
ViSession rm, inst;
ViStatus rmStatus;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// We want to create an average trace of 20 sweeps
int averageCount = 20;
// Set the measurement mode to sweep
viPrintf(inst, "INSTRUMENT:SELECT SA\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
// Configure a 20MHz span sweep at 1GHz
// Set the RBW/VBW to auto
viPrintf(inst, "SENS:BAND:RES:AUTO ON; :BAND:VID:AUTO ON; :BAND:SHAPE FLATTOP\n");
// Center/span
viPrintf(inst, "SENS:FREQ:SPAN 20MHZ; CENT 1GHZ\n");
// Reference level/Div
viPrintf(inst, "SENS:POW:RF:RLEV -30DBM; PDIV 10\n");
// Average power detector
viPrintf(inst, "SENS:SWE:DET:FUNC AVERAGE; UNIT POWER\n");
// Configure the trace. Ensures trace 1 is active and enabled for averaging
// These commands are not required to be sent everytime, this is for illustrative purposes only.
viPrintf(inst, "TRAC:SEL 1\n"); // Select trace 1
viPrintf(inst, "TRAC:TYPE AVERAGE\n"); // Set clear and write mode
viPrintf(inst, "TRACE:AVER:COUNT %d\n", averageCount);
viPrintf(inst, "TRAC:UPD ON\n"); // Set update state to on
viPrintf(inst, "TRAC:DISP ON\n"); // Set un-hidden
viPrintf(inst, "TRACE:CLEAR\n"); // Clear it
// Perform 'averageCount' sweeps
for(int i = 0; i < averageCount; i++) {
int opc;
// Trigger a sweep, and wait for it to complete
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
assert(opc == 1);
}
// Now lets get the full sweep
int traceLength;
// First query the number of points in the sweep
viQueryf(inst, "TRACE:POINTS?\n", "%d", &traceLength);
// Preallocate array for the sweep
traceLength *= 2;
std::vector<float> points(traceLength);
// Ask for the sweep data
// Sweep data is returned as comma separated values
viQueryf(inst, "TRACE:DATA?\n", "%,#f", &traceLength, &points[0]);
// Query information needed to know what frequency each point in the sweep refers to
double xStart, xInc;
viQueryf(inst, "TRACE:XSTART?; XINC?\n", "%lf;%lf\n", &xStart, &xInc);
// Find the peak point in the sweep
int peakIx = 0;
float peakVal = points[0];
for(int i = 1; i < traceLength; i++) {
if(points[i] > peakVal) {
peakIx = i;
peakVal = points[i];
}
}
// Print out peak information
printf("Peak Freq %f MHz, Peak Ampl %f dBm\n",
(xStart + xInc * peakIx) / 1.0e6, peakVal);
// Done
viClose(inst);
}

Peak Search

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example is an extension of the scpi_simple_sweep
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Put the device into non-continuous mode
// 3. Configure the marker and trace
// 4. Perform and wait for a sweep to complete
// 5. Peak search and output peak information
// The intended input tone for this example is a CW at 1GHz below -20dBm amplitude
void scpi_peak_search()
{
ViSession rm, inst;
ViStatus rmStatus;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to sweep
viPrintf(inst, "INSTRUMENT:SELECT SA\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
// Configure a 20MHz span sweep at 1GHz
// Set the RBW/VBW to auto
viPrintf(inst, "SENS:BAND:RES:AUTO ON; :BAND:VID:AUTO ON; :BAND:SHAPE FLATTOP\n");
// Center/span
viPrintf(inst, "SENS:FREQ:SPAN 20MHZ; CENT 1GHZ\n");
// Reference level/Div
viPrintf(inst, "SENS:POW:RF:RLEV -20DBM; PDIV 10\n");
// Peak detector
viPrintf(inst, "SENS:SWE:DET:FUNC MINMAX; UNIT POWER\n");
// Configure the trace
// These commands are not required to be sent everytime, this is for illustrative
// purposes only. Ensures trace 1 is active and enabled for clear-and-write.
viPrintf(inst, "TRAC:SEL 1\n"); // Select trace 1
viPrintf(inst, "TRAC:TYPE WRITE\n"); // Set clear and write mode
viPrintf(inst, "TRAC:UPD ON\n"); // Set update state to on
viPrintf(inst, "TRAC:DISP ON\n"); // Set un-hidden
// Configure the marker
// Below is a blown out list of commands that could be sent to ensure the marker is configured
// properly. Not all of these commands are required to be sent everytime. The commands
// below are used for illustrative purposes only.
viPrintf(inst, "CALC:MARK:SEL 1\n"); // Select marker 1
viPrintf(inst, "CALC:MARK:TRACE 1\n"); // Put marker on trace 1
viPrintf(inst, "CALC:MARK:MODE POS\n"); // Set marker to position mode
viPrintf(inst, "CALC:MARK:DELTA OFF\n"); // Disable delta marker
viPrintf(inst, "CALC:MARK:PKTR OFF\n"); // Disable peak tracking if enabled
// Trigger a sweep, and wait for it to complete
int opc;
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
// Perform a peak search, and query the frequency and amplitude
// If the marker is not currently enabled, then it is enabled on peak search
viPrintf(inst, "CALC:MARK:MAX; X?; Y?\n");
double x, y;
viScanf(inst, "%lf;%lf", &x, &y);
printf("Marker Peak: %.6f MHz, Ampl: %.2f dBm\n", x/1.0e6, y);
// Done
viClose(inst);
}

Delta Marker

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Configuring and performing a single sweep
// 3. Making a delta marker measurement by moving the marker to
// two different frequencies on the sweep and measuring the delta freq and
// amplitude between them.
// This example is a slight extension of the scpi_peak_search example
// Most of the commands are the same except the marker manipulation at the
// end of the function.
// The intended input tone for this example is a CW at 1GHz below -20dBm amplitude
void scpi_delta_marker()
{
ViSession rm, inst;
ViStatus rmStatus;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to sweep
viPrintf(inst, "INSTRUMENT:SELECT SA\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
// Configure a 20MHz span sweep at 1GHz
// Set the RBW/VBW to auto
viPrintf(inst, "SENS:BAND:RES:AUTO ON; :BAND:VID:AUTO ON; :BAND:SHAPE FLATTOP\n");
// Center/span
viPrintf(inst, "SENS:FREQ:SPAN 20MHZ; CENT 1GHZ\n");
// Reference level/Div
viPrintf(inst, "SENS:POW:RF:RLEV -20DBM; PDIV 10\n");
// Peak detector
viPrintf(inst, "SENS:SWE:DET:FUNC MINMAX; UNIT POWER\n");
// Configure the trace
// These commands are not required to be sent everytime, this is for illustrative
// purposes only. Ensures trace 1 is active and enabled for clear-and-write.
viPrintf(inst, "TRAC:SEL 1\n"); // Select trace 1
viPrintf(inst, "TRAC:TYPE WRITE\n"); // Set clear and write mode
viPrintf(inst, "TRAC:UPD ON\n"); // Set update state to on
viPrintf(inst, "TRAC:DISP ON\n"); // Set un-hidden
// Configure the marker
// Below is a blown out list of commands that could be sent to ensure the marker is configured
// properly. Not all of these commands are required to be sent everytime. The commands
// below are used for illustrative purposes only.
viPrintf(inst, "CALC:MARK:SEL 1\n"); // Select marker 1
viPrintf(inst, "CALC:MARK:TRACE 1\n"); // Put marker on trace 1
viPrintf(inst, "CALC:MARK:MODE POS\n"); // Set marker to position mode
viPrintf(inst, "CALC:MARK:DELTA OFF\n"); // Disable delta marker
viPrintf(inst, "CALC:MARK:PKTR OFF\n"); // Disable peak tracking if enabled
// Trigger a sweep, and wait for it to complete
int opc;
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
// Move marker to peak,
viPrintf(inst, "CALC:MARK:MAX\n");
// Set the delta reference
// Even if the delta reference is already enabled, this will move the delta reference
// to the current marker position.
viPrintf(inst, "CALC:MARK:DELT ON\n");
// Now move it off the center by 1MHz
viPrintf(inst, "CALC:MARK:X 1.001GHz\n");
// Query the delta freq and ampl
viPrintf(inst, "CALC:MARK:X?; Y?\n");
double x, y;
viScanf(inst, "%lf;%lf", &x, &y);
printf("Delta Freq %.6f MHz, Delta Ampl %.2f dBm\n", x/1.0e6, y);
// Done
viClose(inst);
}

Channel Power Measurement

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to the Spike software
// 2. Configuring a sweep
// 3. Configuring a channel power measurement
// 4. Performing a sweep
// 5. Performing the channel power measurement
// The intended input tone for this example is a modulated signal at 1GHz below -20dBm amplitude
void scpi_channel_power()
{
ViSession rm, inst;
ViStatus rmStatus;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Set the measurement mode to sweep
viPrintf(inst, "INSTRUMENT:SELECT SA\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
// Configure a 20MHz span sweep at 1GHz
// Set the RBW/VBW to auto
viPrintf(inst, "SENS:BAND:RES:AUTO ON; :BAND:VID:AUTO ON; :BAND:SHAPE FLATTOP\n");
// Center/span
viPrintf(inst, "SENS:FREQ:SPAN 20MHZ; CENT 1GHZ\n");
// Reference level/Div
viPrintf(inst, "SENS:POW:RF:RLEV -20DBM; PDIV 10\n");
// Average detector
viPrintf(inst, "SENS:SWE:DET:FUNC AVERAGE; UNIT POWER\n");
// Set up our channel power, 3 channels, spaced 5MHz apart, each channel is 1MHz wide
// This has to be setup before we sweep
viPrintf(inst, "SENSE:CHPOWER:STATE ON; TRACE 1; WIDTH 1MHZ; CHANNEL:STATE 1,ON; OFFSET 1,5MHZ; WIDTH 1,1MHZ\n");
// Do a sweep
int opc;
viQueryf(inst, "INIT:IMM; *OPC?\n", "%d", &opc);
assert(opc == 1);
// Get the center channel power as dBm
// Get both adjacent channels as dB difference from center channel
double chpower, acpowerL, acpowerR;
viQueryf(inst, "SENSE:CHPOWER:CHPOWER?; :CHP:ACPOWER:LOWER? 1; :CHP:ACPOWER:UPPER? 1\n",
"%lf;%lf;%lf", &chpower, &acpowerL, &acpowerR);
printf("Channel Power %f dBm, Adj Left %f dB, Adj Right %f dB\n",
chpower, acpowerL, acpowerR);
// Done
viClose(inst);
}

Occupied Bandwidth

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to the Spike software
// 2. Configuring a sweep
// 3. Configuring the occupied bandwidth measurement
// 4. Performing a sweep
// 5. Performing the occupied bandwidth measurement
// The intended input tone for this example is a modulated signal at 1GHz below -20dBm amplitude
void scpi_occupied_bandwidth()
{
ViSession rm, inst;
ViStatus rmStatus;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Set the measurement mode to sweep
viPrintf(inst, "INSTRUMENT:SELECT SA\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
// Configure a 20MHz span sweep at 1GHz
// Set the RBW/VBW to auto
viPrintf(inst, "SENS:BAND:RES:AUTO ON; :BAND:VID:AUTO ON; :BAND:SHAPE FLATTOP\n");
// Center/span
viPrintf(inst, "SENS:FREQ:SPAN 20MHZ; CENT 1GHZ\n");
// Reference level/Div
viPrintf(inst, "SENS:POW:RF:RLEV -20DBM; PDIV 10\n");
// Peak detector
viPrintf(inst, "SENS:SWE:DET:FUNC AVERAGE; UNIT POWER\n");
// Set up occupied bandwidth
// This has to be setup before we sweep
viPrintf(inst, "SENSE:OBWIDTH:STATE ON; TRACE 1; PERCENT 95\n");
// Do a sweep
int opc;
viQueryf(inst, "INIT:IMM; *OPC?\n", "%d", &opc);
assert(opc == 1);
// Get the center channel power as dBm
// Get both adjacent channels as dB difference from center channel
double obWidth, obCenter, obPower;
viQueryf(inst, "SENSE:OBWIDTH:OBWIDTH?; CENTER?; POWER?\n",
"%lf;%lf;%lf", &obWidth, &obCenter, &obPower);
printf("OB Width %f MHz\n", obWidth / 1.0e6);
printf("OB Center %f MHz\n", obCenter / 1.0e6);
printf("OB Power %f dBm\n", obPower);
// Done
viClose(inst);
}

Sweep List

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example sweeps several small spans around a fundamental and several
// harmonics of the input frequency. This code illustrates sweeping different
// portions of the spectrum in a loop.
// This example uses standard sweep measurement mode to accomplish this task. A
// future update might include the harmonic measurement mode to simplify this task.
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Sweeping several harmonic frequencies of an input tone
// 3. Finding the peak at each harmonic frequency
// 4. Printing the harmonic freq/ampl to the console
void scpi_sweep_list()
{
ViSession rm, inst;
ViStatus rmStatus;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
double fundamental = 1.0e6; // 1MHz input tone
int harmonics = 10; // Measure 10 harmonics including the fundmental
double span = 100.0e3; // 100kHz span around each tone
double inputLevel = -20.0; // Input CW at -20dBm
// Some initial one time setup
// Set the measurement mode to sweep
viPrintf(inst, "INSTRUMENT:SELECT SA\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
// Set the RBW/VBW to auto
viPrintf(inst, "SENS:BAND:RES:AUTO ON; :BAND:VID:AUTO ON; :BAND:SHAPE FLATTOP\n");
// Reference level/Div
viPrintf(inst, "SENS:POW:RF:RLEV %fDBM; PDIV 10\n", inputLevel + 5.0);
// Average power detector
viPrintf(inst, "SENS:SWE:DET:FUNC MINMAX; UNIT POWER\n");
// Configure the trace. Ensures trace 1 is active and enabled for clear/write
// These commands are not required to be sent everytime, this is for illustrative purposes only.
viPrintf(inst, "TRAC:SEL 1\n"); // Select trace 1
viPrintf(inst, "TRAC:TYPE WRITE\n"); // Set clear and write mode
viPrintf(inst, "TRAC:UPD ON\n"); // Set update state to on
viPrintf(inst, "TRAC:DISP ON\n"); // Set un-hidden
double fundAmpl = 0.0;
for(int i = 0; i < harmonics; i++) {
double harmonicFreq = (i+1) * fundamental;
// Set freq
viPrintf(inst, "SENS:FREQ:SPAN %f; CENT %f\n", span, harmonicFreq);
int opc;
// Trigger a sweep, and wait for it to complete
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
assert(opc == 1);
// Perform a peak search, and query the frequency and amplitude
// If the marker is not currently enabled, then it is enabled on peak search
viPrintf(inst, "CALC:MARK:MAX; X?; Y?\n");
double x, y;
viScanf(inst, "%lf;%lf", &x, &y);
// Set our fundamental amplitude, so we can calculate dBc for all harmonics
if(i == 0) {
fundAmpl = y;
}
printf("Marker Peak: %.6f MHz, Ampl: %.2f dBm, Delta: %.2f dBc\n",
x/1.0e6, y, y - fundAmpl);
}
// Done
viClose(inst);
}

Path Loss Tables

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Configure a path loss table with several points
// 3. Perform a single sweep
// 4. Perform a peak search with path loss applied
// No input signal required
void scpi_path_loss_table()
{
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to Swept Analysis
viPrintf(inst, "INSTRUMENT:SELECT SA\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
viQueryf(inst, "*OPC?\n", "%d", &opc);
// Configure path loss table 1
viPrintf(inst, "SENS:CORR:PATH1:CLEAR\n"); // Clear table
viPrintf(inst, "SENS:CORR:PATH1:DESC SCPI Demo\n"); // Set table name
viPrintf(inst, "SENS:CORR:PATH1:STATE ON\n"); // Activate table
// Load table data:
//
// Freq (GHz) | Offset (dB)
// -----------|------------
// 1 | 10
// 2 | 20
// 3 | 30
double table[6] = { 1e9, 10, 2e9, 20, 3e9, 30 };
viPrintf(inst, "SENS:CORR:PATH1:DATA %,6lf\n", table);
// Get a sweep with table applied
viPrintf(inst, ":INIT\n");
viQueryf(inst, "*OPC?\n", "%d", &opc);
// Find peak
double peak;
viQueryf(inst, "CALC:MARK:MAX; Y?\n", "%lf", &peak);
// Reset table
viPrintf(inst, "SENS:CORR:PATH1:CLEAR\n");
viPrintf(inst, "SENS:CORR:PATH1:DESC Antenna Factor\n");
viPrintf(inst, "SENS:CORR:PATH1:STATE OFF\n");
// Done
viClose(inst);
}

Limit Lines

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Configure a limit line to match the current sweep span of the device.
// 3. Perform a single sweep
// 4. Test whether the limit line test passed/failed
// No input signal required
void scpi_configure_lline()
{
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to Digital Modulation Analysis
viPrintf(inst, "INSTRUMENT:SELECT SA\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
viQueryf(inst, "*OPC?\n", "%d", &opc);
// Get the current frequency range of the device, we will create a limit line with this
// frequency range as well.
double startFreq, stopFreq;
viQueryf(inst, ":FREQ:START?; :FREQ:STOP?\n", "%lf;%lf", &startFreq, &stopFreq);
// Configure, upper limit with no offset
viPrintf(inst, ":CALC:LLINE1:STATE ON\n");
viPrintf(inst, ":CALC:LLINE1:TRACE 1\n");
viPrintf(inst, ":CALC:LLINE1:TYPE UPPER\n");
viPrintf(inst, ":CALC:LLINE1:OFFSET:Y 0.0\n");
viPrintf(inst, ":CALC:LLINE1:STATE ON\n");
// Create limit line at -50 dBm across full freq range
double lline[4];
lline[0] = startFreq;
lline[1] = -50;
lline[2] = stopFreq;
lline[3] = -50;
// Load limit line
viPrintf(inst, ":CALC:LLINE1:DATA %,4lf\n", &lline[0]);
// Test
int fail = 0;
viQueryf(inst, ":INIT; *OPC; :CALC:LLINE1:FAIL?\n", "%d", &fail);
// No longer need limit lines, clear them
viPrintf(inst, ":CALC:LLINE1:CLEAR\n");
// Done
viClose(inst);
}

Zero Span Video Trigger

#include <cassert>
#include <cstdio>
#include <cmath>
#include <vector>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Configuring Spike for zero span measurements with video trigger
// 3. Performing the measurement
// 4. Fetching the resultant IQ data
// The intended input tone for this example is a pulse signal at 1GHz, -20dBm power or less
void scpi_zero_span_video_trigger()
{
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set timeout to 10 sec to wait for trigger
viSetAttribute(inst, VI_ATTR_TMO_VALUE, 10e3);
// Set the measurement mode to Zero-Span
viPrintf(inst, "INSTRUMENT:SELECT ZS\n");
// Disable continuous meausurement operation and wait for any active measurements
// to finish.
viPrintf(inst, "INIT:CONT OFF\n");
// Used for scaling
double REFLEVEL = -10.0;
// Configure the measurement, 1GHz, -20dBm input level
viPrintf(inst, "SENSE:ZS:CAPTURE:RLEVEL %.2fDBM\n", REFLEVEL);
viPrintf(inst, "SENSE:ZS:CAPTURE:CENTER 1GHZ\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:SRATE 50MHZ\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:IFBW:AUTO OFF\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:IFBW 40MHZ\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:SWEEP:TIME 0.0015\n"); // sec
// Configure the trigger
viPrintf(inst, "TRIG:ZS:SOURCE IF\n");
viPrintf(inst, "TRIG:ZS:SLOPE POS\n");
viPrintf(inst, "TRIG:ZS:IF:LEVEL -60\n");
viPrintf(inst, "TRIG:ZS:POS 30.0\n");
// Do two measurements and wait for them to complete
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
// Use binary format for IQ data
viPrintf(inst, "FORMAT:IQ:DATA BINARY\n");
// Query number of points and allocate buffer
int length;
viQueryf(inst, "FETCh:ZS? 2\n", "%d", &length);
std::vector<ViInt16> rdBuffer(length * 2);
printf("Length: %d\n", length);
// Fetch the results and print them off
ViInt32 rdBufferSize = rdBuffer.size() * sizeof(ViInt16);
viQueryf(inst, "FETCh:ZS? 1\n", "%#b", &rdBufferSize, rdBuffer.data());
printf("Length fetched: %d\n", (int)(rdBufferSize / (double)sizeof(ViInt16) / 2.0));
// Convert from 16-bit ints back to floats
double mwReference = pow(10.0, REFLEVEL / 10.0);
float scaleFactor = 1.0 / sqrt(mwReference);
std::vector<float> interleaved(rdBuffer.size());
for(int i = 0; i < interleaved.size(); i++) {
interleaved[i] = rdBuffer[i] / 32768.0 / scaleFactor;
}
// Convert to AM
std::vector<float> am(length);
for(int i = 0; i < am.size(); i++) {
am[i] = 10.0 * log10(interleaved[i*2] * interleaved[i*2] + interleaved[i*2+1] * interleaved[i*2+1]);
}
// Print first 10
for(int i = 0; i < 10; i++) {
printf("%.2f\n", am[i]);
}
// Done
viClose(inst);
}

Zero Span External Trigger

#include <cassert>
#include <cstdio>
#include <cmath>
#include <vector>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Configuring Spike for zero span measurements with external triggering, using the SM200B
// 3. Performing the measurement
// 4. Fetching the resultant IQ data
// The intended input tone for this example is at 1GHz, -20dBm power or less,
// plus a trigger into the external trigger port.
void scpi_zero_span_external_trigger()
{
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set timeout to 10 sec to wait for trigger
viSetAttribute(inst, VI_ATTR_TMO_VALUE, 10e3);
// Set the measurement mode to Zero-Span
viPrintf(inst, "INSTRUMENT:SELECT ZS\n");
// Disable continuous meausurement operation and wait for any active measurements
// to finish.
viPrintf(inst, "INIT:CONT OFF\n");
// Used for scaling
double REFLEVEL = -10.0;
// Configure the measurement, 1GHz, -20dBm input level
// NOTE: This sample rate and IFBW are valid for the SM200B only
viPrintf(inst, "SENSE:ZS:CAPTURE:RLEVEL %.2fDBM\n", REFLEVEL);
viPrintf(inst, "SENSE:ZS:CAPTURE:CENTER 1GHZ\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:SRATE 250MHZ\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:IFBW:AUTO OFF\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:IFBW 160MHZ\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:SWEEP:TIME 0.000001\n"); // sec
// Configure the trigger
viPrintf(inst, "TRIG:ZS:SOURCE EXT\n");
viPrintf(inst, "TRIG:ZS:SLOPE POS\n");
viPrintf(inst, "TRIG:ZS:POS 30.0\n");
// Do a measurement and wait for it to complete
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
// Use binary format for IQ data
viPrintf(inst, "FORMAT:IQ:DATA BINARY\n");
// Query number of points and allocate buffer
int length;
viQueryf(inst, "FETCh:ZS? 2\n", "%d", &length);
std::vector<ViInt16> rdBuffer(length * 2);
printf("Length: %d\n", length);
// Fetch the results and print them off
ViInt32 rdBufferSize = rdBuffer.size() * sizeof(ViInt16);
viQueryf(inst, "FETCh:ZS? 1\n", "%#b", &rdBufferSize, rdBuffer.data());
printf("Length fetched: %d\n", (int)(rdBufferSize / (double)sizeof(ViInt16) / 2.0));
// Convert from 16-bit ints back to floats
double mwReference = pow(10.0, REFLEVEL / 10.0);
float scaleFactor = 1.0 / sqrt(mwReference);
std::vector<float> interleaved(rdBuffer.size());
for(int i = 0; i < interleaved.size(); i++) {
interleaved[i] = rdBuffer[i] / 32768.0 / scaleFactor;
}
// Convert to AM
std::vector<float> am(length);
for(int i = 0; i < am.size(); i++) {
am[i] = 10.0 * log10(interleaved[i*2] * interleaved[i*2] + interleaved[i*2+1] * interleaved[i*2+1]);
}
// Print 10 from trigger capture range
int start = am.size() * 0.5;
for(int i = start; i < start + 10; i++) {
printf("%.2f\n", am[i]);
}
// Done
viClose(inst);
}

Zero Span I/Q Capture

#include <cassert>
#include <cstdio>
#include <cmath>
#include <vector>
#include <complex>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Configuring Spike for zero span measurements
// 3. Performing the measurement
// 4. Fetching the resultant IQ data in ASCII format
// The intended input tone for this example is a signal at 1GHz, -20dBm power or less
void scpi_zero_span_iq_capture()
{
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to Zero-Span
viPrintf(inst, "INSTRUMENT:SELECT ZS\n");
// Disable continuous meausurement operation and wait for any active measurements
// to finish.
viPrintf(inst, "INIT:CONT OFF\n");
// Used for scaling
const double REFLEVEL = -10.0;
// Configure the measurement, 1GHz, -20dBm input level
viPrintf(inst, "SENSE:ZS:CAPTURE:RLEVEL %.2fDBM\n", REFLEVEL);
viPrintf(inst, "SENSE:ZS:CAPTURE:CENTER 1GHZ\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:SRATE 50MHZ\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:IFBW:AUTO OFF\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:IFBW 40MHZ\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:SWEEP:TIME 0.0015\n"); // sec
// Do two measurements and wait for them to complete
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
// Use binary format for IQ data
viPrintf(inst, "FORMAT:IQ:DATA ASCII\n");
// Query number of points and allocate buffer
int length;
viQueryf(inst, "FETCh:ZS? 2\n", "%d", &length);
printf("Length: %d\n", length);
// Fetch the results and print them off
std::vector<std::complex<float>> iq(length);
ViInt32 rdBufferSize = iq.size() * sizeof(std::complex<float>);
viQueryf(inst, "FETCh:ZS? 1\n", "%,#f", &rdBufferSize, iq.data());
printf("Length fetched: %d\n", (int)(rdBufferSize / (double)sizeof(std::complex<float>)));
// Convert to AM
std::vector<float> am(length);
for(int i = 0; i < am.size(); i++) {
am[i] = 10.0 * log10(iq[i].real() * iq[i].real() + iq[i].imag() * iq[i].imag());
}
// Print first 10
for(int i = 0; i < 10; i++) {
printf("%.2f\n", am[i]);
}
// Done
viClose(inst);
}

Zero Span Binary I/Q Capture

#include <cassert>
#include <cstdio>
#include <cmath>
#include <vector>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Configuring Spike for zero span measurements
// 3. Performing the measurement
// 4. Fetching the resultant IQ data in binary format
// The intended input tone for this example is a signal at 1GHz, -20dBm power or less
void scpi_zero_span_iq_capture_binary()
{
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to Zero-Span
viPrintf(inst, "INSTRUMENT:SELECT ZS\n");
// Disable continuous meausurement operation and wait for any active measurements
// to finish.
viPrintf(inst, "INIT:CONT OFF\n");
// Used for scaling
const double REFLEVEL = -10.0;
// Configure the measurement, 1GHz, -20dBm input level
viPrintf(inst, "SENSE:ZS:CAPTURE:RLEVEL %.2fDBM\n", REFLEVEL);
viPrintf(inst, "SENSE:ZS:CAPTURE:CENTER 1GHZ\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:SRATE 50MHZ\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:IFBW:AUTO OFF\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:IFBW 40MHZ\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:SWEEP:TIME 0.0015\n"); // sec
// Do two measurements and wait for them to complete
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
// Use binary format for IQ data
viPrintf(inst, "FORMAT:IQ:DATA BINARY\n");
// Query number of points and allocate buffer
int length;
viQueryf(inst, "FETCh:ZS? 2\n", "%d", &length);
std::vector<ViInt16> rdBuffer(length * 2);
printf("Length: %d\n", length);
// Fetch the results and print them off
ViInt32 rdBufferSize = rdBuffer.size() * sizeof(ViInt16);
viQueryf(inst, "FETCh:ZS? 1\n", "%#b", &rdBufferSize, rdBuffer.data());
printf("Length fetched: %d\n", (int)(rdBufferSize / (double)sizeof(ViInt16) / 2.0));
// Convert from 16-bit ints back to floats
double mwReference = pow(10.0, REFLEVEL / 10.0);
float scaleFactor = 1.0 / sqrt(mwReference);
std::vector<float> interleaved(rdBuffer.size());
for(int i = 0; i < interleaved.size(); i++) {
interleaved[i] = rdBuffer[i] / 32768.0 / scaleFactor;
}
// Convert to AM
std::vector<float> am(length);
for(int i = 0; i < am.size(); i++) {
am[i] = 10.0 * log10(interleaved[i*2] * interleaved[i*2] + interleaved[i*2+1] * interleaved[i*2+1]);
}
// Print first 10
for(int i = 0; i < 10; i++) {
printf("%.2f\n", am[i]);
}
// Done
viClose(inst);
}

Harmonic Analysis

#include <cassert>
#include <cmath>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to the Spike software
// 2. Configuring a harmonic sweep measurement for the first 10 harmonics
// 3. Performing the sweep
// 4. Fetch the measurement results
// The intended input tone for this example is a modulated signal at 1MHz below -20dBm amplitude
void scpi_harmonic_sweep()
{
ViSession rm, inst;
ViStatus rmStatus;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Set the measurement mode to harmonic sweep
viPrintf(inst, ":INST HARM\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
viPrintf(inst, "SENS:HARM:NUMB 10\n"); // 10 harmonics
viPrintf(inst, ":HARM:TRACK OFF\n"); // Peak tracking off
viPrintf(inst, ":HARM:MODE PEAK\n"); // Peak measurement mode
viPrintf(inst, ":HARM:FREQ:FUND 1MHz\n"); // 1MHz fundamental frequency
viPrintf(inst, ":HARM:FREQ:SPAN 100KHZ\n"); // 100kHz span
viPrintf(inst, ":HARM:BAND:RES 1kHz; VID 100\n"); // 1kHz RBW, 100Hz VBW
viPrintf(inst, ":HARM:POW:RF:RLEV -15\n"); // -15dBm input reference level
viPrintf(inst, ":HARM:VIEW:RLEV -15; PDIV 10\n"); // View at -15dBm reference level, 10dB division
viPrintf(inst, ":HARM:TRACE:TYPE WRITE\n"); // Clear and write trace type
// Make sure we have a reasonable timeout value for the sweep to complete. Certain Signal
// Hound receivers will take long than others to complete a full harmonic sweep.
viSetAttribute(inst, VI_ATTR_TMO_VALUE, 10e3);
// Do the sweep, wait for completion
int opc;
viQueryf(inst, "INIT; *OPC?\n", "%d", &opc);
// Reset our timeout time
viSetAttribute(inst, VI_ATTR_TMO_VALUE, 2e3);
// Fetch measurement results
printf("Harmonic, Frequency, Amplitude");
for(int i = 0; i < 10; i++) {
double freq, ampl;
viQueryf(inst, ":FETC:HARM:FREQ? %d; AMPL? %d\n", "%lf;%lf", i+1, i+1, &freq, &ampl);
printf("%d, %.3f MHz, %.2f dBm\n", i+1, freq * 1.0e-6, ampl);
}
double distortion = 0.0;
viQueryf(inst, ":FETC:HARM:DIST?\n", "%lf", &distortion);
printf("\nTHD %.3f %%\n", distortion);
printf("%.2f dB\n", 20 * log10(distortion / 100.0));
// Done
viClose(inst);
}

Network Analysis

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Put the device into non-continuous mode
// 4. Perform and wait for a sweep to complete
void scpi_network_analyzer_sweep()
{
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to sweep
viPrintf(inst, "INSTRUMENT:SELECT NA\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
// Configure a 20MHz span sweep at 1GHz
// Center/span
viPrintf(inst, "SENS:FREQ:START 100MHZ; STOP 4GHZ\n");
// Fast sweep with 100 points
viPrintf(inst, ":NA:SWEEP:POINTS 100; TYPE PASSIVE; HRANGE ON\n");
// Configure view
viPrintf(inst, ":NA:VIEW:SCALE LOG; RLEVEL 10; DIV 10\n");
// Configure the trace. Ensures trace 1 is active and enabled for clear-and-write.
// These commands are not required to be sent everytime, this is for illustrative purposes only.
viPrintf(inst, "TRAC:SEL 1\n"); // Select trace 1
viPrintf(inst, "TRAC:TYPE WRITE\n"); // Set clear and write mode
viPrintf(inst, "TRAC:UPD ON\n"); // Set update state to on
viPrintf(inst, "TRAC:DISP ON\n"); // Set un-hidden
// Trigger a sweep, and wait for it to complete
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
// Tell the software to perform a store through on the next sweep
viPrintf(inst, ":CORR:NA:STORE:THRU\n");
// The sweep after the store through calibrates the sweep path.
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
// At this point you would insert the DUT and subsequent sweeps would be calibrated
int calibrated = 0;
viQueryf(inst, "CORR:NA:STORE:THRU:ACTIVE?\n", "%d", &calibrated);
// Do another sweep
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
// Done
viClose(inst);
}

Analog Demodulation Measurement

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Configuring Spike for analog demodulation measurements
// 3. Performing the measurement
// 4. Fetching the measurement results.
// The intended input tone for this example is a signal at 1GHz, -20dBm power or less
// The signal ideally is AM/FM modulation but it is not strictly necessary.
void scpi_analog_demod()
{
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to sweep
viPrintf(inst, "INSTRUMENT:SELECT ADEMOD\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
// Configure the measurement, 1GHz, -20dBm input level, 20KHz analog cutoff freq
viPrintf(inst, "ADEMOD:FREQ:CENT 1GHz\n");
viPrintf(inst, "ADEMOD:POW:RF:RLEV -20DBM\n");
viPrintf(inst, "ADEMOD:LPF 20kHz\n");
// Perform the measurement
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
// Fetch the results and print them off
double amResults[8], fmResults[8];
viQueryf(inst, ":FETCH:ADEMOD:AM? 1,2,3,4,5,6,7,8\n", "%,8lf", amResults);
viQueryf(inst, ":FETCH:ADEMOD:FM? 1,2,3,4,5,6,7,8\n", "%,8lf", fmResults);
printf("Carrier Freq %f\n", amResults[0]);
printf("Carrier Power %f\n", amResults[1]);
printf("\n");
printf("AM Mod Rate %f\n", amResults[2]);
printf("AM Depth (RMS) %f\n", amResults[3]);
printf("AM Depth (Peak+) %f\n", amResults[4]);
printf("AM Depth (Peak-) %f\n", amResults[5]);
printf("AM SINAD %f\n", amResults[6]);
printf("AM THD %f\n", amResults[7]);
printf("\n");
// Carrier freq/power is the same for FM, skip printing again
printf("FM Mod Rate %f\n", fmResults[2]);
printf("FM Depth (RMS) %f\n", fmResults[3]);
printf("FM Depth (Peak+) %f\n", fmResults[4]);
printf("FM Depth (Peak-) %f\n", fmResults[5]);
printf("FM SINAD %f\n", fmResults[6]);
printf("FM THD %f\n", fmResults[7]);
// Done
viClose(inst);
}

Spectrum Emission Mask

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Configuring Spike for spectrum emission mask measurements
// - Includes defining a mask by loading data into an offset table
// 3. Performing the measurement
// 4. Fetching the measurement results
// The intended input tone for this example is a signal at 1GHz, -20dBm power or less
void scpi_spectrum_emission_mask_basic()
{
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to Spectrum Emission Mask
viPrintf(inst, "INSTRUMENT:SELECT SEM\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
// Configure the measurement
// 1GHz, -20dBm input level, channel power measurement type
// Manually input Bluetooth mask into offset table
// Frequency
viPrintf(inst, "SEM:FREQ:CENT 1GHz\n");
viPrintf(inst, "SEM:FREQ:CENT:STEP:INCR 10MHz\n");
viPrintf(inst, "SEM:FREQ:SPAN 10MHz\n");
// Bandwidth
viPrintf(inst, "SEM:BAND:RES:AUTO ON\n");
viPrintf(inst, "SEM:BAND:VID:AUTO ON\n");
// Amplitude
viPrintf(inst, "SEM:POW:RF:RLEV -20\n");
viPrintf(inst, "SEM:POW:RF:PDIV 10\n");
// Detector / Trace
viPrintf(inst, "SEM:SWE:DET:UNIT POW\n");
viPrintf(inst, "SEM:SWE:DET:FUNC AVER\n");
viPrintf(inst, "TRAC:SEM:TYPE WRITE\n");
// Measurement Reference
viPrintf(inst, "SEM:REF:TYPE PSD\n");
viPrintf(inst, "SEM:REF:BANDwidth:MODE AUTO\n");
// Load mask into offset table (Bluetooth)
viPrintf(inst, "SEM:OFFS:DATA ON, 1MHz, 1.5MHz, -26, -26, REL, ON, 1.5MHz, 2.5MHz, -46, -46, ABS, ON, 2.5MHz, 5MHz, -86, -86, ABS\n");
// Do two measurements
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
// Get carrier / reference power
double carrierPower = 0;
viQueryf(inst, "SEM:CARR:POW?\n", "%lf", &carrierPower);
printf("Carrier (Reference) Power: %f dBm\n", carrierPower);
printf("\n");
// Test against mask and print
int fail = false;
viQueryf(inst, "SEM:OFFSET:FAIL?\n", "%d", &fail);
printf((bool)fail ? "Mask failed\n" : "Mask passed\n");
printf("\n");
// Find lower frequency, level, and margin (limit - peak) of offset 2
double lowerFreq = 0, lowerLevel = 0, lowerMargin = 0;
viQueryf(inst, "SEM:OFFSET2:PEAK:FREQ:LOWER?\n", "%lf", &lowerFreq);
viQueryf(inst, "SEM:OFFSET2:PEAK:LEVEL:LOWER?\n", "%lf", &lowerLevel);
viQueryf(inst, "SEM:OFFSET2:MARGIN:LOWER?\n", "%lf", &lowerMargin);
printf("Offset 2:\n\tPeak Freq: %.2f MHz\n\tPeak Level: %.2f dBm\n\tMargin (Limit - Peak): %.2f dB\n", lowerFreq/1e6, lowerLevel, lowerMargin);
printf("\n");
// Done
viClose(inst);
}

Noise Figure

#include <cassert>
#include <cstdio>
#include <Windows.h>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Configuring a Noise Figure mode measurement
// 3. Creating a new ENR table for a noise source
// 4. Loading ENR tables for calibration and measurement steps
// 5. Performing a user-interactive calibration
// 6. Performing a user-interactive noise figure and gain measurement
// 7. Waiting for the measurements to complete
// 8. Fetching the measurement results
// This example involves manual connection steps, and provides a basic
// command line interface to accept user input for progressing through these steps.
// User needs to press return to signal that a setup task has been completed.
// This example requires a powered noise source, such as a Keysight 346B.
void waitForUser()
{
printf("Press enter to continue..");
char response[256];
while(response[0] != '\n') {
fgets(response, 255, stdin);
}
}
void doNextAction(ViSession inst)
{
char str[4096];
viQueryf(inst, "STATUS:NFIG:NEXT?\n", "%t", &str);
printf("\n%s", str);
waitForUser();
}
void scpi_noise_figure()
{
ViSession rm, inst;
ViStatus status;
int opc;
char str[4096];
// Get the VISA resource manager
status = viOpenDefaultRM(&rm);
assert(status == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Switch to noise figure mode
viPrintf(inst, "INSTRUMENT:SELECT NFIGURE\n");
// Configure measurement
viPrintf(inst, "NFIG:FREQ:MODE SWEPT\n");
viPrintf(inst, "NFIG:FREQ:START 10MHz\n");
viPrintf(inst, "NFIG:FREQ:STOP 3GHZ\n");
viPrintf(inst, "NFIG:FREQ:POINTS 301\n");
viPrintf(inst, "NFIG:POWER:RLEVEL -40\n");
viPrintf(inst, "NFIG:BAND:RES:AUTO ON\n");
viPrintf(inst, "NFIG:BAND:VID:AUTO ON\n");
viPrintf(inst, "NFIG:MEAS:SPAN 4MHZ\n");
viPrintf(inst, "NFIG:AVERAGE ON\n");
viPrintf(inst, "NFIG:AVERAGE:COUNT 10\n");
viPrintf(inst, "NFIG:CORR:TCOLD:VAL 290.0\n");
// Enter a new ENR table
viPrintf(inst, "NFIG:CORR:ENR:TABLE:NEW\n");
int enrTableCount = -1;
viQueryf(inst, "NFIG:CORR:ENR:TABLE:COUNT?\n", "%d", &enrTableCount);
viPrintf(inst, "NFIG:CORR:ENR:TABLE:LOAD %d\n", enrTableCount - 1);
viPrintf(inst, "NFIG:CORR:ENR:TABLE:TITLE Keysight 346B 123456789\n");
viPrintf(inst, "NFIG:CORR:ENR:TABLE:DATA 10000000,15.45,100e6,15.45,1000e6,15.32,2e9,15.15,3e9,15.09\n");
// Set new ENR table for noise source of both cal and meas steps
viPrintf(inst, "NFIG:CORR:ENR:CAL:TABLE %d\n", enrTableCount - 1);
viPrintf(inst, "NFIG:CORR:ENR:MEAS:TABLE %d\n", enrTableCount - 1);
viQueryf(inst, "NFIG:CORR:ENR:TABLE:TITLE?\n", "%t", &str);
printf("Using Noise Source: %s", str);
// Begin cal
printf("\nStarting calibration\n");
viQueryf(inst, "NFIG:CAL:INIT; *OPC?\n", "%d", &opc);
// Get next action and wait for user
doNextAction(inst); // Connect noise source directly to spectrum analyzer
// Continue
viQueryf(inst, "NFIG:CONT; *OPC?\n", "%d", &opc);
// Set timeout to 30 seconds for long sweeps
viSetAttribute(inst, VI_ATTR_TMO_VALUE, 30e3);
doNextAction(inst); // Turn noise source on
// Wait with OPC for sweep to complete
printf("\nSweeping..\n");
viQueryf(inst, "NFIG:CONT; *OPC?\n", "%d", &opc);
doNextAction(inst); // Turn noise source off
// Get sweep progress intermittently
viPrintf(inst, "NFIG:CONT\n");
while(strcmp(str, "100%")) {
viQueryf(inst, "STATUS:NFIG:PROGRESS?\n", "%t", &str); // Turn noise source off
str[strcspn(str, "\n")] = 0;
printf("\nSweep progress: %s", str);
Sleep(250);
}
printf("\n\nCalibration complete\n");
// Begin meas
printf("\nStarting measurement\n");
viQueryf(inst, "NFIG:MEAS:INIT; *OPC?\n", "%d", &opc);
doNextAction(inst); // Connect noise source to DUT to spectrum analyzer
viQueryf(inst, "NFIG:CONT; *OPC?\n", "%d", &opc);
doNextAction(inst); // Turn noise source off
printf("\nSweeping..\n");
viQueryf(inst, "NFIG:CONT; *OPC?\n", "%d", &opc);
doNextAction(inst); // Turn noise source on
printf("\nSweeping..\n");
viQueryf(inst, "NFIG:CONT; *OPC?\n", "%d", &opc);
printf("\n\nMeasurement complete\n\n");
// Done
viClose(inst);
}

Phase Noise Measurement

#include <cassert>
#include <cstdio>
#include <vector>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Configuring a phase noise measurement
// 3. Performing several sweeps to generate an average phase noise trace
// 4. Using the marker to create a decade table
// Intended input signal is a 1GHz CW above the amplitude threshold set in the software
void scpi_phase_noise_simple()
{
ViSession rm, inst;
ViStatus rmStatus;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Select phase noise measurement mode
viPrintf(inst, "INSTRUMENT:SELECT PN\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
// Signal search configuration
viPrintf(inst, "PN:CARRIER:SEARCH 1\n");
// Set to small/large values to force clamp to range of instrument
viPrintf(inst, "PN:CARRIER:SEARCH:START 1Hz\n");
viPrintf(inst, "PN:CARRIER:SEARCH:STOP 99GHz\n");
viPrintf(inst, "PN:CARRIER:THR:MIN -40\n");
// Measure phase noise only
viPrintf(inst, "PN:TYPE PN\n");
// 100Hz to 10MHz offsets
viPrintf(inst, "PN:FREQ:OFFS:STAR 100Hz; STOP 10MHz\n");
// Configure plot
viPrintf(inst, "PN:VIEW:RLEV -50; PDIV 10\n");
int averageCount = 5;
// Phase noise measurements can take awhile, rather than spin a loop waiting for
// a non-timeout, lets just increase our timeout value for the measurements.
// The sweep time is measured in Spike first to determine a reasonable timeout val.
viSetAttribute(inst, VI_ATTR_TMO_VALUE, 10e3);
// Setup the traces
viPrintf(inst, "TRAC:PN:SEL 1; TYPE NORMAL\n");
viPrintf(inst, "TRAC:PN:SEL 2; TYPE AVERAGE; AVER:COUNT 5\n");
// Do a single sweep and set it as the reference
// For instructive purposes only
int opc;
viQueryf(inst, "INIT; *OPC?\n", "%d", &opc);
viPrintf(inst, "TRAC:PN:SEL 1; TO 3\n"); // Store the reference
viPrintf(inst, "TRAC:PN:SEL 2; CLEAR\n"); // Clear the average trace
// Now do the sweeps, wait for each one to complete
for(int i = 0; i < averageCount; i++) {
int opc;
viQueryf(inst, "INIT; *OPC?\n", "%d", &opc);
}
// Get decade marker tables
const int tblSize = 6;
double offsets[tblSize] = {100, 1e3, 10e3, 100e3, 1e6, 10e6};
double table[tblSize];
viPrintf(inst, "CALC:PN:MARKER:SELECT 1");
viPrintf(inst, "CALC:PN:MARK ON\n");
for(int m = 0; m < 3; m++) {
viPrintf(inst, "CALCULATE:PNOISE:MARKER:TRACE %d\n", m+1);
for(int i = 0; i < tblSize; i++) {
viPrintf(inst, "CALC:PN:MARK:X %fHz\n", offsets[i]);
viQueryf(inst, "CALC:PN:MARK:Y?\n", "%lf", table + i);
}
// Print it off to the console
printf("Decade table for trace %d\n", m);
for(int i = 0; i < tblSize; i++) {
printf("%g Offset: %f dBc\n", offsets[i], table[i]);
}
}
viClose(inst);
}

Phase Noise Cross Correlation Measurement

#include <cassert>
#include <cstdio>
#include <vector>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
#include <Windows.h>
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Setting up a cross correlation measurement. This requires connecting to the
// PN400 and a second SM series spectrum analyzer.
// 3. Waiting for the measurement to complete.
// 4. Querying some measurement results.
// Intended input signal is a 1GHz CW above the amplitude threshold set in the software
// Spike software should be running with default startup parameters, connected to a single SM device.
// A second SM device should be connected to the PC and inactive.
// The PN400 should also be connected to the PC and inactive.
void scpi_phase_noise_xcorr()
{
ViSession rm, inst;
ViStatus rmStatus;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Several steps in phase noise measurements can take a long time. Set a long timeout
// to account for this. 20 seconds
viSetAttribute(inst, VI_ATTR_TMO_VALUE, 20e3);
// Select phase noise measurement mode
viPrintf(inst, "INSTRUMENT:SELECT PN\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
// Now setup measurement
// Signal search
viPrintf(inst, "PN:CARRIER:SEARCH 1\n");
viPrintf(inst, "PN:CARRIER:SEARCH:START 500MHz\n");
viPrintf(inst, "PN:CARRIER:SEARCH:STOP 1.5GHz\n");
viPrintf(inst, "PN:CARRIER:THR:MIN -40\n");
// Sweep settings
viPrintf(inst, "PN:VIEW:RLEV -70; PDIV 10\n");
viPrintf(inst, "PN:FREQ:CENT 1GHz\n");
viPrintf(inst, "PN:FREQ:OFFS:STAR 10Hz; STOP 10MHz\n");
viPrintf(inst, "PN:TYPE PN\n");
// Setup cross correlation
// Connect to PN400
int connected;
viQueryf(inst, "PN:VCO:CONNECT?\n", "%d", &connected);
if(!connected) {
printf("Unable to connect to PN400\n");
return;
}
// Connect to second SM
// In this case we know it's an SM200C with a specific address. If it was a USB device,
// replace with the serial number of the device rather than the SOCKET string.
int openSuccess;
viQueryf(inst, "PN:XCORR:DEVICE:CONNECT? SOCKET::192.168.2.10::51665\n", "%d", &openSuccess);
if(!openSuccess) {
// Device failed to open
printf("Device failed to open\n");
}
// Setup the trace, just 1 normal trace
viPrintf(inst, "TRAC:PN:SEL 1; TYPE NORMAL\n");
// Now configure cross correlation
viPrintf(inst, "PN:XCORR:REF INT\n");
viPrintf(inst, "PN:XCORR:FACTOR 10\n");
viPrintf(inst, "DISPLAY:PN:XCORR:GINDICATOR ON\n");
viPrintf(inst, "DISPLAY:PN:XCORR:COUNT ON\n");
viPrintf(inst, "PN:XCORR ON\n");
// We now wait for the sweep to complete
while(true) {
int progress;
viQueryf(inst, "PN:XCORR:MEAS:PROGRESS?\n", "%d", &progress);
if(progress < 10) {
printf("Progress %d/%d\n", progress, 10);
Sleep(2000);
} else {
printf("Sweep complete\n");
break;
}
}
// Get decade marker tables
const int tblSize = 6;
double offsets[tblSize] = {100, 1e3, 10e3, 100e3, 1e6, 10e6};
double table[tblSize];
viPrintf(inst, "CALC:PN:MARKER:SELECT 1");
viPrintf(inst, "CALC:PN:MARKER ON\n");
viPrintf(inst, "CALC:PN:MARKER:TRACE 1");
for(int i = 0; i < tblSize; i++) {
viPrintf(inst, "CALC:PN:MARK:X %fHz\n", offsets[i]);
viQueryf(inst, "CALC:PN:MARK:Y?\n", "%lf", table + i);
}
// Print it off to the console
printf("Decade table\n");
for(int i = 0; i < tblSize; i++) {
printf("%g Offset: %f dBc\n", offsets[i], table[i]);
}
viClose(inst);
}

VCO Measurement

#include <cassert>
#include <cstdio>
#include <vector>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Configuring Spike for VCO characterization measurements
// 3. Performing a full VCO characterization sweep measurement
// 4. Querying the trace data of the resulting measurements
// Equipment needed is a BB, SP, or SM series spectrum analyzer, a PN400, and a VCO to test
void scpi_vco()
{
ViSession rm, inst;
ViStatus rmStatus;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to VCO Characterization
viPrintf(inst, "INSTRUMENT:SELECT VCO\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
const double START = 1.0;
const double STOP = 17.0;
const int POINTS = 100;
// Configure sweep
viPrintf(inst, "SENS:VCO:SWEEP:START %.2f; :VCO:SWEEP:STOP %.2f; :VCO:SWEEP:POINTS %d\n", START, STOP, POINTS);
viPrintf(inst, "SENS:VCO:SWEEP:RLEV -10; :VCO:SWEEP:FCO:RES 10KHZ; :VCO:SWEEP:DEL 1\n");
// Configure source
viPrintf(inst, "SENS:VCO:SOUR:VOLT:VTUN:LIM:LOW -1.0; :VCO:SOUR:VOLT:VTUN:LIM:HIGH 28.0\n");
viPrintf(inst, "SENS:VCO:SOUR:VOLT:VSUP:LIM:LOW 0.5; :VCO:SOUR:VOLT:VSUP:LIM:HIGH 15.25\n");
viPrintf(inst, "SENS:VCO:SOURCE:VOLT:FIXED 5.0\n");
viPrintf(inst, "SENS:VCO:SOURCE:VOLT ON\n");
// Perform a measurement
int opc;
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
assert(opc == 1);
// Retrieve the measurement results
// Preallocate arrays for the measurements
std::vector<float> frequency(POINTS);
std::vector<float> sensitivity(POINTS);
std::vector<float> power(POINTS);
std::vector<float> current(POINTS);
const int HARMONIC_COUNT = 6;
std::vector<std::vector<float>> harmonics(HARMONIC_COUNT, std::vector<float>(POINTS));
int length = POINTS;
// Request data
// Measurement data is returned as comma separated values
viQueryf(inst, "FETCh:VCO:FREQ?\n", "%,#f", &length, frequency.data());
viQueryf(inst, "FETCh:VCO:SENS?\n", "%,#f", &length, sensitivity.data());
viQueryf(inst, "FETCh:VCO:POW?\n", "%,#f", &length, power.data());
viQueryf(inst, "FETCh:VCO:CURR?\n", "%,#f", &length, current.data());
for(int harm = 0; harm < HARMONIC_COUNT; harm++) {
viQueryf(inst, "FETCh:VCO:HARM? %d\n", "%,#f", harm + 1, &length, harmonics[harm].data());
}
// Print out meas information
const double vStep = (STOP - START) / POINTS;
for(int i = 0; i < POINTS; i++) {
printf("V Tune: %.2f V\n\tFreq: %.4f MHz\n\tSensitivity: %.4f Hz\n\tPower: %.4f dBm\n\tCurrent: %.4f mA\n\t",
START + i * vStep, frequency[i] / 1e6, sensitivity[i], power[i], current[i]);
for(int harm = 0; harm < HARMONIC_COUNT; harm++) {
printf("Harmonic %d: %.4f dBm\n\t", harm + 1, harmonics[harm][i]);
}
printf("\n");
}
// Done
viClose(inst);
}

Digital Demod PSK

#include <cassert>
#include <fstream>
#include <vector>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Configuring Spike for digital demodulation measurements of basic PSK signal
// 3. Performing the measurement
// 4. Fetching the demod measurements
// 5. Fetching the constellation plot and saving it to a file
// See configuration below for intended input signal
void scpi_digital_demod_psk_basic()
{
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to Digital Modulation Analysis
viPrintf(inst, "INSTRUMENT:SELECT DDEMOD\n");
// Disable continuous meausurement operation and wait for any active measurements
// to finish.
viPrintf(inst, "INIT:CONT OFF\n");
// Configure the measurement, 1GHz, -20dBm input level
// QPSK, 1 MHz sym/s, RRC filter
viPrintf(inst, "DDEMOD:FREQ:CENT 1GHz\n");
viPrintf(inst, "DDEMOD:POW:RF:RLEV -20DBM\n");
viPrintf(inst, "DDEMOD:SRAT 1MHz\n");
viPrintf(inst, "DDEMOD:MOD QPSK\n");
viPrintf(inst, "DDEMOD:RLEN 127\n");
viPrintf(inst, "DDEMOD:FILTER RNYQUIST\n");
viPrintf(inst, "DDEMOD:FILT:ABT 0.35\n");
viPrintf(inst, "DDEMOD:IFBW:AUTO ON\n");
viPrintf(inst, "DDEMOD:AVER ON\n");
viPrintf(inst, "DDEMOD:AVER:COUN 10\n");
viPrintf(inst, "TRIG:DDEM:SOUR IMM\n");
// Do two measurements
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
// Fetch the results and print them off
double evmResults[14];
viQueryf(inst, ":FETCH:DDEMOD? 1,2,3,4,5,6,7,8,9,10,11,12,13,14\n", "%,14lf", evmResults);
printf("RMS EVM Avg (%%) %f\n", evmResults[0]);
printf("RMS EVM Peak (%%) %f\n", evmResults[1]);
printf("\n");
printf("RMS Mag Err Avg (%%) %f\n", evmResults[2]);
printf("RMS Mag Err Peak (%%) %f\n", evmResults[3]);
printf("\n");
printf("RMS Phase Err Avg (deg) %f\n", evmResults[4]);
printf("RMS Phase Err Peak (deg) %f\n", evmResults[5]);
printf("\n");
printf("IQ Offset Avg (dB) %f\n", evmResults[6]);
printf("IQ Offset Peak (dB) %f\n", evmResults[7]);
printf("\n");
printf("Freq Error Avg (Hz) %f\n", evmResults[8]);
printf("Freq Error Peak (Hz) %f\n", evmResults[9]);
printf("\n");
printf("RF Power Avg (dBm) %f\n", evmResults[10]);
printf("RF Power Peak (dBm) %f\n", evmResults[11]);
printf("\n");
printf("SNR Avg (dB) %f\n", evmResults[12]);
printf("SNR Peak (dB) %f\n", evmResults[13]);
printf("\n");
// Fetch the constellation plot and save it to a CSV
// Query constellation plot length, as number of complex values
int constLen;
viQueryf(inst, "FETCH:DDEMOD? 40\n", "%d", &constLen);
// constLen is the number of I/Q samples, so we need to request 2 times as many real values
constLen *= 2;
std::vector<float> rdBuffer(constLen);
// Fetch the constellation plot
viQueryf(inst, ":FETCH:DDEMOD? 41\n", "%,#f", &constLen, &rdBuffer[0]);
// Save it to CSV, two columns, I and Q
std::ofstream file("constellation_plot.csv");
for(int i = 0; i < constLen/2; i++) {
file << rdBuffer[i*2] << ", " << rdBuffer[i*2+1] << std::endl;
}
file.close();
printf("Constellation plot saved.\n");
// Done
viClose(inst);
}

Digital Demod FSK

#include <cassert>
#include <cstdio>
#include <fstream>
#include <vector>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Configuring Spike for digital demodulation measurements of basic PSK signal
// 3. Performing the measurement
// 4. Fetching the measurement results
// 5. Fetching the frequency vs sample array and saving it to a file
// See configuration below for expected input signal
void scpi_digital_demod_fsk_basic()
{
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to Digital Modulation Analysis
viPrintf(inst, "INSTRUMENT:SELECT DDEMOD\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
// Configure the measurement, 1GHz, -20dBm input level
// 2FSK, 1MHz sym/s
viPrintf(inst, "DDEMOD:FREQ:CENT 1GHz\n");
viPrintf(inst, "DDEMOD:POW:RF:RLEV -20DBM\n");
viPrintf(inst, "DDEMOD:SRAT 1MHz\n");
viPrintf(inst, "DDEMOD:MOD FSK2\n");
viPrintf(inst, "DDEMOD:RLEN 127\n");
viPrintf(inst, "DDEMOD:FILTER GAUS\n");
viPrintf(inst, "DDEMOD:FILT:ABT 0.5\n");
viPrintf(inst, "DDEMOD:IFBW:AUTO ON\n");
viPrintf(inst, "DDEMOD:AVER ON\n");
viPrintf(inst, "DDEMOD:AVER:COUN 10\n");
// Do two measurements
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
// Fetch the results and print them off
double evmResults[8];
viQueryf(inst, ":FETCH:DDEMOD? 9,10,11,12,15,16,17,18\n", "%,8lf", evmResults);
printf("Freq Error Avg (Hz) %f\n", evmResults[0]);
printf("Freq Error Peak (Hz) %f\n", evmResults[1]);
printf("\n");
printf("RF Power Avg (dBm) %f\n", evmResults[2]);
printf("RF Power Peak (dBm) %f\n", evmResults[3]);
printf("\n");
printf("RMS FSK Avg (%%) %f\n", evmResults[4]);
printf("RMS FSK Peak (%%) %f\n", evmResults[5]);
printf("\n");
printf("FSK Dev Avg (Hz) %f\n", evmResults[6]);
printf("FSK Dev Peak (Hz) %f\n", evmResults[7]);
printf("\n");
// Fetch the constellation/frequency plot and save it to a CSV
// Query plot length
int plotLen;
viQueryf(inst, "FETCH:DDEMOD? 40\n", "%d", &plotLen);
// constLen is the number of I/Q samples, so we need to request 2 times as many real values
std::vector<float> rdBuffer(plotLen);
// Fetch the constellation plot
viQueryf(inst, ":FETCH:DDEMOD? 41\n", "%,#f", &plotLen, &rdBuffer[0]);
// Save it to CSV
std::ofstream file("freq_vs_time_plot.csv");
for (int i = 0; i < plotLen; i++) {
file << rdBuffer[i] * evmResults[6] << std::endl;
}
file.close();
printf("Plot saved.\n");
// Done
viClose(inst);
}

Digital Demod Equalization

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike.
// 2. Configuring Spike for digital demodulation measurements of a PSK signal.
// 3. Configuring adaptive equalization
// 4. Making several measurement.
// The intended input signal for this example is at
// 1GHz center freq
// -20dBm maximum input power
// BPSK
// 10MSym/s
void scpi_digital_demod_equalization()
{
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to Digital Modulation Analysis
viPrintf(inst, "INSTRUMENT:SELECT DDEMOD\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
// Configure the measurement, 1GHz, -20dBm input level
// BPSK, 24.3 kHz sample rate, 127 symbol length, root raised cosine filter (alpha 0.35)
viPrintf(inst, "DDEMOD:FREQ:CENT 1GHz\n");
viPrintf(inst, "DDEMOD:POW:RF:RLEV -20DBM\n");
viPrintf(inst, "DDEMOD:SRAT 10MHz\n");
viPrintf(inst, "DDEMOD:MOD BPSK\n");
viPrintf(inst, "DDEMOD:RLEN 256\n");
viPrintf(inst, "DDEMOD:FILTER RNYQUIST\n");
viPrintf(inst, "DDEMOD:FILT:ABT 0.35\n");
viPrintf(inst, "DDEMOD:IFBW:AUTO ON\n");
viPrintf(inst, "DDEMOD:AVER OFF\n");
viPrintf(inst, "DDEMOD:AVER:COUN 1\n");
// Setup equalization
viPrintf(inst, "DDEM:EQU ON\n");
viPrintf(inst, "DDEM:EQU:LENG 15\n");
viPrintf(inst, "DDEM:EQU:CONV 10.0\n");
viPrintf(inst, "DDEM:EQU:RESET\n");
// Perform several measurements allowing the equalizer to adapt printing EVM
// on each measurement.
for(int i = 0; i < 25; i++) {
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
double evm;
viQueryf(inst, ":FETCH:DDEMOD? 1\n", "%,1lf", &evm);
printf("EVM (%%) %f\n", evm);
}
// Done
viClose(inst);
}

Digital Demod Sync Search

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike.
// 2. Configuring Spike for digital demodulation measurements of a PSK signal.
// 3. Configuring sync search.
// 4. Making a measurement.
// The intended input signal for this example is at
// 1GHz center freq
// -20dBm maximum input power
// BPSK
// 100kSym/s
void scpi_digital_demod_sync_search()
{
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to Digital Modulation Analysis
viPrintf(inst, "INSTRUMENT:SELECT DDEMOD\n");
// Disable continuous meausurement operation
viPrintf(inst, "INIT:CONT OFF\n");
// Configure the measurement, 1GHz, -20dBm input level
// BPSK, 24.3 kHz sample rate, 127 symbol length, root raised cosine filter (alpha 0.35)
viPrintf(inst, "DDEMOD:FREQ:CENT 1GHz\n");
viPrintf(inst, "DDEMOD:POW:RF:RLEV -20DBM\n");
viPrintf(inst, "DDEMOD:SRAT 100.0kHz\n");
viPrintf(inst, "DDEMOD:MOD BPSK\n");
viPrintf(inst, "DDEMOD:RLEN 256\n");
viPrintf(inst, "DDEMOD:FILTER RNYQUIST\n");
viPrintf(inst, "DDEMOD:FILT:ABT 0.35\n");
viPrintf(inst, "DDEMOD:IFBW:AUTO ON\n");
viPrintf(inst, "DDEMOD:AVER ON\n");
viPrintf(inst, "DDEMOD:AVER:COUN 10\n");
// Setup a sync pattern trigger
// Trigger on pattern AAAA (16 BPSK symbols)
// Search length is 1k symbols
viPrintf(inst, "DDEM:SYNC ON\n");
viPrintf(inst, "DDEM:SYNC:SWOR:PATT AAAA\n");
viPrintf(inst, "DDEM:SYNC:SWOR:LENG 16\n");
viPrintf(inst, "DDEM:SYNC:SLEN 1000\n");
viPrintf(inst, "DDEM:SYNC:OFFSET 0\n");
// Perform the measurement
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
// Read the measured bits and print them off
char bits[257];
// Initialize string to zero, pad with 1 char for null termination
for(int i = 0; i < 257; i++) bits[i] = 0;
viPrintf(inst, ":FETCH:DDEMOD? 30\n");
viScanf(inst, "%s", bits);
printf("Measured bits:\n%s\n", bits);
// Done
viClose(inst);
}

Digital Demod Custom Modulation

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Configuring Spike for digital demodulation measurements using a custom modulation
void scpi_digital_demod_custom_modulation()
{
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to Digital Modulation Analysis
viPrintf(inst, "INSTRUMENT:SELECT DDEMOD\n");
// Configure custom modulation
viPrintf(inst, "DDEM:CUST:IQ:DATA 1,1,-1,1,-1,-1,1,-1\n");
viPrintf(inst, "DDEMOD:MOD CUSTom\n");
// Done
viClose(inst);
}

Bluetooth LE

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Configuring Spike for BLE measurement of test transmitter.
// 3. Perform both demod and in-band emission test.
// 4. Fetching the measurement results.
// The intended input tone for this example is a signal
// - at 2.402GHz,
// - +10dBm power or less
// - BLE advertising or test packet with 10101010 or 01010101 payload for demod meas
// - PN payload for IBE packet (left to user)
// Modulation characteristics are left to user, will require user to output and measure
// both the 01010101 and 00001111 patterns to measure all f1/f2 parameters.
void scpi_ble()
{
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to Digital Modulation Analysis
viPrintf(inst, "INSTRUMENT:SELECT BLE\n");
// Disable continuous meausurement operation and wait for any active measurements
// to finish.
viPrintf(inst, "INIT:CONT OFF\n");
// Configure the measurement
viPrintf(inst, ":BLE:MEAS DEMOD\n");
viPrintf(inst, ":BLE:FREQ:CENT 2.402GHz\n");
viPrintf(inst, ":BLE:POW:RF:RLEV +10\n"); // dBm
viPrintf(inst, ":BLE:IFBW 2MHz\n"); // default
viPrintf(inst, ":BLE:CHANNEL:AUTO 1\n"); // automatically determine ch. index
// Configure the trigger
viPrintf(inst, ":TRIG:BLE:SLEN 20ms\n");
// Perform 10 measurements
for(int i = 0; i < 10; i++) {
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
}
int powAvg;
double powMeas[5];
int cfoAvg;
double cfoMeas[7];
// Fetch power demod measurement results
viQueryf(inst, ":FETCH:BLE? 1\n", "%d", &powAvg);
viQueryf(inst, ":FETCH:BLE? 2,3,4,5,6\n", "%,5lf", powMeas);
// Fetch CFO demod measurement results
viQueryf(inst, ":FETCH:BLE? 200\n", "%d", &cfoAvg);
viQueryf(inst, ":FETCH:BLE? 201,202,203,204,205,206,207\n", "%,7lf", cfoMeas);
// Print results
printf("Output power averages %d\n", powAvg);
printf("Total avg power %.2f dBm\n", powMeas[0]);
printf("Max avg power %.2f dBm\n", powMeas[1]);
printf("Last peak power %.2f dBm\n", powMeas[2]);
printf("Last avg power %.2f dBm\n", powMeas[3]);
printf("Last pk-avg power %.2f dBm\n", powMeas[4]);
printf("\n");
printf("CFO averages %d\n", cfoAvg);
printf("Preamble CFO %.3f kHz\n", cfoMeas[0] / 1.0e3);
printf("Last max CFO %.3f kHz\n", cfoMeas[1] / 1.0e3);
printf("Last max drift %.3f kHz\n", cfoMeas[2] / 1.0e3);
printf("Last max drift/50us %.3f kHz\n", cfoMeas[3] / 1.0e3);
printf("Overall Max CFO %.3f kHz\n", cfoMeas[4] / 1.0e3);
printf("Overal max drift %.3f kHz\n", cfoMeas[5] / 1.0e3);
printf("Overal max drift/50us %.3f kHz\n", cfoMeas[6] / 1.0e3);
printf("\n");
// Now perform in-band emissions measurement
// Here is where you would change your transmission to a PN based PDU
// Config for IBE measurement
viPrintf(inst, ":BLE:MEAS IBE\n");
// Do a few measurements if needed for settling
for(int i = 0; i < 3; i++) {
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
}
double ibeMeas[6];
viQueryf(inst, ":FETCH:BLE? 300,301,302,303,304,305\n", "%,6lf", ibeMeas);
printf("IBE result %s\n", ibeMeas[0] ? "Pass" : "Fail");
printf("IBE Tx channel %.0f\n", ibeMeas[1]);
printf("IBE pk power %.2f dBm\n", ibeMeas[2]);
printf("IBE adjacent power (lower) %.2f dBm\n", ibeMeas[3]);
printf("IBE adjacent power (upper) %.2f dBm\n", ibeMeas[4]);
printf("IBE failed channels %.0f\n", ibeMeas[5]);
// Done
viClose(inst);
}

WLAN 802.11a Measurement

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Configuring Spike for an 802.11a measurement.
// 3. Performing the measurement
// 4. Fetching the measurement results.
// The intended input tone for this example is a signal at 1GHz, -20dBm power or less
// The signal should have 802.11a modulation
void scpi_wlan_a_simple()
{
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to WLAN analysis
viPrintf(inst, "INSTRUMENT:SELECT WLAN\n");
// Disable continuous meausurement operation and wait for any active measurements
// to finish.
viPrintf(inst, "INIT:CONT OFF\n");
// Configure the measurement
viPrintf(inst, "WLAN:STAN AG\n");
viPrintf(inst, "WLAN:FREQ:CENT 1GHz\n");
viPrintf(inst, "WLAN:POW:RF:RLEV -10\n"); //dBm
viPrintf(inst, "WLAN:IFBW 20MHz\n");
// Configure the trigger
viPrintf(inst, "TRIG:WLAN:SLEN 20ms\n");
viPrintf(inst, "TRIG:WLAN:IF:LEVEL -20\n");
// Start measurement and wait for trigger
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
// Fetch the results and print them off
char modType[16], encoding[16], guardInterval[16];
double evmResults[9];
viQueryf(inst, ":FETCH:WLAN? 1\n", "%s", modType);
viQueryf(inst, ":FETCH:WLAN? 2\n", "%s", encoding);
viQueryf(inst, ":FETCH:WLAN? 3\n", "%s", guardInterval);
viQueryf(inst, ":FETCH:WLAN? 4,5,6,7,8,9,10,11,12\n", "%,9lf", evmResults);
printf("Modulation Type %s\n", modType);
printf("Modulation Encoding %s\n", encoding);
printf("Guard Interval %s\n", guardInterval);
printf("\n");
printf("Freq error %f\n", evmResults[0]);
printf("EVM %% %f\n", evmResults[1]);
printf("EVM dB %f\n", evmResults[2]);
printf("\n");
printf("Avg Power dBm %f\n", evmResults[3]);
printf("Peak Power dBm %f\n", evmResults[4]);
printf("Crest Factor %f\n", evmResults[5]);
printf("\n");
printf("Initial Scrambler State %f\n", evmResults[6]);
printf("Symbol Count %f\n", evmResults[7]);
printf("Payload Bit Count %f\n", evmResults[8]);
printf("\n");
// Done
viClose(inst);
}

WLAN 802.11ah Measurement

#include <cassert>
#include <cstdio>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example
// 1. Uses VISA to connect to Spike
// 2. Configures Spike for an 802.11ah measurement.
// 3. Performs N measurements
// 4. Prints the measurement results
void scpi_wlan_ah()
{
int N = 10;
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Set the measurement mode to WLAN analysis
viPrintf(inst, "INSTRUMENT:SELECT WLAN\n");
// Disable continuous meausurement operation and wait for any active measurements
// to finish.
viPrintf(inst, "INIT:CONT OFF\n");
// Configure the measurement
viPrintf(inst, "WLAN:STANDARD AH\n");
// Enabled PSDU encoding even though we can't query the bits
viPrintf(inst, "WLAN:PSDU:DECODE 1\n");
// -50% symbol offset
viPrintf(inst, "WLAN:SYMBOL:OFFSET -50\n");
viPrintf(inst, "WLAN:FREQ:CENT 900MHz\n");
viPrintf(inst, "WLAN:POW:RF:RLEV -10\n");
viPrintf(inst, "WLAN:IFBW 20MHz\n");
// Configure the trigger
viPrintf(inst, "TRIG:WLAN:SLEN 20ms\n");
viPrintf(inst, "TRIG:WLAN:IF:THRESHOLD 20\n");
for(int i = 0; i < N; i++) {
// Start measurement and wait for trigger
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
// Fetch the results and print them off
char modType[16];
char encoding[16];
char guardInterval[16];
double evmResults[11];
viQueryf(inst, ":FETCH:WLAN? 1\n", "%s", modType);
viQueryf(inst, ":FETCH:WLAN? 2\n", "%s", encoding);
viQueryf(inst, ":FETCH:WLAN? 3\n", "%s", guardInterval);
viQueryf(inst, ":FETCH:WLAN? 4,5,6,7,8,9,10,11,12,13,14\n", "%,11lf", evmResults);
printf("Measurement %d\n", i + 1);
printf("Modulation Type %s\n", modType);
printf("Modulation Encoding %s\n", encoding);
printf("Guard Interval %s\n", guardInterval);
printf("Bandwidth %f MHz\n", evmResults[10]);
printf("Freq error %f Hz\n", evmResults[0]);
printf("Sample rate error %f ppm\n", evmResults[9]);
printf("EVM %% %f\n", evmResults[1]);
printf("EVM dB %f\n", evmResults[2]);
printf("Avg Power dBm %f\n", evmResults[3]);
printf("Peak Power dBm %f\n", evmResults[4]);
printf("Crest Factor %f\n", evmResults[5]);
printf("Initial Scrambler State %f\n", evmResults[6]);
printf("Symbol Count %f\n", evmResults[7]);
printf("Payload Bit Count %f\n", evmResults[8]);
printf("\n\n");
}
// Done
viClose(inst);
}

LTE Direct Measurement

#include <cassert>
#include <cstdio>
#include <Windows.h>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Put the device into non-continuous mode
// 3. Configure the device for a direct LTE measurement
// 4. Perform and wait for a measurement to complete
// 5. Request measurement data
// The intended input is an LTE signal at the specified center frequency (751MHz)
// If not valid signal is present, the *OPC? command will timeout.
void scpi_lte_direct_meas()
{
ViSession rm, inst;
ViStatus status;
// Get the VISA resource manager
status = viOpenDefaultRM(&rm);
assert(status == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Extend VISA timeout to ensure we have enough time for the LTE measurement to complete
viSetAttribute(inst, VI_ATTR_TMO_VALUE, 10e3);
// Set the measurement mode to sweep
viPrintf(inst, ":INSTRUMENT:SELECT LTE\n");
// As of right now, the software will not respond to commands while the LTE
// module is loading.
// Sleep 15 seconds to ensure the LTE mode has loaded. You can reduce this wait
// if you know it loads faster for you, or remove it altogether is you know
// it has already been loaded.
Sleep(1000 * 15);
// Disable continuous meausurement operation
viPrintf(inst, ":INIT:CONT OFF\n");
// Configure a direct measurement
viPrintf(inst, ":LTE:FREQ:CENTER 751MHz\n");
viPrintf(inst, ":LTE:POW:RF:RLEVEL -30\n");
viPrintf(inst, ":LTE:MEAS:INCLUDE 0\n");
// Perform a single measurement and wait for it to complete
int opc;
viQueryf(inst, ":INIT; *OPC?\n", "%d", &opc);
// Make sure we haven't timed out
assert(status == 0);
// Get measurement info, RSSI, cellID, network name, and more.
double rssi, rsrp, rsrq, earfcn;
int physicalCellID, cellID;
char bw[32], network[32];
int sib1Valid;
viQueryf(inst, ":FETCH:LTE? 5,6,7,100,103,200\n", "%lf,%lf,%lf,%d,%31[^,],%d",
&rssi, &rsrp, &rsrq, &physicalCellID, bw, &sib1Valid);
// If SIB1 was decoded, request data from the SIB1
if(sib1Valid) {
viQueryf(inst, ":FETCH:LTE? 201,214,203\n", "%lf,%31[^,],%d",
&earfcn, network, &cellID);
}
// Done
viClose(inst);
}

LTE Scan

#include <cassert>
#include <cstdio>
#include <Windows.h>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates
// 1. Using VISA to connect to Spike
// 2. Load an LTE preset with scan bands preconfigured
// 3. Perform a single scan
// 4. Wait for the scan to complete
// 5. Pull cell search results
// For this exmaple to work, preset 1 must be setup for LTE measurement mode
// with at the scan configured. An antenna should be connected to the unit,
// and ideally scan bands should be selected that have known LTE cells.
void scpi_lte_scan()
{
ViSession rm, inst;
ViStatus status;
// Get the VISA resource manager
status = viOpenDefaultRM(&rm);
assert(status == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Load preset for LTE with scan bands
viPrintf(inst, "*RCL 1\n");
// As of right now, the software will not respond to commands while the LTE
// module is loading.
// Sleep 15 seconds to ensure the LTE mode has loaded. You can reduce this wait
// if you know it loads faster for you, or remove it altogether is you know
// it has already been loaded.
Sleep(1000 * 15);
// Disable continuous meausurement operation
viPrintf(inst, ":INIT:CONT OFF\n");
// Ensure direct measurements don't get added to cell search results
viPrintf(inst, ":LTE:MEAS:INCLUDE 0\n");
// Configure cell search window
viPrintf(inst, ":LTE:SCAN:TYPE SINGLE\n");
viPrintf(inst, ":LTE:SCAN:RESULTS:SORT FREQ\n");
viPrintf(inst, ":LTE:SCAN:RESULTS:KEEP PEAK\n");
viPrintf(inst, ":LTE:SCAN:RESULTS:GROUP 1\n");
viPrintf(inst, ":LTE:SCAN:RESULTS:MAX 100\n");
// Clear any accrued cell search results
viPrintf(inst, ":LTE:SCAN:RESULTS:CLEAR\n");
// Perform scan
int response = 0;
viQueryf(inst, ":LTE:SCAN:START?\n", "%d", &response);
// Wait for scan to complete
while(true) {
int scanActive = 0;
viQueryf(inst, ":LTE:SCAN:ACTIVE?\n", "%d", &scanActive);
if(!scanActive) {
break;
} else {
Sleep(1000);
}
}
// Get number of cell search results
int cellSearchResults = 0;
viQueryf(inst, ":LTE:SCAN:RESULTS:COUNT?\n", "%d", &cellSearchResults);
// Loop through all results and query
for(int i = 0; i < cellSearchResults; i++) {
// Set query index into cell search results table
viPrintf(inst, ":LTE:SCAN:RESULTS:INDEX %d\n", i);
double freq, earfcn, rssi;
int physicalCellID, cellID, plmnCount;
char network[32];
viQueryf(inst, ":FETCH:LTE? 301,302,303,307,311\n",
"%lf,%lf,%lf,%d,%d,%d",
&freq, &earfcn, &rssi, &physicalCellID, &plmnCount);
if(plmnCount > 0) {
viQueryf(inst, ":FETCH:LTE? 315,306\n", "%s,%d",
network, &cellID);
}
printf("Result %d: Freq, %.3f MHz\n", i+1, freq / 1.0e6);
printf("Result %d: EARFCN, %.2f\n", i+1, earfcn);
printf("Result %d: RSSI, %.2f dB\n", i+1, rssi);
printf("Result %d: Phy Cell ID, %d\n", i+1, physicalCellID);
if(plmnCount > 0) {
printf("Result %d: Cell ID, %d\n", i+1, cellID);
printf("Result %d: Network, %s\n", i+1, network);
}
printf("\n");
}
// Done
viClose(inst);
}

Device Auto Reconnect

#include <cassert>
#include <cstdio>
#include <vector>
#include <Windows.h>
#include "visa.h"
#pragma comment(lib, "visa32.lib")
// This example demonstrates using VISA to connect to Spike, checking for whether
// a device is currently active after each sweep, and automatically reconnecting
// after a forced disconnect.
//
// For this example to be fully illustrative, follow along with the directions printed
// to the console. When prompted, disconnect the cable of the Signal Hound device
// while running, and then plug it back in a few seconds later to trigger a reconnect.
//
// Note that Spike has an auto-reconnect option, accessed through
// Edit > Preferences > General Settings > Connection Settings > Auto Reconnect.
// This should be turned OFF in Spike for this example, as it accomplishes the same
// thing. The difference is this example does it manually, over SCPI.
void setup_device(ViSession inst)
{
// Set the measurement mode to Zero-Span
viPrintf(inst, "INSTRUMENT:SELECT ZS\n");
// Disable continuous meausurement operation and wait for any active measurements to finish.
viPrintf(inst, "INIT:CONT OFF\n");
// Configure the measurement, 1GHz, -20dBm input level
viPrintf(inst, "SENSE:ZS:CAPTURE:RLEVEL -20DBM\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:CENTER 1GHZ\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:IFBW:AUTO ON\n");
viPrintf(inst, "SENSE:ZS:CAPTURE:SWEEP:TIME 0.0015\n"); // sec
}
void scpi_device_auto_reconnect()
{
ViSession rm, inst;
ViStatus rmStatus;
int opc;
// Get the VISA resource manager
rmStatus = viOpenDefaultRM(&rm);
assert(rmStatus == 0);
// Open a session to the Spike software, Spike must be running at this point
ViStatus instStatus = viOpen(rm, "TCPIP::localhost::5025::SOCKET", VI_NULL, VI_NULL, &inst);
assert(instStatus == 0);
// For SOCKET programming, we want to tell VISA to use a terminating character
// to end a read operation. In this case we want the newline character to end a
// read operation. The termchar is typically set to newline by default. Here we
// set it for illustrative purposes.
viSetAttribute(inst, VI_ATTR_TERMCHAR_EN, VI_TRUE);
viSetAttribute(inst, VI_ATTR_TERMCHAR, '\n');
// Configure device in routine so it can be reconfigured after reconnect
setup_device(inst);
// Get connection string of current active device so it can be identified
// in case there are multiple Signal Hound devices connected to PC.
char conStr[256];
viQueryf(inst, "SYST:DEV:CURR?\n", "%s", conStr);
printf("Connection string for currently active device: %s\n\n", conStr);
// Sweep with connection check
// While this loop is running, manually disconnect the device to advance the demonstration
int activeDevice;
do {
// Trigger a sweep, and wait for it to complete
viQueryf(inst, ":INIT;\n", "%d", &opc);
// Check that device is still connected
viQueryf(inst, "SYST:DEV:ACT?\n", "%d", &activeDevice);
if(activeDevice) printf("Device Active. Manually disconnect to continue demo\n");
} while(activeDevice == 1);
// Device has been forcibly disconnected
printf("\nDevice disconnected\n\n");
// Spin on reconnect attempts with a two second timeout
viSetAttribute(inst, VI_ATTR_TMO_VALUE, 2e3);
int openSuccess = 0;
while(openSuccess == 0) {
viQueryf(inst, "SYST:DEVICE:CONNECT? %s\n", "%s", conStr, &openSuccess);
if(!openSuccess) {
// Device failed to open
printf("Waiting for reconnect..\n");
}
}
printf("\nDevice reconnected\n\n");
// Reconfigure device
printf("Reconfiguring device to previous state\n\n");
setup_device(inst);
// Begin taking measurements again
viQueryf(inst, ":INIT;\n", "%d", &opc);
viQueryf(inst, ":INIT;\n", "%d", &opc);
viQueryf(inst, ":INIT;\n", "%d", &opc);
// Done
printf("Done");
viClose(inst);
}