Author Topic: Basic help with Allen Bradley UDT  (Read 1706 times)

danm

  • Newbie
  • *
  • Posts: 8
    • View Profile
Basic help with Allen Bradley UDT
« on: September 01, 2023, 09:53:38 AM »
I have a UDT in a Allen Bradly PLC.  I am using version 3.99x.  I have tried 'READUDT' but it returns "'ReadUDT' is not a member of 'EthernetIPforCLXCom1'"?  I am having issue understanding how to determine where to start each tag and how many bytes to read.  All strings are 82 long and the format of the UDT is:
Code: [Select]
Public Class CDS 'Common Data Structure
  Public PalletNumber As String
  Public ProductionOrderID As String
  Public InternalOrderID As String
  Public ItemNumber As String
  Public ItemName As String
  Public LotCode As String
  Public ItemGroup As String
  Public Barcode As String
  Public CasesPerPallet As Int16
  Public ProductType As String
  Public Quarantine As Boolean
  Public QuarantineOrderID As String
  Public TimeStamp As String
  Public PartialCaseCount As Int16
  Public PartialP As Boolean
  Public MoverClassification As String
  Public ReservedSalesOrderID As String
  Public Destination As String
  Public Location As String
  Public State As String
  Public Notes As String
End Class

I am using the following to read and display the UDT for testing but some of them come back as gibberish.  I am sure it is in my not understanding what bytes belong to each tag.  As the control works amazing for reading the tags separately.  Can someone help give me a basic understanding of the byte offsets and how to calculate them?

Code: [Select]
  Private Function ReadWO(ByVal tag As String) As String
    Dim bytes As Byte() = EthernetIPforCLXCom1.ReadRaw(tag)
    Dim CommonData As CDS = New CDS With {
    .PalletNumber = ExtractStringField(bytes, 4, 82),
    .ProductionOrderID = ExtractStringField(bytes, 90, 82),
    .InternalOrderID = ExtractStringField(bytes, 176, 82),
    .ItemNumber = ExtractStringField(bytes, 268, 82),
    .ItemName = ExtractStringField(bytes, 354, 82),
    .LotCode = ExtractStringField(bytes, 440, 82),
    .ItemGroup = ExtractStringField(bytes, 529, 82),
    .Barcode = ExtractStringField(bytes, 612, 82),
    .CasesPerPallet = BitConverter.ToInt16(bytes, 698),
    .ProductType = ExtractStringField(bytes, 710, 82),
    .Quarantine = BitConverter.ToBoolean(bytes, 744),
    .QuarantineOrderID = ExtractStringField(bytes, 746, 82),
    .TimeStamp = ExtractStringField(bytes, 890, 82),
    .PartialCaseCount = BitConverter.ToInt16(bytes, 976),
    .PartialP = BitConverter.ToBoolean(bytes, 912),
    .MoverClassification = ExtractStringField(bytes, 914, 82),
    .ReservedSalesOrderID = ExtractStringField(bytes, 996, 82),
    .Destination = ExtractStringField(bytes, 1078, 82),
    .Location = ExtractStringField(bytes, 1160, 82),
    .State = ExtractStringField(bytes, 1242, 82),
    .Notes = ExtractStringField(bytes, 1324, 82)
}
    PrintClassFields(CommonData)
    ' Dim MyUDT As DateTimeUDT = EthernetIPforCLXCom1.ReadUDT("MyUDT", GetType(DateTimeUDT))
  End Function

  Private Function ExtractStringField(bytes As Byte(), offset As Integer, length As Integer) As String
    Dim fieldBytes(length - 1) As Byte
    Array.Copy(bytes, offset, fieldBytes, 0, length)
    Return Encoding.Default.GetString(fieldBytes).Trim().Replace(Convert.ToChar(0), "")
  End Function

 Sub PrintClassFields(obj As Object)
   Dim type As Type = obj.GetType()
   For Each fieldInfo As FieldInfo In type.GetFields()
     Dim fieldName As String = fieldInfo.Name
     Dim fieldValue As Object = fieldInfo.GetValue(obj)
     Debug.WriteLine(fieldName & " : " & fieldValue)
   Next
 End Sub


dmroeder

  • Administrator
  • Full Member
  • *****
  • Posts: 212
    • View Profile
Re: Basic help with Allen Bradley UDT
« Reply #1 on: September 01, 2023, 10:29:45 AM »
Minimum size of a UDT is 4 bytes.  A single bool is 4 bytes  UDT's are packed in 4 byte chunks.  A simple 2 INT UDT will be 4 bytes.  A simple UDT with a INT and BOOL will be 4 bytes.

A string takes 88 bytes of memory.  82 for the characters, 4 for the length and 2 pad bytes.

That INT will be in its own 4 byte chunk.  Take the example STRING/INT/STRING.

STRING = bytes [0-87]
INT = bytes [88-91] (2 pad bytes because next STRING won't fit in the 2 available bytes)
STRING = bytes [92-179]

Similarly, that BOOL Quarantine will occupy its own 4 byte chunk.

I bet if you reorganized your UDT to be strings first, then INTs then BOOLs, you'll see a size change.

bachphi

  • Hero Member
  • *****
  • Posts: 671
    • View Profile
Re: Basic help with Allen Bradley UDT
« Reply #2 on: September 01, 2023, 11:38:32 AM »
Any reason for not using the latest version which supports the ReadUDT?
===================================================
This is NOT alt.read.my.mind.
No such thing is sh^t-for-brains unless you are posting to alt.read.my.mind.
===================================================

dmroeder

  • Administrator
  • Full Member
  • *****
  • Posts: 212
    • View Profile
Re: Basic help with Allen Bradley UDT
« Reply #3 on: September 01, 2023, 01:22:12 PM »
Any reason for not using the latest version which supports the ReadUDT?

LOL, sometimes I overlook the simple solutions :)  But it was fun to think about.

bachphi

  • Hero Member
  • *****
  • Posts: 671
    • View Profile
Re: Basic help with Allen Bradley UDT
« Reply #4 on: September 01, 2023, 02:24:53 PM »
I do that too!

The memory base in RSLogix 5000 is a 32-bit data type.
A single BOOL UDT or an array of BOOL[32] UDT  have the same size as one DINT.
And the next BOOL after 32 will increase the UDT size  to 2 DINT
===================================================
This is NOT alt.read.my.mind.
No such thing is sh^t-for-brains unless you are posting to alt.read.my.mind.
===================================================

danm

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: Basic help with Allen Bradley UDT
« Reply #5 on: September 01, 2023, 04:59:48 PM »
Any reason for not using the latest version which supports the ReadUDT?
The ReleaseNotes399.txt says it is the version 3.99x however as I mentioned when I try and use the ReadUDT method it highlights that line with the error "ReadUDT is not a member of EthernetIPforCLXCom".  I am not sure why because that was my first thought to try.

danm

  • Newbie
  • *
  • Posts: 8
    • View Profile
Re: Basic help with Allen Bradley UDT
« Reply #6 on: September 01, 2023, 05:02:39 PM »
Minimum size of a UDT is 4 bytes.  A single bool is 4 bytes  UDT's are packed in 4 byte chunks.  A simple 2 INT UDT will be 4 bytes.  A simple UDT with a INT and BOOL will be 4 bytes.

A string takes 88 bytes of memory.  82 for the characters, 4 for the length and 2 pad bytes.

That INT will be in its own 4 byte chunk.  Take the example STRING/INT/STRING.

STRING = bytes [0-87]
INT = bytes [88-91] (2 pad bytes because next STRING won't fit in the 2 available bytes)
STRING = bytes [92-179]

Similarly, that BOOL Quarantine will occupy its own 4 byte chunk.

I bet if you reorganized your UDT to be strings first, then INTs then BOOLs, you'll see a size change.

I will talk to the PLC guys!  I don't do any PLC work myself just tasked with connecting them to our other systems.

bachphi

  • Hero Member
  • *****
  • Posts: 671
    • View Profile
Re: Basic help with Allen Bradley UDT
« Reply #7 on: September 02, 2023, 09:46:17 AM »
Any reason for not using the latest version 3.99y which supports the ReadUDT?
===================================================
This is NOT alt.read.my.mind.
No such thing is sh^t-for-brains unless you are posting to alt.read.my.mind.
===================================================