| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708 |
- using System;
- using APS7100TestTool.Models;
- using APS7100TestTool.Services;
- namespace APS7100TestTool.Controllers
- {
- /// <summary>
- /// APS-7100 AC 可编程电源控制器
- ///
- /// ⚠ 重要说明:APS7100 使用完整的、层级严格的 SCPI 命令树
- /// 核心根节点:MEAS / SOUR / OUTP / STAT / DATA
- ///
- /// 命令特点:
- /// 1. 几乎都带二级/三级节点
- /// 2. 不支持简写的无子节点查询(如 OUTP? 不行,必须 OUTP:STAT?)
- /// 3. 测量命令必须走 SCALar 路径
- /// </summary>
- public class APS7100Controller : IPowerSupplyController
- {
- private readonly ScpiDevice _device;
- public DeviceType DeviceType => DeviceType.APS7100;
- public DeviceInfo DeviceInfo => DeviceInfo.GetDeviceInfo(DeviceType.APS7100);
- public APS7100Controller(ScpiDevice device)
- {
- _device = device ?? throw new ArgumentNullException(nameof(device));
- }
- #region IEEE 488.2 标准命令
- /// <summary>
- /// 获取设备识别信息
- /// ⚠ APS7100 在收到任何 SCPI 命令后会自动进入远程模式
- /// </summary>
- public string GetIdentification()
- {
- string result = _device.Query("*IDN?");
- // APS7100 收到 SCPI 命令后自动进入远程模式
- _isInRemoteMode = true;
- return result;
- }
- /// <summary>
- /// 重置设备到出厂状态
- /// </summary>
- public void Reset()
- {
- _device.SendCommand("*RST");
- System.Threading.Thread.Sleep(1000);
- }
- /// <summary>
- /// 清除状态寄存器
- /// </summary>
- public void ClearStatus()
- {
- _device.SendCommand("*CLS");
- }
- /// <summary>
- /// 等待所有挂起操作完成
- /// </summary>
- public void WaitComplete()
- {
- _device.SendCommand("*WAI");
- }
- /// <summary>
- /// 查询操作完成状态
- /// </summary>
- public bool QueryOperationComplete()
- {
- string result = _device.Query("*OPC?");
- return result.Trim() == "1";
- }
- /// <summary>
- /// 触发设备
- /// </summary>
- public void Trigger()
- {
- _device.SendCommand("*TRG");
- }
- /// <summary>
- /// 自检
- /// </summary>
- public int SelfTest()
- {
- string result = _device.Query("*TST?");
- return int.TryParse(result.Trim(), out int code) ? code : -1;
- }
- /// <summary>
- /// 保存设置到指定位置
- /// </summary>
- public void SaveSettings(int location)
- {
- _device.SendCommand($"*SAV {location}");
- }
- /// <summary>
- /// 从指定位置恢复设置
- /// </summary>
- public void RecallSettings(int location)
- {
- _device.SendCommand($"*RCL {location}");
- }
- /// <summary>
- /// 查询事件状态寄存器
- /// </summary>
- public int QueryEventStatusRegister()
- {
- string result = _device.Query("*ESR?");
- return int.TryParse(result.Trim(), out int value) ? value : 0;
- }
- /// <summary>
- /// 设置事件状态使能寄存器
- /// </summary>
- public void SetEventStatusEnable(int mask)
- {
- _device.SendCommand($"*ESE {mask}");
- }
- /// <summary>
- /// 查询状态字节
- /// </summary>
- public int QueryStatusByte()
- {
- string result = _device.Query("*STB?");
- return int.TryParse(result.Trim(), out int value) ? value : 0;
- }
- /// <summary>
- /// 设置服务请求使能
- /// </summary>
- public void SetServiceRequestEnable(int mask)
- {
- _device.SendCommand($"*SRE {mask}");
- }
- #endregion
- #region SYSTEM 系统命令
- // 内部状态跟踪,避免重复发送 SYST:REM 导致 SCPI Error
- private bool _isInRemoteMode = false;
- /// <summary>
- /// 进入远程控制模式
- /// ⚠ APS7100 如果已经是远程模式,再次发送 SYST:REM 会报错
- /// </summary>
- public void SetRemoteMode()
- {
- // 如果已知在远程模式,跳过
- if (_isInRemoteMode) return;
-
- try
- {
- _device.SendCommand("SYST:REM");
- _isInRemoteMode = true;
- }
- catch
- {
- // 如果报错,可能已经在远程模式,标记状态并忽略
- _isInRemoteMode = true;
- }
- }
- /// <summary>
- /// 返回本地控制模式
- /// </summary>
- public void SetLocalMode()
- {
- try
- {
- _device.SendCommand("SYST:COMM:RLST LOCAL");
- _isInRemoteMode = false;
- }
- catch
- {
- // 忽略错误
- _isInRemoteMode = false;
- }
- }
- /// <summary>
- /// 锁定/解锁前面板按键
- /// ⚠ APS7100 使用 KLOC 命令,不是 RWLOCK
- /// </summary>
- public void SetPanelLock(bool locked)
- {
- _device.SendCommand(locked ? "SYST:KLOC ON" : "SYST:KLOC OFF");
- }
- /// <summary>
- /// 查询系统错误
- /// </summary>
- public string QueryError()
- {
- return _device.Query("SYST:ERR?");
- }
-
- /// <summary>
- /// 清除系统错误队列
- /// </summary>
- public void ClearErrors()
- {
- // 循环读取直到没有错误
- try
- {
- for (int i = 0; i < 10; i++) // 最多清除 10 个错误
- {
- string error = _device.Query("SYST:ERR?");
- if (error.StartsWith("0") || error.Contains("No error"))
- break;
- }
- }
- catch { }
- }
- /// <summary>
- /// 查询 SCPI 版本
- /// </summary>
- public string QueryVersion()
- {
- return _device.Query("SYST:VERS?");
- }
- /// <summary>
- /// 查询当前是否为远程模式
- /// </summary>
- public bool IsRemoteMode()
- {
- // 返回内部跟踪的状态
- // 如果能通讯就说明至少连接正常
- try
- {
- _device.Query("*IDN?");
- return _isInRemoteMode;
- }
- catch
- {
- return false;
- }
- }
- #endregion
- #region OUTPUT 输出控制
- /// <summary>
- /// 设置输出开关
- /// ⚠ APS7100 必须使用 OUTPut:STATe,不支持 OUTP ON
- /// </summary>
- public void SetOutput(bool enable)
- {
- _device.SendCommand(enable ? "OUTP:STAT ON" : "OUTP:STAT OFF");
- }
- /// <summary>
- /// 获取输出状态
- /// ⚠ APS7100 必须使用 OUTPut:STATe?,不支持 OUTP?
- /// </summary>
- public bool GetOutputState()
- {
- string result = _device.Query("OUTP:STAT?");
- return result.Trim() == "1" || result.ToUpper().Contains("ON");
- }
- /// <summary>
- /// 清除输出保护状态
- /// </summary>
- public void ClearOutputProtection()
- {
- _device.SendCommand("OUTP:PROT:CLE");
- }
- #endregion
- #region SOURCE 源设置 - 电压
- /// <summary>
- /// 设置输出电压 (V)
- /// </summary>
- public void SetVoltage(double voltage)
- {
- _device.SendCommand($"SOUR:VOLT {voltage}");
- }
- /// <summary>
- /// 获取电压设定值 (V)
- /// </summary>
- public double GetVoltage()
- {
- string result = _device.Query("SOUR:VOLT?");
- return double.TryParse(result.Trim(), out double value) ? value : 0;
- }
- /// <summary>
- /// 设置电压量程
- /// ⚠ APS7100 量程选项:R155 / R310 / R600 / AUTO
- /// ❌ 不支持 LOW / HIGH
- /// </summary>
- public void SetVoltageRange(APS7100VoltageRange range)
- {
- string rangeStr = range switch
- {
- APS7100VoltageRange.R155 => "R155",
- APS7100VoltageRange.R310 => "R310",
- APS7100VoltageRange.R600 => "R600",
- APS7100VoltageRange.Auto => "AUTO",
- _ => "AUTO"
- };
- _device.SendCommand($"SOUR:VOLT:RANG {rangeStr}");
- }
- /// <summary>
- /// 获取电压量程
- /// </summary>
- public APS7100VoltageRange GetVoltageRangeAPS()
- {
- string result = _device.Query("SOUR:VOLT:RANG?").Trim().ToUpper();
- return result switch
- {
- "R155" or "155" => APS7100VoltageRange.R155,
- "R310" or "310" => APS7100VoltageRange.R310,
- "R600" or "600" => APS7100VoltageRange.R600,
- "AUTO" => APS7100VoltageRange.Auto,
- _ => APS7100VoltageRange.Auto
- };
- }
- /// <summary>
- /// 设置电压量程(接口兼容方法)
- /// ⚠ 注意:VoltageRange.Low 映射为 R155,High 映射为 R310
- /// </summary>
- public void SetVoltageRange(VoltageRange range)
- {
- // 接口兼容:Low -> R155, High -> R310
- SetVoltageRange(range == VoltageRange.Low ? APS7100VoltageRange.R155 : APS7100VoltageRange.R310);
- }
- /// <summary>
- /// 获取电压量程(接口兼容方法)
- /// </summary>
- public VoltageRange GetVoltageRange()
- {
- var range = GetVoltageRangeAPS();
- return range == APS7100VoltageRange.R155 ? VoltageRange.Low : VoltageRange.High;
- }
- #endregion
- #region SOURCE 源设置 - 频率
- /// <summary>
- /// 设置输出频率 (Hz)
- /// 常用值:50 / 60 / 400 Hz
- /// </summary>
- public void SetFrequency(double frequency)
- {
- _device.SendCommand($"SOUR:FREQ {frequency}");
- }
- /// <summary>
- /// 获取频率设定值 (Hz)
- /// </summary>
- public double GetFrequency()
- {
- string result = _device.Query("SOUR:FREQ?");
- return double.TryParse(result.Trim(), out double value) ? value : 50;
- }
- #endregion
- #region SOURCE 源设置 - 相位
- /// <summary>
- /// 设置输出相位 (度)
- /// 用于多相或并机控制
- /// </summary>
- public void SetPhase(double degrees)
- {
- _device.SendCommand($"SOUR:PHAS {degrees}");
- }
- /// <summary>
- /// 获取相位设定值 (度)
- /// </summary>
- public double GetPhase()
- {
- string result = _device.Query("SOUR:PHAS?");
- return double.TryParse(result.Trim(), out double value) ? value : 0;
- }
- #endregion
- #region SOURCE 源设置 - 电流限制
- /// <summary>
- /// 设置电流限值 (A)
- /// ⚠ APS7100 只有电流限制,没有"电流设定"概念
- /// 必须使用 SOURce:CURRent:LIMit
- /// </summary>
- public void SetCurrent(double current)
- {
- _device.SendCommand($"SOUR:CURR:LIM:RMS {current}");
- }
- /// <summary>
- /// 设置电流限值 (A) - 显式方法
- /// </summary>
- public void SetCurrentLimit(double current)
- {
- SetCurrent(current);
- }
- /// <summary>
- /// 获取电流限值 (A)
- /// ⚠ 必须使用 SOURce:CURRent:LIMit?
- /// ❌ SOUR:CURR? 不可用
- /// </summary>
- public double GetCurrent()
- {
- string result = _device.Query("SOUR:CURR:LIM:RMS?");
- return double.TryParse(result.Trim(), out double value) ? value : 0;
- }
- /// <summary>
- /// 获取电流限值 (A) - 显式方法
- /// </summary>
- public double GetCurrentLimit()
- {
- return GetCurrent();
- }
- #endregion
- #region MEASURE 测量命令
- /// <summary>
- /// 测量实际输出电压 (V RMS)
- /// ⚠ 必须使用 MEASure:SCALar 路径
- /// </summary>
- public double MeasureVoltage()
- {
- string result = _device.Query("MEAS:SCAL:VOLT?");
- return double.TryParse(result.Trim(), out double value) ? value : 0;
- }
- /// <summary>
- /// 测量实际输出电流 (A RMS)
- /// ⚠ 必须使用 MEASure:SCALar 路径
- /// </summary>
- public double MeasureCurrent()
- {
- string result = _device.Query("MEAS:SCAL:CURR?");
- return double.TryParse(result.Trim(), out double value) ? value : 0;
- }
- /// <summary>
- /// 测量实际频率 (Hz)
- /// ⚠ 必须使用 MEASure:SCALar 路径
- /// </summary>
- public double MeasureFrequency()
- {
- string result = _device.Query("MEAS:SCAL:FREQ?");
- return double.TryParse(result.Trim(), out double value) ? value : 0;
- }
- /// <summary>
- /// 测量有功功率 P (W)
- /// ⚠ 必须使用完整路径 MEASure:SCALar:POWer:AC:REAL?
- /// ❌ MEAS:POW? 不可用
- /// </summary>
- public double MeasurePower()
- {
- string result = _device.Query("MEAS:SCAL:POW:AC:REAL?");
- return double.TryParse(result.Trim(), out double value) ? value : 0;
- }
- /// <summary>
- /// 测量有功功率 P (W) - 别名
- /// </summary>
- public double MeasureRealPower()
- {
- return MeasurePower();
- }
- /// <summary>
- /// 测量视在功率 S (VA)
- /// </summary>
- public double MeasureApparentPower()
- {
- string result = _device.Query("MEAS:SCAL:POW:AC:APP?");
- return double.TryParse(result.Trim(), out double value) ? value : 0;
- }
- /// <summary>
- /// 测量功率因数 PF
- /// ⚠ 使用 MEASure:SCALar:POWer:AC:PFAC?
- /// ❌ MEAS:PF? 不可用
- /// </summary>
- public double MeasurePowerFactor()
- {
- string result = _device.Query("MEAS:SCAL:POW:AC:PFAC?");
- return double.TryParse(result.Trim(), out double value) ? value : 0;
- }
- #endregion
- #region INITIATE 触发/执行命令
- /// <summary>
- /// 立即执行(启动 Sequence / Simulation / 瞬态测试)
- /// </summary>
- public void InitiateImmediate()
- {
- _device.SendCommand("INIT:IMM");
- }
- /// <summary>
- /// 立即执行瞬态
- /// </summary>
- public void InitiateTransient()
- {
- _device.SendCommand("INIT:IMM:TRAN");
- }
- #endregion
- #region STATUS 状态命令
- /// <summary>
- /// 查询操作状态寄存器
- /// </summary>
- public int QueryOperationStatus()
- {
- string result = _device.Query("STAT:OPER?");
- return int.TryParse(result.Trim(), out int value) ? value : 0;
- }
- /// <summary>
- /// 查询可疑状态寄存器
- /// </summary>
- public int QueryQuestionableStatus()
- {
- string result = _device.Query("STAT:QUES?");
- return int.TryParse(result.Trim(), out int value) ? value : 0;
- }
- #endregion
- #region DATA/TRACE 序列和模拟命令
- /// <summary>
- /// 清除序列数据
- /// 用于:电压跌落、频率扫变、IEC测试波形等
- /// </summary>
- public void SequenceClear()
- {
- _device.SendCommand("DATA:SEQ:CLE");
- }
- /// <summary>
- /// 存储序列到指定位置
- /// </summary>
- public void SequenceStore(int index)
- {
- _device.SendCommand($"DATA:SEQ:STOR {index}");
- }
- /// <summary>
- /// 从指定位置调用序列
- /// </summary>
- public void SequenceRecall(int index)
- {
- _device.SendCommand($"DATA:SEQ:REC {index}");
- }
- /// <summary>
- /// 清除模拟数据
- /// </summary>
- public void SimulationClear()
- {
- _device.SendCommand("DATA:SIM:CLE");
- }
- /// <summary>
- /// 存储模拟到指定位置
- /// </summary>
- public void SimulationStore(int index)
- {
- _device.SendCommand($"DATA:SIM:STOR {index}");
- }
- /// <summary>
- /// 从指定位置调用模拟
- /// </summary>
- public void SimulationRecall(int index)
- {
- _device.SendCommand($"DATA:SIM:REC {index}");
- }
- #endregion
- #region 波形设置(APS7100 不支持传统波形)
- /// <summary>
- /// 设置波形 - APS7100 不支持传统波形设置
- /// ⚠ APS7100 使用 DATA:SEQuence 和 DATA:SIMulation 进行
- /// 电压跌落、频率扫变、IEC测试波形,不是 SINE/SQUARE
- /// </summary>
- public void SetWaveform(Waveform waveform)
- {
- // APS7100 不支持传统的 SOUR:WAVE 命令
- // 它的"波形"是通过序列和模拟功能实现的
- throw new NotSupportedException(
- "APS7100 不支持传统波形设置。" +
- "请使用 SequenceStore/SequenceRecall 或 SimulationStore/SimulationRecall 进行波形模拟。");
- }
- /// <summary>
- /// 获取当前波形 - APS7100 不支持
- /// </summary>
- public Waveform GetWaveform()
- {
- throw new NotSupportedException(
- "APS7100 不支持传统波形查询。输出始终为正弦波。");
- }
- #endregion
- #region 自定义命令
- /// <summary>
- /// 发送自定义 SCPI 命令
- /// </summary>
- public void SendCustomCommand(string command)
- {
- _device.SendCommand(command);
- }
- /// <summary>
- /// 发送自定义 SCPI 查询
- /// </summary>
- public string SendCustomQuery(string command)
- {
- return _device.Query(command);
- }
- #endregion
- }
- #region APS7100 专用枚举
- /// <summary>
- /// APS7100 电压量程
- /// ⚠ 注意:与其他设备不同,APS7100 使用 R155/R310/R600/AUTO
- /// </summary>
- public enum APS7100VoltageRange
- {
- /// <summary>0-155V 量程</summary>
- R155,
- /// <summary>0-310V 量程</summary>
- R310,
- /// <summary>0-600V 量程(如果支持)</summary>
- R600,
- /// <summary>自动量程</summary>
- Auto
- }
- #endregion
- #region 通用枚举(接口兼容)
- /// <summary>
- /// 电压量程(通用接口)
- /// </summary>
- public enum VoltageRange
- {
- /// <summary>低档量程</summary>
- Low,
- /// <summary>高档量程</summary>
- High
- }
- /// <summary>
- /// 波形类型(通用接口)
- /// ⚠ 注意:APS7100 不支持波形设置,仅用于接口兼容
- /// </summary>
- public enum Waveform
- {
- /// <summary>正弦波</summary>
- Sine,
- /// <summary>方波</summary>
- Square,
- /// <summary>三角波</summary>
- Triangle
- }
- #endregion
- }
|