This commit is contained in:
xyy
2026-05-24 10:36:57 +08:00
parent 24f438b81a
commit eb95de74ed
4 changed files with 140 additions and 97 deletions

View File

@@ -19,6 +19,9 @@ namespace ASTM_D7896_Tester.Services
public int ConnectTimeoutMs { get; set; } = 3000;
public int ReadWriteTimeoutMs { get; set; } = 5000;
// 默认电压量程(伏特),可根据实际信号修改,例如 0.1, 1, 10, 100, 1000
public double DefaultVoltageRange { get; set; } = 1.0;
public async Task ConnectAsync(string ipAddress, int port = 45454)
{
if (_tcpClient != null && _tcpClient.Connected)
@@ -37,6 +40,9 @@ namespace ASTM_D7896_Tester.Services
_stream.WriteTimeout = ReadWriteTimeoutMs;
}
/// <summary>
/// 发送命令并等待完整响应(支持多行/大数据量)
/// </summary>
public async Task<string> QueryAsync(string command)
{
EnsureConnected();
@@ -44,19 +50,30 @@ namespace ASTM_D7896_Tester.Services
await _stream.WriteAsync(cmdBytes, 0, cmdBytes.Length);
var responseBuilder = new StringBuilder();
byte[] buffer = new byte[4096];
byte[] buffer = new byte[65536];
int bytesRead;
while (true)
bool endReached = false;
while (!endReached)
{
bytesRead = await _stream.ReadAsync(buffer, 0, buffer.Length);
if (bytesRead == 0) break;
string chunk = Encoding.ASCII.GetString(buffer, 0, bytesRead);
responseBuilder.Append(chunk);
if (chunk.Contains("\n")) break;
// 如果收到换行符再等50ms确认没有更多数据TCP分包情况
if (chunk.Contains("\n"))
{
await Task.Delay(50);
if (!_stream.DataAvailable)
endReached = true;
}
}
return responseBuilder.ToString().Trim();
}
/// <summary>
/// 发送命令,不等待响应
/// </summary>
public async Task SendCommandAsync(string command)
{
EnsureConnected();
@@ -65,60 +82,76 @@ namespace ASTM_D7896_Tester.Services
}
/// <summary>
/// 配置为高速直流电压测量(外部触发模式)
/// 配置为高速直流电压测量(BUS触发模式固定量程0.02PLC,关闭自归零
/// </summary>
public async Task ConfigureForHighSpeedDcvAsync()
{
await SendCommandAsync("CONF:VOLT:DC AUTO");
// 1. 重置到默认状态(可选)
await SendCommandAsync("*RST");
await Task.Delay(100);
// 2. 固定量程(避免自动量程降低速度)
await SendCommandAsync($"VOLT:DC:RANG {DefaultVoltageRange}");
// 3. 设置积分时间 0.02PLC(最快速度)
await SendCommandAsync("VOLT:DC:NPLC 0.02");
// 4. 关闭自动归零(提高速度)
await SendCommandAsync("VOLT:DC:ZERO:AUTO OFF");
await SendCommandAsync("TRIG:SOUR EXT");
// 5. 触发源设为 BUS软件触发
await SendCommandAsync("TRIG:SOUR BUS");
// 6. 关闭自动延迟延迟设为0
await SendCommandAsync("TRIG:DEL:AUTO OFF");
await SendCommandAsync("TRIG:DEL 0");
}
/// <summary>
/// 预置采样点数并进入等待触发状态
/// 预置采样点数并进入等待触发状态(发送 INIT
/// </summary>
public async Task PrepareBatchAsync(int sampleCount)
{
await SendCommandAsync($"SAMP:COUN {sampleCount}");
await SendCommandAsync("INIT"); // 等待外部触发
await SendCommandAsync("INIT"); // 进入等待触发状态
}
/// <summary>
/// 发送触发信号(软件触发,用于测试,但外部触发模式不使用)
/// 此方法仅用于 BUS 触发模式,当前配置为 EXT 触发,实际触发由硬件信号完成。
/// 保留此方法以备将来切换触发模式。
/// 发送软件触发信号(*TRG开始采集
/// </summary>
public async Task TriggerAsync()
{
// 当前为外部触发模式,不需要软件触发;若需软件触发,请先执行 TRIG:SOUR BUS
// 保留空实现或抛出 NotSupportedException根据需求选择
// 为避免编译错误,提供一个空实现
await Task.CompletedTask;
await SendCommandAsync("*TRG");
}
/// <summary>
/// 批量采集(假设已经配置并等待外部触发完成
/// </summary>
public async Task<double[]> AcquireBatchAsync(int sampleCount)
{
await SendCommandAsync($"SAMP:COUN {sampleCount}");
await SendCommandAsync("INIT");
int waitMs = (int)(sampleCount / 1000.0 * 1000) + 200;
await Task.Delay(waitMs);
string response = await QueryAsync("FETCh?");
return ParseResponse(response, sampleCount);
}
/// <summary>
/// 获取批量采集结果(在 PrepareBatchAsync 和外部触发之后调用)
/// 获取批量采集结果FETCh?
/// </summary>
public async Task<double[]> FetchBatchAsync()
{
string response = await QueryAsync("FETCh?");
// 注意:此时不知道预期点数,但可以从返回数组长度得知
return ParseResponse(response);
}
/// <summary>
/// 一次性批量采集(简化接口,内部自动完成 SAMP:COUN + READ?
/// 注意:此方法会阻塞直到采集完成,适合不需要分离触发时序的场景
/// </summary>
public async Task<double[]> ReadBatchAsync(int sampleCount)
{
await SendCommandAsync($"SAMP:COUN {sampleCount}");
string response = await QueryAsync("READ?");
return ParseResponse(response);
}
/// <summary>
/// 解析逗号分隔的电压值数组
/// </summary>
private double[] ParseResponse(string response)
{
if (string.IsNullOrWhiteSpace(response))
throw new Exception("返回数据为空");
string[] parts = response.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
double[] values = new double[parts.Length];
for (int i = 0; i < parts.Length; i++)
@@ -130,21 +163,9 @@ namespace ASTM_D7896_Tester.Services
return values;
}
private double[] ParseResponse(string response, int expectedCount)
{
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,
System.Globalization.CultureInfo.InvariantCulture, out values[i]))
throw new Exception($"解析失败: {parts[i]}");
}
if (values.Length != expectedCount)
throw new Exception($"期望 {expectedCount} 个点,实际收到 {values.Length}");
return values;
}
/// <summary>
/// 单次读取电压(保留,但不推荐用于高速采集)
/// </summary>
public async Task<double> ReadVoltageAsync()
{
string resp = await QueryAsync("MEAS:VOLT:DC?");