Author Topic: Error trying to WriteUDT with array  (Read 4630 times)

yovanino

  • Newbie
  • *
  • Posts: 4
    • View Profile
Error trying to WriteUDT with array
« on: November 04, 2019, 06:05:35 PM »
Im getting an error when try to write a UDT

C# side

public struct Order_Info
        {
            public Int32 Id;
            public string Name;
            public Int32 Plan_Qty;
            public Int32 Time_Est;
        }

Order_Info[] Orders = new Order_Info[5];

DriverAB.WriteUDT("Orders_Pool", Orders);

I Get      "Not Enough Data"

PLC side

Order_Pool
       Order_Pool[0].ID    DINT
       Order_Pool[0].Name    STRING
       Order_Pool[0].Plan_QTY    DINT
       Order_Pool[0].Time_Est    DINT

Thanks

Godra

  • Hero Member
  • *****
  • Posts: 1447
    • View Profile
Re: Error trying to WriteUDT with array
« Reply #1 on: November 04, 2019, 06:38:16 PM »
Archie would probably know better about this but where do you assign values to structure members?

If I try your code as it is, Name is null for each one of them (while the other 3 have value of "0").

yovanino

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Error trying to WriteUDT with array
« Reply #2 on: November 04, 2019, 07:30:29 PM »
I asign the values from a DB, no nulls.
But allways get the same error.

Ive read that maybe is the length of the string but idont know.

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Error trying to WriteUDT with array
« Reply #3 on: November 04, 2019, 08:07:27 PM »
What version are you using? 3.99y Beta 28 introduced some fixes related to UDT arrays

yovanino

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Error trying to WriteUDT with array
« Reply #4 on: November 05, 2019, 11:47:21 AM »
Im using 3.99y beta 34

Godra

  • Hero Member
  • *****
  • Posts: 1447
    • View Profile
Re: Error trying to WriteUDT with array
« Reply #5 on: November 05, 2019, 10:16:26 PM »
It looks like ReadUDT and WriteUDT don't work properly while ReadRaw and WriteRaw do work.

For my example I used this code:

Code: [Select]
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        public struct Order_Info
        {
            public Int32 ID;
            public string Name;
            public Int32 Plan_QTY;
            public Int32 Time_Est;
        }
       
        private void MainForm_Load(object sender, EventArgs e)
        {
            var tags = ethernetIPforCLXCom1.GetTagList(); //Used to confirm that PLC is responding properly


            var udtReadBytes = ethernetIPforCLXCom1.ReadRaw("Orders_Pool", 5); //Read UDT with ReadRaw method (works - this example has 100 bytes returned per UDT member)
            Order_Info[] Orders = new Order_Info[5];
            for (int i = 0; i < Orders.Length; i++)
            {
                Orders[i] = new Order_Info
                {
                    ID = BitConverter.ToInt32(udtReadBytes, 0 + i * 100),
                    Name = System.Text.Encoding.Default.GetString(udtReadBytes, 8 + i * 100, BitConverter.ToInt32(udtReadBytes, 4 + i * 100)),
                    Plan_QTY = BitConverter.ToInt32(udtReadBytes, 92 + i * 100),
                    Time_Est = BitConverter.ToInt32(udtReadBytes, 96 + i * 100),
                };
            }


            var udt1 = ethernetIPforCLXCom1.ReadUDT<Order_Info>("Orders_Pool"); //Read UDT with ReadUDT method (doesn't work properly, all values are 0 or null)
            var udt2 = ethernetIPforCLXCom1.ReadUDT<Order_Info>("Orders_Pool", 5); //Read UDT with ReadUDT method (doesn't work properly, all values are 0 or null)


            Byte[] udtWriteBytes = new Byte[500];
            Order_Info[] Orders_Pool = new Order_Info[5];
            for (int i = 0; i < Orders_Pool.Length; i++)
            {
                Orders_Pool[i].ID = i;
                BitConverter.GetBytes(Orders_Pool[i].ID).CopyTo(udtWriteBytes, 0 + i * 100);
                Orders_Pool[i].Name = "Name" + i.ToString();
                BitConverter.GetBytes(Orders_Pool[i].Name.Length).CopyTo(udtWriteBytes, 4 + i * 100);
                System.Text.Encoding.Default.GetBytes(Orders_Pool[i].Name).CopyTo(udtWriteBytes, 8 + i * 100);
                Orders_Pool[i].Plan_QTY = i + 1;
                BitConverter.GetBytes(Orders_Pool[i].Plan_QTY).CopyTo(udtWriteBytes, 92 + i * 100);
                Orders_Pool[i].Time_Est = i + 2;
                BitConverter.GetBytes(Orders_Pool[i].Time_Est).CopyTo(udtWriteBytes, 96 + i * 100);
            }
            ethernetIPforCLXCom1.WriteRaw("Orders_Pool", 5, udtWriteBytes); //Write UDT with WriteRaw method (works)

            ethernetIPforCLXCom1.WriteUDT("Orders_Pool", Orders_Pool); //Write UDT with WriteUDT method (doesn't work properly - "Not Enough Data")
        }

    }

It is possible that I wasn't doing it right.
« Last Edit: November 05, 2019, 10:47:46 PM by Godra »

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Error trying to WriteUDT with array
« Reply #6 on: November 06, 2019, 08:01:14 AM »
Im getting an error when try to write a UDT

C# side

public struct Order_Info
        {
            public Int32 Id;
            public string Name;
            public Int32 Plan_Qty;
            public Int32 Time_Est;
        }

Order_Info[] Orders = new Order_Info[5];

DriverAB.WriteUDT("Orders_Pool", Orders);

I Get      "Not Enough Data"

PLC side

Order_Pool
       Order_Pool[0].ID    DINT
       Order_Pool[0].Name    STRING
       Order_Pool[0].Plan_QTY    DINT
       Order_Pool[0].Time_Est    DINT
Is your tag in the PLC declared as type Order_Pool[5] ?

Godra

  • Hero Member
  • *****
  • Posts: 1447
    • View Profile
Re: Error trying to WriteUDT with array
« Reply #7 on: November 06, 2019, 02:32:30 PM »
If it's of any help, the attached pictures show how I have it.

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Error trying to WriteUDT with array
« Reply #8 on: November 06, 2019, 05:23:57 PM »
This definitely does not work, for now the work-around is this:

DriverAB.WriteUDT("Orders_Pool[0]", Orders[0]);
DriverAB.WriteUDT("Orders_Pool[1]", Orders[1]);
DriverAB.WriteUDT("Orders_Pool[2]", Orders[2]);
DriverAB.WriteUDT("Orders_Pool[3]", Orders[3]);
DriverAB.WriteUDT("Orders_Pool[4]", Orders[4]);

Godra

  • Hero Member
  • *****
  • Posts: 1447
    • View Profile
Re: Error trying to WriteUDT with array
« Reply #9 on: November 06, 2019, 06:01:29 PM »
How about ReadUDT?

All the following show 0 or null:

Code: [Select]
            var udt1 = ethernetIPforCLXCom1.ReadUDT<Order_Info>("Orders_Pool");
            var udt2 = ethernetIPforCLXCom1.ReadUDT<Order_Info>("Orders_Pool", 5);

            var udt3 = ethernetIPforCLXCom1.ReadUDT<Order_Info>("Orders_Pool[0]", 5);
            var udt4 = ethernetIPforCLXCom1.ReadUDT<Order_Info>("Orders_Pool[1]");

Is this correct code or should I be doing it differently?

Godra

  • Hero Member
  • *****
  • Posts: 1447
    • View Profile
Re: Error trying to WriteUDT with array
« Reply #10 on: November 06, 2019, 06:27:46 PM »
This seems to work, the structure was converted to class::

Code: [Select]
        public class Order_Info
        {
            public Int32 ID;
            public string Name;
            public Int32 Plan_QTY;
            public Int32 Time_Est;

            public Order_Info()
            {
                ID = 0;
                Name = string.Empty;
                Plan_QTY = 0;
                Time_Est = 0;
            }
        }

        var udt = ethernetIPforCLXCom1.ReadUDT<Order_Info>("Orders_Pool", 5);

Archie

  • Administrator
  • Hero Member
  • *****
  • Posts: 5322
    • View Profile
    • AdvancedHMI
Re: Error trying to WriteUDT with array
« Reply #11 on: November 06, 2019, 06:36:26 PM »
This seems to work, the structure was converted to class::
I was just about to post code using a class instead of structure that works.

Godra

  • Hero Member
  • *****
  • Posts: 1447
    • View Profile
Re: Error trying to WriteUDT with array
« Reply #12 on: November 06, 2019, 07:28:51 PM »
GetTagList() does get tag info, as in the attached picture, and shows it as a structure but doesn't know how many members it has.

100 bytes shown are for a single member.

Godra

  • Hero Member
  • *****
  • Posts: 1447
    • View Profile
Re: Error trying to WriteUDT with array
« Reply #13 on: November 06, 2019, 08:10:43 PM »
Maybe you should keep the current WriteUDT code since it allows writing any member of the structure individually.

Some people might find it useful.

yovanino

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Error trying to WriteUDT with array
« Reply #14 on: November 06, 2019, 09:59:21 PM »
I try this and works fine

for (i = 0; i < 5; i++)
   {
     Fill Orders(i) ==>>>>> Call Procedure to fill Order
     DriverAB.WriteUDT("Orders_Pool[" + i + "]", Orders);
    }