Author Topic: Modify DF1Com or EthernetIPforPLCSLCMicroCom drivers to access COM over ethernet  (Read 9161 times)

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
The STX, ETX, and Checksum are all part the Data Link Layer (technically part of the transport layer).

There is a shared function that calculates the checksum:

MfgControl.AdvancedHMI.Drivers.Checksum.CalculateCRC16ForDF1


Godra

  • Hero Member
  • *****
  • Posts: 1447
    • View Profile
I did find checksum in the following property:

Code: [Select]
    Private m_CheckSumType As MfgControl.AdvancedHMI.Drivers.DF1Transport.ChecksumOptions
    Public Property CheckSumType() As MfgControl.AdvancedHMI.Drivers.DF1Transport.ChecksumOptions
        Get
            Return m_CheckSumType
        End Get
        Set(ByVal value As MfgControl.AdvancedHMI.Drivers.DF1Transport.ChecksumOptions)
            m_CheckSumType = value
            If MyDLLInstance > 0 AndAlso DLL.Count > 0 AndAlso DLL(MyDLLInstance) IsNot Nothing Then   'AndAlso Not DLL(MyDLLInstance).IsPortOpen Then
                DLL(MyDLLInstance).ChecksumType = m_CheckSumType
            End If
        End Set
    End Property

From the packet in previous post, would the last 00 be extra byte?

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
10 02      STX
01           Destination Node
00           Source Node
06           Command
00           STS  (error code)
AC 24      TNS (Transaction Number)
03            Function
10 03       ETX
E0 00       CRC16 checksum (2 bytes). Should only be a single byte is BCC is used

Godra

  • Hero Member
  • *****
  • Posts: 1447
    • View Profile
Archie,

With info from this last reply of yours, I did manage to modify the packet, shoot it out the socket and actually get the PLC to respond to it with several different packets (check the attached picture). I did get those packets into the receive buffer but was not sure of how to send them to AB classes for processing and returning the information to AHMI application.

This would indicate to me that this way of communication is definitly possible for DF1 driver.

All my testing was nothing but using a "brute force" instead of creating a proper code that would route packets to a destination other than COM port. I will leave that part to you, if you ever decide to include it in the driver.

Godra

  • Hero Member
  • *****
  • Posts: 1447
    • View Profile
For those who might be interested, here is what I did:

1) Add Import statements at the top of the file:

Code: [Select]
    Imports System.Net
    Imports System.Net.Sockets
    Imports System.Windows.Forms

2) Create 2 new properties to hold the IP address and the port of the remote computer

Code: [Select]
    Private m_IPAddress As String = "192.168.0.197"
    <System.ComponentModel.Category("Communication Settings")> _
    Public Property RemoteIPAddress() As String
        Get
            Return m_IPAddress
        End Get
        Set(ByVal value As String)
            If m_IPAddress <> value Then
                '* Stop the subscriptions and allow the last request to complete
                Dim SubscriptionStatus As Boolean = Me.DisableSubscriptions
                Me.DisableSubscriptions = True
                System.Threading.Thread.Sleep(500)

                m_IPAddress = value

                '* Restart the subscriptions
                Me.DisableSubscriptions = SubscriptionStatus

            End If
        End Set
    End Property

    Private m_remotePort As UShort = &H205A 'Port 8282
    Public Property RemotePort As Integer
        Get
            Return m_remotePort
        End Get
        Set(ByVal value As Integer)
            If m_remotePort <> value Then
                '* Limit the value to 0-65535
                m_remotePort = CUShort(Math.Max(0, Math.Min(value, 65535)))
            End If
        End Set
    End Property

3) Add some variables before and some new code inside the SendPacket sub of the DF1 driver, just after the packet was sent to serial port:

Code: [Select]
    Private socket As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
    Private remoteEP As New IPEndPoint(IPAddress.Parse(m_IPAddress), m_remotePort)
    Private buff As Byte() = New Byte(8191) {}
    Friend Overrides Sub SendPacket(ByVal packet As MfgControl.AdvancedHMI.Drivers.PCCCCommandPacket, ByVal TNS As Integer)
        Dim TNSByte As Byte = Convert.ToByte(TNS And 255)
        RawRequests(TNSByte) = packet
        RawRequests(TNSByte).Responded = False

        Dim data() As Byte = packet.GetBytes
        Dim dataWithNodes(data.Length + 1) As Byte
        data.CopyTo(dataWithNodes, 2)
        dataWithNodes(0) = m_TargetNode
        dataWithNodes(1) = m_MyNode

        DLL(MyDLLInstance).SendData(dataWithNodes, TNS, MyObjectID)

        If m_IPAddress <> Nothing AndAlso m_remotePort <> Nothing Then
            Dim CRC As UShort = MfgControl.AdvancedHMI.Drivers.Checksum.CalculateCRC16ForDF1(dataWithNodes, dataWithNodes.Length)
            Dim CRCbytes As Byte() = BitConverter.GetBytes(CRC)
            Dim dataWithNodesPacket(dataWithNodes.Length + 5) As Byte
            dataWithNodes.CopyTo(dataWithNodesPacket, 2)
            dataWithNodesPacket(0) = &H10 '
            dataWithNodesPacket(1) = &H2  ' Not sure if these 4 entries were specific to my setup
            dataWithNodesPacket(9) = &H10 '
            dataWithNodesPacket(10) = &H3 '
            dataWithNodesPacket(11) = CRCbytes(0)
            dataWithNodesPacket(12) = CRCbytes(1)

            ' *** Using socket to send/receive packets ***
            Try
                If Not socket.Connected Then socket.Connect(remoteEP)
                socket.Send(dataWithNodesPacket)
                If socket.Available > 0 Then
                    Dim bytesAvailable As Integer = Math.Min(socket.Available, 8192)
                    Dim rawData() As Byte = New Byte(bytesAvailable - 1) {}
                    socket.Receive(buff, bytesAvailable, SocketFlags.None)
                    For i As Integer = 0 To bytesAvailable - 1
                        rawData(i) = buff(i)
                    Next
                    Dim rawDataReduced(rawData.Length - 7) As Byte
                    Array.ConstrainedCopy(rawData, 6, rawDataReduced, 0, rawDataReduced.Length)
                    Dim e1 As New MfgControl.AdvancedHMI.Drivers.Common.PlcComEventArgs(rawDataReduced, "B3:0/0", TNS, MyObjectID)
                    DataLinkLayer_DataReceived(Me, e1)
                End If
            Catch ex As Exception
                MessageBox.Show(ex.ToString)
            End Try
        End If
    End Sub

The part of sending the received data to DF1DataLinkLayerDataReceived didn't work properly. I did try sending the data as it was and then stripped of 2 bytes and then stripped of 4 bytes <-- none of these would work.
« Last Edit: September 25, 2016, 04:03:01 PM by Godra »