Source code for cmd_mm_ki_6517

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# 
# Copyright 2012-2017 Frédéric Magniette, Miguel Rubio-Roy
# This file is part of Pyrame.
# 
# Pyrame is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# Pyrame is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
# 
# You should have received a copy of the GNU Lesser General Public License
# along with Pyrame.  If not, see <http://www.gnu.org/licenses/>

import time,json
import scpi

# CLASS ##########################################################

class mm_ki_6517_class(scpi.scpi):
    # Available channels
    channels=["1"]

    def __init__(self):
        super(mm_ki_6517_class,self).__init__("mm_ki_6517")

    def check_range(self,range):
        retcode,res=super(mm_ki_6517_class,self).check_range(range,[])
        if retcode==0:
            return 0,res
        if retcode==1:
            return 1,":AUTO ON"
        if retcode==2:
            return 1," "+res

    def config(self,mm_ki_6517_id):
        command= r"*CLS\n" # clear status and error queue
        command+=r":INIT:CONT ON\n" # continuous INIT of trigger model
        command+=r":SYST:TSC ON\n" # read temperature
        command+=r":UNIT:TEMP C\n" # temperature in Celsius
        command+=r"FORM:DATA ASC\n" # read in ASCII
        command+=r"FORM:ELEM ALL\n" # read all elements
        command+=r":TRAC:FEED:PRET:SOUR MAN\n" # buffer store source manual
        command+=r":SYST:TST:TYPE REL\n" # timestamp relative
        command+=r":SYST:TST:REL:RES" # reset timestamp
        return super(mm_ki_6517_class,self).config(mm_ki_6517_id,command)

    def reset(self,mm_ki_6517_id):
        command= r"*RST\n" # reset
        command+=r":INIT:CONT ON\n" # continuous INIT of trigger model
        command+=r":SYST:TSC ON\n" # read temperature
        command+=r":UNIT:TEMP C\n" # temperature in Celsius
        command+=r"FORM:DATA ASC\n" # read in ASCII
        command+=r"FORM:ELEM ALL\n" # read all elements
        command+=r":SYST:TST:TYPE REL\n" # timestamp relative
        command+=r":SYST:TST:REL:RES" # reset timestamp
        retcode,res=self.free_command(ki_6517_id,command)
        if retcode==0:
            return 0,res
        time.sleep(1)
        command="SYST:ZCH OFF" # turn off zero-check
        return self.free_command(mm_ki_6517_id,command)
    
    def get_conf_cmd_dc_current(self,mm_ki_6517_id,range="undef",resolution="undef"):
        conf_cmd=":FUNC 'CURR:DC'"
        #range
        if range!="undef":
            retcode,res=self.check_range(range)
            if retcode==0:
                return 0,res
            range=res
            conf_cmd+=r"\n:CURR:DC:RANG%s"%(range)
        #resolution
        if resolution!="undef":
            if resolution.lower().endswith("plc"):
                retcode,res=self.check_resolution(resolution,"plc")
                if retcode in [0,3]:
                    return 0,"Invalid PLC resolution"
                resolution=res
                if retcode==2:
                    conf_cmd+=r"\nCURR:NPLC %s"%(resolution)
            else:
                retcode,res=self.check_resolution(resolution,"s")
                if retcode in [0,3]:
                    return 0,"Invalid resolution"
                resolution=res
                if retcode==2:
                    conf_cmd+=r"\nCURR:APER %s"%(resolution)
        return 1,conf_cmd

    def get_dc_current(self,mm_ki_6517_id,range="undef",resolution="undef"):
        retcode,res=self.get_conf_cmd_dc_current(mm_ki_6517_id,range,resolution)
        if retcode==0:
            return 0,"unable to set range and resolution: %s"%(res)
        conf_cmd=res
        measure_query="FETCH?"
        retcode,res=self.measure(mm_ki_6517_id,range,resolution,conf_cmd,measure_query)
        if retcode==0:
            return 0,res
        if res.split(",")[0][-3:]!="ADC":
            return 0,"set instrument in current mode"
        if res.split(",")[0][-4:-3]=="O":
            return 1,"OL"
        return 1,str(float(res.split(",")[0][:-4]))

    def get_temp(self,mm_ki_6517_id):
        conf_cmd=""
        measure_query="FETCH?"
        retcode,res=self.measure(mm_ki_6517_id,"","",conf_cmd,measure_query)
        if retcode==0:
            return 0,res
        if res.split(",")[4][-7:]!="exttemp":
            return 0,"temperature reading disabled, reset or reconfigure instrument"
        return 1,str(float(res.split(",")[4][:-8]))

    def timed_acq(self,mm_ki_6517_id,value_type,nb_measures,period,vrange,resolution):
        if value_type=="dc_current":
            retcode,res=self.get_conf_cmd_dc_current(mm_ki_6517_id,vrange,resolution)
            if retcode==0:
                return 0,"unable to set range and resolution: %s"%(res)
        else:
            return 0,"unknown value_type %s"%(value_type)
        conf_cmd=res+r"\n"
        conf_cmd+=r":TRAC:FEED:PRET:SOUR MAN\n" # buffer store source manual
        conf_cmd+=r":SYST:TST:TYPE REL\n" # relative timer
        conf_cmd+=r":TRIG:SOUR TIM\n" # trigger source to timer
        conf_cmd+=r":TRIGger:TIMer %f\n"%(float(period)) # trigger period
        conf_cmd+=r":TRIGger:COUNt %d\n"%(int(nb_measures)) # trigger count
        conf_cmd+=r":TRACe:POINts %d\n"%(int(nb_measures)) # buffer size
        conf_cmd+=r":TRACe:CLEar\n" # clear buffer
        conf_cmd+=r":SYST:TST:REL:RES\n" # reset clock
        conf_cmd+=r":TRAC:FEED:CONT NEXT" # start
        retcode,res=self.free_command(mm_ki_6517_id,conf_cmd)
        if retcode==0:
            return 0,"error configuring buffered acq: %s"%(res)
        query=":STAT:MEAS:EVEN?"
        finished=False
        while not finished:
            retcode,res=self.free_query(mm_ki_6517_id,query)
            if retcode==0:
                return 0,"error getting measurement register: %s"%(res)
            finished=(int(res)&512)==512 # 512 = Buffer Full (BUF)
            time.sleep(0.2)
        measure_query=":TRAC:DATA?" # get data
        retcode,res=self.free_query(mm_ki_6517_id,measure_query)
        if retcode==0:
            return 0,"error getting buffer on attempt %d: %s"%(attempt,res)
        buf=res.split(",")
        elements=["dc_current","time","nb","chan","temp","ohm","vsrc"]
        try:
            el=elements.index(value_type)
        except:
            el=0
        data=[]
        for i in range(len(buf)/7):
            t=buf[i*7+1]
            if t[-4:]=="secs":
                t=t[:-4]
            v=buf[i*7+el]
            if v[-8:] in ["Cexttemp","Kexttemp"]:
                v=v[:-8]
            if v[-3:] in ["ADC","ADC","OHM"]:
                v=v[:-3]
            if v[-1:] in ["N","Z","O","U","R","L"]:
                v=v[:-1]
            datum={}
            datum["time"]="%f"%float(t)
            datum["value"]="%e"%float(v)
            data.append(datum)
        return 1,json.dumps(data)

# CREATE POOL ####################################################

me=mm_ki_6517_class()

# COMMANDS #######################################################

def init():
    scpi.submod=submod

# Functions

[docs]def init_mm_ki_6517(mm_ki_6517_id,conf_string): """Initialize mm_ki_6517 power supply identified by *mm_ki_6517_id* *conf_string* must include the parameter: - bus: conf_string of the underlying link module (GPIB, TCP, ...) - channel: channel on which the id will act""" return me.init(mm_ki_6517_id,conf_string)
[docs]def deinit_mm_ki_6517(mm_ki_6517_id): "Deinitialize an mm_ki_6517" return me.deinit(mm_ki_6517_id)
[docs]def config_mm_ki_6517(mm_ki_6517_id): "Configure an mm_ki_6517" return me.config(mm_ki_6517_id)
[docs]def inval_mm_ki_6517(mm_ki_6517_id): "Invalidate an mm_ki_6517" return me.inval(mm_ki_6517_id)
[docs]def reset_mm_ki_6517(mm_ki_6517_id): "Send RST signal to PS" return me.reset(mm_ki_6517_id)
[docs]def get_dc_current_mm_ki_6517(mm_ki_6517_id,range="undef",resolution="undef"): """Get DC current in Ampers. The optional *range* can be: auto or a value in Ampers The optional *resolution* is either the number of power-line cycles that will be used to integrate, followed by PLC (e.g. 10PLC) or the number of seconds followed by s (e.g. 0.2s) MIN or MAX can be used for both parameters (for resolution, MAX means the highest resolution).""" return me.get_dc_current(mm_ki_6517_id,range,resolution)
[docs]def get_temp_mm_ki_6517(mm_ki_6517_id): "Get temperature in degrees Celsius." return me.get_temp(mm_ki_6517_id)
[docs]def timed_acq_mm_ki_6517(mm_ki_6517_id,value_type,nb_measures,period,range="undef",resolution="undef"): "Make a timed acquisition every *period* seconds of *nb_measures* of *value_type* with *range* and *resolution*" return me.timed_acq(mm_ki_6517_id,value_type,nb_measures,period,range,resolution)
[docs]def free_command_mm_ki_6517(mm_ki_6517_id,command): "Send a raw command to the PS" return me.free_command(mm_ki_6517_id,command)
[docs]def free_query_mm_ki_6517(mm_ki_6517_id,query): "Send a raw query to the PS" return me.free_query(mm_ki_6517_id,query)
[docs]def get_error_queue_mm_ki_6517(mm_ki_6517_id): "Read error queue until the end (code 0)" return me.get_error_queue(mm_ki_6517_id)