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