一、前置必备 SCPI 查询指令
1、日志与时间戳校验(拆分循环的前提)
scpi
DLOG:DEST?
DLOG:FILE:TIMESTAMP? ! 必须返回1.带绝对时间戳
DLOG:PER? ! DLOG采样周期(s)
DLOG:FILE:CAT? ! 获取历史日志文件名
2、LIST 序列时序参数(用来划分每一轮边界)
scpi
SOUR:LIST:STEP? ! 单轮总步数
SOUR:LIST:DWEL? ! 逗号分隔每步保持时长
TRIG:COUN? ! 预设总循环轮数
TRIG:DEL? ! 轮间等待延时
计算单轮完整运行时长: 数组
3、读取完整历史采样数据(功率字段内置)
scpi
DLOG:FILE:DATA?"你的日志.csv"
带时间戳标准行结构: YYYY-MM-DD HH:MM:SS.fff,Voltage(V),Current(A),Power(W) 第四列即为瞬时输出功率。
4、实时运行中快速读取当前峰值(未停止采集时)
运行状态下可读取缓冲区极值,不用读文件:
scpi
FETC:POW:MAX? ! 自启动记录以来全局最大功率
FETC:POW:MIN? ! 最小功率(回馈负功率)
STAT:TRIG:COUN? ! 已完成完整循环数量
SOUR:LIST:CURR:STEP? ! 当前执行步骤
二、核心计算逻辑:按循环分组提取峰值功率
取日志第一条时间戳t0作为时间基准;
对每条采样行的时间t_sample,计算相对偏移 Δt=tsample−t0;
归属循环编号:Loop=Floor(Δt÷Tround)+1;
把同一 Loop 下所有瞬时功率归集,取最大值 = 该轮峰值输出功率;
双向机型区分:正值 = 放电输出功率,负值 = 充电回馈功率,可分别取正峰值、负峰值。
三、全套 SCPI 调试下发序列
scpi
!1 基础环境校验
*IDN?
DLOG:DEST FILE
DLOG:FILE:TIMESTAMP 1
!2 读取LIST时序,划分循环边界
SOUR:LIST:STEP?
SOUR:LIST:DWEL?
TRIG:COUN?
TRIG:DEL?
!3 日志文件操作
DLOG:FILE:CAT?
DLOG:FILE:INFO?"log001.csv"
DLOG:FILE:DATA?"log001.csv"
!4 实时峰值查询(采集进行中)
FETC:POW:MAX?
FETC:POW:MIN?
STAT:TRIG:COUN?
四、边界补充指令
清空仪器内置极值缓存(重新统计峰值)
scpi
FETC:CLEAR
读取单 LIST 步骤设定功率(理论预设值,非实测峰值)
scpi
SOUR:LIST:VOLT? X
SOUR:LIST:CURR? X
! 理论功率=V*I,仅设定值,不等于实际采样峰值
五、Python 解析示例(分组求每轮功率峰值)
python
运行
import pyvisa
from datetime import datetime
rm = pyvisa.ResourceManager()
inst = rm.open_resource("TCPIP::192.168.1.50::INSTR", timeout=30000)
# 1. 获取单轮总时长
dwel = list(map(float, inst.query("SOUR:LIST:DWEL?").split(",")))
trig_delay = float(inst.query("TRIG:DEL?"))
t_round = sum(dwel) + trig_delay
# 2. 读取日志数据
fname = inst.query("DLOG:FILE:CAT?").split(",")[0].strip()
raw = inst.query(f'DLOG:FILE:DATA?"{fname}"')
lines = raw.strip().splitlines()
loop_power_dict = {}
t0 = None
for line in lines:
if not line:
continue
ts_str, v, i, p = line.split(",")
p_val = float(p)
dt = datetime.strptime(ts_str, "%Y-%m-%d %H:%M:%S.%f")
if t0 is None:
t0 = dt
delta_t = (dt - t0).total_seconds()
loop_num = int(delta_t / t_round) + 1
# 初始化循环功率列表
if loop_num not in loop_power_dict:
loop_power_dict[loop_num] = []
loop_power_dict[loop_num].append(p_val)
# 遍历每一轮,提取峰值功率
result = []
for loop, p_list in sorted(loop_power_dict.items()):
max_p = max(p_list)
min_p = min(p_list) # 回馈负功率峰值
result.append({"循环次数":loop, "正向峰值功率(W)":max_p, "回馈峰值功率(W)":min_p})
# 打印对照表
for item in result:
print(item)
六、关键注意事项
无时间戳日志(Timestamp=0)精度差 仅能用DLOG:PER理论间隔拆分循环,时序偏移会导致分组错误,务必开启DLOG:FILE:TIMESTAMP 1;
中途断电 / 异常终止的日志文件,元数据损坏会丢失起止时间,分组失效;
FETC:POW:MAX?是全局全程最大值,不能区分每一轮独立峰值,只能做整体参考;
ELOG 事件日志只存故障,无完整功率时序,无法用来提取循环峰值;
N6705A 初代 Agilent 机型无DLOG:FILE:INFO/DATA完整文件接口,只能实时 FETC 读取全局峰值,无法历史回溯每轮峰值。