问题描述
我正在将三菱 PLC 与我们在 ViualBasic 中构建的“廉价手工”HMI 通信。
我需要在 VisualBasic HMI 的 PLC 内存中跟踪布尔变量的值,我们通过使用 OPC 服务器来实现这一点。这一步没有大的并发症。
接下来,我要把这个变量的状态写到一个sql数据库中,当这个变量改变他的状态时,比如:
If MyVar Changes from 0 to 1 Then
Write "True" in sql (1 entry)
End If
If MyVar Changes from 1 to 0 Then
Write "False" in sql (1 entry)
End If
我的问题是我不知道如何在不不断轮询的情况下捕捉变量状态的变化。这意味着我不断地向我的 sql 数据库添加条目,但我只想要每个状态变化的 1 个条目。
解决方法
您可以创建一个类来跟踪布尔值:
Public Class BooleanWithEvent
Private _value As Boolean
Public Event ValueChanged(sender As Object,e As EventArgs)
Public Property Value
Get
Return _value
End Get
Set(value)
If _value <> value Then
_value = value
RaiseEvent ValueChanged(Me,EventArgs.Empty)
End If
End Set
End Property
End Class
您可以创建此类的实例并添加事件处理程序:
Public WithEvents MyBoolean As New BooleanWithEvent
Private Sub MyBoolean_ValueChanged(sender As Object,e As EventArgs) Handles MyBoolean.ValueChanged
Select Case MyBoolean.Value
Case True
' Write "True" in SQL (1 entry)
Case False
' Write "False" in SQL (1 entry)
End Select
End Sub
编辑
一个更精细的版本,可以跟踪无限数量的值并触发单个事件:
Public Class BooleanValuesWithEvent
Private _values As New Dictionary(Of Integer,Boolean)
''' <summary>
''' Occurs when a value has changed.
''' </summary>
''' <param name="index"></param>
Public Event ValueChanged(index As Integer)
''' <summary>
''' Gets or sets a default value.
''' </summary>
Public Property DefaultValue As Boolean = False
''' <summary>
''' Gets or sets a value.
''' </summary>
''' <param name="index"></param>
Public Property Value(index As Integer) As Boolean
Get
If _values.ContainsKey(index) Then
Return _values.Item(index)
Else
Return DefaultValue
End If
End Get
Set(value As Boolean)
If _values.ContainsKey(index) Then
If _values.Item(index) <> value Then
_values.Item(index) = value
RaiseEvent ValueChanged(index)
End If
Else
_values.Add(index,value)
RaiseEvent ValueChanged(index)
End If
End Set
End Property
End Class
,
大多数工业协议通过请求-响应系统工作,而知道变量已更改的唯一方法是通过不断轮询。
还有其他协议通过发布订阅方法工作,通过它们,您可以在每次变量更改时收到更新,而无需进行轮询。 支持该系统的两种协议是 MQTT(通过代理)和 OPC UA 订阅。
我不知道你使用的那个 OPC 服务器是否是 UA,它是否支持订阅,也许你应该检查一下。