This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
|
||||
namespace ASTM_D7896_Tester.Services
|
||||
{
|
||||
@@ -31,41 +32,64 @@ namespace ASTM_D7896_Tester.Services
|
||||
|
||||
public bool IsOpen => _serialPort?.IsOpen == true;
|
||||
|
||||
/// <summary>
|
||||
/// 发送命令并等待响应(同步读写,但因在Task.Run中执行,不阻塞UI)
|
||||
/// </summary>
|
||||
private async Task<string> QueryAsync(string command)
|
||||
{
|
||||
if (!_serialPort.IsOpen) throw new InvalidOperationException("串口未打开");
|
||||
// 使用 Task.Run 避免阻塞 UI 线程
|
||||
var tcs = new TaskCompletionSource<string>();
|
||||
Task.Run(() =>
|
||||
return await Task.Run(() =>
|
||||
{
|
||||
try
|
||||
lock (_serialPort)
|
||||
{
|
||||
// 清空缓冲区
|
||||
_serialPort.DiscardInBuffer();
|
||||
_serialPort.DiscardOutBuffer();
|
||||
|
||||
_serialPort.WriteLine(command);
|
||||
string result = _serialPort.ReadLine();
|
||||
tcs.SetResult(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
tcs.SetException(ex);
|
||||
System.Diagnostics.Debug.WriteLine($"[发送] {command}");
|
||||
|
||||
string response = _serialPort.ReadLine();
|
||||
System.Diagnostics.Debug.WriteLine($"[接收] {response}");
|
||||
return response.Trim();
|
||||
}
|
||||
});
|
||||
return await tcs.Task;
|
||||
}
|
||||
|
||||
|
||||
public string TestCommunication()
|
||||
{
|
||||
if (!_serialPort.IsOpen) throw new InvalidOperationException("串口未打开");
|
||||
_serialPort.DiscardInBuffer();
|
||||
_serialPort.WriteLine("*IDN?");
|
||||
return _serialPort.ReadLine().Trim();
|
||||
}
|
||||
|
||||
|
||||
private async Task SendCommandAsync(string command)
|
||||
{
|
||||
if (!_serialPort.IsOpen) throw new InvalidOperationException("串口未打开");
|
||||
await Task.Run(() => _serialPort.WriteLine(command));
|
||||
await Task.Run(() =>
|
||||
{
|
||||
lock (_serialPort)
|
||||
{
|
||||
_serialPort.WriteLine(command);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置为高速直流电压测量(FAST 分辨率)
|
||||
/// 配置为高速直流电压测量(根据8255文档)
|
||||
/// </summary>
|
||||
public async Task ConfigureHighSpeedDcvAsync()
|
||||
{
|
||||
// 配置直流电压,自动量程
|
||||
await SendCommandAsync("CONFigure:VOLTage:DC AUTO");
|
||||
// 设置精度为FAST(高速模式)
|
||||
await SendCommandAsync("SENSe:VOLTage:DC:RESolution FAST");
|
||||
await SendCommandAsync("TRIGger:SOURce BUS"); // 使用软件触发
|
||||
// 使用软件触发
|
||||
await SendCommandAsync("TRIGger:SOURce BUS");
|
||||
// 关闭自动延迟
|
||||
await SendCommandAsync("TRIGger:DELay:AUTO OFF");
|
||||
await SendCommandAsync("TRIGger:DELay 0");
|
||||
}
|
||||
@@ -80,7 +104,7 @@ namespace ASTM_D7896_Tester.Services
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送触发信号(*TRG)
|
||||
/// 发送软件触发信号
|
||||
/// </summary>
|
||||
public async Task TriggerAsync()
|
||||
{
|
||||
@@ -88,24 +112,31 @@ namespace ASTM_D7896_Tester.Services
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取批量采集结果(在 PrepareBatchAsync 和 TriggerAsync 之后调用)
|
||||
/// 获取批量采集结果
|
||||
/// </summary>
|
||||
public async Task<double[]> FetchBatchAsync()
|
||||
{
|
||||
string response = await QueryAsync("FETCh?");
|
||||
if (string.IsNullOrWhiteSpace(response))
|
||||
throw new Exception("FETCh? 返回空响应");
|
||||
|
||||
// 文档示例返回值如 "+1.234500E-02,+2.345600E-02"
|
||||
string[] parts = response.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
double[] values = new double[parts.Length];
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
if (!double.TryParse(parts[i], System.Globalization.NumberStyles.Float,
|
||||
string valStr = parts[i].Trim();
|
||||
if (!double.TryParse(valStr, System.Globalization.NumberStyles.Float,
|
||||
System.Globalization.CultureInfo.InvariantCulture, out values[i]))
|
||||
throw new Exception($"解析失败: {parts[i]}");
|
||||
{
|
||||
throw new Exception($"解析失败: {valStr},原始响应: {response}");
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单次读取电压(用于实时监控)
|
||||
/// 单次读取电压
|
||||
/// </summary>
|
||||
public async Task<double> ReadVoltageAsync()
|
||||
{
|
||||
|
||||
127
Services/Victory8255LanService.cs
Normal file
127
Services/Victory8255LanService.cs
Normal file
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Globalization; // 确保添加此命名空间
|
||||
|
||||
namespace ASTM_D7896_Tester.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// 胜利 VICTOR 8255 5位半万用表 LAN (TCP/IP) 通信服务
|
||||
/// 支持 SCPI 命令,实现高速批量采集
|
||||
/// 根据其技术规格,通过优化命令可实现 150 次/秒 的读数速率
|
||||
/// </summary>
|
||||
public class Victory8255LanService : IDisposable
|
||||
{
|
||||
private TcpClient _tcpClient;
|
||||
private NetworkStream _stream;
|
||||
private bool _disposed = false;
|
||||
private readonly object _lock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// 连接到 VICTOR 8255 万用表
|
||||
/// </summary>
|
||||
/// <param name="ipAddress">仪器 IP 地址,如 "192.168.1.100"</param>
|
||||
/// <param name="port">端口号,胜利仪器通常使用 5025,请参照说明书确认</param>
|
||||
public async Task ConnectAsync(string ipAddress, int port = 5025)
|
||||
{
|
||||
if (_tcpClient != null && _tcpClient.Connected)
|
||||
return;
|
||||
|
||||
_tcpClient = new TcpClient();
|
||||
await _tcpClient.ConnectAsync(ipAddress, port);
|
||||
_stream = _tcpClient.GetStream();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送 SCPI 命令并等待响应
|
||||
/// </summary>
|
||||
public async Task<string> QueryAsync(string command)
|
||||
{
|
||||
await SendCommandAsync(command);
|
||||
byte[] buffer = new byte[1024];
|
||||
int bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length);
|
||||
return Encoding.ASCII.GetString(buffer, 0, bytesRead).Trim();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送命令但不等待响应
|
||||
/// </summary>
|
||||
public async Task SendCommandAsync(string command)
|
||||
{
|
||||
if (_stream == null) throw new InvalidOperationException("未连接到仪器,请先调用 ConnectAsync");
|
||||
byte[] cmdBytes = Encoding.ASCII.GetBytes(command + "\n");
|
||||
await _stream.WriteAsync(cmdBytes, 0, cmdBytes.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置为高速直流电压测量模式
|
||||
/// </summary>
|
||||
public async Task ConfigureForHighSpeedDcvAsync()
|
||||
{
|
||||
await SendCommandAsync("CONF:VOLT:DC AUTO");
|
||||
// 设置到最快测量速率 (4.5位, 高速)
|
||||
await SendCommandAsync("SENS:VOLT:DC:RES FAST");
|
||||
// 关闭自动归零以提高速度
|
||||
await SendCommandAsync("SENS:VOLT:DC:ZERO:AUTO OFF");
|
||||
// 使用软件触发模式
|
||||
await SendCommandAsync("TRIG:SOUR BUS");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 预置采样点数并进入等待触发状态
|
||||
/// </summary>
|
||||
public async Task PrepareBatchAsync(int sampleCount)
|
||||
{
|
||||
await SendCommandAsync($"SAMP:COUN {sampleCount}");
|
||||
await SendCommandAsync("INIT");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送软件触发信号
|
||||
/// </summary>
|
||||
public async Task TriggerAsync()
|
||||
{
|
||||
await SendCommandAsync("*TRG");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取批量采集结果
|
||||
/// </summary>
|
||||
public async Task<double[]> FetchBatchAsync()
|
||||
{
|
||||
string response = await QueryAsync("FETCh?");
|
||||
string[] parts = response.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
double[] values = new double[parts.Length];
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
if (!double.TryParse(parts[i], NumberStyles.Float, CultureInfo.InvariantCulture, out values[i]))
|
||||
throw new Exception($"解析电压值失败: {parts[i]}");
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取单次读数(用于实时监控)
|
||||
/// </summary>
|
||||
public async Task<double> ReadVoltageAsync()
|
||||
{
|
||||
string response = await QueryAsync("MEAS:VOLT:DC?");
|
||||
if (double.TryParse(response, NumberStyles.Float, CultureInfo.InvariantCulture, out double value))
|
||||
return value;
|
||||
throw new Exception($"电压读数无效: {response}");
|
||||
}
|
||||
|
||||
public bool IsConnected => _tcpClient != null && _tcpClient.Connected;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
_stream?.Close();
|
||||
_tcpClient?.Close();
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -109,7 +109,7 @@ public partial class D7896ViewModel : ObservableObject
|
||||
// TH1963 IP 地址需要根据实际配置修改,建议从配置文件读取
|
||||
_th1963Ustd = new Th1963LanService();
|
||||
// 5位半万用表串口名,例如 "COM3"
|
||||
_fiveHalfUpt = new FiveHalfDmmService("COM3", 115200);
|
||||
_fiveHalfUpt = new FiveHalfDmmService("COM6", 115200);
|
||||
|
||||
StartBackgroundMonitoring();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user