SCPI Python examples
Preconditions
Before running the examples start the SCPI server, verify and adapt the IP-address and the port number in the python code. The connection to the SCPI server can be verified using NI MAX.
The PyVISA package for the VISA communication must be added to the used Python projects. The currently used version ist the 1.11.3.
Connection test
This examples shows how to:
- build a connection with a SCPI server (i.e. the one provided by Bode 100)
- test the connection with the SCPI server
# use pyvisa or similar package
import pyvisa
# *** TO DO: adapt IP address and SCPI port according to your needs ***
SCPI_server_IP = '172.22.44.29'
SCPI_Port = '5025'
VISA_resource_name = 'TCPIP::' + SCPI_server_IP + '::' + SCPI_Port + '::SOCKET'
print('Trying to connect to VISA resource: ' + VISA_resource_name)
visaSession = pyvisa.ResourceManager().open_resource(VISA_resource_name)
visaSession.read_termination = '\n'
print('SCPI client connected to SCPI server: ' + visaSession.query("*IDN?"))
Define and execute a measurement and display the results
This examples shows how to:
- build a connection with a SCPI server (i.e. the one provided by Bode 100)
- parametrize a measurement sweep defining start and stop frequencies, number of measurement points a.s.o.
- execute the measurement also in a loop in order to implement a continous sweep
- retrieve and handle measurement data
This example also shows a case of trigger handling for measurement on demand:
- Step 1. Use the :INIT{1-4}:CONT command to turn on continuous initiation mode for the channels you want to measure and turn the mode off for any other channels.
- Step 2. Issue the :TRIG:SOUR command to set the trigger source to “Bus Trigger”.
- Step 3. Trigger the instrument at any time you want to perform measurement. :TRIG:SING this should be followed by a *OPC? command
- Step 4. To start the next measurement cycle, repeat step 3.
For more information about the trigger handling please have a look at the trigger system page.
# use pyvisa or similar package
import pyvisa
import locale
import time
# *** TO DO: adapt IP address and SCPI port according to your needs ***
SCPI_server_IP = '172.22.61.136'
SCPI_Port = '5025'
SCPI_timeout = 20000 # milliseconds
VISA_resource_name = 'TCPIP::' + SCPI_server_IP + '::' + SCPI_Port + '::SOCKET'
# Start and Stop frequencies can be set either as strings or as double. In the latter case a convertion to string will be required before assemblying the SCPI command using them
# if the values are entered as numbers then the "." (dot) shall be used as decimal separator.
# Alternative: entering the values as string e.g. '10MAHz' no coversion to string shall be used building the SCPI command later on
Start_frequency = '10kHz'
Stop_frequency = 10000000.0
Number_of_measurement_points = 201 # the minimum amount of measurement points is 2!
Sweep_type = 'LOG'
Receiver_bandwidth = '300Hz'
Number_of_measurement_cycles = 2
def Init():
start_time = time.time()
print('Trying to connect to VISA resource: ' + VISA_resource_name + '. Be sure that IP address and port number are correct!')
visaSession = pyvisa.ResourceManager().open_resource(VISA_resource_name)
visaSession.timeout = SCPI_timeout
visaSession.read_termination = '\n'
print('SCPI client connected to SCPI server: ' + visaSession.query("*IDN?"))
print()
print("Number of measurement cycles to perform: " + str(Number_of_measurement_cycles))
# Here comes the measurement configuration data for measurement sweep
visaSession.write(':SENS:FREQ:STAR ' + Start_frequency) # Start_frequency is already string and doesn´t require any conversion
visaSession.write(':SENS:FREQ:STOP ' + str(Stop_frequency)) # Stop_frequency is a number and must be converted to string
visaSession.write(':SENS:SWE:POIN ' + str(Number_of_measurement_points))
visaSession.write(':SENS:SWE:TYPE ' + Sweep_type)
visaSession.write(':SENS:BAND ' + Receiver_bandwidth)
visaSession.write(':CALC:PAR:DEF Z') # configuring 'one-port' impedance measurement
visaSession.write(":CALC:FORM SLIN") # linear magnitude in Ohms + phase(deg)
print()
visaSession.write(':TRIG:SOUR BUS') # Intializes trigger system to use BUS - to be used in combination with TRIG:SING and OPC
visaSession.write(':INIT:CONT ON') # Sets the trigger in continous mode. This way after a measurement the trigges gets back in state "ready" and waits for a further measurement.
for i in range(Number_of_measurement_cycles):
visaSession.write(':TRIG:SING')
visaSession.query('*OPC?') # this command waits for all pending operations to finish and afterwards returns an 1
allResults = visaSession.query(":CALC:DATA:SDAT?")
frequencyValues = visaSession.query(":SENS:FREQ:DATA?")
# Magnitude and phase from the results (first to the list, then out of the list to the FLOAT array)
allResults_list_raw = list(map(float, allResults.split(",")))
magnitude_raw = allResults_list_raw[0:Number_of_measurement_points - 1]
phase_raw = allResults_list_raw[Number_of_measurement_points:len(allResults_list_raw)]
# Frequency raw data to list
freq_list_raw = list(map(float, frequencyValues.split(",")))
# Printing just the first results of each measurement cycle
print ("Measurement number: " + str(i + 1) + "; " + "\tFrequency: " + str(freq_list_raw[0]) + " Hz;" + "\tMagnitude: " + str(magnitude_raw[0]) + " Ω;" + "\tPhase: " + str(phase_raw[0]) + "°")
visaSession.close()
print()
print("---Measurement time: %s seconds ---" % (time.time() - start_time))
if __name__ == "__main__":
Init()