Dear Archie it is about Tow weeks so far since my last replay . I was digging inside the AdvancedHmi Project and For me it was So hard As this is my first time with Visual Basic and .Net
any way during this periode I tried understand the way the project is connected and I did a lot of tests So I found Some Points Which I Hope they will be Helpful for you to make the fixing much more quick
Some of These points are accisple for me so I made the changes by my self the others wich I found are inside the library and as the source of the library is not available so it si very hard for me to make the changs but I put my suggestion about those points
as I do not have a full over view about all the project and the hierarchical connections
between the functions and the objects I tried my best to find a solutions wich are not changing any thing for the other objects
of course you can do it in the best perfect way I hope this will help
and again I repeat my high appreciation of this great work and wish you all the best
E.E.mb
'******************************************************************************
'AdvancedHMIBeta363\AdvancedHMIDrivers\Modbus\ModbusRTUCom.vb
'*
'*
'*Private Function ExtractData(ByVal RawData As List(Of Byte), ByVal startByte As Integer, ByVal address As ModbusAddress) As String()
'*
'*
'* Reference :
'*
'*
'*
'******************************************************************************
'***************************************
'* Extract the returned data
'***************************************
'Original Code********************************************************************************************************************************************************************
'Private Function ExtractData(ByVal RawData As List(Of Byte), ByVal startByte As Integer, ByVal address As ModbusAddress) As String()
'End Original Code****************************************************************************************************************************************************************
'My Code**************************************************************************************************************************************************************************
Private Function ExtractData(ByVal RawData As List(Of Byte), ByVal startByte As Integer, ByVal address As ModbusAddress, ByVal FunctinCode As Integer) As String()
'
Dim ThePlcAddres As String = address.Address
'End My Code ******************************************************************************************************************************************************************
Dim values(address.NumberOfElements - 1) As String
Dim NumberOfBytes As Integer = CInt(Math.Ceiling(address.BitsPerElement / 8))
'The Added Code****************************************************************
'******************************************************************************
'* Modbus RTU Communication driver
'*
'* Extract Data For Function 1 & 2
'*
'* Reference :
'*
'*
'*
'******************************************************************************
If ((FunctinCode = 1) Or (FunctinCode = 2)) Then
Dim InwichByte As Integer = 0
Dim WichBit As Integer = 0
For CurrentBit As Integer = 1 To (address.NumberOfElements)
InwichByte = CInt(Math.Ceiling(CurrentBit / 8))
WichBit = (CurrentBit Mod 8)
If Not m_TreatDataAsHex Then
values(CurrentBit - 1) = CStr(CLng(RawData(InwichByte) >> (WichBit - 1)) And 1)
Else
'values(i) = CalculationsAndConversions.ByteToHex(RawData(startByte + i * NumberOfBytes))
values(CurrentBit - 1) = CStr(CLng(RawData(InwichByte) >> (WichBit - 1)) And 1)
End If
Next
Return values
End If
'End Of Added Code*************************************************************
Dim i As Integer
While i < address.NumberOfElements And (startByte + i) < Math.Floor(RawData.Count / NumberOfBytes)
'Dim HexByte1 As String = Chr(RawData(startByte + i * NumberOfBytes)) & Chr(RawData(startByte + (i * NumberOfBytes) + 1))
If NumberOfBytes > 1 Then
'Dim HexByte2 As String = Chr(RawData(startByte + (i * NumberOfBytes) + 2)) & Chr(RawData(startByte + (i * NumberOfBytes) + 3))
If Not m_TreatDataAsHex Then
values(i) = CStr(RawData(startByte + i * NumberOfBytes) * 256 + RawData(startByte + i * NumberOfBytes + 1))
Else
values(i) = CalculationsAndConversions.ByteToHex(RawData(startByte + i * NumberOfBytes)) & CalculationsAndConversions.ByteToHex(RawData(startByte + i * NumberOfBytes + 1))
End If
Else
If Not m_TreatDataAsHex Then
values(i) = CStr(RawData(startByte + i * NumberOfBytes + 1))
Else
values(i) = CalculationsAndConversions.ByteToHex(RawData(startByte + i * NumberOfBytes))
End If
End If
i += 1
End While
Return values
End Function
'******************************************************************************
'AdvancedHMIBeta363\AdvancedHMIDrivers\Modbus\ModbusRTUCom.vb
'*
'*
'*Protected Sub DataLinkLayerDataReceived(ByVal sender As Object, ByVal e As PlcComEventArgs)
'*
'*
'* Reference :
'*
'*
'*
'******************************************************************************
Protected Sub DataLinkLayerDataReceived(ByVal sender As Object, ByVal e As PlcComEventArgs)
'* Not enough data to make up a FINS packet
'Dim TheCoilNomber As String = SavedResponse(e.TransactionNumber).PlcAddress
If e.RawData Is Nothing OrElse e.RawData.Count < 4 Then
Exit Sub
End If
Dim CoileNumber As Integer = (e.RawData(3) * 16 + e.RawData(2))
Dim RTU As New ModbusRTUFrame(New List(Of Byte)(e.RawData).ToArray, e.RawData.Count)
Dim sid As Integer = e.TransactionNumber
If Not TNS.IsMyTNS(sid) Then
Exit Sub
End If
TNS.ReleaseNumber(sid)
SavedResponse(sid) = e
'Dim HostFrame As New HostLinkFrame(e.RawData)
e.PlcAddress = SavedRequests(sid).Address
'* Is it a FINS excapsulated command?
'If HostFrame.HeaderCode = "FA" Then
'* Extract the RTU Frame
'Dim RTU As New ModbusRTUFrame(HostFrame.EncapsulatedData)
If RTU.PDU.ExceptionCode = 0 Then
If Not SavedRequests(sid).IsWrite Then
'* Extract the data
'Dim values() As String = ExtractData(New List(Of Byte)(Fins.GetEncapsulatedData), 0, SavedRequests(sid))
'Original Code******************************************************************************
'Dim values() As String = ExtractData(RTU.PDU.EncapsulatedData, 1, SavedRequests(sid))
'End Original Code**************************************************************************
'My Code************************************************************************************
'Private Function ExtractData(ByVal RawData As List(Of Byte), ByVal startByte As Integer, ByVal address As ModbusAddress) As String()
Dim _startByte As Integer = 1
Dim values() As String = ExtractData(RTU.PDU.EncapsulatedData, _startByte, SavedRequests(sid), RTU.PDU.FunctionCode)
'End My Code *******************************************************************************
For i As Integer = 0 To values.Length - 1
e.Values.Add(values(i))
Next
'*******************************************************************************************
'* Verify that enough elements were returned before continuing V1.11 6-MAR-12
If e.Values.Count < SavedRequests(sid).NumberOfElements Then
Exit Sub
End If
If m_SynchronizingObject IsNot Nothing Then
'* Is this from a subscription?
If Not SavedRequests(sid).InternallyRequested Then
Dim Parameters() As Object = {Me, e}
m_SynchronizingObject.BeginInvoke(drsd, Parameters)
Else
Dim i As Integer
'* 07-MAR-12 V1.12 If a subscription was deleted, then ignore
Dim SavedCount As Integer = PolledAddressList.Count
While i < PolledAddressList.Count
'* 06-MAR-12 V1.11 Make sure there are enough values returned (4th condition)
'* trap and ignore because subscription may change in the middle of processin
Try
If SavedRequests(sid).ReadFunctionCode = PolledAddressList(i).Address.ReadFunctionCode AndAlso _
SavedRequests(sid).Element <= PolledAddressList(i).Address.Element AndAlso _
(SavedRequests(sid).Element + SavedRequests(sid).NumberOfElements) >= (PolledAddressList(i).Address.Element + PolledAddressList(i).Address.NumberOfElements) AndAlso _
(PolledAddressList(i).Address.Element - SavedRequests(sid).Element + PolledAddressList(i).Address.NumberOfElements) <= SavedResponse(sid).Values.Count Then
Dim f As New PlcComEventArgs(New Byte() {0}, PolledAddressList(i).Address.Address, CUShort(sid))
Dim index As Integer = 0
While index < PolledAddressList(i).Address.NumberOfElements
f.Values.Add(SavedResponse(sid).Values(PolledAddressList(i).Address.Element - SavedRequests(sid).Element + index))
index += 1
End While
Dim x As Object() = {Me, f}
'm_SynchronizingObject.Invoke(PolledAddressList(i).dlgCallBack, x)
Try
'* 07-MAR-12 V1.12
If SavedCount = PolledAddressList.Count Then
m_SynchronizingObject.BeginInvoke(PolledAddressList(i).dlgCallBack, x)
End If
Catch ex As Exception
Dim debug = 0
End Try
End If
Catch ex As Exception
Dim debug = 0
End Try
i += 1
End While
End If
Else
RaiseEvent DataReceived(Me, e)
End If
End If
SavedRequests(sid).Responded = True
Else
If m_SynchronizingObject IsNot Nothing Then
Dim Parameters() As Object = {Me, New PlcComEventArgs(RTU.PDU.ExceptionCode, "Error Code " & CalculationsAndConversions.ByteToHex(CByte(RTU.PDU.ExceptionCode >> 8)))}
m_SynchronizingObject.BeginInvoke(errorsd, Parameters)
Else
RaiseEvent ComError(Me, New PlcComEventArgs(RTU.PDU.ExceptionCode, "Error Code " & CalculationsAndConversions.ByteToHex(CByte(RTU.PDU.ExceptionCode >> 8))))
End If
SavedRequests(sid).ErrorReturned = True
End If
'End If
End Sub
Namespace MfgControl.AdvancedHMI.Drivers.Modbus
Public Class ModbusPDUFrame
'******************************************************************************
'* Namespace MfgControl.AdvancedHMI.Drivers.Modbus
'* Public Class ModbusPDUFrame
'* Public Sub New(ByVal functionCode As Byte, ByVal address As ModbusAddress, ByVal data As Byte())
'*
'* Reference :
'*
'* Note:
'* My Suggestion Code
'******************************************************************************
Public Sub New(ByVal functionCode As Byte, ByVal address As ModbusAddress, ByVal data As Byte())
Me.FullPacket = New List(Of Byte)
Me.FunctionCode = functionCode
'****************************************************************************
'****************************************************************************
'****************************************************************************
If (Me.FunctionCode <> 5) And (Me.FunctionCode <> 6) Then
'The original Code ******************************************************
Me.m_EncapsulatedData = New List(Of Byte)(New Byte() {CByte((address.Element >> 8)), CByte((address.Element And &HFF)), CByte((address.NumberOfElements >> 8)), CByte((address.NumberOfElements And &HFF))})
Me.m_EncapsulatedData.Add(CByte((data.Length And &HFF)))
Dim num2 As Integer = (data.Length - 1)
Dim i As Integer = 0
Do While (i <= num2)
Me.m_EncapsulatedData.Add(data(i))
i += 1
Loop
'End Of the Original Code Block *****************************************
ElseIf Me.FunctionCode = 5 Then
If data(0) = 1 Then
Me.m_EncapsulatedData = New List(Of Byte)(New Byte() {CByte((address.Element >> 8)), CByte((address.Element And &HFF)), CByte(&HFF), CByte((&H0))})
Else
Me.m_EncapsulatedData = New List(Of Byte)(New Byte() {CByte((address.Element >> 8)), CByte((address.Element And &HFF)), CByte(&H0), CByte((&H0))})
End If
ElseIf Me.FunctionCode = 6 Then
'CByte((address.Element >> 8)), CByte((address.Element And &HFF)), CByte((address.NumberOfElements >> 8)), CByte((address.NumberOfElements And &HFF))
Me.m_EncapsulatedData = New List(Of Byte)(New Byte() {CByte((address.Element >> 8)), CByte((address.Element And &HFF))})
'Me.m_EncapsulatedData.Add(CByte((data.Length And &HFF)))
Dim num2 As Integer = (data.Length - 1)
Dim i As Integer = 0
Do While (i <= num2)
Me.m_EncapsulatedData.Add(data(i))
i += 1
Loop
End If
'****************************************************************************
'****************************************************************************
'****************************************************************************
End Sub
Later also I found This Bug
'******************************************************************************
'* Namespace MfgControl.AdvancedHMI.Drivers.Modbus
'* Public Class ModbusPDUFrame
'* Public Sub New(ByVal packet As Byte(), ByVal lengthOfThePacket As Integer, ByVal offset As Integer)
'*
'* Reference :
'*
'* Note:
'* My Suggestion Code
'******************************************************************************
Public Sub New(ByVal packet As Byte(), ByVal lengthOfThePacket As Integer, ByVal offset As Integer)
Me.FullPacket = New List(Of Byte)
'Original Code*********************************************************************************
'offset = 0 From caller
'End Original Code*****************************************************************************
If (offset < 0) Then
offset = 0
End If
'Original Code*********************************************************************************
'Me.m_FunctionCode = packet((0 + offset)) 'The original Bug
'End Original Code*****************************************************************************
'My Code***************************************************************************************
Me.m_FunctionCode = packet((1 + offset))
'End My Code **********************************************************************************
If ((Me.m_FunctionCode >= &H80) AndAlso (packet.Length > 1)) Then
Me.m_ExceptionCode = packet((1 + offset))
Else
Me.m_ExceptionCode = 0
End If
Me.m_EncapsulatedData = New List(Of Byte)
If ((lengthOfThePacket + offset) > packet.Length) Then
lengthOfThePacket = (packet.Length - offset)
End If
Dim newPacketLength As Integer = ((lengthOfThePacket + offset) - 1)
Dim i As Integer = (2 + offset)
Do While (i <= newPacketLength)
Me.m_EncapsulatedData.Add(packet(i))
i += 1
Loop
End Sub 'Stop ************************************************************************************