CAN的定时发送的更改和一些其他的改动

This commit is contained in:
2025-05-06 11:03:51 +08:00
parent 16eaa230d8
commit df4b481bbb
7 changed files with 238 additions and 24 deletions

View File

@@ -1,6 +1,7 @@
using CapMachine.Wpf.Models.Tag; using CapMachine.Wpf.Models.Tag;
using CapMachine.Wpf.Services; using CapMachine.Wpf.Services;
using HslCommunication; using HslCommunication;
using ImTools;
using NPOI.OpenXmlFormats.Wordprocessing; using NPOI.OpenXmlFormats.Wordprocessing;
using Prism.Ioc; using Prism.Ioc;
using Prism.Mvvm; using Prism.Mvvm;
@@ -21,6 +22,8 @@ namespace CapMachine.Wpf.CanDrive
{ {
/// <summary> /// <summary>
/// Toomoss CAN /// Toomoss CAN
/// 如果精度达不到的话则使用CAN通信调度表模式实现方案
/// 目前有0-1ms的抖动
/// </summary> /// </summary>
public class ToomossCan : BindableBase public class ToomossCan : BindableBase
{ {
@@ -33,6 +36,7 @@ namespace CapMachine.Wpf.CanDrive
{ {
ContainerProvider = containerProvider; ContainerProvider = containerProvider;
HighSpeedDataService = ContainerProvider.Resolve<HighSpeedDataService>(); HighSpeedDataService = ContainerProvider.Resolve<HighSpeedDataService>();
HightDriveMsgService = ContainerProvider.Resolve<HightDriveMsgService>();
//Stopwatch.Frequency表示高精度计时器每秒的计数次数ticks/秒每毫秒的ticks数 = 每秒的ticks数 ÷ 1000 //Stopwatch.Frequency表示高精度计时器每秒的计数次数ticks/秒每毫秒的ticks数 = 每秒的ticks数 ÷ 1000
TicksPerMs = Stopwatch.Frequency / 1000.0; TicksPerMs = Stopwatch.Frequency / 1000.0;
@@ -478,8 +482,6 @@ namespace CapMachine.Wpf.CanDrive
RaisePropertyChanged(); RaisePropertyChanged();
_IsSendOk = value; _IsSendOk = value;
} }
} }
} }
@@ -604,7 +606,6 @@ namespace CapMachine.Wpf.CanDrive
CycleSendCts = cancellationTokenSource;//将取消标记源保存到类的成员变量CycleSendCts这样在外部调用停止方法时可以访问它 CycleSendCts = cancellationTokenSource;//将取消标记源保存到类的成员变量CycleSendCts这样在外部调用停止方法时可以访问它
NextExecutionTime = 0;//初始化NextExecutionTime为0这个变量用于记录下一次执行的目标时间点 NextExecutionTime = 0;//初始化NextExecutionTime为0这个变量用于记录下一次执行的目标时间点
CycleSendTask = Task.Factory.StartNew(async () => CycleSendTask = Task.Factory.StartNew(async () =>
{ {
try try
@@ -667,6 +668,7 @@ namespace CapMachine.Wpf.CanDrive
lastTicks = Stopwatcher.ElapsedTicks; lastTicks = Stopwatcher.ElapsedTicks;
//Console.WriteLine($"--当前时间(毫秒): {DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}"); //Console.WriteLine($"--当前时间(毫秒): {DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}");
// 执行发送CAN逻辑 // 执行发送CAN逻辑
{ {
@@ -796,7 +798,7 @@ namespace CapMachine.Wpf.CanDrive
Category = "CAN", Category = "CAN",
MsgInfo = "0x" + CanMsgBuffer[i].ID.ToString("X8"), MsgInfo = "0x" + CanMsgBuffer[i].ID.ToString("X8"),
MsgData = BitConverter.ToString(CanMsgBuffer[i].Data), MsgData = BitConverter.ToString(CanMsgBuffer[i].Data),
Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") Time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
}); });
//报文给高速报文处理服务 //报文给高速报文处理服务
@@ -805,7 +807,7 @@ namespace CapMachine.Wpf.CanDrive
Category = "CAN", Category = "CAN",
MsgInfo = "0x" + CanMsgBuffer[i].ID.ToString("X8"), MsgInfo = "0x" + CanMsgBuffer[i].ID.ToString("X8"),
MsgData = BitConverter.ToString(CanMsgBuffer[i].Data), MsgData = BitConverter.ToString(CanMsgBuffer[i].Data),
Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") Time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
}); });
} }
} }

View File

@@ -12,9 +12,9 @@ namespace CapMachine.Wpf.Models.HighSpeed
public class CommMsg public class CommMsg
{ {
/// <summary> /// <summary>
/// 时间 /// 整数时间戳(毫秒)
/// </summary> /// </summary>
public string? Time { get; set; } public long Time { get; set; }
/// <summary> /// <summary>
/// 分类 /// 分类

View File

@@ -86,6 +86,45 @@ namespace CapMachine.Wpf.Services
#region CAN #region CAN
private bool _CanAutoHand;
/// <summary>
/// CAN 手自动 模式,自动代表接受程序步骤的数据,手动代表接受手动输入的数据
/// True代表自动False代表手动
/// </summary>
public bool CanAutoHand
{
get { return _CanAutoHand; }
set
{
if (_CanAutoHand != value)
{
RaisePropertyChanged();
_CanAutoHand = value;
}
}
}
private bool _CanHandEnable;
/// <summary>
/// CAN 手动 模式,是否使能,用于报文的使能和非使能的数据
/// True代表使能False代表禁用
/// </summary>
public bool CanHandEnable
{
get { return _CanHandEnable; }
set
{
if (_CanHandEnable != value)
{
RaisePropertyChanged();
_CanHandEnable = value;
}
}
}
private int _AutoSpeedSv; private int _AutoSpeedSv;
/// <summary> /// <summary>
/// 转速SV /// 转速SV
@@ -93,7 +132,15 @@ namespace CapMachine.Wpf.Services
public int AutoSpeedSv public int AutoSpeedSv
{ {
get { return _AutoSpeedSv; } get { return _AutoSpeedSv; }
set { _AutoSpeedSv = value; RaisePropertyChanged(); } set
{
if (value!= _AutoSpeedSv)
{
_AutoSpeedSv = value;
RaisePropertyChanged();
}
}
} }
@@ -167,7 +214,7 @@ namespace CapMachine.Wpf.Services
{ {
//LogicRuleService.ApplyExpressionFast(SpeedData, SpeedCanCmdData.LogicRuleDto); //LogicRuleService.ApplyExpressionFast(SpeedData, SpeedCanCmdData.LogicRuleDto);
SpeedCanCmdData.SignalCmdValue = LogicRuleService.ApplyExpressionFast(SpeedData, SpeedCanCmdData.LogicRuleDto); SpeedCanCmdData.SignalCmdValue = LogicRuleService.ApplyExpressionFast(SpeedData, SpeedCanCmdData.LogicRuleDto);
Console.WriteLine($"实时转换后转速值:{SpeedCanCmdData.SignalCmdValue}-SV值:{SpeedData}"); //Console.WriteLine($"实时转换后转速值:{SpeedCanCmdData.SignalCmdValue}-SV值:{SpeedData}");
} }
} }
@@ -184,7 +231,7 @@ namespace CapMachine.Wpf.Services
public void UpdateCapEnableCmdData(bool IsEnable) public void UpdateCapEnableCmdData(bool IsEnable)
{ {
if (!ToomossCanDrive.IsCycleSend) return; if (!ToomossCanDrive.IsCycleSend) return;
if (!CanAutoHand) return;
if (EnableCanCmdData != null) if (EnableCanCmdData != null)
{ {
EnableCanCmdData.SignalCmdValue = IsEnable ? 1 : 0; EnableCanCmdData.SignalCmdValue = IsEnable ? 1 : 0;
@@ -194,6 +241,7 @@ namespace CapMachine.Wpf.Services
/// <summary> /// <summary>
/// 发送消息给CAN 驱动 /// 发送消息给CAN 驱动
/// 手动发送时使用
/// </summary> /// </summary>
public void SendMsgToCanDrive(double SpeedData) public void SendMsgToCanDrive(double SpeedData)
{ {

View File

@@ -3068,10 +3068,12 @@ namespace CapMachine.Wpf.Services
switch (itemStepExd.ValueType) switch (itemStepExd.ValueType)
{ {
case ExdValueType.Bool: case ExdValueType.Bool:
SiemensDrive.Write(DataAdrees.Address, (bool)itemStepExd.Value == true ? 1 : 0); var ResultBool = SiemensDrive.Write(DataAdrees.Address, (bool)itemStepExd.Value == true ? 1 : 0);
if (!ResultBool.IsSuccess) Console.WriteLine($"{ProRunChannelData.MeterName}:{itemStepExd.Name}写入失败");
break; break;
case ExdValueType.Short: case ExdValueType.Short:
SiemensDrive.Write(DataAdrees.Address, (short)itemStepExd.Value); var ResultShort = SiemensDrive.Write(DataAdrees.Address, (short)itemStepExd.Value);
if (!ResultShort.IsSuccess) Console.WriteLine($"{ProRunChannelData.MeterName}:{itemStepExd.Name}写入失败");
break; break;
case ExdValueType.Double: case ExdValueType.Double:
break; break;
@@ -3117,6 +3119,7 @@ namespace CapMachine.Wpf.Services
/// <summary> /// <summary>
/// 发送速度SV到压缩机 /// 发送速度SV到压缩机
/// 自动步骤数据发送
/// </summary> /// </summary>
private void SendSpeedSvToCap(int SpeedSv) private void SendSpeedSvToCap(int SpeedSv)
{ {
@@ -3124,7 +3127,11 @@ namespace CapMachine.Wpf.Services
{ {
case CanLinEnum.Can: case CanLinEnum.Can:
//获取PLC的SV数据 更新SV的速度值到压缩机 //获取PLC的SV数据 更新SV的速度值到压缩机
if (CanDriveService.CanAutoHand)//自动时步骤的数据可以赋值数据
{
CanDriveService.UpdateSpeedCmdData(SpeedSv); CanDriveService.UpdateSpeedCmdData(SpeedSv);
}
//itemTag.Value.EngPvValue = 0; //itemTag.Value.EngPvValue = 0;
break; break;
case CanLinEnum.Lin: case CanLinEnum.Lin:

View File

@@ -25,6 +25,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents; using System.Windows.Documents;
using static CapMachine.Wpf.Models.ComEnum; using static CapMachine.Wpf.Models.ComEnum;
@@ -96,7 +97,7 @@ namespace CapMachine.Wpf.ViewModels
public ComActionService ComActionService { get; } public ComActionService ComActionService { get; }
public LogicRuleService LogicRuleService { get; } public LogicRuleService LogicRuleService { get; }
public ConfigService ConfigService { get; } public ConfigService ConfigService { get; }
public CanDriveService CanDriveService { get; } public CanDriveService CanDriveService { get; set; }
public HightDriveMsgService HightDriveMsgService { get; } public HightDriveMsgService HightDriveMsgService { get; }
public IMapper Mapper { get; } public IMapper Mapper { get; }
private MachineRtDataService MachineRtDataService { get; } private MachineRtDataService MachineRtDataService { get; }
@@ -999,6 +1000,87 @@ namespace CapMachine.Wpf.ViewModels
} }
private DelegateCommand<object> _CanAutoHandCmd;
/// <summary>
/// CAN的手自动切换
/// </summary>
public DelegateCommand<object> CanAutoHandCmd
{
set
{
_CanAutoHandCmd = value;
}
get
{
if (_CanAutoHandCmd == null)
{
_CanAutoHandCmd = new DelegateCommand<object>((p) => CanAutoHandCmdCall(p));
}
return _CanAutoHandCmd;
}
}
/// <summary>
/// CAN的手自动切换操作指令执行方法
/// CAN的手自动切换在调试时手动操作在正常运行时自动操作
/// </summary>
/// <exception cref="NotImplementedException"></exception>
private void CanAutoHandCmdCall(object Par)
{
if (Par != null && Par is ToggleButton)
{
var ControlData = Par as ToggleButton;
var Name = ControlData.ToolTip;
var Data = ControlData.IsChecked;
//ToDo cmd
CanDriveService.CanAutoHand = (bool)Data!;
//CAN手自动切换时报文的展示需要配置一下自动时报文不再展示节省资源手动时报文才展示
HightDriveMsgService.IsDisplayEnabled= !(bool)Data!;
}
}
private DelegateCommand<object> _CanHandEnableCmd;
/// <summary>
/// CAN 手动 模式,是否使能,用于报文的使能和非使能的数据
/// True代表使能False代表禁用
/// </summary>
public DelegateCommand<object> CanHandEnableCmd
{
set
{
_CanHandEnableCmd = value;
}
get
{
if (_CanHandEnableCmd == null)
{
_CanHandEnableCmd = new DelegateCommand<object>((p) => CanHandEnableCmdCall(p));
}
return _CanHandEnableCmd;
}
}
/// <summary>
/// CAN 手动 模式,是否使能,用于报文的使能和非使能的数据
/// True代表使能False代表禁用
/// </summary>
/// <exception cref="NotImplementedException"></exception>
private void CanHandEnableCmdCall(object Par)
{
if (Par != null && Par is ToggleButton)
{
var ControlData = Par as ToggleButton;
var Name = ControlData.ToolTip;
var Data = ControlData.IsChecked;
//ToDo cmd
CanDriveService.CanHandEnable = (bool)Data!;
//给使能数据
CanDriveService.UpdateCapEnableCmdData(CanDriveService.CanHandEnable);
}
}
private double _HandSpeed; private double _HandSpeed;
/// <summary> /// <summary>
/// 手动转速数据 /// 手动转速数据

View File

@@ -383,7 +383,6 @@
</StackPanel> </StackPanel>
</Button> </Button>
</StackPanel> </StackPanel>
</Grid> </Grid>
<Grid Grid.Row="1"> <Grid Grid.Row="1">
@@ -578,19 +577,93 @@
VerticalAlignment="Center" VerticalAlignment="Center"
FontFamily="/Assets/Fonts/#iconfont" FontFamily="/Assets/Fonts/#iconfont"
FontSize="18" FontSize="18"
Foreground="LimeGreen" Foreground="DodgerBlue"
Text="&#xe673;" /> Text="&#xe673;" />
<TextBlock <TextBlock
Width="auto" Width="auto"
Foreground="LimeGreen" Foreground="DodgerBlue"
Style="{StaticResource TextBlockStyle}" Style="{StaticResource TextBlockStyle}"
Text="自动转速(rpm)" /> Text="自动转速(rpm)" />
<TextBlock <TextBlock
Margin="5,0" Margin="5,0"
Foreground="LimeGreen" Foreground="DodgerBlue"
Style="{StaticResource TextBlockStyle}" Style="{StaticResource TextBlockStyle}"
Text="{Binding CanDriveService.AutoSpeedSv}" /> Text="{Binding CanDriveService.AutoSpeedSv}" />
</StackPanel> </StackPanel>
<StackPanel Grid.Column="2" Orientation="Horizontal">
<TextBlock
Margin="5,0,5,0"
VerticalAlignment="Center"
FontFamily="/Assets/Fonts/#iconfont"
FontSize="18"
Foreground="DodgerBlue"
Text="&#xe95a;" />
<TextBlock
Width="auto"
Foreground="DodgerBlue"
Style="{StaticResource TextBlockStyle}"
Text="CAN手自动" />
<ToggleButton
Width="70"
Margin="10,0,0,0"
Command="{Binding CanAutoHandCmd}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
FontSize="11"
ToolTip="自动时:接受程序步骤的转速控制;手动时:手动发送转速数据">
<ToggleButton.Style>
<Style BasedOn="{StaticResource MaterialDesignSwitchToggleButton}" TargetType="ToggleButton">
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content" Value="自动" />
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Content" Value="手动" />
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
</StackPanel>
<StackPanel
Grid.Row="1"
Grid.Column="1"
Orientation="Horizontal">
<TextBlock
Margin="5,0,5,0"
VerticalAlignment="Center"
FontFamily="/Assets/Fonts/#iconfont"
FontSize="18"
Foreground="DodgerBlue"
Text="&#xe921;" />
<TextBlock
Width="auto"
Foreground="DodgerBlue"
Style="{StaticResource TextBlockStyle}"
Text="CAN使能" />
<ToggleButton
Width="70"
Margin="10,0,0,0"
Command="{Binding CanHandEnableCmd}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
FontSize="11"
ToolTip="使能时:触发报文中使能;禁用时:触发报文中使能=False">
<ToggleButton.Style>
<Style BasedOn="{StaticResource MaterialDesignSwitchToggleButton}" TargetType="ToggleButton">
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content" Value="使能" />
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Content" Value="禁用" />
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
</StackPanel>
</Grid> </Grid>
</Grid> </Grid>
@@ -998,6 +1071,8 @@
</TabItem> </TabItem>
<TabItem Header="CAN报文"> <TabItem Header="CAN报文">
<ListView <ListView
BorderBrush="Black"
BorderThickness="1"
ItemsSource="{Binding HightDriveMsgService.DisplayMessages}" ItemsSource="{Binding HightDriveMsgService.DisplayMessages}"
ScrollViewer.IsDeferredScrollingEnabled="True" ScrollViewer.IsDeferredScrollingEnabled="True"
VirtualizingPanel.CacheLength="1,1" VirtualizingPanel.CacheLength="1,1"

View File

@@ -1411,7 +1411,7 @@
</StackPanel> </StackPanel>
<StackPanel Grid.Column="2" HorizontalAlignment="Center"> <StackPanel Grid.Column="2" HorizontalAlignment="Center">
<TextBlock FontSize="12" Text="EV(13)" /> <TextBlock FontSize="12" Text="EV(14)" />
<TextBox Style="{StaticResource txtboxStyle}" Text="{Binding SelectedSlopMeterSpeed.Ev}" /> <TextBox Style="{StaticResource txtboxStyle}" Text="{Binding SelectedSlopMeterSpeed.Ev}" />
</StackPanel> </StackPanel>
<StackPanel Grid.Column="3" HorizontalAlignment="Center"> <StackPanel Grid.Column="3" HorizontalAlignment="Center">