使用TwinCAT.Ads通过C#应用程序编写struct数组

时间:2016-08-22 18:10:48

标签: c# twincat twincat-ads twincat-ads-.net

我正在通过c#应用程序使用TwinCAT.Ads(TwinCAT 3)进行Beckhoff plc通信。应用程序正在读写几个plc变量。我收到了一个错误:

  

“无法编组对象。参数名称:值“

编写struct变量数组时。但应用程序正在读取它而没有任何错误。 任何帮助将不胜感激。下面是我的代码示例。

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

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;
}

我正在编写下面的代码,其中 handle [0] 是变量句柄, station 是长度为5的类数组。

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

1 个答案:

答案 0 :(得分:4)

我猜你错过了PLC中的对应物。请确保在您的PLC中声明了一系列工作站:

public string getPassword(StaffLogin obj)
 {
     connection();
     string passwordStr = String.Empty;
     using (SqlCommand com = new SqlCommand("getPassword", con))
     {
         com.CommandType = CommandType.StoredProcedure;
         com.Parameters.AddWithValue("@Email", obj.Email);
         passwordStr = (string)com.ExecuteScalar();
     }
     return passwordStr;
 }

这个C#代码对我有用:

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

我不知道你的句柄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]数组不应该在plc中的一个结构中结束。试试我的版本,请评论它是否适合您。

编辑:我在C#中使用了这个类定义:

Station

并创建了一个[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; } 并在PLC中使用了这个结构定义:

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 s的数组变量。

它有效。我能够将结构写到PLC并查看数组中的Station"ID: 0""ID: 1"等字符串