SCPI指令是可編程儀器標(biāo)準(zhǔn)命令(Standard Commands for Programmable Instruments)的簡稱,它實(shí)際定義了一套用于控制可編程測量儀器的標(biāo)準(zhǔn)語法和命令。
SCP命令實(shí)際是通過ASCII字符串形式在命令與儀器進(jìn)行交互。命令一般由一系列的關(guān)鍵字構(gòu)成,有的還需要包括參數(shù),命令一般由英文單詞的4個大寫首字母定義,一般儀器對于命令的返回也是一系列的ASCII字符串,當(dāng)然在進(jìn)行大量數(shù)據(jù)傳輸?shù)臅r候直接采用二進(jìn)制的形式也是可以的。
基本語法
一般的儀器指令可以分為控制指令和查詢指令,比如將電源開關(guān)的開關(guān)和查詢電源的輸出電流,在SCPI指令中查詢指令一般是以?結(jié)束的,多個指令之間還可以通過:進(jìn)行串聯(lián),指令的參數(shù)一般跟在指令后面,以空格隔開,多個級聯(lián)的指令還可以通過一條語句下發(fā),指令之間以;分隔,比如測量直流電壓和交流電流可以通過以下的形式實(shí)現(xiàn):
MEASure:VOLTage:DC?;:MEASure:CURRent:AC?
用SCPI指令控制萬用表
最近要用到萬用表測量很多數(shù)據(jù),如果人肉測量的話就太麻煩了,并且容易出錯,對現(xiàn)代人來說,不要在重復(fù)的事情上花太多的時間,于是就用python結(jié)合SCPI指令寫了一個簡單的腳本,也就一個小時的時間就可以搞定幾天的工作,騰出一點(diǎn)時間來寫寫文章也是非常不錯的呀。
實(shí)際萬用表的控制只用到了一點(diǎn)非?;镜拿睿贿^還是碰到一個坑,這里也記錄一下。在用串口通過SCPI指令控制萬用表的時候,需要注意的是首先要將萬用表的操作模式設(shè)置為遠(yuǎn)程模式,否則所有的命令都會報錯,模式的切換可以通過以下的命令實(shí)現(xiàn):
SYSTem:REMote
之后就可以將萬用表設(shè)置為直流電壓測量模式:MEAS:VOLT:DC? AUTO,這個指令的含義是用自動的量程進(jìn)行直流電壓測量。
最后就可以在一個循環(huán)中不停地讀取測量結(jié)果了:READ?
用SCPI指令控制SMU
在控制源測量單元的時候,有一個需要需要注意的地方就是前后面板的切換,一般的儀器都會在前后面板上都有測試端子,我們在使用的時候需要去選擇前面板還是后面板,在SMU中這個選擇是通過命令切換的:ROUT:TERM REAR, 其它一些基本都是通用的指令,完整的程序這里也直接貼出來好了:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Script to run dcdc loading test, using source meter
as DCDC loading and DMM to measure DCDC output voltage
"""
import serial
import time
SOURCE_METER_DEV = "COM3"
DMM_DEV = "COM10"
BUFFER_LEN = 1024
class SCPI():
"""
Source meter class
"""
def __init__(self, port, timeout=2, stop=1, baudrate=9600, reset=True):
# open serial port
# baudrate: 9600
# timeout 1s
self.com = serial.Serial(
port,
timeout=timeout,
stopbits=stop,
baudrate=baudrate
)
if reset:
self.reset()
def send(self, cmd):
"""
Send out a command, will automaticlly add \n
at the end of command
"""
if not cmd.endswith("\n"):
cmd += "\n"
return self.com.write(cmd.encode())
def query(self, cmd, decode=True):
self.send(cmd)
echo = self.com.read(BUFFER_LEN)
if decode:
try:
# try to decode to utf8
echo = echo.decode()
# try to decode to float
echo = float(echo)
except:
pass
return echo
def reset(self):
return self.send("*RST")
def close(self):
return self.com.close()
def dcdc_loading():
sm = SCPI(SOURCE_METER_DEV)
dmm = SCPI(DMM_DEV, stop=2)
# init source meter to current source
sm.send(":OUTP OFF")
sm.send(":ROUT:TERM REAR")
sm.send(":SOUR:FUNC CURR")
sm.send(":SOUR:CURR:RANG:AUTO ON")
sm.send(":SOUR:CURR:LEV 0")
sm.send(":OUTP ON")
# init dmm
dmm.send("SYST:REM")
dmm.query("MEAS:VOLT:DC? AUTO")
for i in range(50):
# set current source
curr = -(i / 100)
sm.send("SOUR:CURR:LEV " + str(curr))
# read result
time.sleep(1)
print(curr, ", ", dmm.query("READ?"))
sm.send(":OUTP OFF")
sm.close()
dmm.close()
dcdc_loading()