Fix - AllenBradley fails to read 16/32bit I/O

Help
Anonymous
2012-08-05
2013-05-30

  • Anonymous
    2012-08-05

    If you try to use an address value of O:3 or O:3.0 or O:3.1  they all fail to read anything.

    this is my quick fix:
    in AdvancedHMIDrivers\AllenBradleyPCCC.vb

    in PollUpdate() we need to allow 2 words to be read if the high word is selected.  O:3.1
    around line 400 change the code to:

                Dim isIOfile As Boolean = PolledAddressList(i).FileType = &H8B Or PolledAddressList(i).FileType = &H8C
                While i < PolledAddressList.Count - 1 AndAlso (PolledAddressList(i).FileNumber = PolledAddressList(i + 1).FileNumber And _
                                ((PolledAddressList(i + 1).ElementNumber - PolledAddressList(i).ElementNumber < 20 And Not isIOfile) Or _
                                    PolledAddressList(i + 1).ElementNumber = PolledAddressList(i).ElementNumber))
                    NumberToReadCalc = PolledAddressList(i + 1).ElementNumber - PolledAddressList(FirstElement).ElementNumber + PolledAddressList(i + 1).ElementsToRead
                    If NumberToReadCalc > NumberToRead Then NumberToRead = NumberToReadCalc
                    '* This is used for IO addresses where the bit can be above 15
                    If PolledAddressList(i).BitNumber < 99 AndAlso PolledAddressList(i).BitNumber > HighestBit Then
                        HighestBit = PolledAddressList(i).BitNumber
                    ElseIf PolledAddressList(i).BitNumber = 99 AndAlso isIOfile AndAlso PolledAddressList(i).SubElement = 1 Then
                        NumberToRead = 2
                    End If
                    i += 1
                End While
    

    in DataLinkLayer_DataReceived() we need to allow I/O files to select the second word
    around line 2418 change the code to:

                            EnoughElements = False                    '* Are there enought elements read for this request
                            If (PolledAddressList(i).ElementNumber - PLCAddressByTNS(rTNS).Element + PolledAddressList(i).ElementsToRead <= d.Length) And _
                                (PolledAddressList(i).FileType <> 134 And PolledAddressList(i).FileType <> 135 And PolledAddressList(i).FileType <> &H8B And PolledAddressList(i).FileType <> &H8C) Then
                                EnoughElements = True
                            ElseIf (PolledAddressList(i).BitNumber < 16) And ((PolledAddressList(i).ElementNumber - PLCAddressByTNS(rTNS).Element + PolledAddressList(i).ElementsToRead) / 16 <= d.Length) Then
                                EnoughElements = True
                            ElseIf (PolledAddressList(i).FileType = 134 Or PolledAddressList(i).FileType = 135) And (PolledAddressList(i).ElementNumber - PLCAddressByTNS(rTNS).Element + PolledAddressList(i).ElementsToRead) <= d.Length Then
                                EnoughElements = True
                            ElseIf (PolledAddressList(i).FileType = &H8B Or PolledAddressList(i).FileType = &H8C And _
                                    PolledAddressList(i).ElementNumber = PLCAddressByTNS(rTNS).Element) Then
                                Dim WordToUse As Integer = 0
                                If PolledAddressList(i).BitNumber = 99 Then
                                    WordToUse = PolledAddressList(i).SubElement
                                Else
                                    WordToUse = PolledAddressList(i).BitNumber >> 4
                                End If
                                If (d.Length - 1) >= (PolledAddressList(i).ElementNumber - PLCAddressByTNS(rTNS).Element + WordToUse) Then
                                    EnoughElements = True
                                End If
                            End If
    

    a bit further down change it to:

                                    If PolledAddressList(i).BitNumber < 99 Then
                                        '*TODO : Make this handle a rquest for multiple bits
                                        Try
                                            '* Test to see if bits or integers returned
                                            'Dim x As Integer
                                            Try
                                                'x = d(0)
                                                If PolledAddressList(i).BitNumber < 16 Then
                                                    BitResult(0) = (d(PolledAddressList(i).ElementNumber - PLCAddressByTNS(rTNS).Element) And 2 ^ PolledAddressList(i).BitNumber) > 0
                                                Else
                                                    Dim WordToUse As Integer = PolledAddressList(i).BitNumber >> 4
                                                    Dim ModifiedBitToUse As Integer = PolledAddressList(i).BitNumber Mod 16
                                                    BitResult(0) = (d(PolledAddressList(i).ElementNumber - PLCAddressByTNS(rTNS).Element + (WordToUse)) And 2 ^ ModifiedBitToUse) > 0
                                                End If
                                            Catch ex As Exception
                                                BitResult(0) = d(0)
                                            End Try
                                        Catch ex As Exception
                                            MsgBox("Error in returning data from datareceived - " & ex.Message)
                                        End Try
                                    ElseIf (PolledAddressList(i).FileType = &H8B Or PolledAddressList(i).FileType = &H8C) _
                                        AndAlso PolledAddressList(i).SubElement > 0 Then
                                        BitResult(0) = d(1)
                                    Else
                                        '* All other data types
                                        For k As Integer = 0 To PolledAddressList(i).ElementsToRead - 1
                                            BitResult(k) = d((PolledAddressList(i).ElementNumber - PLCAddressByTNS(rTNS).Element + k))
                                        Next
                                        'm_SynchronizingObject.BeginInvoke(PolledAddressList(i).dlgCallBack, d(PolledAddressList(i).ElementNumber - PLCAddressByTNS(TNSReturned).Element))
                                    End If
                                    SynchronizingObject.BeginInvoke(PolledAddressList(i).dlgCallBack, New Object() {BitResult})
    

    With this O:3 and O:3.0 will give you the lower 16bit Word O:3.0 to O:3.15
    O:3.1 will give you the higher 16bit Word O:3.16 to O:3.31

    I imagine that using O:3 should be made to give you a full 32bit DWord, but I'm not sure if there is an easy way to do it.

    BTW it would not hurt to add descriptions to the properties so we can see it in visual designer.  eg:

        <System.ComponentModel.Category("PLC Properties")> _
        <System.ComponentModel.Description("PLC Driver")> _
        Public Property CommComponent() As AdvancedHMIDrivers.IComComponent
    
     

  • Anonymous
    2012-08-05

    Not the prettiest description of the fix, but I hope it helps.

     

  • Anonymous
    2012-08-06

    Ignore the second block of code above, it should be:

                Dim isIOfile As Boolean = PolledAddressList(i).FileType = &H8B Or PolledAddressList(i).FileType = &H8C
                While i < PolledAddressList.Count - 1 AndAlso (PolledAddressList(i).FileNumber = PolledAddressList(i + 1).FileNumber And _
                                ((PolledAddressList(i + 1).ElementNumber - PolledAddressList(i).ElementNumber < 20 And Not isIOfile) Or _
                                    PolledAddressList(i + 1).ElementNumber = PolledAddressList(i).ElementNumber))
                    NumberToReadCalc = PolledAddressList(i + 1).ElementNumber - PolledAddressList(FirstElement).ElementNumber + PolledAddressList(i + 1).ElementsToRead
    ' skip some good code ...........
    ' then change this
                '*****************************************************
                '* IO addresses can exceed bit 15 on the same element
                '*****************************************************
                If isIOfile Then
                    If PolledAddressList(FirstElement).FileType = PolledAddressList(i).FileType Then
                        If HighestBit > 15 And HighestBit < 99 Then
                            If ((HighestBit >> 4) + 1) > NumberToRead Then
                                NumberToRead = (HighestBit >> 4) + 1
                            End If
                        ElseIf PolledAddressList(i).BitNumber = 99 AndAlso PolledAddressList(i).SubElement = 1 Then
                            NumberToRead = 2
                        End If
                    End If
                End If
    
     

  • Anonymous
    2012-08-06

    Oops, I meant use the last code block I posted for the first block of code. PollUpdate()

    Man sourceforge postings need an edit feature.  And the ability to attach a diff.
    :)