AdsStream的使用
阅读原文时间:2023年07月08日阅读:1

本例子是测试ads通信的。

1.首先添加TwinCAT.Ads引用

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using TwinCAT.Ads;
namespace AdsProject
{
public partial class Main : Form
{
public TcAdsClient _client = null;
//创建句柄
public int _handleBool = 0;
public int _handleByte = 0;
public int _handleInt = 0;
public int _handleArray= 0;//int
public int _handleStruct = 0;//int16 byte real(2+1+4=7) (plc中的Int对应的C#中的int16,Dint对应int,real对应float,lreal对应double,Dword对应uint32)
public int _handleStruct2 = 0;//高级结构体句柄

    public int \_notificationHandleInt = 0;  
    public int \_notificationHandleStruct = 0;  
    public int \_notificationHandleStruct2 = 0;

    \[StructLayout(LayoutKind.Sequential, Pack = 8)\]  
    struct TestStruct  
    {  
        \[MarshalAs(UnmanagedType.I2)\]  
        public Int16 nData;  
        \[MarshalAs(UnmanagedType.I1)\]  
        public byte byVal;  
        \[MarshalAs(UnmanagedType.R4)\]  
        public float fVal;  
    }

    public Main()  
    {  
        InitializeComponent();  
    }  
    private void Main\_Load(object sender, EventArgs e)  
    {  
        try  
        {  
            if (\_client == null)  
            {  
                \_client = new TcAdsClient();  
            }

            //Occurs when the ADS device sends a ADS Notification(通知) to the client.  
            //当PLC发送数据给客户端的时候触发回调函数  
            //回调方式1  
            \_client.AdsNotification += new AdsNotificationEventHandler(AdsNotificationEventOnChange);  
            //回调方式2  
            \_client.AdsNotificationEx += new AdsNotificationExEventHandler(AdsNotificationEventOnChangeEx);  
            \_client.Connect(851);  
            \_handleBool = \_client.CreateVariableHandle("MAIN.Data\_Bool");  
            \_handleByte = \_client.CreateVariableHandle("MAIN.Data\_Byte");  
            \_handleInt = \_client.CreateVariableHandle("MAIN.Data\_Int");  
            \_handleArray = \_client.CreateVariableHandle("MAIN.Data\_Array");  
            \_handleStruct = \_client.CreateVariableHandle("MAIN.Data\_Struct");  
            \_handleStruct2 = \_client.CreateVariableHandle("GVL.stAxis");  
        }  
        catch(Exception ex)  
        {  
            MessageBox.Show(ex.Message);  
        }

    }

    //回调函数2:当设备向客户端发送数据的时候触发  
    private void AdsNotificationEventOnChangeEx(object sender, AdsNotificationExEventArgs e)  
    {  
        if (e.NotificationHandle == \_notificationHandleInt)  
        {  
            Debug.WriteLine(e.Value.ToString());  
            this.BeginInvoke(new Action(() =>  
            {  
                this.txtReadInt.Text = e.Value.ToString();  
            }));  
        }  
        else if (e.NotificationHandle == \_notificationHandleStruct)  
        {  
            TestStruct testc = (TestStruct)e.Value;  
            Debug.WriteLine(testc.nData.ToString());  
            Debug.WriteLine(testc.byVal.ToString());  
            Debug.WriteLine(testc.fVal.ToString());  
            //因为是跨线程操作  
            this.BeginInvoke(new Action(() =>  
            {  
                this.txtReadStructInt16.Text = testc.nData.ToString();  
                this.txtReadStructByte.Text = testc.byVal.ToString();  
                this.txtReadStructFloat.Text = testc.fVal.ToString();  
            }));  
        }  
        //读取高级结构体  
        else if (e.NotificationHandle==\_notificationHandleStruct2)  
        {  
            Plc\_StAxisInfo plcStAxis = new Plc\_StAxisInfo();  
            plcStAxis = (Plc\_StAxisInfo)e.Value;  
            foreach (Plc\_StAxis plc\_StAxis in plcStAxis.Axis)  
            {  
                //获取结构体中的所有字段  
                FieldInfo\[\] fieldInfos = typeof(Plc\_StAxis).GetFields();  
                int FieldCount = fieldInfos.Length;  
                for(int i=0;i< FieldCount;i++)  
                {  
                    if (fieldInfos\[i\].FieldType.Name == "Byte\[\]")  
                    {  
                        byte\[\] b = (byte\[\])fieldInfos\[i\].GetValue(plc\_StAxis);  
                        foreach (var item in b)  
                        {  
                            Debug.WriteLine(item.ToString());  
                        }  
                    }  
                    else if (fieldInfos\[i\].FieldType.Name == "Double\[\]")  
                    {  
                        double\[\] d = (double\[\])fieldInfos\[i\].GetValue(plc\_StAxis);  
                        foreach (var item in d)  
                        {  
                            Debug.WriteLine(item.ToString());  
                        }  
                    }  
                    else  
                    {  
                        //获取字段值  
                        Debug.WriteLine(fieldInfos\[i\].GetValue(plc\_StAxis));  
                    }  
                }  
            }  
        }  
    }

    //回调函数1:当设备向客户端发送数据的时候触发  
    private void AdsNotificationEventOnChange(object sender, AdsNotificationEventArgs e)  
    {  
        //AdsBinaryReader reader = new AdsBinaryReader(e.DataStream);  
        //if (e.NotificationHandle == \_notificationHandleInt)  
        //    Debug.WriteLine(reader.ReadInt16());  
        //else if (e.NotificationHandle == \_notificationHandleStruct)  
        //{  
        //    Debug.WriteLine(reader.ReadInt16());  
        //    Debug.WriteLine(reader.ReadByte());  
        //    reader.ReadByte();  
        //    Debug.WriteLine(reader.ReadSingle());  
        //}  
    }

    //read  
    private void btnRead\_Click(object sender, EventArgs e)  
    {  
        AdsStream stream = new AdsStream(100);  
        AdsBinaryReader reader = new AdsBinaryReader(stream);  
        \_client.Read(\_handleBool,stream);//读取设备中的数据并写入到文件流stream中  
        txtReadBool.Text = reader.ReadBoolean().ToString();//从当前文件流中读取Boolean值,并使当前流的位置提升1个字节

        \_client.Read(\_handleByte, stream);  
        stream.Seek(0,System.IO.SeekOrigin.Begin);//设定流的位置为开头  
        txtReadByte.Text = reader.ReadByte().ToString();//从当前文件流中读取Boolean值,并使当前流的位置提升1个字节

        \_client.Read(\_handleInt, stream);  
        stream.Seek(0, System.IO.SeekOrigin.Begin);//设定流的位置为开头  
        txtReadInt.Text = reader.ReadInt16().ToString();//从当前文件流中读取Boolean值,并使当前流的位置提升2个字节

        \_client.Read(\_handleArray,stream);  
        stream.Seek(0, System.IO.SeekOrigin.Begin);//设定流的位置为开头  
        txtReadArrayInt1.Text = reader.ReadInt16().ToString();//从当前文件流中读取Boolean值,并使当前流的位置提升2个字节  
        txtReadArrayInt2.Text = reader.ReadInt16().ToString();  
        txtReadArrayInt3.Text = reader.ReadInt16().ToString();  
        txtReadArrayInt4.Text = reader.ReadInt16().ToString();

        \_client.Read(\_handleStruct,stream);  
        stream.Seek(0,System.IO.SeekOrigin.Begin);  
        txtReadStructInt16.Text = reader.ReadInt16().ToString();  
        txtReadStructByte.Text = reader.ReadByte().ToString();  
        reader.ReadByte();//前面Int16是两个字节,byte是一个字节,一共三个字节,而float是占四个字节,要从第五个字节开始读,所以要再读第四个字节,然后跳到第五个字节  
        txtReadStructFloat.Text = reader.ReadSingle().ToString();

    }

    //write  
    private void btnWrite\_Click(object sender, EventArgs e)  
    {  
        try  
        {  
            AdsStream stream = new AdsStream(100);  
            AdsBinaryWriter writer = new AdsBinaryWriter(stream);

            writer.Write(Boolean.Parse(txtWriteBool.Text));  
            \_client.Write(\_handleBool, stream, 0, 1);

            stream.Seek(0, System.IO.SeekOrigin.Begin);//设定流的位置为开头  
            writer.Write(Byte.Parse(txtWriteByte.Text));  
            \_client.Write(\_handleByte, stream, 0, 1);

            stream.Seek(0, System.IO.SeekOrigin.Begin);//设定流的位置为开头  
            writer.Write(Int16.Parse(txtWriteInt.Text));  
            \_client.Write(\_handleInt, stream, 0, 2);

            stream.Seek(0, System.IO.SeekOrigin.Begin);//设定流的位置为开头  
            writer.Write(Int16.Parse(txtWriteArrayInt1.Text));  
            writer.Write(Int16.Parse(txtWriteArrayInt2.Text));  
            writer.Write(Int16.Parse(txtWriteArrayInt3.Text));  
            writer.Write(Int16.Parse(txtWriteArrayInt4.Text));  
            \_client.Write(\_handleArray, stream, 0, 8);

            stream.Seek(0, System.IO.SeekOrigin.Begin);  
            writer.Write(Int16.Parse(txtWriteStructInt16.Text));  
            writer.Write(Byte.Parse(txtWriteStructByte.Text));  
            writer.Write((Byte)0);//写入第四个字节  
            writer.Write(float.Parse(txtWriteStructFloat.Text));  
            \_client.Write(\_handleStruct, stream, 0, 8);

        }  
        catch (Exception ex)  
        {  
            MessageBox.Show(ex.Message);  
        }  
    }

    //readany  
    private void btnReadAny\_Click(object sender, EventArgs e)  
    {  
        try  
        {  
            txtReadBool.Text = \_client.ReadAny(\_handleBool, typeof(Boolean)).ToString();  
            txtReadByte.Text = \_client.ReadAny(\_handleByte, typeof(Byte)).ToString();  
            txtReadInt.Text = \_client.ReadAny(\_handleInt, typeof(Int16)).ToString();  
            //从设备中读取short\[\]  
            short\[\] testint = (short\[\])\_client.ReadAny(\_handleArray, typeof(short\[\]),new int\[\] { 4});  
            txtReadArrayInt1.Text = testint\[0\].ToString();  
            txtReadArrayInt2.Text = testint\[1\].ToString();  
            txtReadArrayInt3.Text = testint\[2\].ToString();  
            txtReadArrayInt4.Text = testint\[3\].ToString();  
            // //从设备中读取TestStruct  
            TestStruct tstruct = (TestStruct)\_client.ReadAny(\_handleStruct, typeof(TestStruct));  
            txtReadStructInt16.Text = tstruct.nData.ToString();  
            txtReadStructByte.Text = tstruct.byVal.ToString();  
            txtReadStructFloat.Text = tstruct.fVal.ToString();  
        }  
        catch (Exception ex) {  
            MessageBox.Show(ex.Message);  
        }  
    }

    //writeany  
    private void btnWriteAny\_Click(object sender, EventArgs e)  
    {  
        short\[\] arraytest = new short\[4\]  
        {  
            short.Parse(txtWriteArrayInt1.Text),  
            short.Parse(txtWriteArrayInt2.Text),  
            short.Parse(txtWriteArrayInt3.Text),  
            short.Parse(txtWriteArrayInt4.Text)  
        };  
        TestStruct tstruct = new TestStruct();  
        tstruct.nData = Int16.Parse(txtWriteStructInt16.Text);  
        tstruct.byVal = Byte.Parse(txtWriteStructByte.Text);  
        tstruct.fVal = float.Parse(txtWriteStructFloat.Text);

        \_client.WriteAny(\_handleBool, Boolean.Parse(txtWriteBool.Text));//写入值到设备中  
        \_client.WriteAny(\_handleByte, Byte.Parse(txtWriteByte.Text));//写入值到设备中  
        \_client.WriteAny(\_handleInt, Int16.Parse(txtWriteInt.Text));//写入值到设备中  
        \_client.WriteAny(\_handleArray, arraytest);//写入值到设备中  
        \_client.WriteAny(\_handleStruct, tstruct);//写入值到设备中  
    }  

//tryread
private void btnTryRead_Click(object sender, EventArgs e)
{
int readBytes = 0;
AdsStream stream = new AdsStream(100);
AdsBinaryReader reader = new AdsBinaryReader(stream);
//tryread函数如果读不出来将会返回errorcode,而不是抛出异常
AdsErrorCode code = _client.TryRead((uint)AdsReservedIndexGroups.SymbolValueByHandle, (uint)_handleBool, stream, out readBytes);
txtReadBool.Text = reader.ReadBoolean().ToString();

        stream.Seek(0, System.IO.SeekOrigin.Begin);  
        \_client.TryRead((uint)AdsReservedIndexGroups.SymbolValueByHandle, (uint)\_handleInt, stream, out readBytes);  
        txtReadInt.Text = reader.ReadInt16().ToString();

        stream.Seek(0, System.IO.SeekOrigin.Begin);  
        \_client.TryRead((uint)AdsReservedIndexGroups.SymbolValueByHandle, (uint)\_handleByte, stream, out readBytes);  
        txtReadByte.Text = reader.ReadByte().ToString();

        stream.Seek(0, System.IO.SeekOrigin.Begin);  
        \_client.TryRead((uint)AdsReservedIndexGroups.SymbolValueByHandle, (uint)\_handleStruct, stream, out readBytes);  
        txtReadStructInt16.Text = reader.ReadInt16().ToString();  
        txtReadStructByte.Text = reader.ReadByte().ToString();  
        reader.ReadByte();  
        txtReadStructFloat.Text = reader.ReadSingle().ToString();

        \_client.TryRead((uint)AdsReservedIndexGroups.SymbolValueByHandle, (uint)\_handleArray, stream, out readBytes);  
        stream.Seek(0, System.IO.SeekOrigin.Begin);  
        txtReadArrayInt1.Text = reader.ReadInt16().ToString();  
        txtReadArrayInt2.Text = reader.ReadInt16().ToString();  
        txtReadArrayInt3.Text = reader.ReadInt16().ToString();  
        txtReadArrayInt4.Text = reader.ReadInt16().ToString();  
    }  
    //trywrite  
    private void btnTryWrite\_Click(object sender, EventArgs e)  
    {  
        AdsStream stream = new AdsStream(100);  
        AdsBinaryWriter writer = new AdsBinaryWriter(stream);  
        //trywrite函数如果读不出来将会返回errorcode,而不是抛出异常  
        writer.Write(Boolean.Parse(txtWriteBool.Text));  
        AdsErrorCode code1 = \_client.TryWrite((uint)AdsReservedIndexGroups.SymbolValueByHandle, (uint)\_handleBool, stream,0,1);

        stream.Seek(0, System.IO.SeekOrigin.Begin);  
        writer.Write(Byte.Parse(txtWriteByte.Text));  
        AdsErrorCode code2 = \_client.TryWrite((uint)AdsReservedIndexGroups.SymbolValueByHandle, (uint)\_handleByte, stream, 0, 1);

        stream.Seek(0, System.IO.SeekOrigin.Begin);  
        writer.Write(Int16.Parse(txtWriteInt.Text));  
        AdsErrorCode code3 = \_client.TryWrite((uint)AdsReservedIndexGroups.SymbolValueByHandle, (uint)\_handleInt, stream, 0, 2);

        stream.Seek(0, System.IO.SeekOrigin.Begin);  
        writer.Write(Int16.Parse(txtWriteArrayInt1.Text));  
        writer.Write(Int16.Parse(txtWriteArrayInt2.Text));  
        writer.Write(Int16.Parse(txtWriteArrayInt3.Text));  
        writer.Write(Int16.Parse(txtWriteArrayInt4.Text));  
        AdsErrorCode code4 = \_client.TryWrite((uint)AdsReservedIndexGroups.SymbolValueByHandle, (uint)\_handleArray, stream, 0, 8);

        stream.Seek(0, System.IO.SeekOrigin.Begin);  
        writer.Write(Int16.Parse(txtWriteStructInt16.Text));  
        writer.Write(Byte.Parse(txtWriteStructByte.Text));  
        writer.Write((Byte)0);//写入第四个字节  
        writer.Write(float.Parse(txtWriteStructFloat.Text));  
        AdsErrorCode code5 = \_client.TryWrite((uint)AdsReservedIndexGroups.SymbolValueByHandle, (uint)\_handleStruct, stream, 0, 8);  
    }

    private void btnAsyncRead\_Click(object sender, EventArgs e)  
    {  
        //启动回调  
        \_notificationHandleInt = \_client.AddDeviceNotificationEx("MAIN.Data\_Int", AdsTransMode.OnChange, 1, 0, this, typeof(short));  
        \_notificationHandleStruct = \_client.AddDeviceNotificationEx("MAIN.Data\_Struct", AdsTransMode.OnChange, 1, 0, this, typeof(TestStruct));

    }

    private void Main\_FormClosed(object sender, FormClosedEventArgs e)  
    {  
        if (\_client != null)  
        {  
            \_client.Disconnect();  
        }  
        \_client.Dispose();  
    }

    //利用回调的方式读取高级结构体数据  
    private void btn\_ReadStruct\_Click\_1(object sender, EventArgs e)  
    {  
        \_notificationHandleStruct2 = \_client.AddDeviceNotificationEx("GVL.stAxis", AdsTransMode.OnChange, 1, 0, this, typeof(Plc\_StAxisInfo));

    }

    //写高级结构体  
    private void btn\_WriteStruct\_Click(object sender, EventArgs e)  
    {  
        Plc\_StAxisInfo plcStAxis = new Plc\_StAxisInfo();  
        plcStAxis.Axis = new Plc\_StAxis\[10\];  
        plcStAxis.Axis\[0\].ToDriverIO = 26;  
        plcStAxis.Axis\[1\].ToDriverIO = 36;  
        plcStAxis.Axis\[2\].ToDriverIO = 46;  
        plcStAxis.Axis\[3\].ToDriverIO = 56;  
        plcStAxis.Axis\[4\].ToDriverIO = 66;  
        plcStAxis.Axis\[5\].ToDriverIO = 76;  
        plcStAxis.Axis\[6\].ToDriverIO = 86;  
        plcStAxis.Axis\[7\].ToDriverIO = 96;  
        plcStAxis.Axis\[8\].ToDriverIO = 106;  
        \_client.WriteAny(\_handleStruct2, plcStAxis);//写入值到设备中  
    }

    //readonly方式  
    private void btnReadAnyStruct\_Click(object sender, EventArgs e)  
    {  
        Plc\_StAxisInfo plcStAxis = (Plc\_StAxisInfo)\_client.ReadAny(\_handleStruct2, typeof(Plc\_StAxisInfo));  
        foreach (Plc\_StAxis plc\_StAxis in plcStAxis.Axis)  
        {  
            //获取结构体中的所有字段  
            FieldInfo\[\] fieldInfos = typeof(Plc\_StAxis).GetFields();  
            int FieldCount = fieldInfos.Length;  
            for (int i = 0; i < FieldCount; i++)  
            {  
                if (fieldInfos\[i\].FieldType.Name == "Byte\[\]")  
                {  
                    byte\[\] b = (byte\[\])fieldInfos\[i\].GetValue(plc\_StAxis);  
                    foreach (var item in b)  
                    {  
                        Debug.WriteLine(item.ToString());  
                    }  
                }  
                else if (fieldInfos\[i\].FieldType.Name == "Double\[\]")  
                {  
                    double\[\] d = (double\[\])fieldInfos\[i\].GetValue(plc\_StAxis);  
                    foreach (var item in d)  
                    {  
                        Debug.WriteLine(item.ToString());  
                    }  
                }  
                else  
                {  
                    //获取字段值  
                    Debug.WriteLine(fieldInfos\[i\].GetValue(plc\_StAxis));  
                }  
            }  
        }  
    }  
}  

}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace AdsProject
{
//对于一些超复杂的结构体,使用普通DataStream是很难读取的,比较方便的方式是申请一个同等大小的结构体,然后用readany读取
//PLC-->c#:BOOL--->bool, UINT--->Uint16, DWORD--->int32,LREAL-->Double,UDINT--->Uint32,ARRAY--->数组

\[StructLayout(LayoutKind.Sequential, Pack = 8)\]  
public struct Plc\_StAxis  
{  
    //UINT  
    \[MarshalAs(UnmanagedType.U2)\]  
    public UInt16 DriverIO;  
    \[MarshalAs(UnmanagedType.U2)\]  
    public UInt16 DriverErrorID;

    //BOOL  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool Q\_Brake;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool AxisCamDog1;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool AxisCamDog2;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool LimitP;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool LimitN;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool HOME;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool HomingDirection;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool EXT1;

    //DWORD  
    \[MarshalAs(UnmanagedType.U4)\]  
    public UInt32 ToDriverIO;

    //BOOL  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool ServoOn\_HMI;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool ServoOnInt;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool Homing\_HMI;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool HomingInt;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool BrakeBtn\_HMI;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool Inch\_HMI;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool JogF\_HMI;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool JogB\_HMI;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool StationIni;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool AutoPStart\_HMI;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool StopCond;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool ServoOn\_L;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool OriginOk\_L;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool SingleCycle;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool Busy;

    //LREAL  
    \[MarshalAs(UnmanagedType.R8)\]  
    public double ActPos;  
    \[MarshalAs(UnmanagedType.R8)\]  
    public double AutoPosition;

    //DWORD  
    \[MarshalAs(UnmanagedType.U4)\]  
    public UInt32 Alarm1;  
    //DINT  
    \[MarshalAs(UnmanagedType.U4)\]  
    public UInt32 ErrorID;

    //BOOL  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool ActionEnable;   //轴可动作  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool ActionM;   //轴手动基本条件  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool PosEnable;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool PosEnableM;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool BackAutoPosEN;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool Homing;   //轴回原点  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool MotionMethod;   //轴初始化回原点  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool ServoOn\_M;   //伺服ON  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool Inch\_M;   //寸动  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool JogF\_M;   //正向微动  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool JogB\_M;   //反向微动  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool AutoPStart\_M;   //轴自动停位启动  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool BrakeBtn\_M;   //刹车  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool GrabSafetyPos;  
    \[MarshalAs(UnmanagedType.I1)\]  
    public bool PlacedSafetyPos;

    // //ARRAY\[1..10\] OF BYTE  
    \[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)\]  
    public byte\[\] PosHandStart;   //轴手动启动  
    \[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)\]  
    public byte\[\] PosHandStartM;   //轴手动启动  
    \[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)\]  
    public byte\[\] PosAutoStart;   //轴自动启动  
    \[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)\]  
    public byte\[\] PosStart\_M;   //轴启动  
    \[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)\]  
    public byte\[\] Position\_L;   //轴位指示  
    \[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)\]  
    public byte\[\] PosHandEnable;   //轴手动条件

    //LREAL  
    \[MarshalAs(UnmanagedType.R8)\]  
    public double VelocityTotal;  //速度汇总  
    \[MarshalAs(UnmanagedType.R8)\]  
    public double OriginCompensation;  //原点补偿  
    \[MarshalAs(UnmanagedType.R8)\]  
    public double InchingLength;  //寸动长度  
    \[MarshalAs(UnmanagedType.R8)\]  
    public double Override;  //速度倍率  
    \[MarshalAs(UnmanagedType.R8)\]  
    public double JogVelocity;  //微动速度  
    \[MarshalAs(UnmanagedType.R8)\]  
    public double VelocityManual;  //轴手动速度  
    \[MarshalAs(UnmanagedType.R8)\]  
    public double VelocityAuto;  //轴自动速度  
    \[MarshalAs(UnmanagedType.R8)\]  
    public double VelocityAutoM;  //轴自动速度M  
    \[MarshalAs(UnmanagedType.R8)\]  
    public double VelocityDebug;  //调试速度  
    \[MarshalAs(UnmanagedType.R8)\]  
    public double HomingVelocity;  //原点补偿与寸动速度  
    \[MarshalAs(UnmanagedType.R8)\]  
    public double ErrorRangeSet;  //轴误差范围设定 

    \[MarshalAs(UnmanagedType.I4)\]  
    public Int32 AlarmCount;   //报警计数

    //ARRAY\[1..10\] OF LREAL  
    \[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)\]  
    public double\[\] PositionSet;

    //LREAL  
    \[MarshalAs(UnmanagedType.R8)\]  
    public double DTerminalVelocity;  //对端子速度  
    \[MarshalAs(UnmanagedType.R8)\]  
    public double TerminalvelocityManual;  //对端子手动速度  
    \[MarshalAs(UnmanagedType.R8)\]  
    public double TerminalvelocityAuto;    //对端子自动速度

}  
//GVL中的stAxis数组  
\[StructLayout(LayoutKind.Sequential, Pack = 8)\]  
public struct Plc\_StAxisInfo  
{  
    \[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)\]  
    public Plc\_StAxis\[\] Axis;  
}  

}

倍福plc端

StAixis代码:

(********************************************************************)
//结构体数据说明:
//备注:
(********************************************************************)

TYPE stAxis :
STRUCT
DriverIO AT%I*:UINT; //与驱动器Digital inputs关联
DriverErrorID AT%I*:UINT; //与驱动器Error code关联
// ModelOperation AT%Q*:SINT; //操作模式与驱动器Model of operation关联
Q_Brake AT%Q*:BOOL; //刹车
AxisCamDog1 AT%Q*:BOOL; //凸轮轴原点接近1
AxisCamDog2 AT%Q*:BOOL; //凸轮轴原点接近2
LimitP :BOOL; //正极限
LimitN :BOOL; //负极限
HOME :BOOL; //原点
HomingDirection :BOOL; //回原点方向
EXT1 :BOOL; //外部锁存
ToDriverIO :DWORD;//驱动器IO数据位

ServoOn\_HMI                       :BOOL; //伺服ON按钮  
ServoOnInt                        :BOOL; //初始化伺服ON  
Homing\_HMI                        :BOOL; //回原点启动  
HomingInt                         :BOOL; //初始化回原点  
BrakeBtn\_HMI                      :BOOL; //刹车  
Inch\_HMI                          :BOOL; //寸动  
JogF\_HMI                          :BOOL; //正向微动  
JogB\_HMI                          :BOOL; //反向微动  
StationIni                        :BOOL; //轴所在工位初始化中  
AutoPStart\_HMI                    :BOOL; //轴自动停位启动  
StopCond                          :BOOL; //轴停止条件

ServoOn\_L                         :BOOL; //伺服ON\_L  
OriginOk\_L                        :BOOL; //原点OK标志  
SingleCycle                       :BOOL; //轴所在工位单循环  
Busy                              :BOOL; //轴忙  
ActPos                            :LREAL;//轴当前实际位置  
AutoPosition                      :LREAL;//轴自动停位  
Alarm                             :DWORD;  //报警:00伺服报警 01负极限异常 02正极限异常 03原点接近异常 04轴未找到原点 05轴不在自停位 06伺服驱动器异常 08轴未伺服On  
ErrorID                           :UDINT;

ActionEnable                      :BOOL; //轴可动作  
ActionEnableM                     :BOOL; //轴可动作M  
PosEnable                         :BOOL; //轴手动基本条件  
PosEnableM                        :BOOL; //轴手动基本条件M  
BackAutoPosEN                     :BOOL; //轴可自动回自停位  
Homing                            :BOOL; //轴回原点  
MotionMethod                      :BOOL; //运动方式 0相对1绝对  
ServoOn\_M                         :BOOL; //伺服ON  
Inch\_M                            :BOOL; //寸动  
JogF\_M                            :BOOL; //正向微动  
JogB\_M                            :BOOL; //反向微动  
AutoPStart\_M                      :BOOL; //轴自动停位启动  
BrakeBtn\_M                        :BOOL; //刹车    

GrabSafetyPos                     :BOOL;  //抓取安全位  
PlacedSafetyPos                   :BOOL;  //放料安全位

PosHandStart                      :ARRAY\[1..10\] OF BOOL; //轴手动启动  
PosHandStartM                     :ARRAY\[1..10\] OF BOOL; //轴手动启动  
PosAutoStart                      :ARRAY\[1..10\] OF BOOL; //轴自动启动  
PosStart\_M                        :ARRAY\[1..10\] OF BOOL; //轴启动  
Position\_L                        :ARRAY\[1..10\] OF BOOL; //轴位指示

PositionDone                      :BOOL; //轴动作完成

PosHandEnable                     :ARRAY\[1..10\] OF BOOL; //轴手动条件

VelocityTotal                     :LREAL;//速度汇总  

//
originCompensation :LREAL;//原点补偿

InchLength                         :LREAL;//寸动长度  
Override                           :LREAL;//速度倍率  
JogVelocity                        :LREAL;//微动速度  
VelocityManual                     :LREAL;//轴手动速度  
VelocityAuto                       :LREAL;//轴自动速度  
VelocityAutoM                      :LREAL;//轴自动速度M  
VelocityDebug                      :LREAL;//调试速度  
HomeVelocity                       :LREAL;//原点补偿与寸动速度  
ErrorRangeSet                      :LREAL;//轴误差范围设定  
AlarmCount                         :DINT; //报警计数

PositionSet                        :ARRAY\[1..10\] OF LREAL;//轴位置设置

DTerminalVelocity                  :LREAL;//对端子速度  
TerminalvelocityManual             :LREAL;//对端子手动速度  
TerminalvelocityAuto               :LREAL;//对端子自动速度  

END_STRUCT
END_TYPE

Struct_Data结构体代码

TYPE Struct_Data :
STRUCT
StrData:INT:=45;
StrByte:BYTE:=45;
strFloat:REAL:=45.0;
END_STRUCT
END_TYPE

MAIN(PRO)代码:

PROGRAM MAIN
VAR
Data_Cloud1: LREAL := 0;
Data_Cloud2: LREAL := 0;
bTestData:ARRAY[0..15] OF BOOL;
dData2:ARRAY[0..15] OF LREAL;
nTest:INT:=0;

//c# test  
Data\_Bool  : BOOL:=TRUE;  
Data\_Byte  : BYTE:=120;  
Data\_Int  : INT:=45;  
Data\_Array  : ARRAY \[1..4\] OF INT:=\[256,128,456,789\];  
Data\_Struct  : Struct\_Data;

nEventBool AT %MW10: BOOL;  
nEventByte AT %MW20: BYTE;

fbMathTest:FB\_Math;  

END_VAR

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章