现场优化2
This commit is contained in:
@@ -221,8 +221,8 @@ namespace BenchMovementModule.ViewModels
|
||||
if (!EnsureConnected()) return;
|
||||
try
|
||||
{
|
||||
await _gantry!.SetAxisTargetPositionAsync(1, TargetX);
|
||||
await _gantry.StartSingleAxisAsync(1);
|
||||
await _gantry!.设置轴目标位置(1, TargetX);
|
||||
await _gantry.启动单轴(1);
|
||||
LoggerHelper.Info($"[BenchMovement] X轴移动到 {TargetX}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -237,8 +237,8 @@ namespace BenchMovementModule.ViewModels
|
||||
if (!EnsureConnected()) return;
|
||||
try
|
||||
{
|
||||
await _gantry!.SetAxisTargetPositionAsync(2, TargetY);
|
||||
await _gantry.StartSingleAxisAsync(2);
|
||||
await _gantry!.设置轴目标位置(2, TargetY);
|
||||
await _gantry.启动单轴(2);
|
||||
LoggerHelper.Info($"[BenchMovement] Y轴移动到 {TargetY}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -253,8 +253,8 @@ namespace BenchMovementModule.ViewModels
|
||||
if (!EnsureConnected()) return;
|
||||
try
|
||||
{
|
||||
await _gantry!.SetAxisTargetPositionAsync(3, TargetZ);
|
||||
await _gantry.StartSingleAxisAsync(3);
|
||||
await _gantry!.设置轴目标位置(3, TargetZ);
|
||||
await _gantry.启动单轴(3);
|
||||
LoggerHelper.Info($"[BenchMovement] Z轴移动到 {TargetZ}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -269,10 +269,10 @@ namespace BenchMovementModule.ViewModels
|
||||
if (!EnsureConnected()) return;
|
||||
try
|
||||
{
|
||||
await _gantry!.SetAxisTargetPositionAsync(1, TargetX);
|
||||
await _gantry.SetAxisTargetPositionAsync(2, TargetY);
|
||||
await _gantry.SetAxisTargetPositionAsync(3, TargetZ);
|
||||
await _gantry.StartAllAxesAsync();
|
||||
await _gantry!.设置轴目标位置(1, TargetX);
|
||||
await _gantry.设置轴目标位置(2, TargetY);
|
||||
await _gantry.设置轴目标位置(3, TargetZ);
|
||||
await _gantry.启动全部轴();
|
||||
LoggerHelper.Info($"[BenchMovement] 三轴同时移动: X={TargetX}, Y={TargetY}, Z={TargetZ}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -287,7 +287,7 @@ namespace BenchMovementModule.ViewModels
|
||||
if (!EnsureConnected()) return;
|
||||
try
|
||||
{
|
||||
await _gantry!.HomeAsync();
|
||||
await _gantry!.回零();
|
||||
LoggerHelper.Info("[BenchMovement] 回原点已触发");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -302,7 +302,7 @@ namespace BenchMovementModule.ViewModels
|
||||
if (!EnsureConnected()) return;
|
||||
try
|
||||
{
|
||||
await _gantry!.SetEStopStateAsync(true);
|
||||
await _gantry!.设置急停状态(true);
|
||||
LoggerHelper.Info("[BenchMovement] 急停已触发");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -316,9 +316,9 @@ namespace BenchMovementModule.ViewModels
|
||||
if (!EnsureConnected()) return;
|
||||
try
|
||||
{
|
||||
await _gantry!.SetStopStateAsync(1, true);
|
||||
await _gantry!.设置轴停止状态(1, true);
|
||||
await Task.Delay(100);
|
||||
await _gantry.SetStopStateAsync(1, false);
|
||||
await _gantry.设置轴停止状态(1, false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -331,9 +331,9 @@ namespace BenchMovementModule.ViewModels
|
||||
if (!EnsureConnected()) return;
|
||||
try
|
||||
{
|
||||
await _gantry!.SetStopStateAsync(2, true);
|
||||
await _gantry!.设置轴停止状态(2, true);
|
||||
await Task.Delay(100);
|
||||
await _gantry.SetStopStateAsync(2, false);
|
||||
await _gantry.设置轴停止状态(2, false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -346,9 +346,9 @@ namespace BenchMovementModule.ViewModels
|
||||
if (!EnsureConnected()) return;
|
||||
try
|
||||
{
|
||||
await _gantry!.SetStopStateAsync(3, true);
|
||||
await _gantry!.设置轴停止状态(3, true);
|
||||
await Task.Delay(100);
|
||||
await _gantry.SetStopStateAsync(3, false);
|
||||
await _gantry.设置轴停止状态(3, false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -361,10 +361,10 @@ namespace BenchMovementModule.ViewModels
|
||||
if (!EnsureConnected()) return;
|
||||
try
|
||||
{
|
||||
await _gantry!.SetAxisSpeedAsync(1, SpeedX);
|
||||
await _gantry.SetAxisSpeedAsync(2, SpeedY);
|
||||
await _gantry.SetAxisSpeedAsync(3, SpeedZ);
|
||||
await _gantry.SetHomePositionSpeedAsync(HomeSpeed);
|
||||
await _gantry!.设置轴速度(1, SpeedX);
|
||||
await _gantry.设置轴速度(2, SpeedY);
|
||||
await _gantry.设置轴速度(3, SpeedZ);
|
||||
await _gantry.设置回零速度(HomeSpeed);
|
||||
LoggerHelper.Info($"[BenchMovement] 速度设定完成: X={SpeedX}, Y={SpeedY}, Z={SpeedZ}, 回零={HomeSpeed}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -379,7 +379,7 @@ namespace BenchMovementModule.ViewModels
|
||||
if (!EnsureConnected()) return;
|
||||
try
|
||||
{
|
||||
await _gantry!.SetHomePositionAsync(HomeX, HomeY, HomeZ);
|
||||
await _gantry!.设置原点位置(HomeX, HomeY, HomeZ);
|
||||
LoggerHelper.Info($"[BenchMovement] 零点设定完成: X={HomeX}, Y={HomeY}, Z={HomeZ}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -419,16 +419,16 @@ namespace BenchMovementModule.ViewModels
|
||||
if (_gantry == null || !_gantry.IsConnected) return;
|
||||
try
|
||||
{
|
||||
var (x, y, z) = await _gantry.GetHomePositionAsync();
|
||||
var (x, y, z) = await _gantry.查询原点位置();
|
||||
HomeX = x; HomeY = y; HomeZ = z;
|
||||
|
||||
SpeedX = await _gantry.GetAxisSpeedAsync(1);
|
||||
SpeedY = await _gantry.GetAxisSpeedAsync(2);
|
||||
SpeedZ = await _gantry.GetAxisSpeedAsync(3);
|
||||
HomeSpeed = await _gantry.GetHomePositionSpeedAsync();
|
||||
SpeedX = await _gantry.查询轴速度(1);
|
||||
SpeedY = await _gantry.查询轴速度(2);
|
||||
SpeedZ = await _gantry.查询轴速度(3);
|
||||
HomeSpeed = await _gantry.查询回零速度();
|
||||
|
||||
// 读取 6 轴绝对位置
|
||||
var positions = await _gantry.GetAllAbsolutePositionsAsync();
|
||||
var positions = await _gantry.查询全部轴绝对位置();
|
||||
AbsPos1 = positions.Axis1; AbsPos2 = positions.Axis2; AbsPos3 = positions.Axis3;
|
||||
AbsPos4 = positions.Axis4; AbsPos5 = positions.Axis5; AbsPos6 = positions.Axis6;
|
||||
}
|
||||
@@ -444,7 +444,7 @@ namespace BenchMovementModule.ViewModels
|
||||
try
|
||||
{
|
||||
// 批量读取 6 轴绝对位置(一次性通信,高效)
|
||||
var pos = await _gantry.GetAllAbsolutePositionsAsync();
|
||||
var pos = await _gantry.查询全部轴绝对位置();
|
||||
AbsPos1 = pos.Axis1; AbsPos2 = pos.Axis2; AbsPos3 = pos.Axis3;
|
||||
AbsPos4 = pos.Axis4; AbsPos5 = pos.Axis5; AbsPos6 = pos.Axis6;
|
||||
}
|
||||
|
||||
@@ -347,6 +347,7 @@ namespace CANModule.ViewModels
|
||||
DeleteDcAutoLoadCommand = new DelegateCommand(DeleteDcAutoLoad);
|
||||
SendCustomMessageCommand = new DelegateCommand(SendCustomMessage);
|
||||
_canfd.OnDbcMessageDecoded += OnDbcMessageDecoded;
|
||||
_canfd.OnRawMessageReceived += OnRawMessageReceived;
|
||||
LoadCommand = new DelegateCommand(Load);
|
||||
}
|
||||
|
||||
@@ -368,6 +369,7 @@ namespace CANModule.ViewModels
|
||||
if (_canfd != null)
|
||||
{
|
||||
_canfd.OnDbcMessageDecoded -= OnDbcMessageDecoded;
|
||||
_canfd.OnRawMessageReceived -= OnRawMessageReceived;
|
||||
}
|
||||
_refreshCts?.Cancel();
|
||||
}
|
||||
@@ -627,6 +629,32 @@ namespace CANModule.ViewModels
|
||||
});
|
||||
}
|
||||
|
||||
private void OnRawMessageReceived(uint channel, uint canId, byte[] data, ulong timestamp, bool isFD, byte dlcLength)
|
||||
{
|
||||
// 原始报文回调:不依赖 DBC,自定义报文也能收到
|
||||
Application.Current.Dispatcher.BeginInvoke(() =>
|
||||
{
|
||||
// 提取实际 CAN ID(去掉扩展帧标志位)
|
||||
int actualId = (int)(canId & 0x1FFFFFFF);
|
||||
var find = CanMessageList.FirstOrDefault(s => s.报文ID == actualId && s.通道 == channel);
|
||||
if (find != null)
|
||||
{
|
||||
find.时间戳 = (ulong)DateTimeOffset.Now.ToUnixTimeMilliseconds();
|
||||
find.长度 = dlcLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
CanMessageList.Add(new CanMessageShowVM
|
||||
{
|
||||
通道 = (byte)channel,
|
||||
报文ID = actualId,
|
||||
时间戳 = (ulong)DateTimeOffset.Now.ToUnixTimeMilliseconds(),
|
||||
长度 = dlcLength
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private string 十六进制字符串转换(System.Span<byte> s)
|
||||
{
|
||||
if (s == null || s.Length == 0)
|
||||
|
||||
@@ -84,12 +84,12 @@ namespace DeviceCommand.Devices
|
||||
/// <summary>
|
||||
/// 轴使能控制
|
||||
/// </summary>
|
||||
/// <param name="axis">轴编号 (1 - 6)</param>
|
||||
/// <param name="enable">true: 使能轴, false: 禁用轴</param>
|
||||
/// <param name="ct">取消令牌</param>
|
||||
public async Task SetAxisEnableAsync(int axis, bool enable, CancellationToken ct = default)
|
||||
/// <param name="轴编号">轴编号 (1 - 6)</param>
|
||||
/// <param name="使能">true: 使能轴, false: 禁用轴</param>
|
||||
/// <param name="取消令牌">取消令牌</param>
|
||||
public async Task 设置轴使能(int 轴编号, bool 使能, CancellationToken 取消令牌 = default)
|
||||
{
|
||||
ushort address = axis switch
|
||||
ushort address = 轴编号 switch
|
||||
{
|
||||
1 => ADDR_HM_AXIS1_ENABLE,
|
||||
2 => ADDR_HM_AXIS2_ENABLE,
|
||||
@@ -97,64 +97,64 @@ namespace DeviceCommand.Devices
|
||||
4 => ADDR_HM_AXIS4_ENABLE,
|
||||
5 => ADDR_HM_AXIS5_ENABLE,
|
||||
6 => ADDR_HM_AXIS6_ENABLE,
|
||||
_ => throw new ArgumentException("轴通道错误,仅支持 1 - 6", nameof(axis))
|
||||
_ => throw new ArgumentException("轴通道错误,仅支持 1 - 6", nameof(轴编号))
|
||||
};
|
||||
|
||||
await WriteSingleCoilAsync(_slaveAddress, address, enable, ct);
|
||||
await WriteSingleCoilAsync(_slaveAddress, address, 使能, 取消令牌);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取指定轴的使能状态
|
||||
/// </summary>
|
||||
/// <param name="axis">1: X轴, 2: Y轴, 3: Z轴</param>
|
||||
/// <param name="ct">取消令牌</param>
|
||||
/// <param name="轴编号">1: X轴, 2: Y轴, 3: Z轴</param>
|
||||
/// <param name="取消令牌">取消令牌</param>
|
||||
/// <returns>true: 已使能, false: 未使能</returns>
|
||||
public async Task<bool> GetAxisEnableAsync(int axis, CancellationToken ct = default)
|
||||
public async Task<bool> 查询轴使能(int 轴编号, CancellationToken 取消令牌 = default)
|
||||
{
|
||||
ushort address = axis switch
|
||||
ushort address = 轴编号 switch
|
||||
{
|
||||
1 => ADDR_HM_AXIS1_ENABLE,
|
||||
2 => ADDR_HM_AXIS2_ENABLE,
|
||||
3 => ADDR_HM_AXIS3_ENABLE,
|
||||
_ => throw new ArgumentException("轴通道错误,仅支持 1(X), 2(Y), 3(Z)", nameof(axis))
|
||||
_ => throw new ArgumentException("轴通道错误,仅支持 1(X), 2(Y), 3(Z)", nameof(轴编号))
|
||||
};
|
||||
|
||||
bool[] coils = await ReadCoilsAsync(_slaveAddress, address, 1, ct);
|
||||
bool[] coils = await ReadCoilsAsync(_slaveAddress, address, 1, 取消令牌);
|
||||
return coils != null && coils.Length > 0 && coils[0];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同时设置 X/Y/Z 轴的原点位置(带各自独立的范围检查)
|
||||
/// </summary>
|
||||
/// <param name="xPos">X轴原点位置 (范围: 0 ~ 50000)</param>
|
||||
/// <param name="yPos">Y轴原点位置 (范围: 0 ~ 50000)</param>
|
||||
/// <param name="zPos">Z轴原点位置 (范围: 0 ~ 20000)</param>
|
||||
/// <param name="ct">取消令牌</param>
|
||||
public async Task SetHomePositionAsync(int xPos, int yPos, int zPos, CancellationToken ct = default)
|
||||
/// <param name="X轴原点">X轴原点位置 (范围: 0 ~ 50000)</param>
|
||||
/// <param name="Y轴原点">Y轴原点位置 (范围: 0 ~ 50000)</param>
|
||||
/// <param name="Z轴原点">Z轴原点位置 (范围: 0 ~ 20000)</param>
|
||||
/// <param name="取消令牌">取消令牌</param>
|
||||
public async Task 设置原点位置(int X轴原点, int Y轴原点, int Z轴原点, CancellationToken 取消令牌 = default)
|
||||
{
|
||||
if (xPos < 0 || xPos > 50000)
|
||||
throw new ArgumentOutOfRangeException(nameof(xPos), $"X轴原点设置值 [{xPos}] 超出合法范围 (0 - 50000)");
|
||||
if (X轴原点 < 0 || X轴原点 > 50000)
|
||||
throw new ArgumentOutOfRangeException(nameof(X轴原点), $"X轴原点设置值 [{X轴原点}] 超出合法范围 (0 - 50000)");
|
||||
|
||||
if (yPos < 0 || yPos > 50000)
|
||||
throw new ArgumentOutOfRangeException(nameof(yPos), $"Y轴原点设置值 [{yPos}] 超出合法范围 (0 - 50000)");
|
||||
if (Y轴原点 < 0 || Y轴原点 > 50000)
|
||||
throw new ArgumentOutOfRangeException(nameof(Y轴原点), $"Y轴原点设置值 [{Y轴原点}] 超出合法范围 (0 - 50000)");
|
||||
|
||||
if (zPos < 0 || zPos > 20000)
|
||||
throw new ArgumentOutOfRangeException(nameof(zPos), $"Z轴原点设置值 [{zPos}] 超出合法范围 (0 - 20000)");
|
||||
if (Z轴原点 < 0 || Z轴原点 > 20000)
|
||||
throw new ArgumentOutOfRangeException(nameof(Z轴原点), $"Z轴原点设置值 [{Z轴原点}] 超出合法范围 (0 - 20000)");
|
||||
|
||||
await WriteMultipleRegistersAsync(_slaveAddress, ADDR_HD_X_HOME_POS, Int32ToUshorts(xPos), ct);
|
||||
await WriteMultipleRegistersAsync(_slaveAddress, ADDR_HD_Y_HOME_POS, Int32ToUshorts(yPos), ct);
|
||||
await WriteMultipleRegistersAsync(_slaveAddress, ADDR_HD_Z_HOME_POS, Int32ToUshorts(zPos), ct);
|
||||
await WriteMultipleRegistersAsync(_slaveAddress, ADDR_HD_X_HOME_POS, Int32ToUshorts(X轴原点), 取消令牌);
|
||||
await WriteMultipleRegistersAsync(_slaveAddress, ADDR_HD_Y_HOME_POS, Int32ToUshorts(Y轴原点), 取消令牌);
|
||||
await WriteMultipleRegistersAsync(_slaveAddress, ADDR_HD_Z_HOME_POS, Int32ToUshorts(Z轴原点), 取消令牌);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量查询当前 X、Y、Z 三轴设定的原点位置值
|
||||
/// </summary>
|
||||
/// <param name="ct">取消令牌</param>
|
||||
/// <param name="取消令牌">取消令牌</param>
|
||||
/// <returns>返回包含三轴原点位置的元组 (X, Y, Z)</returns>
|
||||
public async Task<(int X, int Y, int Z)> GetHomePositionAsync(CancellationToken ct = default)
|
||||
public async Task<(int X, int Y, int Z)> 查询原点位置(CancellationToken 取消令牌 = default)
|
||||
{
|
||||
// 41218(Y) - 41198(X) = 20,加Y轴自身的 2 个寄存器,共批量读取 22 个连续寄存器
|
||||
ushort[] registers = await ReadHoldingRegistersAsync(_slaveAddress, ADDR_HD_X_HOME_POS, 22, ct);
|
||||
ushort[] registers = await ReadHoldingRegistersAsync(_slaveAddress, ADDR_HD_X_HOME_POS, 22, 取消令牌);
|
||||
|
||||
if (registers == null || registers.Length < 22)
|
||||
throw new InvalidOperationException("从 PLC 读取三轴原点位置失败,返回数据长度不足。");
|
||||
@@ -169,24 +169,24 @@ namespace DeviceCommand.Devices
|
||||
/// <summary>
|
||||
/// 设置回原点定位速度(带 0 - 100000 范围检查)
|
||||
/// </summary>
|
||||
/// <param name="speed">回原点定位速度 (范围: 0 - 100000)</param>
|
||||
/// <param name="ct">取消令牌</param>
|
||||
public async Task SetHomePositionSpeedAsync(int speed, CancellationToken ct = default)
|
||||
/// <param name="速度">回原点定位速度 (范围: 0 - 100000)</param>
|
||||
/// <param name="取消令牌">取消令牌</param>
|
||||
public async Task 设置回零速度(int 速度, CancellationToken 取消令牌 = default)
|
||||
{
|
||||
if (speed < 0 || speed > 100000)
|
||||
throw new ArgumentOutOfRangeException(nameof(speed), $"回原点定位速度值 [{speed}] 超出合法范围 (0 - 100000)");
|
||||
if (速度 < 0 || 速度 > 100000)
|
||||
throw new ArgumentOutOfRangeException(nameof(速度), $"回原点定位速度值 [{速度}] 超出合法范围 (0 - 100000)");
|
||||
|
||||
await WriteMultipleRegistersAsync(_slaveAddress, ADDR_HD_HOME_POS_SPEED, Int32ToUshorts(speed), ct);
|
||||
await WriteMultipleRegistersAsync(_slaveAddress, ADDR_HD_HOME_POS_SPEED, Int32ToUshorts(速度), 取消令牌);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询当前设定的回原点定位速度
|
||||
/// </summary>
|
||||
/// <param name="ct">取消令牌</param>
|
||||
/// <param name="取消令牌">取消令牌</param>
|
||||
/// <returns>当前回原点定位速度值</returns>
|
||||
public async Task<int> GetHomePositionSpeedAsync(CancellationToken ct = default)
|
||||
public async Task<int> 查询回零速度(CancellationToken 取消令牌 = default)
|
||||
{
|
||||
ushort[] registers = await ReadHoldingRegistersAsync(_slaveAddress, ADDR_HD_HOME_POS_SPEED, 2, ct);
|
||||
ushort[] registers = await ReadHoldingRegistersAsync(_slaveAddress, ADDR_HD_HOME_POS_SPEED, 2, 取消令牌);
|
||||
|
||||
if (registers == null || registers.Length < 2)
|
||||
throw new InvalidOperationException("从 PLC 读取回原点定位速度失败,返回数据长度不足。");
|
||||
@@ -197,44 +197,44 @@ namespace DeviceCommand.Devices
|
||||
/// <summary>
|
||||
/// 设置指定轴的运行速度(带 0 - 100000 范围检查)
|
||||
/// </summary>
|
||||
/// <param name="axis">1: X轴, 2: Y轴, 3: Z轴</param>
|
||||
/// <param name="speed">运行速度 (范围: 0 - 100000)</param>
|
||||
/// <param name="ct">取消令牌</param>
|
||||
public async Task SetAxisSpeedAsync(int axis, int speed, CancellationToken ct = default)
|
||||
/// <param name="轴编号">1: X轴, 2: Y轴, 3: Z轴</param>
|
||||
/// <param name="速度">运行速度 (范围: 0 - 100000)</param>
|
||||
/// <param name="取消令牌">取消令牌</param>
|
||||
public async Task 设置轴速度(int 轴编号, int 速度, CancellationToken 取消令牌 = default)
|
||||
{
|
||||
if (speed < 0 || speed > 100000)
|
||||
throw new ArgumentOutOfRangeException(nameof(speed), $"轴速度设置值 [{speed}] 超出合法范围 (0 - 100000)");
|
||||
if (速度 < 0 || 速度 > 100000)
|
||||
throw new ArgumentOutOfRangeException(nameof(速度), $"轴速度设置值 [{速度}] 超出合法范围 (0 - 100000)");
|
||||
|
||||
ushort address = axis switch
|
||||
ushort address = 轴编号 switch
|
||||
{
|
||||
1 => ADDR_HD_X_SPEED,
|
||||
2 => ADDR_HD_Y_SPEED,
|
||||
3 => ADDR_HD_Z_SPEED,
|
||||
_ => throw new ArgumentException("轴通道错误,仅支持 1(X), 2(Y), 3(Z)", nameof(axis))
|
||||
_ => throw new ArgumentException("轴通道错误,仅支持 1(X), 2(Y), 3(Z)", nameof(轴编号))
|
||||
};
|
||||
|
||||
await WriteMultipleRegistersAsync(_slaveAddress, address, Int32ToUshorts(speed), ct);
|
||||
await WriteMultipleRegistersAsync(_slaveAddress, address, Int32ToUshorts(速度), 取消令牌);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取指定轴当前设定的运行速度
|
||||
/// </summary>
|
||||
/// <param name="axis">1: X轴, 2: Y轴, 3: Z轴</param>
|
||||
/// <param name="ct">取消令牌</param>
|
||||
/// <param name="轴编号">1: X轴, 2: Y轴, 3: Z轴</param>
|
||||
/// <param name="取消令牌">取消令牌</param>
|
||||
/// <returns>当前设定的运行速度值</returns>
|
||||
public async Task<int> GetAxisSpeedAsync(int axis, CancellationToken ct = default)
|
||||
public async Task<int> 查询轴速度(int 轴编号, CancellationToken 取消令牌 = default)
|
||||
{
|
||||
ushort address = axis switch
|
||||
ushort address = 轴编号 switch
|
||||
{
|
||||
1 => ADDR_HD_X_SPEED,
|
||||
2 => ADDR_HD_Y_SPEED,
|
||||
3 => ADDR_HD_Z_SPEED,
|
||||
_ => throw new ArgumentException("轴通道错误,仅支持 1(X), 2(Y), 3(Z)", nameof(axis))
|
||||
_ => throw new ArgumentException("轴通道错误,仅支持 1(X), 2(Y), 3(Z)", nameof(轴编号))
|
||||
};
|
||||
|
||||
ushort[] registers = await ReadHoldingRegistersAsync(_slaveAddress, address, 2, ct);
|
||||
ushort[] registers = await ReadHoldingRegistersAsync(_slaveAddress, address, 2, 取消令牌);
|
||||
if (registers == null || registers.Length < 2)
|
||||
throw new InvalidOperationException($"从 PLC 读取轴 {axis} 速度失败。");
|
||||
throw new InvalidOperationException($"从 PLC 读取轴 {轴编号} 速度失败。");
|
||||
|
||||
return UshortsToInt32(registers);
|
||||
}
|
||||
@@ -242,18 +242,18 @@ namespace DeviceCommand.Devices
|
||||
/// <summary>
|
||||
/// 写入指定轴的目标位置(动态安全校验:目标位置不能超过 [轴最大物理极限 - 当前轴原点设置值])
|
||||
/// </summary>
|
||||
/// <param name="axis">1: X轴, 2: Y轴, 3: Z轴</param>
|
||||
/// <param name="targetPos">目标位置</param>
|
||||
/// <param name="ct">取消令牌</param>
|
||||
public async Task SetAxisTargetPositionAsync(int axis, int targetPos, CancellationToken ct = default)
|
||||
/// <param name="轴编号">1: X轴, 2: Y轴, 3: Z轴</param>
|
||||
/// <param name="目标位置">目标位置</param>
|
||||
/// <param name="取消令牌">取消令牌</param>
|
||||
public async Task 设置轴目标位置(int 轴编号, int 目标位置, CancellationToken 取消令牌 = default)
|
||||
{
|
||||
var (xHome, yHome, zHome) = await GetHomePositionAsync(ct);
|
||||
var (xHome, yHome, zHome) = await 查询原点位置(取消令牌);
|
||||
|
||||
ushort targetAddress;
|
||||
int maxLimit;
|
||||
int currentHomePos;
|
||||
|
||||
switch (axis)
|
||||
switch (轴编号)
|
||||
{
|
||||
case 1:
|
||||
targetAddress = ADDR_HD_X_TARGET;
|
||||
@@ -271,42 +271,42 @@ namespace DeviceCommand.Devices
|
||||
currentHomePos = zHome;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("轴通道错误,仅支持 1(X), 2(Y), 3(Z)", nameof(axis));
|
||||
throw new ArgumentException("轴通道错误,仅支持 1(X), 2(Y), 3(Z)", nameof(轴编号));
|
||||
}
|
||||
|
||||
int allowedMaxLimit = maxLimit - currentHomePos;
|
||||
|
||||
if (targetPos < 0 || targetPos > allowedMaxLimit)
|
||||
if (目标位置 < 0 || 目标位置 > allowedMaxLimit)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(
|
||||
nameof(targetPos),
|
||||
$"轴 {axis} 目标位置 [{targetPos}] 不合法!当前原点为 [{currentHomePos}],允许的有效写入范围为: 0 - {allowedMaxLimit}"
|
||||
nameof(目标位置),
|
||||
$"轴 {轴编号} 目标位置 [{目标位置}] 不合法!当前原点为 [{currentHomePos}],允许的有效写入范围为: 0 - {allowedMaxLimit}"
|
||||
);
|
||||
}
|
||||
|
||||
await WriteMultipleRegistersAsync(_slaveAddress, targetAddress, Int32ToUshorts(targetPos), ct);
|
||||
await WriteMultipleRegistersAsync(_slaveAddress, targetAddress, Int32ToUshorts(目标位置), 取消令牌);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取指定轴当前设定的目标指定位置
|
||||
/// </summary>
|
||||
/// <param name="axis">1: X轴, 2: Y轴, 3: Z轴</param>
|
||||
/// <param name="ct">取消令牌</param>
|
||||
/// <param name="轴编号">1: X轴, 2: Y轴, 3: Z轴</param>
|
||||
/// <param name="取消令牌">取消令牌</param>
|
||||
/// <returns>当前设定的目标位置值</returns>
|
||||
public async Task<int> GetAxisTargetPositionAsync(int axis, CancellationToken ct = default)
|
||||
public async Task<int> 查询轴目标位置(int 轴编号, CancellationToken 取消令牌 = default)
|
||||
{
|
||||
ushort address = axis switch
|
||||
ushort address = 轴编号 switch
|
||||
{
|
||||
1 => ADDR_HD_X_TARGET,
|
||||
2 => ADDR_HD_Y_TARGET,
|
||||
3 => ADDR_HD_Z_TARGET,
|
||||
_ => throw new ArgumentException("轴通道错误,仅支持 1(X), 2(Y), 3(Z)", nameof(axis))
|
||||
_ => throw new ArgumentException("轴通道错误,仅支持 1(X), 2(Y), 3(Z)", nameof(轴编号))
|
||||
};
|
||||
|
||||
ushort[] registers = await ReadHoldingRegistersAsync(_slaveAddress, address, 2, ct);
|
||||
ushort[] registers = await ReadHoldingRegistersAsync(_slaveAddress, address, 2, 取消令牌);
|
||||
|
||||
if (registers == null || registers.Length < 2)
|
||||
throw new InvalidOperationException($"从 PLC 读取轴 {axis} 目标位置失败。");
|
||||
throw new InvalidOperationException($"从 PLC 读取轴 {轴编号} 目标位置失败。");
|
||||
|
||||
return UshortsToInt32(registers);
|
||||
}
|
||||
@@ -314,60 +314,60 @@ namespace DeviceCommand.Devices
|
||||
/// <summary>
|
||||
/// 设置系统紧停锁定状态 (true: 锁定激活, false: 解除锁定)
|
||||
/// </summary>
|
||||
/// <param name="state">true: 锁定激活, false: 解除锁定</param>
|
||||
/// <param name="ct">取消令牌</param>
|
||||
public async Task SetEStopStateAsync(bool state, CancellationToken ct = default)
|
||||
/// <param name="状态">true: 锁定激活, false: 解除锁定</param>
|
||||
/// <param name="取消令牌">取消令牌</param>
|
||||
public async Task 设置急停状态(bool 状态, CancellationToken 取消令牌 = default)
|
||||
{
|
||||
await WriteSingleCoilAsync(_slaveAddress, ADDR_M_ESTOP, state, ct);
|
||||
await WriteSingleCoilAsync(_slaveAddress, ADDR_M_ESTOP, 状态, 取消令牌);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置指定轴的停止控制状态 (true: 持续输出停止信号, false: 释放停止信号)
|
||||
/// </summary>
|
||||
/// <param name="axis">1: X轴, 2: Y轴, 3: Z轴</param>
|
||||
/// <param name="state">true: 持续输出停止信号, false: 释放停止信号</param>
|
||||
/// <param name="ct">取消令牌</param>
|
||||
public async Task SetStopStateAsync(int axis, bool state, CancellationToken ct = default)
|
||||
/// <param name="轴编号">1: X轴, 2: Y轴, 3: Z轴</param>
|
||||
/// <param name="状态">true: 持续输出停止信号, false: 释放停止信号</param>
|
||||
/// <param name="取消令牌">取消令牌</param>
|
||||
public async Task 设置轴停止状态(int 轴编号, bool 状态, CancellationToken 取消令牌 = default)
|
||||
{
|
||||
ushort address = axis switch
|
||||
ushort address = 轴编号 switch
|
||||
{
|
||||
1 => ADDR_M_X_STOP,
|
||||
2 => ADDR_M_Y_STOP,
|
||||
3 => ADDR_M_Z_STOP,
|
||||
_ => throw new ArgumentException("轴通道错误,仅支持 1(X), 2(Y), 3(Z)", nameof(axis))
|
||||
_ => throw new ArgumentException("轴通道错误,仅支持 1(X), 2(Y), 3(Z)", nameof(轴编号))
|
||||
};
|
||||
|
||||
await WriteSingleCoilAsync(_slaveAddress, address, state, ct);
|
||||
await WriteSingleCoilAsync(_slaveAddress, address, 状态, 取消令牌);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 全局回零(安全校验版:先检查回原点速度是否为 0,为0则拒绝触发)
|
||||
/// </summary>
|
||||
/// <param name="ct">取消令牌</param>
|
||||
public async Task HomeAsync(CancellationToken ct = default)
|
||||
/// <param name="取消令牌">取消令牌</param>
|
||||
public async Task 回零(CancellationToken 取消令牌 = default)
|
||||
{
|
||||
int currentSpeed = await GetHomePositionSpeedAsync(ct);
|
||||
int currentSpeed = await 查询回零速度(取消令牌);
|
||||
|
||||
if (currentSpeed == 0)
|
||||
throw new InvalidOperationException("无法触发回原点!当前回原点定位速度为 0,请先设置合法的回零速度。");
|
||||
|
||||
await TriggerCoilAsync(ADDR_M_HOME_TRIGGER, ct);
|
||||
await TriggerCoilAsync(ADDR_M_HOME_TRIGGER, 取消令牌);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单轴指定位置启动(含速度判定、使能自动补齐、动作目标位置独立范围校验)
|
||||
/// </summary>
|
||||
/// <param name="axis">1: X轴, 2: Y轴, 3: Z轴</param>
|
||||
/// <param name="ct">取消令牌</param>
|
||||
public async Task StartSingleAxisAsync(int axis, CancellationToken ct = default)
|
||||
/// <param name="轴编号">1: X轴, 2: Y轴, 3: Z轴</param>
|
||||
/// <param name="取消令牌">取消令牌</param>
|
||||
public async Task 启动单轴(int 轴编号, CancellationToken 取消令牌 = default)
|
||||
{
|
||||
ushort startAddress;
|
||||
int maxLimit;
|
||||
int currentHomePos;
|
||||
|
||||
// 1. 获取基础参数与校验边界
|
||||
var (xHome, yHome, zHome) = await GetHomePositionAsync(ct);
|
||||
switch (axis)
|
||||
var (xHome, yHome, zHome) = await 查询原点位置(取消令牌);
|
||||
switch (轴编号)
|
||||
{
|
||||
case 1:
|
||||
startAddress = ADDR_M_X_START;
|
||||
@@ -385,50 +385,50 @@ namespace DeviceCommand.Devices
|
||||
currentHomePos = zHome;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("轴通道错误,仅支持 1(X), 2(Y), 3(Z)", nameof(axis));
|
||||
throw new ArgumentException("轴通道错误,仅支持 1(X), 2(Y), 3(Z)", nameof(轴编号));
|
||||
}
|
||||
|
||||
// 2. 检查动作轴的速度
|
||||
int currentSpeed = await GetAxisSpeedAsync(axis, ct);
|
||||
int currentSpeed = await 查询轴速度(轴编号, 取消令牌);
|
||||
if (currentSpeed == 0)
|
||||
throw new InvalidOperationException($"轴 {axis} 无法启动!当前设定速度为 0。");
|
||||
throw new InvalidOperationException($"轴 {轴编号} 无法启动!当前设定速度为 0。");
|
||||
|
||||
// 3. 检查动作轴使能,若为 false 则自动补写 true 激活驱动器
|
||||
bool isEnabled = await GetAxisEnableAsync(axis, ct);
|
||||
bool isEnabled = await 查询轴使能(轴编号, 取消令牌);
|
||||
if (!isEnabled)
|
||||
{
|
||||
await SetAxisEnableAsync(axis, true, ct);
|
||||
await Task.Delay(100, ct); // 等待硬件继电器响应与伺服驱动就绪
|
||||
await 设置轴使能(轴编号, true, 取消令牌);
|
||||
await Task.Delay(100, 取消令牌); // 等待硬件继电器响应与伺服驱动就绪
|
||||
}
|
||||
|
||||
// 4. 精准独立校验当前需要动作轴的目标定位是否越界
|
||||
int currentTarget = await GetAxisTargetPositionAsync(axis, ct);
|
||||
int currentTarget = await 查询轴目标位置(轴编号, 取消令牌);
|
||||
int allowedMaxLimit = maxLimit - currentHomePos;
|
||||
if (currentTarget < 0 || currentTarget > allowedMaxLimit)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException($"轴 {axis} 无法启动!当前指定目标位置 [{currentTarget}] 超过了允许的最大安全极限值 [{allowedMaxLimit}]。");
|
||||
throw new ArgumentOutOfRangeException($"轴 {轴编号} 无法启动!当前指定目标位置 [{currentTarget}] 超过了允许的最大安全极限值 [{allowedMaxLimit}]。");
|
||||
}
|
||||
|
||||
// 5. 校验完成,边缘触发点动启动
|
||||
await TriggerCoilAsync(startAddress, ct);
|
||||
await TriggerCoilAsync(startAddress, 取消令牌);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 三轴同时启动(全开:严格校验全部运行轴速度、批量检测与补正1~6号轴使能、联动校验三轴目标范围极限)
|
||||
/// </summary>
|
||||
/// <param name="ct">取消令牌</param>
|
||||
public async Task StartAllAxesAsync(CancellationToken ct = default)
|
||||
/// <param name="取消令牌">取消令牌</param>
|
||||
public async Task 启动全部轴(CancellationToken 取消令牌 = default)
|
||||
{
|
||||
// 1. 一次性读取三轴速度,严禁任何一轴速度为 0
|
||||
int xSpeed = await GetAxisSpeedAsync(1, ct);
|
||||
int ySpeed = await GetAxisSpeedAsync(2, ct);
|
||||
int zSpeed = await GetAxisSpeedAsync(3, ct);
|
||||
int xSpeed = await 查询轴速度(1, 取消令牌);
|
||||
int ySpeed = await 查询轴速度(2, 取消令牌);
|
||||
int zSpeed = await 查询轴速度(3, 取消令牌);
|
||||
|
||||
if (xSpeed == 0 || ySpeed == 0 || zSpeed == 0)
|
||||
throw new InvalidOperationException($"无法全开启动!存在运行速度为 0 的轴。当前速度 -> X:{xSpeed}, Y:{ySpeed}, Z:{zSpeed}");
|
||||
|
||||
// 2. 批量读取 1 ~ 6 号轴连续的使能状态线圈,极大地优化网络性能
|
||||
bool[] enableStates = await ReadCoilsAsync(_slaveAddress, ADDR_HM_AXIS1_ENABLE, 6, ct);
|
||||
bool[] enableStates = await ReadCoilsAsync(_slaveAddress, ADDR_HM_AXIS1_ENABLE, 6, 取消令牌);
|
||||
if (enableStates == null || enableStates.Length < 6)
|
||||
throw new InvalidOperationException("从 PLC 读取 1~6 号轴使能状态失败。");
|
||||
|
||||
@@ -439,21 +439,21 @@ namespace DeviceCommand.Devices
|
||||
{
|
||||
if (!enableStates[i])
|
||||
{
|
||||
await WriteSingleCoilAsync(_slaveAddress, enableAddresses[i], true, ct);
|
||||
await WriteSingleCoilAsync(_slaveAddress, enableAddresses[i], true, 取消令牌);
|
||||
hasModifiedEnable = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果执行过使能补齐补齐写入,在循环外进行统一延时,保证PLC时序安全
|
||||
if (hasModifiedEnable)
|
||||
await Task.Delay(100, ct);
|
||||
await Task.Delay(100, 取消令牌);
|
||||
|
||||
// 3. 获取三轴原点及当前设定的目标指定位置
|
||||
var (xHome, yHome, zHome) = await GetHomePositionAsync(ct);
|
||||
var (xHome, yHome, zHome) = await 查询原点位置(取消令牌);
|
||||
|
||||
int xTarget = await GetAxisTargetPositionAsync(1, ct);
|
||||
int yTarget = await GetAxisTargetPositionAsync(2, ct);
|
||||
int zTarget = await GetAxisTargetPositionAsync(3, ct);
|
||||
int xTarget = await 查询轴目标位置(1, 取消令牌);
|
||||
int yTarget = await 查询轴目标位置(2, 取消令牌);
|
||||
int zTarget = await 查询轴目标位置(3, 取消令牌);
|
||||
|
||||
// X轴安全范围联动校验
|
||||
int xMaxAllowed = 50000 - xHome;
|
||||
@@ -471,15 +471,15 @@ namespace DeviceCommand.Devices
|
||||
throw new ArgumentOutOfRangeException(nameof(zTarget), $"Z轴目标位置 [{zTarget}] 越界,当前原点下最大范围 0-{zMaxAllowed}");
|
||||
|
||||
// 4. 全部联动校验通过,三轴点动同步启动
|
||||
await WriteSingleCoilAsync(_slaveAddress, ADDR_M_X_START, true, ct);
|
||||
await WriteSingleCoilAsync(_slaveAddress, ADDR_M_Y_START, true, ct);
|
||||
await WriteSingleCoilAsync(_slaveAddress, ADDR_M_Z_START, true, ct);
|
||||
await WriteSingleCoilAsync(_slaveAddress, ADDR_M_X_START, true, 取消令牌);
|
||||
await WriteSingleCoilAsync(_slaveAddress, ADDR_M_Y_START, true, 取消令牌);
|
||||
await WriteSingleCoilAsync(_slaveAddress, ADDR_M_Z_START, true, 取消令牌);
|
||||
|
||||
await Task.Delay(100, ct); // 保持高电平状态以适配 PLC 扫描周期
|
||||
await Task.Delay(100, 取消令牌); // 保持高电平状态以适配 PLC 扫描周期
|
||||
|
||||
await WriteSingleCoilAsync(_slaveAddress, ADDR_M_X_START, false, ct);
|
||||
await WriteSingleCoilAsync(_slaveAddress, ADDR_M_Y_START, false, ct);
|
||||
await WriteSingleCoilAsync(_slaveAddress, ADDR_M_Z_START, false, ct);
|
||||
await WriteSingleCoilAsync(_slaveAddress, ADDR_M_X_START, false, 取消令牌);
|
||||
await WriteSingleCoilAsync(_slaveAddress, ADDR_M_Y_START, false, 取消令牌);
|
||||
await WriteSingleCoilAsync(_slaveAddress, ADDR_M_Z_START, false, 取消令牌);
|
||||
}
|
||||
|
||||
#region 内部高低字工具转化方法
|
||||
@@ -521,12 +521,12 @@ namespace DeviceCommand.Devices
|
||||
/// <summary>
|
||||
/// 读取指定轴的绝对位置(相对原点的实时位置,只读)
|
||||
/// </summary>
|
||||
/// <param name="axis">轴编号 (1-6)</param>
|
||||
/// <param name="ct">取消令牌</param>
|
||||
/// <param name="轴编号">轴编号 (1-6)</param>
|
||||
/// <param name="取消令牌">取消令牌</param>
|
||||
/// <returns>指定轴的绝对位置值</returns>
|
||||
public async Task<int> GetAbsolutePositionAsync(int axis, CancellationToken ct = default)
|
||||
public async Task<int> 查询轴绝对位置(int 轴编号, CancellationToken 取消令牌 = default)
|
||||
{
|
||||
ushort address = axis switch
|
||||
ushort address = 轴编号 switch
|
||||
{
|
||||
1 => ADDR_ABS_AXIS1_POS,
|
||||
2 => ADDR_ABS_AXIS2_POS,
|
||||
@@ -534,12 +534,12 @@ namespace DeviceCommand.Devices
|
||||
4 => ADDR_ABS_AXIS4_POS,
|
||||
5 => ADDR_ABS_AXIS5_POS,
|
||||
6 => ADDR_ABS_AXIS6_POS,
|
||||
_ => throw new ArgumentException("轴编号错误,仅支持 1-6", nameof(axis))
|
||||
_ => throw new ArgumentException("轴编号错误,仅支持 1-6", nameof(轴编号))
|
||||
};
|
||||
|
||||
ushort[] registers = await ReadHoldingRegistersAsync(_slaveAddress, address, 2, ct);
|
||||
ushort[] registers = await ReadHoldingRegistersAsync(_slaveAddress, address, 2, 取消令牌);
|
||||
if (registers == null || registers.Length < 2)
|
||||
throw new InvalidOperationException($"读取轴 {axis} 绝对位置失败。");
|
||||
throw new InvalidOperationException($"读取轴 {轴编号} 绝对位置失败。");
|
||||
|
||||
return UshortsToInt32(registers);
|
||||
}
|
||||
@@ -547,12 +547,12 @@ namespace DeviceCommand.Devices
|
||||
/// <summary>
|
||||
/// 批量读取 1-6 轴的绝对位置(一次性读取 22 个寄存器,高效)
|
||||
/// </summary>
|
||||
/// <param name="ct">取消令牌</param>
|
||||
/// <param name="取消令牌">取消令牌</param>
|
||||
/// <returns>返回 6 轴绝对位置元组</returns>
|
||||
public async Task<(int Axis1, int Axis2, int Axis3, int Axis4, int Axis5, int Axis6)> GetAllAbsolutePositionsAsync(CancellationToken ct = default)
|
||||
public async Task<(int Axis1, int Axis2, int Axis3, int Axis4, int Axis5, int Axis6)> 查询全部轴绝对位置(CancellationToken 取消令牌 = default)
|
||||
{
|
||||
// 从 47232 开始连续读取 22 个寄存器(覆盖 47232-47253)
|
||||
ushort[] registers = await ReadHoldingRegistersAsync(_slaveAddress, ADDR_ABS_AXIS1_POS, 22, ct);
|
||||
ushort[] registers = await ReadHoldingRegistersAsync(_slaveAddress, ADDR_ABS_AXIS1_POS, 22, 取消令牌);
|
||||
if (registers == null || registers.Length < 22)
|
||||
throw new InvalidOperationException("批量读取 6 轴绝对位置失败,返回数据长度不足。");
|
||||
|
||||
|
||||
@@ -56,6 +56,12 @@ namespace ZLGUSBCANFD
|
||||
/// </summary>
|
||||
public event Action<uint, ZDBC.DBCMessage>? OnDbcMessageDecoded;
|
||||
|
||||
/// <summary>
|
||||
/// 事件:当接收到任意 CAN/CANFD 原始报文时触发(不依赖 DBC,自定义报文也能收到)
|
||||
/// 参数:通道号, 帧ID, 数据, 时间戳(微秒), 是否FD, 数据长度
|
||||
/// </summary>
|
||||
public event Action<uint, uint, byte[], ulong, bool, byte>? OnRawMessageReceived;
|
||||
|
||||
public ZLGCANFD(uint deviceType = 76, uint deviceIndex = 0, int maxChannels = 4,
|
||||
string abitBaud = "500000", string dbitBaud = "2000000", bool enableTerminalResistance = true)
|
||||
{
|
||||
@@ -297,6 +303,10 @@ namespace ZLGUSBCANFD
|
||||
{
|
||||
IntPtr framePtr = IntPtr.Add(ptrCanBuffer, i * canStructSize);
|
||||
|
||||
// 触发原始报文事件(不依赖 DBC,自定义报文也能收到)
|
||||
var rawData = (ZLGCAN.ZCAN_Receive_Data)Marshal.PtrToStructure(framePtr, typeof(ZLGCAN.ZCAN_Receive_Data))!;
|
||||
OnRawMessageReceived?.Invoke(channelIndex, rawData.frame.can_id, rawData.frame.data, rawData.timestamp, false, rawData.frame.can_dlc);
|
||||
|
||||
// 只锁定当前通道的DBC句柄进行解码,高并发完全不卡顿
|
||||
lock (_channelLocks[channelIndex])
|
||||
{
|
||||
@@ -319,6 +329,10 @@ namespace ZLGUSBCANFD
|
||||
{
|
||||
IntPtr framePtr = IntPtr.Add(ptrCanFDBuffer, i * canfdStructSize);
|
||||
|
||||
// 触发原始报文事件(不依赖 DBC,自定义报文也能收到)
|
||||
var rawFdData = (ZLGCAN.ZCAN_ReceiveFD_Data)Marshal.PtrToStructure(framePtr, typeof(ZLGCAN.ZCAN_ReceiveFD_Data))!;
|
||||
OnRawMessageReceived?.Invoke(channelIndex, rawFdData.frame.can_id, rawFdData.frame.data, rawFdData.timestamp, true, rawFdData.frame.len);
|
||||
|
||||
lock (_channelLocks[channelIndex])
|
||||
{
|
||||
if (_isDbcLoadedArray[channelIndex] && ZDBC.ZDBC_Decode(_dbcHandles[channelIndex], ptrDbcMsg, framePtr, 1, 1))
|
||||
|
||||
Reference in New Issue
Block a user