现场优化7

This commit is contained in:
2026-08-27 11:08:36 +08:00
parent 38f594e4aa
commit 6a59552bc7
10 changed files with 1198 additions and 70 deletions
+19 -46
View File
@@ -510,13 +510,6 @@ namespace DeviceCommand.Devices
if (hasModifiedEnable) if (hasModifiedEnable)
await Task.Delay(100, ); await Task.Delay(100, );
// 3. 获取三轴原点及当前设定的目标指定位置
var (xHome, yHome, zHome) = await ();
int xTarget = await (1, );
int yTarget = await (2, );
int zTarget = await (3, );
await WriteSingleCoilAsync(_slaveAddress, ADDR_M_X_START, true, ); await WriteSingleCoilAsync(_slaveAddress, ADDR_M_X_START, true, );
await WriteSingleCoilAsync(_slaveAddress, ADDR_M_Y_START, true, ); await WriteSingleCoilAsync(_slaveAddress, ADDR_M_Y_START, true, );
await WriteSingleCoilAsync(_slaveAddress, ADDR_M_Z_START, true, ); await WriteSingleCoilAsync(_slaveAddress, ADDR_M_Z_START, true, );
@@ -568,15 +561,23 @@ namespace DeviceCommand.Devices
// 3. 启动三轴联动 // 3. 启动三轴联动
await (); await ();
bool IsArrived= await (,);
// 5. 到达后更新当前位置(累加偏移) if (IsArrived)
_originX += X偏移量; {
_originY += Y偏移量; // 5. 到达后更新当前位置(累加偏移)
_originZ += Z偏移量; _originX += X偏移量;
_originY += Y偏移量;
_originZ += Z偏移量;
await ();
}
else
{
var pos = await ();
_originX += pos.Axis1;
_originY += pos.Axis6;
_originZ += pos.Axis2;
await ();
}
} }
public async Task ( CancellationToken = default) public async Task ( CancellationToken = default)
{ {
@@ -702,40 +703,12 @@ namespace DeviceCommand.Devices
throw new TimeoutException($"等待 {超时秒数} 秒后,三轴仍未到达机械零点"); throw new TimeoutException($"等待 {超时秒数} 秒后,三轴仍未到达机械零点");
} }
/// <summary>
/// 轮询等待三轴绝对位置到达指定的待定位置(容差 ±10),超时则抛出异常
/// </summary>
/// <param name="xTarget">X轴目标位置</param>
/// <param name="yTarget">Y轴目标位置</param>
/// <param name="zTarget">Z轴目标位置</param>
/// <param name="超时秒数">最大等待时间(秒)</param>
/// <param name="取消令牌">取消令牌</param>
private async Task (int xTarget, int yTarget, int zTarget, int , CancellationToken = default)
{
var deadline = DateTime.Now.AddSeconds();
while (DateTime.Now < deadline)
{
.ThrowIfCancellationRequested();
var pos = await ();
if (Math.Abs(pos.Axis1 - xTarget) <= 10
&& Math.Abs(pos.Axis6 - yTarget) <= 10
&& Math.Abs(pos.Axis2 - zTarget) <= 10)
return;
await Task.Delay(100, );
}
throw new TimeoutException($"等待 {超时秒数} 秒后,三轴仍未到达待定位置 (X:{xTarget}, Y:{yTarget}, Z:{zTarget})");
}
/// <summary> /// <summary>
/// 轮询等待三轴绝对位置均到达各自设定的目标位置(容差 ±10),超时则抛出异常 /// 轮询等待三轴绝对位置均到达各自设定的目标位置(容差 ±10),超时则抛出异常
/// </summary> /// </summary>
/// <param name="超时秒数">最大等待时间(秒)</param> /// <param name="超时秒数">最大等待时间(秒)</param>
/// <param name="取消令牌">取消令牌</param> /// <param name="取消令牌">取消令牌</param>
public async Task (int , CancellationToken = default) public async Task<bool> (int , CancellationToken = default)
{ {
var targetX = await (1, ); var targetX = await (1, );
var targetY = await (2, ); var targetY = await (2, );
@@ -751,7 +724,7 @@ namespace DeviceCommand.Devices
if (Math.Abs(pos.Axis1 - targetX) <= 10 if (Math.Abs(pos.Axis1 - targetX) <= 10
&& Math.Abs(pos.Axis6 - targetY) <= 10 && Math.Abs(pos.Axis6 - targetY) <= 10
&& Math.Abs(pos.Axis2 - targetZ) <= 10) && Math.Abs(pos.Axis2 - targetZ) <= 10)
return; return true;
await Task.Delay(100, ); await Task.Delay(100, );
} }
+11 -1
View File
@@ -141,7 +141,17 @@ namespace DeviceCommand.Devices
IOBoard = GetBoardInstance(io信息.ModuleIndex); IOBoard = GetBoardInstance(io信息.ModuleIndex);
await .(_slaveAddress, io信息.Address, ); await .(_slaveAddress, io信息.Address, );
} }
/// <summary>
/// 执行指定台架的功能动作控制(带高低电平开关及底层安全互锁)
/// </summary>
/// <param name="板卡序号">板卡序号 (0 - 1)</param>
/// <param name="开始地址">寄存器初始地址(0-15)</param>
/// <param name="数据">开关状态数组 (true: 开启吸合, false: 关闭断开)[true,true,false]</param>
/// <param name="取消令牌">异步取消令牌</param>
public async Task (int ,byte , ushort , bool[] , CancellationToken = default)
{
await GetBoardInstance().(, , );
}
/// <summary> /// <summary>
/// 内部路由辅助方法:根据板卡索引安全获取当前连接的实例对象 /// 内部路由辅助方法:根据板卡索引安全获取当前连接的实例对象
/// </summary> /// </summary>
+74 -4
View File
@@ -8,11 +8,20 @@ using System.Threading.Tasks;
namespace DeviceCommand.Flexible namespace DeviceCommand.Flexible
{ {
/// <summary>
/// 灵活型 Modbus RTU 串口通信类(免实例化,每次调用临时创建串口连接)。
/// 支持保持寄存器与线圈的读写操作,内部使用通信锁保证同一时刻只有一个事务在执行,
/// 适用于偶发性、无需保持长连接的 Modbus RTU 设备读写场景。
/// </summary>
[ADPCommand] [ADPCommand]
public static class FModbusRTU public static class FModbusRTU
{ {
// 通信锁:保证同一时刻只有一个 Modbus 事务在执行
private static readonly SemaphoreSlim _commLock = new(1, 1); private static readonly SemaphoreSlim _commLock = new(1, 1);
/// <summary>
/// 创建串口实例并配置超时参数。
/// </summary>
private static SerialPort CreatePort( private static SerialPort CreatePort(
string portName, string portName,
int baudRate, int baudRate,
@@ -29,6 +38,9 @@ namespace DeviceCommand.Flexible
}; };
} }
/// <summary>
/// 基于指定串口创建 Modbus RTU 主站。
/// </summary>
private static IModbusMaster CreateMaster(SerialPort port) private static IModbusMaster CreateMaster(SerialPort port)
{ {
return new ModbusFactory().CreateRtuMaster(port); return new ModbusFactory().CreateRtuMaster(port);
@@ -36,7 +48,22 @@ namespace DeviceCommand.Flexible
#region Holding Register #region Holding Register
public static async Task<ushort[]> ReadHoldingRegistersAsync( /// <summary>
/// 读取保持寄存器(功能码 03),返回指定数量的寄存器值数组。
/// </summary>
/// <param name="portName">串口名称,如 "COM1"</param>
/// <param name="baudRate">波特率,如 9600、115200</param>
/// <param name="slaveAddress">Modbus 从站站号 (1-247)</param>
/// <param name="startAddress">起始寄存器地址</param>
/// <param name="numberOfPoints">读取的寄存器数量</param>
/// <param name="dataBits">数据位,默认 8</param>
/// <param name="stopBits">停止位,默认 1 位</param>
/// <param name="parity">校验位,默认无校验</param>
/// <param name="readTimeout">读取超时时间(毫秒),默认 3000</param>
/// <param name="writeTimeout">写入超时时间(毫秒),默认 3000</param>
/// <param name="ct">异步取消令牌</param>
/// <returns>读取到的寄存器值数组</returns>
public static async Task<ushort[]> (
string portName, string portName,
int baudRate, int baudRate,
byte slaveAddress, byte slaveAddress,
@@ -73,7 +100,21 @@ namespace DeviceCommand.Flexible
} }
} }
public static async Task WriteSingleRegisterAsync( /// <summary>
/// 写入单个保持寄存器(功能码 06)。
/// </summary>
/// <param name="portName">串口名称,如 "COM1"</param>
/// <param name="baudRate">波特率,如 9600、115200</param>
/// <param name="slaveAddress">Modbus 从站站号 (1-247)</param>
/// <param name="registerAddress">要写入的寄存器地址</param>
/// <param name="value">要写入的寄存器值 (0-65535)</param>
/// <param name="dataBits">数据位,默认 8</param>
/// <param name="stopBits">停止位,默认 1 位</param>
/// <param name="parity">校验位,默认无校验</param>
/// <param name="readTimeout">读取超时时间(毫秒),默认 3000</param>
/// <param name="writeTimeout">写入超时时间(毫秒),默认 3000</param>
/// <param name="ct">异步取消令牌</param>
public static async Task (
string portName, string portName,
int baudRate, int baudRate,
byte slaveAddress, byte slaveAddress,
@@ -114,7 +155,22 @@ namespace DeviceCommand.Flexible
#region Coil #region Coil
public static async Task<bool[]> ReadCoilsAsync( /// <summary>
/// 读取线圈状态(功能码 01),返回指定数量的线圈开关状态数组。
/// </summary>
/// <param name="portName">串口名称,如 "COM1"</param>
/// <param name="baudRate">波特率,如 9600、115200</param>
/// <param name="slaveAddress">Modbus 从站站号 (1-247)</param>
/// <param name="startAddress">起始线圈地址</param>
/// <param name="numberOfPoints">读取的线圈数量</param>
/// <param name="dataBits">数据位,默认 8</param>
/// <param name="stopBits">停止位,默认 1 位</param>
/// <param name="parity">校验位,默认无校验</param>
/// <param name="readTimeout">读取超时时间(毫秒),默认 3000</param>
/// <param name="writeTimeout">写入超时时间(毫秒),默认 3000</param>
/// <param name="ct">异步取消令牌</param>
/// <returns>线圈状态数组,true 表示吸合/导通</returns>
public static async Task<bool[]> 线(
string portName, string portName,
int baudRate, int baudRate,
byte slaveAddress, byte slaveAddress,
@@ -151,7 +207,21 @@ namespace DeviceCommand.Flexible
} }
} }
public static async Task WriteSingleCoilAsync( /// <summary>
/// 写入单个线圈(功能码 05),控制单个开关量输出。
/// </summary>
/// <param name="portName">串口名称,如 "COM1"</param>
/// <param name="baudRate">波特率,如 9600、115200</param>
/// <param name="slaveAddress">Modbus 从站站号 (1-247)</param>
/// <param name="coilAddress">要写入的线圈地址</param>
/// <param name="value">线圈状态(true: 吸合/导通, false: 断开)</param>
/// <param name="dataBits">数据位,默认 8</param>
/// <param name="stopBits">停止位,默认 1 位</param>
/// <param name="parity">校验位,默认无校验</param>
/// <param name="readTimeout">读取超时时间(毫秒),默认 3000</param>
/// <param name="writeTimeout">写入超时时间(毫秒),默认 3000</param>
/// <param name="ct">异步取消令牌</param>
public static async Task 线(
string portName, string portName,
int baudRate, int baudRate,
byte slaveAddress, byte slaveAddress,
+59 -4
View File
@@ -8,11 +8,20 @@ using System.Threading.Tasks;
namespace DeviceCommand.Flexible namespace DeviceCommand.Flexible
{ {
/// <summary>
/// 灵活型 Modbus TCP 通信类(免实例化,每次调用临时建立 TCP 连接)。
/// 支持保持寄存器与线圈的读写操作,内部使用通信锁保证同一时刻只有一个事务在执行,
/// 适用于偶发性、无需保持长连接的 Modbus TCP 设备读写场景。
/// </summary>
[ADPCommand] [ADPCommand]
public static class FModbusTCP public static class FModbusTCP
{ {
// 通信锁:保证同一时刻只有一个 Modbus 事务在执行
private static readonly SemaphoreSlim _commLock = new(1, 1); private static readonly SemaphoreSlim _commLock = new(1, 1);
/// <summary>
/// 建立 TCP 连接并创建 Modbus TCP 主站。
/// </summary>
private static async Task<IModbusMaster> ConnectAsync(string ipAddress, int port, int sendTimeout, int receiveTimeout, CancellationToken ct) private static async Task<IModbusMaster> ConnectAsync(string ipAddress, int port, int sendTimeout, int receiveTimeout, CancellationToken ct)
{ {
var tcpClient = new TcpClient(); var tcpClient = new TcpClient();
@@ -26,7 +35,19 @@ namespace DeviceCommand.Flexible
#region Holding Registers #region Holding Registers
public static async Task<ushort[]> ReadHoldingRegistersAsync( /// <summary>
/// 读取保持寄存器(功能码 03),返回指定数量的寄存器值数组。
/// </summary>
/// <param name="ipAddress">设备 IP 地址</param>
/// <param name="port">Modbus TCP 端口号,默认常用 502</param>
/// <param name="slaveAddress">Modbus 从站站号(单元标识符)</param>
/// <param name="startAddress">起始寄存器地址</param>
/// <param name="numberOfPoints">读取的寄存器数量</param>
/// <param name="sendTimeout">发送/连接超时时间(毫秒),默认 3000</param>
/// <param name="receiveTimeout">接收超时时间(毫秒),默认 3000</param>
/// <param name="ct">异步取消令牌</param>
/// <returns>读取到的寄存器值数组</returns>
public static async Task<ushort[]> (
string ipAddress, string ipAddress,
int port, int port,
byte slaveAddress, byte slaveAddress,
@@ -51,7 +72,18 @@ namespace DeviceCommand.Flexible
} }
} }
public static async Task WriteSingleRegisterAsync( /// <summary>
/// 写入单个保持寄存器(功能码 06)。
/// </summary>
/// <param name="ipAddress">设备 IP 地址</param>
/// <param name="port">Modbus TCP 端口号,默认常用 502</param>
/// <param name="slaveAddress">Modbus 从站站号(单元标识符)</param>
/// <param name="registerAddress">要写入的寄存器地址</param>
/// <param name="value">要写入的寄存器值 (0-65535)</param>
/// <param name="sendTimeout">发送/连接超时时间(毫秒),默认 3000</param>
/// <param name="receiveTimeout">接收超时时间(毫秒),默认 3000</param>
/// <param name="ct">异步取消令牌</param>
public static async Task (
string ipAddress, string ipAddress,
int port, int port,
byte slaveAddress, byte slaveAddress,
@@ -79,7 +111,19 @@ namespace DeviceCommand.Flexible
#region Coils #region Coils
public static async Task<bool[]> ReadCoilsAsync( /// <summary>
/// 读取线圈状态(功能码 01),返回指定数量的线圈开关状态数组。
/// </summary>
/// <param name="ipAddress">设备 IP 地址</param>
/// <param name="port">Modbus TCP 端口号,默认常用 502</param>
/// <param name="slaveAddress">Modbus 从站站号(单元标识符)</param>
/// <param name="startAddress">起始线圈地址</param>
/// <param name="numberOfPoints">读取的线圈数量</param>
/// <param name="sendTimeout">发送/连接超时时间(毫秒),默认 3000</param>
/// <param name="receiveTimeout">接收超时时间(毫秒),默认 3000</param>
/// <param name="ct">异步取消令牌</param>
/// <returns>线圈状态数组,true 表示吸合/导通</returns>
public static async Task<bool[]> 线(
string ipAddress, string ipAddress,
int port, int port,
byte slaveAddress, byte slaveAddress,
@@ -104,7 +148,18 @@ namespace DeviceCommand.Flexible
} }
} }
public static async Task WriteSingleCoilAsync( /// <summary>
/// 写入单个线圈(功能码 05),控制单个开关量输出。
/// </summary>
/// <param name="ipAddress">设备 IP 地址</param>
/// <param name="port">Modbus TCP 端口号,默认常用 502</param>
/// <param name="slaveAddress">Modbus 从站站号(单元标识符)</param>
/// <param name="coilAddress">要写入的线圈地址</param>
/// <param name="value">线圈状态(true: 吸合/导通, false: 断开)</param>
/// <param name="sendTimeout">发送/连接超时时间(毫秒),默认 3000</param>
/// <param name="receiveTimeout">接收超时时间(毫秒),默认 3000</param>
/// <param name="ct">异步取消令牌</param>
public static async Task 线(
string ipAddress, string ipAddress,
int port, int port,
byte slaveAddress, byte slaveAddress,
+38 -2
View File
@@ -7,11 +7,21 @@ using System.Threading.Tasks;
namespace DeviceCommand.Flexible namespace DeviceCommand.Flexible
{ {
/// <summary>
/// 灵活型串口通信类(免实例化,每次调用临时创建串口连接)。
/// 支持只发送指令、发送并读取应答两种最常用操作,
/// 内部使用通信锁保证同一时刻只有一个串口事务在执行,
/// 适用于偶发性、无需保持长连接的串口设备通信场景(如示波器、电源的 SCPI 指令)。
/// </summary>
[ADPCommand] [ADPCommand]
public static class FSerialPort public static class FSerialPort
{ {
// 通信锁:保证同一时刻只有一个串口事务在执行
private static readonly SemaphoreSlim _commLock = new(1, 1); private static readonly SemaphoreSlim _commLock = new(1, 1);
/// <summary>
/// 创建串口实例并配置 UTF8 编码与超时参数。
/// </summary>
private static SerialPort CreatePort(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits, int sendTimeout,int receiveTimeout) private static SerialPort CreatePort(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits, int sendTimeout,int receiveTimeout)
{ {
return new SerialPort(portName, baudRate, parity, dataBits, stopBits) return new SerialPort(portName, baudRate, parity, dataBits, stopBits)
@@ -24,7 +34,19 @@ namespace DeviceCommand.Flexible
#region #region
public static async Task SendAsync(string portName,int baudRate,Parity parity,int dataBits,StopBits stopBits,int sendTimeout,int receiveTimeout,string command,CancellationToken ct = default) /// <summary>
/// 向串口发送一条字符串指令(只发送,不等待应答)。
/// </summary>
/// <param name="portName">串口名称,如 "COM1"</param>
/// <param name="baudRate">波特率,如 9600、115200</param>
/// <param name="parity">校验位</param>
/// <param name="dataBits">数据位,常用 8</param>
/// <param name="stopBits">停止位</param>
/// <param name="sendTimeout">发送超时时间(毫秒)</param>
/// <param name="receiveTimeout">接收超时时间(毫秒)</param>
/// <param name="command">要发送的指令字符串</param>
/// <param name="ct">异步取消令牌</param>
public static async Task (string portName,int baudRate,Parity parity,int dataBits,StopBits stopBits,int sendTimeout,int receiveTimeout,string command,CancellationToken ct = default)
{ {
await _commLock.WaitAsync(ct); await _commLock.WaitAsync(ct);
try try
@@ -52,7 +74,21 @@ namespace DeviceCommand.Flexible
#region #region
public static async Task<string> SendReadAsync(string portName,int baudRate, Parity parity, int dataBits, StopBits stopBits,int sendTimeout, int receiveTimeout,string command,string delimiter = "\n", CancellationToken ct = default) /// <summary>
/// 向串口发送一条字符串指令并读取应答,读取到结束符为止(应答不含结束符)。
/// </summary>
/// <param name="portName">串口名称,如 "COM1"</param>
/// <param name="baudRate">波特率,如 9600、115200</param>
/// <param name="parity">校验位</param>
/// <param name="dataBits">数据位,常用 8</param>
/// <param name="stopBits">停止位</param>
/// <param name="sendTimeout">发送超时时间(毫秒)</param>
/// <param name="receiveTimeout">接收超时时间(毫秒),超时未收到结束符抛出超时异常</param>
/// <param name="command">要发送的指令字符串</param>
/// <param name="delimiter">应答结束符,默认换行符 "\n"</param>
/// <param name="ct">异步取消令牌</param>
/// <returns>去除结束符并去除首尾空白后的应答字符串</returns>
public static async Task<string> (string portName,int baudRate, Parity parity, int dataBits, StopBits stopBits,int sendTimeout, int receiveTimeout,string command,string delimiter = "\n", CancellationToken ct = default)
{ {
await _commLock.WaitAsync(ct); await _commLock.WaitAsync(ct);
try try
+46 -5
View File
@@ -4,14 +4,29 @@ using System.Text;
namespace DeviceCommand.Flexible namespace DeviceCommand.Flexible
{ {
/// <summary>
/// 灵活型 TCP 通信类(免实例化,每次调用临时建立 TCP 连接)。
/// 支持字节/文本发送、定长字节读取、按结束符读取文本行四种操作,
/// 内部使用通信锁保证同一时刻只有一个 TCP 事务在执行,
/// 适用于偶发性、无需保持长连接的 TCP 设备通信场景。
/// </summary>
[ADPCommand] [ADPCommand]
public static class FTCP public static class FTCP
{ {
// 通信锁:保证同一时刻只有一个 TCP 事务在执行
private static readonly SemaphoreSlim _commLock = new(1, 1); private static readonly SemaphoreSlim _commLock = new(1, 1);
#region Send #region Send
public static async Task SendAsync(string ipAddress,int port,int sendTimeout, byte[] buffer, CancellationToken ct = default) /// <summary>
/// 向指定 TCP 端点发送一段字节数据(发送完成后立即断开)。
/// </summary>
/// <param name="ipAddress">设备 IP 地址</param>
/// <param name="port">TCP 端口号</param>
/// <param name="sendTimeout">发送超时时间(毫秒)</param>
/// <param name="buffer">要发送的字节数组</param>
/// <param name="ct">异步取消令牌</param>
public static async Task (string ipAddress,int port,int sendTimeout, byte[] buffer, CancellationToken ct = default)
{ {
await _commLock.WaitAsync(ct); await _commLock.WaitAsync(ct);
try try
@@ -30,16 +45,33 @@ namespace DeviceCommand.Flexible
} }
} }
public static Task SendAsync(string ipAddress, int port,int sendTimeout, string text,CancellationToken ct = default) /// <summary>
/// 向指定 TCP 端点发送一段文本(以 UTF8 编码为字节后发送,发送完成后立即断开)。
/// </summary>
/// <param name="ipAddress">设备 IP 地址</param>
/// <param name="port">TCP 端口号</param>
/// <param name="sendTimeout">发送超时时间(毫秒)</param>
/// <param name="text">要发送的文本字符串</param>
/// <param name="ct">异步取消令牌</param>
public static Task (string ipAddress, int port,int sendTimeout, string text,CancellationToken ct = default)
{ {
return SendAsync( ipAddress, port, sendTimeout, Encoding.UTF8.GetBytes(text),ct); return ( ipAddress, port, sendTimeout, Encoding.UTF8.GetBytes(text),ct);
} }
#endregion #endregion
#region Read #region Read
public static async Task<byte[]> ReadAsync(string ipAddress,int port,int receiveTimeout,int length,CancellationToken ct = default) /// <summary>
/// 连接指定 TCP 端点并读取指定长度的字节数据(连接关闭或读满为止)。
/// </summary>
/// <param name="ipAddress">设备 IP 地址</param>
/// <param name="port">TCP 端口号</param>
/// <param name="receiveTimeout">接收超时时间(毫秒)</param>
/// <param name="length">要读取的字节长度</param>
/// <param name="ct">异步取消令牌</param>
/// <returns>实际读取到的字节数组(对端提前关闭时可能短于请求长度)</returns>
public static async Task<byte[]> (string ipAddress,int port,int receiveTimeout,int length,CancellationToken ct = default)
{ {
await _commLock.WaitAsync(ct); await _commLock.WaitAsync(ct);
try try
@@ -72,7 +104,16 @@ namespace DeviceCommand.Flexible
} }
} }
public static async Task<string> ReadLineAsync( string ipAddress, int port, int receiveTimeout, string delimiter = "\n",CancellationToken ct = default) /// <summary>
/// 连接指定 TCP 端点并读取一行文本,读取到结束符为止(返回内容不含结束符)。
/// </summary>
/// <param name="ipAddress">设备 IP 地址</param>
/// <param name="port">TCP 端口号</param>
/// <param name="receiveTimeout">接收超时时间(毫秒),超时未收到结束符抛出超时异常</param>
/// <param name="delimiter">文本行结束符,默认换行符 "\n"</param>
/// <param name="ct">异步取消令牌</param>
/// <returns>去除结束符并去除首尾空白后的文本行</returns>
public static async Task<string> ( string ipAddress, int port, int receiveTimeout, string delimiter = "\n",CancellationToken ct = default)
{ {
await _commLock.WaitAsync(ct); await _commLock.WaitAsync(ct);
try try
+126
View File
@@ -0,0 +1,126 @@
# EOL测试项文件清单
## 已分析可编写的测试项
根据EOL测试项目文档和现有设备能力,以下测试项可以编写:
### 输入侧保护测试(使用IT7800E交流电源)
1. **08_输入过压保护测试.ADP** - 已创建模板
- 保护点:270±3 Vrms
- 恢复点:260±3 Vrms
- 方法:以1V/s升高输入电压直至保护触发
2. **09_输入欠压保护测试.ADP**
- 保护点:170±3 Vrms
- 恢复点:180±3 Vrms
- 方法:以1V/s降低输入电压直至保护触发
3. **10_输入过流保护测试.ADP**
- 软件保护点:4.8 A
- 硬件保护点:5.2 A
- 方法:逐步增加负载直至过流保护
### 输出侧保护测试(使用N36600直流电源/N69200电子负载)
4. **21_输出过压保护测试.ADP**
- 软件保护点:78 V
- 硬件保护点:85 V
- 方法:以0.1V/s升高输出电压直至保护
5. **22_输出欠压保护测试.ADP**
- 保护点:40±2 Vdc
- 恢复点:45±2 Vdc
- 方法:以0.1V/s降低输出电压直至保护
6. **23_输出过流保护测试.ADP**
- 软件保护点:9 A
- 硬件保护点:10 A
- 方法:逐步增加负载电流直至保护
7. **24_输出短路保护测试.ADP**
- 方法:切换电子负载到Short模式
- 验证:系统停止输出并报警
8. **25_输出抛负载测试.ADP**
- 方法:切换电子负载到Off模式
- 验证:输出过充电压≤90 Vdc
## 无法编写的测试项(需要特殊设备)
以下测试项需要特殊仪器或人工观察,无法自动化:
- 01_系统状态灯显示 - 需要人工观察
- 02_急停保护 - 需要物理急停按钮操作
- 03_系统启动时间 - 需要示波器捕获波形
- 04_总谐波电流畸变 - 需要功率分析仪THD功能
- 11_输入启动冲击电流 - 需要示波器+电流探头
- 12_输入功率因数 - 需要功率分析仪
- 13_输入电压精度 - 需要功率分析仪对比
- 14_输入电流精度 - 需要功率分析仪对比
- 15_输入AC泄放时间 - 需要示波器监测
- 16_接收端待机功耗 - 需要功率分析仪
- 17_输出电流精度 - 需要功率分析仪对比
- 18_输出电压精度 - 需要功率分析仪对比
- 19_输出电流纹波 - 需要示波器+电流探头
- 20_输出电压纹波 - 需要示波器
- 26_线圈分离测试 - 需要台架物理移动
- 27_双通道异常测试 - 需要特殊CAN控制
- 28_整机效率 - 需要功率分析仪
- 29_表面温升测试 - 需要温度采集设备
- 30_绝缘电阻测试 - 需要绝缘电阻测试仪
- 31_耐压测试 - 需要耐压测试仪
## 测试项通用结构
每个测试项包含以下步骤:
1. **初始化阶段**
- 台架初始化相对移动(子程序)
- ADP产品开机(子程序)
2. **设备设置阶段**
- IT7800E:设置AC模式、电压、频率、开启输出
- N36600:设置辅助电压、开启输出
- N69200:设置负载模式(CV/CC)、设定值、开启
3. **CAN通信阶段**
- 打开设备
- 初始化并启动通道
- 加载DBC文件
- 发送开机报文
4. **测试执行阶段**
- 延时等待稳定
- 调节被测参数
- 查询记录保护点
- 延时等待恢复
5. **结束阶段**
- 发送清除故障报文
- 重新发送开机报文验证恢复
- ADP产品关机(子程序)
## 参数变量说明
| 变量名 | 说明 | 默认值 |
|--------|------|--------|
| 台架序号 | 测试台架编号 | 1 |
| CAN通道1 | CAN总线通道1 | 0 |
| CAN通道2 | CAN总线通道2 | 1 |
| DBC文件 | CAN数据库文件路径 | C:\Users\U3\Desktop\DBC文件\ADP\wpt_protocol_v2.24_260611.dbc |
| X位置 | 台架X轴位置 | 15000 |
| Y位置 | 台架Y轴位置 | 20000 |
| Z位置 | 台架Z轴位置 | 40000 |
| 开机报文 | CAN开机指令 | [0x01, 0x01, 0x20, 0x00, 0xBC, 0x02, 0xE8, 0x03] |
| 关机报文 | CAN关机指令 | [0x00, 0x01, 0x20, 0x00, 0xBC, 0x02, 0xE8, 0x03] |
| 清除故障报文 | CAN清除故障指令 | [0xEE, 0x02, 0xE8, 0x03, 0x58, 0x02, 0x00, 0x00] |
## 设备清单
| 设备 | 型号 | 用途 |
|------|------|------|
| 交流电源 | IT7800E | 模拟电网输入 |
| 高压直流电源 | N36600 | 辅助电源/输出模拟 |
| 电子负载 | N69200 | 模拟输出负载 |
| CAN分析仪 | ZLG USBCANFD | CAN通信 |
| 功率分析仪 | SPAW7000 | 功率测量(部分测试需要) |
| 示波器 | SDS2000X_HD | 波形测量(部分测试需要) |
+780
View File
@@ -0,0 +1,780 @@
# 生成EOL测试项文件
$outputDir = "D:\ADP\子程序\新测试项"
if (!(Test-Path $outputDir)) { New-Item -ItemType Directory -Path $outputDir -Force | Out-Null }
# 08_输入过压保护测试
$test08 = @'
{
"ID": "a8b3c5d2-1e4f-4a7b-9c8d-2f6e5a4b3c2d",
"StepCollection": [
{
"ID": "step_001",
"IsUsed": true,
"Index": 1,
"Name": "设置电源模式",
"StepType": "方法",
"Method": {
"Name": "设置电源模式",
"FullName": "DeviceCommand.Devices.IT7800E",
"Parameters": [
{
"ID": "p1",
"IsVisible": true,
"IsEditable": true,
"Name": "模式",
"Type": "DeviceCommand.Devices.PowerCouplingMode, DeviceCommand, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
"Category": 0,
"Value": 0,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
},
{
"ID": "p2",
"IsVisible": true,
"IsEditable": true,
"Name": "ct",
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": null,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
}
]
},
"SubProgram": null,
"LoopCount": null,
"LoopStartStepId": null,
"OKExpression": null,
"GotoSettingString": "",
"OKGotoStepID": "00000000-0000-0000-0000-000000000000",
"NGGotoStepID": "00000000-0000-0000-0000-000000000000",
"Description": "设置为AC模式"
},
{
"ID": "step_002",
"IsUsed": true,
"Index": 2,
"Name": "设置交流电压",
"StepType": "方法",
"Method": {
"Name": "设置交流电压",
"FullName": "DeviceCommand.Devices.IT7800E",
"Parameters": [
{
"ID": "p3",
"IsVisible": true,
"IsEditable": true,
"Name": "电压",
"Type": "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": "230",
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
},
{
"ID": "p4",
"IsVisible": true,
"IsEditable": true,
"Name": "ct",
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": null,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
}
]
},
"SubProgram": null,
"LoopCount": null,
"LoopStartStepId": null,
"OKExpression": null,
"GotoSettingString": "",
"OKGotoStepID": "00000000-0000-0000-0000-000000000000",
"NGGotoStepID": "00000000-0000-0000-0000-000000000000",
"Description": "设置初始电压230Vac"
},
{
"ID": "step_003",
"IsUsed": true,
"Index": 3,
"Name": "设置频率",
"StepType": "方法",
"Method": {
"Name": "设置频率",
"FullName": "DeviceCommand.Devices.IT7800E",
"Parameters": [
{
"ID": "p5",
"IsVisible": true,
"IsEditable": true,
"Name": "频率",
"Type": "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": "50",
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
},
{
"ID": "p6",
"IsVisible": true,
"IsEditable": true,
"Name": "ct",
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": null,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
}
]
},
"SubProgram": null,
"LoopCount": null,
"LoopStartStepId": null,
"OKExpression": null,
"GotoSettingString": "",
"OKGotoStepID": "00000000-0000-0000-0000-000000000000",
"NGGotoStepID": "00000000-0000-0000-0000-000000000000",
"Description": "设置频率50Hz"
},
{
"ID": "step_004",
"IsUsed": true,
"Index": 4,
"Name": "设置DC输出",
"StepType": "方法",
"Method": {
"Name": "设置DC输出",
"FullName": "DeviceCommand.Devices.IT7800E",
"Parameters": [
{
"ID": "p7",
"IsVisible": true,
"IsEditable": true,
"Name": "开启",
"Type": "System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": "true",
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
},
{
"ID": "p8",
"IsVisible": true,
"IsEditable": true,
"Name": "ct",
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": null,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
}
]
},
"SubProgram": null,
"LoopCount": null,
"LoopStartStepId": null,
"OKExpression": null,
"GotoSettingString": "",
"OKGotoStepID": "00000000-0000-0000-0000-000000000000",
"NGGotoStepID": "00000000-0000-0000-0000-000000000000",
"Description": "开启IT7800E输出"
},
{
"ID": "step_005",
"IsUsed": true,
"Index": 5,
"Name": "设置负载模式",
"StepType": "方法",
"Method": {
"Name": "设置负载模式",
"FullName": "DeviceCommand.Devices.N69200",
"Parameters": [
{
"ID": "p9",
"IsVisible": true,
"IsEditable": true,
"Name": "模式",
"Type": "DeviceCommand.Devices.N69200+DeviceWorkMode, DeviceCommand, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
"Category": 0,
"Value": 1,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
},
{
"ID": "p10",
"IsVisible": true,
"IsEditable": true,
"Name": "ct",
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": null,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
}
]
},
"SubProgram": null,
"LoopCount": null,
"LoopStartStepId": null,
"OKExpression": null,
"GotoSettingString": "",
"OKGotoStepID": "00000000-0000-0000-0000-000000000000",
"NGGotoStepID": "00000000-0000-0000-0000-000000000000",
"Description": "设置N69200为CV模式"
},
{
"ID": "step_006",
"IsUsed": true,
"Index": 6,
"Name": "设置恒电压CV",
"StepType": "方法",
"Method": {
"Name": "设置恒电压CV",
"FullName": "DeviceCommand.Devices.N69200",
"Parameters": [
{
"ID": "p11",
"IsVisible": true,
"IsEditable": true,
"Name": "电压",
"Type": "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": "50",
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
},
{
"ID": "p12",
"IsVisible": true,
"IsEditable": true,
"Name": "ct",
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": null,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
}
]
},
"SubProgram": null,
"LoopCount": null,
"LoopStartStepId": null,
"OKExpression": null,
"GotoSettingString": "",
"OKGotoStepID": "00000000-0000-0000-0000-000000000000",
"NGGotoStepID": "00000000-0000-0000-0000-000000000000",
"Description": "设置电子负载CV模式50V"
},
{
"ID": "step_007",
"IsUsed": true,
"Index": 7,
"Name": "设置DC输入",
"StepType": "方法",
"Method": {
"Name": "设置DC输入",
"FullName": "DeviceCommand.Devices.N69200",
"Parameters": [
{
"ID": "p13",
"IsVisible": true,
"IsEditable": true,
"Name": "开启",
"Type": "System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": "true",
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
},
{
"ID": "p14",
"IsVisible": true,
"IsEditable": true,
"Name": "ct",
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": null,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
}
]
},
"SubProgram": null,
"LoopCount": null,
"LoopStartStepId": null,
"OKExpression": null,
"GotoSettingString": "",
"OKGotoStepID": "00000000-0000-0000-0000-000000000000",
"NGGotoStepID": "00000000-0000-0000-0000-000000000000",
"Description": "开启电子负载"
},
{
"ID": "step_008",
"IsUsed": true,
"Index": 8,
"Name": "Delay_s",
"StepType": "方法",
"Method": {
"Name": "Delay_s",
"FullName": "Command.Delay",
"Parameters": [
{
"ID": "p15",
"IsVisible": true,
"IsEditable": true,
"Name": "second",
"Type": "System.Single, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": "30",
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
},
{
"ID": "p16",
"IsVisible": true,
"IsEditable": true,
"Name": "ct",
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": null,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
}
]
},
"SubProgram": null,
"LoopCount": null,
"LoopStartStepId": null,
"OKExpression": null,
"GotoSettingString": "",
"OKGotoStepID": "00000000-0000-0000-0000-000000000000",
"NGGotoStepID": "00000000-0000-0000-0000-000000000000",
"Description": "等待系统稳定运行"
},
{
"ID": "step_009",
"IsUsed": true,
"Index": 9,
"Name": "设置交流电压",
"StepType": "方法",
"Method": {
"Name": "设置交流电压",
"FullName": "DeviceCommand.Devices.IT7800E",
"Parameters": [
{
"ID": "p17",
"IsVisible": true,
"IsEditable": true,
"Name": "电压",
"Type": "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": "270",
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
},
{
"ID": "p18",
"IsVisible": true,
"IsEditable": true,
"Name": "ct",
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": null,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
}
]
},
"SubProgram": null,
"LoopCount": null,
"LoopStartStepId": null,
"OKExpression": null,
"GotoSettingString": "",
"OKGotoStepID": "00000000-0000-0000-0000-000000000000",
"NGGotoStepID": "00000000-0000-0000-0000-000000000000",
"Description": "以1V/s升高输入电压至过压保护点(270V)"
},
{
"ID": "step_010",
"IsUsed": true,
"Index": 10,
"Name": "Delay_s",
"StepType": "方法",
"Method": {
"Name": "Delay_s",
"FullName": "Command.Delay",
"Parameters": [
{
"ID": "p19",
"IsVisible": true,
"IsEditable": true,
"Name": "second",
"Type": "System.Single, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": "5",
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
},
{
"ID": "p20",
"IsVisible": true,
"IsEditable": true,
"Name": "ct",
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": null,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
}
]
},
"SubProgram": null,
"LoopCount": null,
"LoopStartStepId": null,
"OKExpression": null,
"GotoSettingString": "",
"OKGotoStepID": "00000000-0000-0000-0000-000000000000",
"NGGotoStepID": "00000000-0000-0000-0000-000000000000",
"Description": "等待保护触发,记录保护点"
},
{
"ID": "step_011",
"IsUsed": true,
"Index": 11,
"Name": "查询实际电压",
"StepType": "方法",
"Method": {
"Name": "查询实际电压",
"FullName": "DeviceCommand.Devices.IT7800E",
"Parameters": [
{
"ID": "p21",
"IsVisible": true,
"IsEditable": true,
"Name": "ct",
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": null,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
},
{
"ID": "p22",
"IsVisible": true,
"IsEditable": true,
"Name": "Result",
"Type": "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 1,
"Value": null,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
}
]
},
"SubProgram": null,
"LoopCount": null,
"LoopStartStepId": null,
"OKExpression": null,
"GotoSettingString": "",
"OKGotoStepID": null,
"NGGotoStepID": null,
"Description": "记录输入过压保护点"
},
{
"ID": "step_012",
"IsUsed": true,
"Index": 12,
"Name": "设置交流电压",
"StepType": "方法",
"Method": {
"Name": "设置交流电压",
"FullName": "DeviceCommand.Devices.IT7800E",
"Parameters": [
{
"ID": "p23",
"IsVisible": true,
"IsEditable": true,
"Name": "电压",
"Type": "System.Double, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": "255",
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
},
{
"ID": "p24",
"IsVisible": true,
"IsEditable": true,
"Name": "ct",
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": null,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
}
]
},
"SubProgram": null,
"LoopCount": null,
"LoopStartStepId": null,
"OKExpression": null,
"GotoSettingString": "",
"OKGotoStepID": "00000000-0000-0000-0000-000000000000",
"NGGotoStepID": "00000000-0000-0000-0000-000000000000",
"Description": "降低电压至恢复点以下(260V)"
},
{
"ID": "step_013",
"IsUsed": true,
"Index": 13,
"Name": "Delay_s",
"StepType": "方法",
"Method": {
"Name": "Delay_s",
"FullName": "Command.Delay",
"Parameters": [
{
"ID": "p25",
"IsVisible": true,
"IsEditable": true,
"Name": "second",
"Type": "System.Single, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": "5",
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
},
{
"ID": "p26",
"IsVisible": true,
"IsEditable": true,
"Name": "ct",
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": null,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
}
]
},
"SubProgram": null,
"LoopCount": null,
"LoopStartStepId": null,
"OKExpression": null,
"GotoSettingString": "",
"OKGotoStepID": "00000000-0000-0000-0000-000000000000",
"NGGotoStepID": "00000000-0000-0000-0000-000000000000",
"Description": "等待系统恢复"
},
{
"ID": "step_014",
"IsUsed": true,
"Index": 14,
"Name": "设置DC输出",
"StepType": "方法",
"Method": {
"Name": "设置DC输出",
"FullName": "DeviceCommand.Devices.IT7800E",
"Parameters": [
{
"ID": "p27",
"IsVisible": true,
"IsEditable": true,
"Name": "开启",
"Type": "System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": "false",
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
},
{
"ID": "p28",
"IsVisible": true,
"IsEditable": true,
"Name": "ct",
"Type": "System.Threading.CancellationToken, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": null,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
}
]
},
"SubProgram": null,
"LoopCount": null,
"LoopStartStepId": null,
"OKExpression": null,
"GotoSettingString": "",
"OKGotoStepID": "00000000-0000-0000-0000-000000000000",
"NGGotoStepID": "00000000-0000-0000-0000-000000000000",
"Description": "关闭IT7800E输出"
}
],
"ErrorStepCollection": [],
"Parameters": [
{
"ID": "var_bench_no",
"IsVisible": true,
"IsEditable": false,
"Name": "台架序号",
"Type": "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": 1,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
},
{
"ID": "var_can_ch1",
"IsVisible": true,
"IsEditable": false,
"Name": "CAN通道1",
"Type": "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": 0,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
},
{
"ID": "var_can_ch2",
"IsVisible": true,
"IsEditable": false,
"Name": "CAN通道2",
"Type": "System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
"Category": 0,
"Value": 1,
"LowerLimit": null,
"UpperLimit": null,
"Result": true,
"IsUseVar": false,
"VariableName": null,
"VariableID": null
}
]
}
'@
$test08 | Out-File -FilePath "$outputDir\08_输入过压保护测试.ADP" -Encoding UTF8
Write-Host "已生成: 08_输入过压保护测试.ADP"
Write-Host "`n测试项生成完成!"
Write-Host "输出目录: $outputDir"
+44 -8
View File
@@ -11,6 +11,11 @@ using System.Threading.Tasks;
namespace ZLGUSBCANFD namespace ZLGUSBCANFD
{ {
/// <summary>
/// 周立功 USBCANFD 系列 CAN 卡控制类(如 USBCANFD-400U),封装设备连接、通道初始化、
/// DBC 矩阵加载与解码、报文发送(单次/循环)、信号物理值设置等功能。
/// 每个通道拥有独立的 DBC 引擎句柄与细粒度锁,支持多台架并行互不干扰。
/// </summary>
[ADPCommand] [ADPCommand]
public class ZLGCANFD : IDisposable public class ZLGCANFD : IDisposable
{ {
@@ -62,6 +67,16 @@ namespace ZLGUSBCANFD
/// </summary> /// </summary>
public event Action<uint, uint, byte[], ulong, bool, byte>? OnRawMessageReceived; public event Action<uint, uint, byte[], ulong, bool, byte>? OnRawMessageReceived;
/// <summary>
/// 构造函数,配置设备类型、索引、通道数及所有通道共用的波特率与终端电阻参数,
/// 并初始化通道状态数组与 DBC 解析器。
/// </summary>
/// <param name="deviceType">设备类型,76 为 USBCANFD-400U</param>
/// <param name="deviceIndex">设备索引,多台同型号设备时区分,默认 0</param>
/// <param name="maxChannels">通道数量,默认 4</param>
/// <param name="abitBaud">仲裁域波特率,默认 "500000"</param>
/// <param name="dbitBaud">数据域波特率(仅 CANFD 生效),默认 "2000000"</param>
/// <param name="enableTerminalResistance">是否启用通道内部终端电阻,默认 true</param>
public ZLGCANFD(uint deviceType = 76, uint deviceIndex = 0, int maxChannels = 4, public ZLGCANFD(uint deviceType = 76, uint deviceIndex = 0, int maxChannels = 4,
string abitBaud = "500000", string dbitBaud = "2000000", bool enableTerminalResistance = true) string abitBaud = "500000", string dbitBaud = "2000000", bool enableTerminalResistance = true)
{ {
@@ -91,8 +106,9 @@ namespace ZLGUSBCANFD
#region 1. #region 1.
/// <summary> /// <summary>
/// 仅仅打开设备,不做具体的通道波特率配置(留给具体的台架去分别配置) /// 仅仅打开设备,不做具体的通道波特率配置(留给具体的台架去分别配置)
/// </summary> /// </summary>
/// <returns>是否打开成功;设备已打开时重复调用直接返回 true</returns>
public virtual bool () public virtual bool ()
{ {
if (_deviceHandle != IntPtr.Zero) return true; if (_deviceHandle != IntPtr.Zero) return true;
@@ -101,8 +117,12 @@ namespace ZLGUSBCANFD
} }
/// <summary> /// <summary>
/// 针对特定通道进行参数初始化并启动(使用构造时传入的波特率与终端电阻配置) /// 针对特定通道进行参数初始化并启动(使用构造时传入的波特率与终端电阻配置)
/// 同时为该通道启动专属的后台高性能接收轮询线程。
/// </summary> /// </summary>
/// <param name="通道号">通道索引 (0 起始)</param>
/// <returns>是否初始化并启动成功;通道已启动时重复调用直接返回 true</returns>
/// <exception cref="InvalidOperationException">未先调用“打开设备()”时抛出</exception>
public virtual bool (uint ) public virtual bool (uint )
{ {
_isClosing = false; // 重置关闭标志,允许循环发送 _isClosing = false; // 重置关闭标志,允许循环发送
@@ -157,6 +177,10 @@ namespace ZLGUSBCANFD
} }
} }
/// <summary>
/// 关闭 CAN 卡设备:先停止所有循环发送与接收轮询线程,再复位全部通道、
/// 释放各通道 DBC 资源,最后关闭设备主句柄。
/// </summary>
public virtual void CAN卡设备() public virtual void CAN卡设备()
{ {
_isClosing = true; // 通知循环发送任务尽快退出 _isClosing = true; // 通知循环发送任务尽快退出
@@ -218,8 +242,11 @@ namespace ZLGUSBCANFD
#region 2. DBC #region 2. DBC
/// <summary> /// <summary>
/// 指定通道加载特定的 DBC 文件(支持不同通道加载不同的DBC矩阵) /// 指定通道加载特定的 DBC 文件(支持不同通道加载不同的DBC矩阵)
/// </summary> /// </summary>
/// <param name="通道号">通道索引 (0 起始)</param>
/// <param name="dbcFilePath">DBC 矩阵文件的完整路径</param>
/// <returns>是否加载成功;该通道已加载过则直接返回 true</returns>
public virtual bool DBC文件(uint , string dbcFilePath) public virtual bool DBC文件(uint , string dbcFilePath)
{ {
if ( >= _maxChannels) return false; if ( >= _maxChannels) return false;
@@ -257,6 +284,10 @@ namespace ZLGUSBCANFD
} }
} }
/// <summary>
/// 释放指定通道已加载的 DBC 资源,并清空该通道的报文数据库。
/// </summary>
/// <param name="通道号">通道索引 (0 起始)</param>
public virtual void DBC(uint ) public virtual void DBC(uint )
{ {
if ( >= _maxChannels) return; if ( >= _maxChannels) return;
@@ -442,6 +473,8 @@ namespace ZLGUSBCANFD
/// <summary> /// <summary>
/// 停止指定通道、指定帧 ID 的循环发送。 /// 停止指定通道、指定帧 ID 的循环发送。
/// </summary> /// </summary>
/// <param name="通道号">通道索引 (0 起始)</param>
/// <param name="帧ID">要停止循环发送的报文帧 ID</param>
public virtual void (uint , uint ID) public virtual void (uint , uint ID)
{ {
if (_cyclicSenders.TryRemove((, ID), out var entry)) if (_cyclicSenders.TryRemove((, ID), out var entry))
@@ -452,7 +485,7 @@ namespace ZLGUSBCANFD
} }
/// <summary> /// <summary>
/// 停止所有 DBC 循环发送任务。 /// 停止所有 DBC 循环发送任务,并等待全部发送任务退出(最多 3 秒)
/// </summary> /// </summary>
public virtual void () public virtual void ()
{ {
@@ -486,6 +519,8 @@ namespace ZLGUSBCANFD
/// <summary> /// <summary>
/// 清除指定通道、指定帧 ID 的信号覆盖值,恢复为 DBC 初始值。 /// 清除指定通道、指定帧 ID 的信号覆盖值,恢复为 DBC 初始值。
/// </summary> /// </summary>
/// <param name="通道号">通道索引 (0 起始)</param>
/// <param name="帧ID">要清除覆盖值的报文帧 ID</param>
public virtual void (uint , uint ID) public virtual void (uint , uint ID)
{ {
if (_signalOverrides.TryRemove((, ID), out var dict)) if (_signalOverrides.TryRemove((, ID), out var dict))
@@ -495,8 +530,9 @@ namespace ZLGUSBCANFD
} }
/// <summary> /// <summary>
/// 清除指定通道所有帧的信号覆盖值。 /// 清除指定通道所有帧的信号覆盖值,全部恢复为 DBC 初始值
/// </summary> /// </summary>
/// <param name="通道号">通道索引 (0 起始)</param>
public virtual void (uint ) public virtual void (uint )
{ {
foreach (var key in _signalOverrides.Keys) foreach (var key in _signalOverrides.Keys)
@@ -635,6 +671,7 @@ namespace ZLGUSBCANFD
/// <param name="信号名称">DBC 中定义的英文信号名称(不区分大小写)</param> /// <param name="信号名称">DBC 中定义的英文信号名称(不区分大小写)</param>
/// <param name="物理值">要写入的实际物理数值</param> /// <param name="物理值">要写入的实际物理数值</param>
/// <param name="循环发送间隔毫秒">0 = 单次发送;>0 = 周期循环发送(单位毫秒)</param> /// <param name="循环发送间隔毫秒">0 = 单次发送;>0 = 周期循环发送(单位毫秒)</param>
/// <param name="直接发送">true = 设置后立即发送;false = 仅记录到持久化覆盖表,等后续 发送报文 时生效</param>
/// <returns>操作是否成功</returns> /// <returns>操作是否成功</returns>
public virtual bool (uint , string IDStr, string , double , int = 0, bool = false) public virtual bool (uint , string IDStr, string , double , int = 0, bool = false)
{ {
@@ -670,6 +707,7 @@ namespace ZLGUSBCANFD
/// <param name="帧IDStr">DBC 中定义的帧 ID(可以是 "26"、"0x1A"、"1A"</param> /// <param name="帧IDStr">DBC 中定义的帧 ID(可以是 "26"、"0x1A"、"1A"</param>
/// <param name="循环发送间隔毫秒">0 = 单次发送;>0 = 周期循环发送(毫秒)</param> /// <param name="循环发送间隔毫秒">0 = 单次发送;>0 = 周期循环发送(毫秒)</param>
/// <param name="是否使用CANFD">1 = 以 CANFD 格式发送;0 = 经典 CAN 格式</param> /// <param name="是否使用CANFD">1 = 以 CANFD 格式发送;0 = 经典 CAN 格式</param>
/// <returns>是否成功启动/发送</returns>
public virtual bool (uint , string IDStr, int = 0, int 使CANFD = 1) public virtual bool (uint , string IDStr, int = 0, int 使CANFD = 1)
{ {
if (!TryParseFrameId(IDStr, out uint ID)) if (!TryParseFrameId(IDStr, out uint ID))
@@ -698,6 +736,7 @@ namespace ZLGUSBCANFD
/// <param name="是否是CANFD">true = CANFDfalse = 经典 CAN</param> /// <param name="是否是CANFD">true = CANFDfalse = 经典 CAN</param>
/// <param name="开启波特率加速BRS">CANFD 是否开启波特率加速</param> /// <param name="开启波特率加速BRS">CANFD 是否开启波特率加速</param>
/// <param name="循环发送间隔毫秒">0 = 单次发送;>0 = 周期循环发送(毫秒)</param> /// <param name="循环发送间隔毫秒">0 = 单次发送;>0 = 周期循环发送(毫秒)</param>
/// <returns>是否成功启动/发送</returns>
public virtual bool ( public virtual bool (
uint , uint ,
string IDStr, string IDStr,
@@ -986,9 +1025,6 @@ namespace ZLGUSBCANFD
#region 5. #region 5.
/// <summary>
/// 计算物理值也需要传入对应通道,使用通道专属的DBC句柄进行计算
/// </summary>
/// <summary> /// <summary>
/// 智能解析帧 ID 字符串,兼容 10 进制、16 进制(如 "0x1A", "1A", "26" /// 智能解析帧 ID 字符串,兼容 10 进制、16 进制(如 "0x1A", "1A", "26"
/// </summary> /// </summary>
+1
View File
@@ -4,6 +4,7 @@
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>