Source code for skippylab.scpi.commands

"""
A namespace for oscilloscope string commands. The commands are send as ASCII
to the scope using a socket connection
"""

ENCODING_UTF8 = "utf-8"
ENCODING_ISO = "iso-8859-1"

query = lambda cmd : cmd  + "?"

[docs]def add_arg(cmd, arg): """ Add an argument to a command string. Concat the two. Args: cmd (str): The base command arg (str): An argument Returns: str """ if not isinstance(arg,str): arg = str(arg) if len(cmd.split()) != 1: cmd = cmd + "," + arg else: cmd = cmd + " " + arg return cmd
[docs]def concat(*cmd): """ Combine several commands Args: cmd: list of commands Returns: str """ cmd = list(cmd) cmd[0].replace(":","") concated = cmd[0] + ";" cmd.remove(cmd[0]) for c in cmd: concated += ":" + str(c) + "; " return concated
#def decode(response): # """ # Decode osciloscope response from bytes to a string, cleaning # trailing EOL characters. # # Args: # response (bytes): recieved from oscilloscope # # Returns: # str # """ # if response is None: # return response # if isinstance(response,bytes): # response = response.decode("utf8") # response = clean_response(response) # if response in [False, "\r\n", "\n\r"]: # response = None # return response
[docs]def clean_response(response): """ Remove some EOL remainders from the resulting scope response Args: response (str): response from the scope Returns: str """ response = response.replace("\r\n>", "") response = response.replace("\r\n", "") response = response.replace("\n\r", "") response = response.replace(">", "") response = response.replace("<", "") response = response.replace("\n", "") return response
[docs]def parse_curve_data(header, curve): """ Make sense out of that what is returned by CURVE. This works only if the scope is set to return the data in ASCII, not binary. Args: header (dict): a parsed header curv (str): returned by CURVE? Returns: tuple: np.ndarray xs, np.ndarray values """ # Value in YUNit units = ((curve_in_dl - YOFf) * YMUlt) + YZEro curve.replace("#", "")
#def encode(cmd): # """ # Append trailing return carriage and convert # to bytes. Trailing EOL characters are important # otherwise the scope will listen for input commands # endlessly. # # Args: # cmd (str): command to be sanitized # # Returns: # bytearray # """ # # if not cmd.endswith("\r\n"): # cmd = cmd + "\r\n" # # # python3 needs byterepresentation for socket # return cmd.encode("utf8")
[docs]def histbox_coordinates(left, top, right, bottom): """ Create a string for the box coordinates for the histogram set up by the scope itself. The result can be send to the scope to set the box. Args: left (int): top (int): right (int): bottom (int): Returns: str """ command = concat([left, top, right, bottom]) return command
# # COMMANDS! # (add more here if needed. See the programming manual) # Queries should end with "Q" # WHOAMI = "*IDN?" SOURCE = "DATa:SOUrce" DATA_START = "DATa:STARt" DATA_STOP = "DATa:STOP" DATA_STARTQ = query(DATA_START) DATA_STOPQ = query(DATA_STOP) SOURCEQ = query(SOURCE) HISTSTART = "HIStogram:STARt" HISTEND = "HIStogram:END" HISTDATA = "HIStogram:DATa?" WAVEFORM = "WAVFrm?" CURVE = "CURVe?" WF_OUTPREQ = "WFMOutre?" WF_XINCRQ = "WFMOutpre:XINcr?" WF_XUNITQ = "WFMOutpre:XUNit?" WF_XZEROQ = "WFMOutpre:XZEro?" WF_YOFFQ = "WFMOutpre:YOFf?" WF_YZEROQ = "WFMOutpre:YZEro?" WF_YMULTQ = "WFMOutpre:YMUlt?" WF_YUNITQ = "WFMOutpre:YUNit?" WF_ENC = "WFMOutpre:ENCdg" WF_ENCQ = query(WF_ENC) WF_NPOINTS = "WFMOutpre:NR_Pt" WF_NPOINTSQ = query(WF_NPOINTS) ACQUIRE = "ACQuire" ACQUIRE_FAST_STATE = "ACQuire:FASTAcq:STATE" ACQUIRE_MAX_SAMPLERATEQ = "ACQuire:MAXSamplerate?" RUN = "ACQuire:STATE" WF_BYTQ = "WFMOutpre:BYT_Nr?" # 1 or 2 for single or double prec ACQUIRE_STOP = "ACQuire:STOPAfter" HISTBOX = "HIStogram:BOX" TRG_RATEQ = "TRIGger:FREQuency?" # command arguments RUN_CONTINOUS = "RUNSTop" RUN_SINGLE = "SEQ" # sequence START_ACQUISITIONS = "RUN" STOP_ACQUISITIONS = "STOP" ACQUIRE_ONE = "ON" SNAP = "SNAP" DATA = "DATA" OFF = "0" ON = "1" ASCII = "ASCii" BINARY = "BINary" SINGLE_ACQUIRE = "1" # combined commands
[docs]class TektronixDPO4104BCommands(object): """ Namespace for the commands for the TektronixDP04104B """ WF_HEADER = concat(WF_BYTQ, WF_ENCQ, WF_NPOINTSQ, WF_XZEROQ, WF_XINCRQ,\ WF_YZEROQ, WF_YOFFQ, WF_YMULTQ,\ WF_XUNITQ, WF_YUNITQ) WF = query("WAVFrm") WF_NOHEAD = query("CURVE") CH1 = "CH1" CH2 = "CH2" CH3 = "CH3" CH4 = "CH4" ON = "ON" OFF = "OFF" ONE = "1" ZERO = "0" WF_BYTEWIDTH = "DATA:WIDTH" TRIGGER_FREQUENCY_ENABLED = "DISplay:TRIGFrequency" TRIGGER_FREQUENCYQ = query("TRIGger:FREQuency") ACQUISITON_MODE = "ACQuire:STOPAfter" N_ACQUISITIONS = query("ACQuire:NUMACq")
[docs]class RhodeSchwarzRTO1044Commands(object): """ Namespace for the commands for the RhodeSchwarz oscilloscope """ CH1 = "CHAN1" CH2 = "CHAN2" CH3 = "CHAN3" CH4 = "CHAN4" WAVEFORM = "DATA?" WF_HEADER = "DATA:HEADer?" CURVE = "DATA:VALues?" N_ACQUISITONS = "ACQuire:CURRent?" RUN = "RUN" SINGLE = "SINGLE" STOP = "STOP"
[docs]class KeysightE3631APowerSupplyCommands(object): """ Namespace for the commands of the KeysightE3631APowerSupply """ ERROR_STATEQ = "SYST:ERR?" OUTPUT = "OUTPUT:STATE" ON = "ON" OFF = "OFF" P6 = "P6V" # the 6V channel P25 = "P25V" # the 25V channel N25 = "N25V" # the 25V channel but with negative polarity APPLY = "APPLY" CHANNEL = "INST" VOLT = "VOLT" MEASURE = "MEASURE" CURRENT = "CURRENT" DC = "DC"