初始值
This commit is contained in:
519
CommunicationProtocol/CommunicationProtocol.vb
Normal file
519
CommunicationProtocol/CommunicationProtocol.vb
Normal file
@@ -0,0 +1,519 @@
|
||||
Imports System.IO.Ports
|
||||
Imports System.Threading
|
||||
Imports NT_CAM_Controller.SendNode
|
||||
|
||||
Public Class CommunicationProtocol
|
||||
'流程列表
|
||||
Public Property FlowList As List(Of (String, SendNode))
|
||||
Public IsFlowList As Boolean
|
||||
'执行流程任务线程
|
||||
Public Property FlowThread As Task
|
||||
Public IsFlowThread As Boolean
|
||||
Public G_RichTextPrint As RichTextPrint
|
||||
Public G_Transmitter As SerialPort
|
||||
Public ControlDic As New Dictionary(Of Integer, Control)
|
||||
|
||||
Sub New(RichTextPrint As RichTextPrint, gTransmitter As SerialPort)
|
||||
|
||||
FlowList = New List(Of (String, SendNode))
|
||||
G_RichTextPrint = RichTextPrint
|
||||
G_Transmitter = gTransmitter
|
||||
'初始化FlowThread
|
||||
IsFlowThread = True
|
||||
FlowThread = New Task(AddressOf FlowThreadRun)
|
||||
FlowThread.Start()
|
||||
IsFlowList = False
|
||||
ControlDic = New Dictionary(Of Integer, Control)
|
||||
End Sub
|
||||
|
||||
'添加控件列表
|
||||
Sub AddControlDic(ControlName As Integer, Control As Control)
|
||||
If IsNothing(ControlDic) Then ControlDic = New Dictionary(Of Integer, Control)
|
||||
If ControlDic.ContainsKey(ControlName) Then
|
||||
ControlDic.Item(ControlName) = Control
|
||||
Else
|
||||
ControlDic.Add(ControlName, Control)
|
||||
End If
|
||||
|
||||
End Sub
|
||||
|
||||
|
||||
'关闭
|
||||
Sub Close()
|
||||
If FlowThread Is Nothing OrElse Not FlowThread.IsCompleted Then Return
|
||||
FlowThread.Dispose()
|
||||
End Sub
|
||||
|
||||
'关闭线程
|
||||
Sub CloseThread()
|
||||
If FlowThread Is Nothing OrElse Not FlowThread.IsCompleted Then Return
|
||||
FlowThread.Dispose()
|
||||
End Sub
|
||||
'设置IsFlowThread
|
||||
Sub SetIsFlowThread(mIsFlowThread As Boolean)
|
||||
Me.IsFlowThread = mIsFlowThread
|
||||
End Sub
|
||||
Sub setIsFlowList(mIsFlowList As Boolean)
|
||||
Me.IsFlowList = mIsFlowList
|
||||
End Sub
|
||||
|
||||
Public Function getIsFlowList() As Boolean
|
||||
Return False
|
||||
Return Me.IsFlowList
|
||||
End Function
|
||||
Public Function getIsFlowList1() As Boolean
|
||||
|
||||
Return Me.IsFlowList
|
||||
End Function
|
||||
'执行流程任务
|
||||
Sub FlowThreadRun()
|
||||
'流程节点执行状态
|
||||
Dim isnode As Boolean
|
||||
Dim nli As New List(Of Integer)
|
||||
While IsFlowThread
|
||||
Thread.Sleep(1)
|
||||
If IsNothing(FlowList) OrElse FlowList.Count = 0 Then
|
||||
'延时100ms
|
||||
Thread.Sleep(100)
|
||||
Else
|
||||
If IsFlowList Then
|
||||
nli.Clear()
|
||||
Dim FlowListCount As Integer = FlowList.Count
|
||||
Console.WriteLine("FlowListCount:" & FlowListCount)
|
||||
' For Each node In FlowList
|
||||
For i As Integer = 0 To FlowListCount - 1
|
||||
If Not IsFlowList Then
|
||||
Exit For
|
||||
End If
|
||||
|
||||
Dim node As (String, SendNode) = FlowList(i)
|
||||
|
||||
'判断本包是否超时接收
|
||||
If (node.Item2.SendCount >= node.Item2.MaxResendCount) OrElse node.Item2.RecvStatus = 1 Then
|
||||
nli.Add(i)
|
||||
Continue For
|
||||
End If
|
||||
|
||||
If IsFlowThread = False Then Exit For
|
||||
While node.Item2.RecvStatus = SendNode.RecvStatusEnum.None
|
||||
If Not node.Item2.IsRecvData Then
|
||||
node.Item2.RecvRefresh(Nothing)
|
||||
End If
|
||||
If IsFlowThread = False Then Exit For
|
||||
'判断是什么类型命令
|
||||
If node.Item2.CommandType = 0 Then
|
||||
'系统命令
|
||||
isnode = SystemCommandSelector(node.Item1, node.Item2)
|
||||
If isnode = False Then
|
||||
'MsgBox(node.Item2.TipInfo)
|
||||
G_RichTextPrint.AddQueue(New RichTextNodeConfig(node.Item2.TipInfo, Color.Red), 1)
|
||||
'IsFlowList = False
|
||||
Exit While
|
||||
Else
|
||||
Exit While
|
||||
End If
|
||||
|
||||
Else
|
||||
'自定义命令
|
||||
isnode = CustomCommandSelector(node.Item1, node.Item2)
|
||||
If isnode = False Then
|
||||
nli.Add(i)
|
||||
'MsgBox(node.Item2.TipInfo)
|
||||
'G_RichTextPrint.AddQueue(New RichTextNodeConfig(node.Item2.TipInfo, Color.Red), 1)
|
||||
'IsFlowList = False
|
||||
'Else
|
||||
Exit While
|
||||
Else
|
||||
'Exit While
|
||||
End If
|
||||
End If
|
||||
|
||||
|
||||
End While
|
||||
Next
|
||||
|
||||
|
||||
|
||||
'从大到小删除
|
||||
For Each i In nli.OrderByDescending(Function(x) x)
|
||||
If Not IsFlowList Then
|
||||
Exit For
|
||||
End If
|
||||
FlowList.RemoveAt(i)
|
||||
Next
|
||||
IsFlowList = False
|
||||
Console.WriteLine($"流程节点数量:{FlowList.Count}")
|
||||
End If
|
||||
End If
|
||||
End While
|
||||
End Sub
|
||||
'系统命令选择器
|
||||
Public Function SystemCommandSelector(nodename As String, ByRef mSendNode As SendNode) As Boolean
|
||||
If mSendNode.SendData.Length > 0 Then
|
||||
Select Case mSendNode.SendData(0)
|
||||
Case 1 '系统延时
|
||||
If mSendNode.SendData.Length > 1 Then
|
||||
mSendNode.ResendRefresh()
|
||||
Thread.Sleep(mSendNode.SendData(1))
|
||||
mSendNode.RecvRefresh({mSendNode.SendData(1)})
|
||||
mSendNode.SetTipInfo("执行延时完成!")
|
||||
Return True
|
||||
Else
|
||||
mSendNode.SetTipInfo($"{nodename}参数异常!")
|
||||
Return False
|
||||
End If
|
||||
|
||||
End Select
|
||||
Else
|
||||
|
||||
mSendNode.SetTipInfo("系统命令参数异常!")
|
||||
Return False
|
||||
End If
|
||||
End Function
|
||||
|
||||
|
||||
'自定义命令选择器
|
||||
Public Function CustomCommandSelector(nodename As String, ByRef mSendNode As SendNode) As Boolean
|
||||
Dim sendbuf As Byte()
|
||||
If mSendNode.SendStatus = SendNode.SendStatusEnum.None Then
|
||||
sendbuf = SendPortData1(nodename, mSendNode)
|
||||
If IsNothing(sendbuf) OrElse sendbuf.Length = 0 Then
|
||||
Return False
|
||||
Else
|
||||
Return SendPortData(nodename, mSendNode, sendbuf, G_Transmitter)
|
||||
End If
|
||||
|
||||
Else
|
||||
'判断节点是否需要重新发送
|
||||
If mSendNode.NeedResend() Then
|
||||
|
||||
sendbuf = SendPortData1(nodename, mSendNode)
|
||||
If IsNothing(sendbuf) OrElse sendbuf.Length = 0 Then
|
||||
Return False
|
||||
Else
|
||||
G_RichTextPrint.AddQueue(New RichTextNodeConfig($"第{mSendNode.SendCount}次重发数据", Color.Black), 1)
|
||||
Return SendPortData(nodename, mSendNode, sendbuf, G_Transmitter)
|
||||
End If
|
||||
Else
|
||||
If mSendNode.SendCount < mSendNode.MaxResendCount Then
|
||||
|
||||
ElseIf mSendNode.SendCount = mSendNode.MaxResendCount Then
|
||||
If mSendNode.SendTime.AddMilliseconds(mSendNode.SendTimeout) < Now Then
|
||||
mSendNode.SendCount = mSendNode.SendCount + 1
|
||||
|
||||
Else
|
||||
|
||||
End If
|
||||
Else
|
||||
mSendNode.RecvStatus = RecvStatusEnum.Timeout
|
||||
mSendNode.SendStatus = SendStatusEnum.Timeout
|
||||
' IsRuningTest = False '退出流程
|
||||
'RefreshCaptureText(Color.Red, $"节点:{node.Item1} :发送失败!")
|
||||
|
||||
G_RichTextPrint.AddQueue(New RichTextNodeConfig($"发数据超时!", Color.Red), 1)
|
||||
mSendNode.SetTipInfo($"发数据超时!")
|
||||
Return False
|
||||
End If
|
||||
End If
|
||||
Return True
|
||||
End If
|
||||
End Function
|
||||
'获取发送数据
|
||||
Public Function SendPortData1(nodename As String, Mysenddata As SendNode) As Byte()
|
||||
If IsNothing(Mysenddata) OrElse Mysenddata.SendData.Length = 0 Then Return Nothing
|
||||
Return Mysenddata.SendData
|
||||
End Function
|
||||
'发送数据
|
||||
Public Function SendPortData(nodename As String, ByRef Mysenddata As SendNode, sendBytes As Byte(), mTransmitter As SerialPort) As Boolean
|
||||
If IsNothing(G_Transmitter) OrElse G_Transmitter.IsOpen = False Then
|
||||
G_RichTextPrint.AddQueue(New RichTextNodeConfig("发送器未打开!", Color.Red), 1)
|
||||
Return False
|
||||
End If
|
||||
Try
|
||||
'发送数据
|
||||
Mysenddata.SetSendData(sendBytes, Mysenddata.SendTimeout)
|
||||
G_RichTextPrint.AddQueue(New RichTextNodeConfig("TX:", Color.Blue, New Font("宋体", 8), Mysenddata.SendData), 1)
|
||||
G_Transmitter.Write(Mysenddata.SendData, 0, Mysenddata.SendData.Length)
|
||||
'发送刷新对应数值
|
||||
Mysenddata.ResendRefresh()
|
||||
Return True
|
||||
Catch ex As Exception
|
||||
G_RichTextPrint.AddQueue(New RichTextNodeConfig("发送器发送异常!", Color.Red), 1)
|
||||
Return False
|
||||
End Try
|
||||
|
||||
End Function
|
||||
Public Function SendPortData(sendBytes As Byte(), mTransmitter As SerialPort) As Boolean
|
||||
If IsNothing(G_Transmitter) OrElse G_Transmitter.IsOpen = False Then
|
||||
G_RichTextPrint.AddQueue(New RichTextNodeConfig("发送器未打开!", Color.Red), 1)
|
||||
Return False
|
||||
End If
|
||||
Try
|
||||
'发送数据
|
||||
|
||||
G_RichTextPrint.AddQueue(New RichTextNodeConfig("TX:", Color.Blue, New Font("宋体", 8), sendBytes), 1)
|
||||
G_Transmitter.Write(sendBytes, 0, sendBytes.Length)
|
||||
'发送刷新对应数值
|
||||
|
||||
Return True
|
||||
Catch ex As Exception
|
||||
G_RichTextPrint.AddQueue(New RichTextNodeConfig("发送器发送异常!", Color.Red), 1)
|
||||
Return False
|
||||
End Try
|
||||
|
||||
End Function
|
||||
|
||||
|
||||
'添加流程节点
|
||||
Public Function AddFlowNode(nodename As String, Mysenddata As SendNode) As Boolean
|
||||
If FlowList Is Nothing Then Return False
|
||||
FlowList.Add((nodename, Mysenddata))
|
||||
End Function
|
||||
'清空流程节点
|
||||
Public Function ClearFlowNode(Optional isclear As Boolean = False) As Boolean
|
||||
If FlowList Is Nothing Then Return False
|
||||
If isclear Then
|
||||
FlowList.Clear()
|
||||
End If
|
||||
'FlowList.Clear()
|
||||
End Function
|
||||
|
||||
|
||||
'处理接收到的数据
|
||||
Public Function ProcessRecvData(RecvData() As Byte) As Boolean
|
||||
If FlowList Is Nothing Then Return False
|
||||
'判断数据包头是否合法
|
||||
If NT_CAM.IsDataValid(RecvData) Then
|
||||
If RecvData(3) >= &HB0 Then
|
||||
Dim sendbuf = NT_CAM.PackData(RecvData(3), {0})
|
||||
SendPortData(sendbuf, G_Transmitter)
|
||||
ElseIf RecvData(3) >= &H10 AndAlso RecvData(3) < &HA0 Then
|
||||
|
||||
|
||||
|
||||
Select Case RecvData(3)
|
||||
Case &H18
|
||||
Dim sendbuf = NT_CAM.PackData(RecvData(3), {0})
|
||||
SendPortData(sendbuf, G_Transmitter)
|
||||
Dim mControl As Control = ControlDic.Item(&H18)
|
||||
If RecvData(6) = 0 Then
|
||||
SharedFunction.SetFromUI(mControl, "未连接", Color.Black, Color.Red)
|
||||
ElseIf RecvData(6) = 1 Then
|
||||
SharedFunction.SetFromUI(mControl, "已连接", Color.Black, Color.Green)
|
||||
Else
|
||||
SharedFunction.SetFromUI(mControl, "连接异常", Color.Black, Color.Red)
|
||||
End If
|
||||
Return True
|
||||
Case &H19
|
||||
Dim mControl As Control = ControlDic.Item(&H19)
|
||||
Dim sendbuf = NT_CAM.PackData(RecvData(3), {0})
|
||||
SendPortData(sendbuf, G_Transmitter)
|
||||
'获取数据长度
|
||||
Dim len As Integer = RecvData(5) * 256 + RecvData(4)
|
||||
'判断数据长度是否合法 且长度能够取到
|
||||
If len > 0 AndAlso len <= RecvData.Length - 6 Then
|
||||
'获取数据
|
||||
Dim data As Byte() = New Byte(len - 1) {}
|
||||
Array.Copy(RecvData, 6, data, 0, len)
|
||||
'将数组转换为字符串
|
||||
Dim str As String = SharedFunction.ByteToHexString(data)
|
||||
SharedFunction.SetFromUI(mControl, str, Color.Black, Color.White)
|
||||
End If
|
||||
Return True
|
||||
|
||||
|
||||
End Select
|
||||
|
||||
|
||||
|
||||
|
||||
Dim node As SendNode
|
||||
Dim nextNode As SendNode
|
||||
For i = 0 To FlowList.Count - 1
|
||||
node = FlowList(i).Item2
|
||||
If node.SendStatus = SendNode.SendStatusEnum.Send Then
|
||||
If node.RecvStatus = SendNode.RecvStatusEnum.None Then
|
||||
If RecvData(3) = node.SendData(3) Then
|
||||
node.RecvRefresh(RecvData)
|
||||
End If
|
||||
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
|
||||
|
||||
Else
|
||||
Dim node As SendNode
|
||||
Dim nextNode As SendNode
|
||||
For i = 0 To FlowList.Count - 1
|
||||
node = FlowList(i).Item2
|
||||
If node.SendStatus = SendNode.SendStatusEnum.Send Then
|
||||
If node.RecvStatus = SendNode.RecvStatusEnum.None Then
|
||||
If RecvData(3) = node.SendData(3) Then
|
||||
node.RecvRefresh(RecvData)
|
||||
End If
|
||||
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
End If
|
||||
|
||||
End If
|
||||
|
||||
End Function
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
End Class
|
||||
|
||||
Public Class SendNode
|
||||
'命令类型
|
||||
Public Property CommandType As Integer '0:系统命令,1:自定义命令
|
||||
|
||||
'发送时间
|
||||
Public Property SendTime As DateTime
|
||||
'发送数据
|
||||
Public Property SendData As Byte()
|
||||
'重发次数
|
||||
Public Property SendCount As Integer
|
||||
'重发间隔
|
||||
Public Property SendInterval As Integer
|
||||
'超时时间
|
||||
Public Property SendTimeout As Integer
|
||||
'发送状态 0:未发送 1:已发送
|
||||
Public Property SendStatus As Integer
|
||||
'接收状态
|
||||
Public Property RecvStatus As Integer
|
||||
'接收数据
|
||||
Public Property RecvDataLisr As List(Of Byte())
|
||||
|
||||
'提示信息
|
||||
Public Property TipInfo As String
|
||||
|
||||
'最大重 发次数
|
||||
Public Property MaxResendCount As Integer
|
||||
|
||||
'是否接收数据
|
||||
Public Property IsRecvData As Boolean
|
||||
'控件对象
|
||||
Public Property Control As Control
|
||||
|
||||
''' <summary>
|
||||
''' 命令
|
||||
''' </summary>
|
||||
''' <param name="mCommandType"></param>
|
||||
Sub New(mCommandType As Integer, Optional mMaxResendCoun As Integer = 3)
|
||||
CommandType = mCommandType
|
||||
RecvDataLisr = New List(Of Byte())
|
||||
MaxResendCount = mMaxResendCoun
|
||||
IsRecvData = True
|
||||
End Sub
|
||||
|
||||
'设置控件
|
||||
Sub SetControl(mControl As Control)
|
||||
Control = mControl
|
||||
End Sub
|
||||
|
||||
'发送状态枚举值
|
||||
Enum SendStatusEnum
|
||||
'未发送
|
||||
None = 0
|
||||
'已发送
|
||||
Send = 1
|
||||
'发送超时
|
||||
Timeout = 2
|
||||
End Enum
|
||||
|
||||
'接收状态枚举值
|
||||
Enum RecvStatusEnum
|
||||
'未接收
|
||||
None = 0
|
||||
'已接收
|
||||
Recv = 1
|
||||
'接收超时
|
||||
Timeout = 2
|
||||
End Enum
|
||||
|
||||
Sub New(Mysenddata() As Byte)
|
||||
SendData = Mysenddata
|
||||
SendInterval = 0
|
||||
SendTimeout = 1000
|
||||
RecvStatus = 0
|
||||
SendStatus = 0
|
||||
RecvDataLisr = New List(Of Byte())
|
||||
End Sub
|
||||
'设置发送数据
|
||||
Sub SetSendData(Mysenddata() As Byte, Optional gSendTimeout As Integer = 1000)
|
||||
SendData = Mysenddata
|
||||
SendInterval = 0
|
||||
SendTimeout = gSendTimeout
|
||||
RecvStatus = 0
|
||||
SendStatus = 0
|
||||
End Sub
|
||||
|
||||
'接收数据并添加到接收列表
|
||||
Sub AddRecvData(RecvData() As Byte)
|
||||
If RecvDataLisr Is Nothing Then
|
||||
RecvDataLisr = New List(Of Byte())
|
||||
End If
|
||||
RecvDataLisr.Add(RecvData)
|
||||
End Sub
|
||||
'判断需不需要重发 False 不需要重发 True 需要重发
|
||||
Function NeedResend() As Boolean
|
||||
'如果接收状态为已加收, 则不需要重发
|
||||
If SendStatus = 1 AndAlso RecvStatus = 1 Then
|
||||
Return False
|
||||
Else
|
||||
'如果发送状态为已发送,则判断是否超时,如果超时则返回True,否则返回False
|
||||
If SendStatus = 1 Then
|
||||
'判断是否到达最大重发次数
|
||||
If SendCount < MaxResendCount Then
|
||||
|
||||
If SendTime.AddMilliseconds(SendTimeout) < Now Then
|
||||
Return True
|
||||
Else
|
||||
Return False
|
||||
End If
|
||||
|
||||
Else
|
||||
|
||||
'RecvStatus = RecvStatusEnum.Timeout
|
||||
'SendStatus = SendStatusEnum.Timeout
|
||||
Return False
|
||||
End If
|
||||
Else
|
||||
Return True
|
||||
End If
|
||||
|
||||
End If
|
||||
|
||||
End Function
|
||||
|
||||
'重发刷新对应数值
|
||||
Sub ResendRefresh()
|
||||
SendStatus = 1
|
||||
SendCount += 1
|
||||
SendTime = Now
|
||||
End Sub
|
||||
|
||||
'发送刷新对应数值
|
||||
Sub SendRefresh()
|
||||
SendStatus = 1
|
||||
SendTime = Now
|
||||
SendCount = 0
|
||||
End Sub
|
||||
'接收刷新对应数值
|
||||
Sub RecvRefresh(Mysenddata() As Byte)
|
||||
AddRecvData(Mysenddata)
|
||||
RecvStatus = 1
|
||||
End Sub
|
||||
|
||||
'设置提示信息
|
||||
Sub SetTipInfo(Mysenddata As String)
|
||||
TipInfo = Mysenddata
|
||||
End Sub
|
||||
|
||||
|
||||
End Class
|
||||
Reference in New Issue
Block a user