Записать массив struct с использованием TwinCAT.Ads через приложение C#

Я использую TwinCAT.Ads (TwinCAT 3) для связи Beckhoff plc через приложение C#. Приложение читает и пишет несколько переменных plc. Я получаю сообщение об ошибке:

"Невозможно собрать объект. Имя параметра: значение "

при написании массива переменных структуры. Однако приложение читает его без каких-либо ошибок. Любая помощь будет оценена. Ниже приведен мой пример кода.

Структура в Plc

TYPE Station :
    STRUCT
        ClusterID   : STRING[10];
        Tech_Type   : USINT;
        Status      : BOOL;
        Reject      : BOOL;
        Rej_Detail  : STRING[50];
        Rej_Catagory : USINT; 
    END_STRUCT
END_TYPE

Класс в с #

[StructLayout(LayoutKind.Sequential, Pack = 0)]
public class Station
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
    public string ClusterID;
    public byte Tech_Type;
    [MarshalAs(UnmanagedType.I1)]
    public bool Status;
    [MarshalAs(UnmanagedType.I1)]
    public bool Reject;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 51)]
    public string Rej_Detail;
    public byte Rej_Catagory;
}

Я пишу с кодом ниже, где дескрипторы [0] это переменная дескриптор, а станции это массив класса с длиной 5.

adsClient.WriteAny(handles[0], stations, new int[] { 5 });

1 ответ

Решение

Я полагаю, вам не хватает аналога в ПЛК. Пожалуйста, убедитесь, что в вашем ПЛК вы объявили массив станций что-то вроде:

// I have it in a global variable list named: STG_Variables
stat_array_Var : array [0..5] of Station;

Этот код C# работает для меня:

TcAdsClient AdsComClient = new TcAdsClient();
AdsComClient.Connect(NetID_TwinCat, 851);

int handle_array = AdsComClient.CreateVariableHandle("STG_Variables.stat_array_Var");

// get some test stations:
Station station = new Station();
Station station2 = new Station();
Station station3 = new Station();
Station station4 = new Station();
Station station5 = new Station();

Station[] station_plural = new Station[] { station, station2, station3, station4, station5 };

// write some stuff to recognize that write test worked
for (int i = 0; i < station_plural.Length; i++)
{
    station_plural[i].ClusterID = "ID: " + i.ToString();
}

// just use the normal WriteAny method without the new int[] { 5 } parameter!
// send it down to the plc
AdsComClient.WriteAny(handle_array, plural);

Я не знаю где твоя ручка handles[0] указывает на. писать массив Station не должен заканчиваться в одной единственной структуре в plc. Попробуйте мою версию и, пожалуйста, прокомментируйте, сработало ли это для вас.

РЕДАКТИРОВАТЬ: я использовал это определение класса в C#:

[StructLayout(LayoutKind.Sequential, Pack = 0)]
public class Station
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
    public string ClusterID;
    public byte Tech_Type;
    [MarshalAs(UnmanagedType.I1)]
    public bool Status;
    [MarshalAs(UnmanagedType.I1)]
    public bool Reject;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 51)]
    public string Rej_Detail;
    public byte Rej_Catagory;
}

и создал DUT и использовал это определение структуры в ПЛК:

TYPE Station :
STRUCT
    ClusterID   : STRING[10];
    Tech_Type   : USINT;
    Status      : BOOL;
    Reject      : BOOL;
    Rej_Detail  : STRING[50];
    Rej_Catagory : USINT; 
END_STRUCT
END_TYPE

и объявил переменную массива Stationкак описано выше.

И это работает. Я могу записать структуру в ПЛК и увидеть "ID: 0", "ID: 1", "ID: 2" и так далее в массиве

Другие вопросы по тегам