自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C# Opcda 應(yīng)用詳解,你學(xué)會(huì)了嗎?

開(kāi)發(fā) 前端
OPC的出現(xiàn)正是為了解決這些問(wèn)題。它采用一種簡(jiǎn)單的接口標(biāo)準(zhǔn),允許不同的供應(yīng)商設(shè)備和應(yīng)用程序之間進(jìn)行數(shù)據(jù)交換。通過(guò)使用OPC,應(yīng)用程序可以自由地組合不同的設(shè)備和應(yīng)用程序,從而實(shí)現(xiàn)更加靈活、高效和經(jīng)濟(jì)的工業(yè)自動(dòng)化系統(tǒng)。

OPC,一句話DA用的越來(lái)越少了。全稱OLE For Process Control,是一種工業(yè)標(biāo)準(zhǔn),旨在解決不同供應(yīng)商設(shè)備與應(yīng)用程序之間的接口標(biāo)準(zhǔn)化問(wèn)題。隨著工業(yè)自動(dòng)化和控制系統(tǒng)的不斷發(fā)展,各種設(shè)備和應(yīng)用程序不斷涌現(xiàn),其之間的通信變得越來(lái)越復(fù)雜。傳統(tǒng)的設(shè)備和應(yīng)用程序之間的通信主要依靠編程和調(diào)試,但這種方式效率低下、不靈活、成本高,也限制了應(yīng)用程序的自由組合和開(kāi)發(fā)。

OPC的出現(xiàn)正是為了解決這些問(wèn)題。它采用一種簡(jiǎn)單的接口標(biāo)準(zhǔn),允許不同的供應(yīng)商設(shè)備和應(yīng)用程序之間進(jìn)行數(shù)據(jù)交換。通過(guò)使用OPC,應(yīng)用程序可以自由地組合不同的設(shè)備和應(yīng)用程序,從而實(shí)現(xiàn)更加靈活、高效和經(jīng)濟(jì)的工業(yè)自動(dòng)化系統(tǒng)。

OPC標(biāo)準(zhǔn)包括一組接口規(guī)范和協(xié)議,可以被用于不同類型的設(shè)備和應(yīng)用程序。OPC的接口規(guī)范包括以下幾個(gè)部分:OPC控制器規(guī)范、OPC數(shù)據(jù)服務(wù)規(guī)范、OPC應(yīng)用程序接口規(guī)范和OPC數(shù)據(jù)傳輸規(guī)范。這些規(guī)范提供了一種通用的接口,允許設(shè)備和應(yīng)用程序之間進(jìn)行數(shù)據(jù)交換。OPC的協(xié)議主要包括基于協(xié)議的和基于消息的兩種方式。

基于協(xié)議的方式是通過(guò)協(xié)議規(guī)范定義的消息格式進(jìn)行通信。每個(gè)設(shè)備和應(yīng)用程序都可以使用OPC協(xié)議生成自己的消息格式,從而實(shí)現(xiàn)與其他設(shè)備和應(yīng)用程序的通信?;谙⒌姆绞絼t是通過(guò)定義消息的格式和目的地來(lái)進(jìn)行通信。消息可以通過(guò)OPC服務(wù)器進(jìn)行傳輸,服務(wù)器可以是本地的或者遠(yuǎn)程的。

OPC標(biāo)準(zhǔn)的實(shí)現(xiàn)依賴于OPC基金會(huì),該基金會(huì)是一個(gè)非營(yíng)利性的組織,致力于推廣和發(fā)展OPC標(biāo)準(zhǔn)。基金會(huì)負(fù)責(zé)維護(hù)OPC標(biāo)準(zhǔn),開(kāi)發(fā)新的規(guī)范和協(xié)議,提供技術(shù)支持和培訓(xùn)等服務(wù)。OPC基金會(huì)的成員包括各種設(shè)備和應(yīng)用程序的供應(yīng)商、系統(tǒng)集成商、工程師和用戶。

利用驅(qū)動(dòng)器的系統(tǒng)連接

圖片圖片

利用 OPC 控制的系統(tǒng)組成

圖片圖片

OPC 的分層結(jié)構(gòu)

OPC 對(duì)象中最上層的對(duì)象是 OPC 服務(wù)器,一個(gè) OPC 服務(wù)器中可以設(shè)置一個(gè)以上的 OPC 組。OPC 服務(wù)器常對(duì)應(yīng)于某種特定的控制設(shè)備,如 DCS 以及 PLC 等。

OPC 組是可以進(jìn)行數(shù)據(jù)訪問(wèn)的多個(gè) OPC 標(biāo)簽的集合,OPC 應(yīng)用程序可以將需要的數(shù)據(jù)分組進(jìn)行批量讀取,也可以以組為單位啟動(dòng)或者停止數(shù)據(jù)訪問(wèn)。此外,OPC 組還提供組內(nèi) OPC 標(biāo)簽數(shù)據(jù)變化時(shí)向 OPC 應(yīng)用程序通知的事件。

圖片圖片

OPC 與 OPC UA

OPC DA 與 OPC UA 都是 OPC 協(xié)議的標(biāo)準(zhǔn):

OPC 是一種通過(guò)微軟 COM/DCOM 技術(shù)來(lái)實(shí)現(xiàn)自動(dòng)化控制的協(xié)定,采用 C/S 架構(gòu)。開(kāi)發(fā)人員只需要按照 OPC 的標(biāo)準(zhǔn)編寫(xiě) OPC-Client 訪問(wèn) OPC-Server 進(jìn)行讀寫(xiě)操作即可實(shí)現(xiàn)與硬件設(shè)備的通信。OPC 的協(xié)定中包括:

DA (Data Access):訪問(wèn)數(shù)據(jù)的主要規(guī)范;

A&E (Alarm and Event):基于事件提供 Client 端訂閱,事件觸發(fā)后 Server 主動(dòng)提交數(shù)據(jù);

HDA (History Data Access):歷史數(shù)據(jù)訪問(wèn);

OPC UA 是 OPC 協(xié)議的新版,其不再依賴于 COM/DCOM 技術(shù),這意味著其具有跨平臺(tái)性,不再局限于 Windows 系統(tǒng)。OPC UA 提供了可靠的通信機(jī)制,接口簡(jiǎn)單一致。

先用KepServerEx 做個(gè)防真環(huán)境

模擬數(shù)據(jù)配制

線形變化型 RAMP(Rate, Low Limit, High Limit, Increment) Rate:變化率,單位毫秒 Low Limit:下限值 High Limit:上限值 Increment:變化量

隨機(jī)變化型

格式:RANDOM(Rate, Low Limit, High Limit)
Rate:變化率,單位毫秒
Low Limit:下限值
High Limit:上限值

三角函數(shù)型 SINE(Rate, Low Limit, High Limit, Frequency, Phase) Rate:變化率/變化周期,單位毫秒 Low Limit:下限值 High Limit:上限值 Frequency:三角函數(shù)頻率 Phase:三角函數(shù)偏移量

用戶自定義型 USER(Rate, User Value1, User Value2, User Value3,…User ValueN) Rate:變化率,單位毫秒 User Value1….ValueN:用戶自定義的值,可以有多個(gè)

OPCDA

OPCDAAuto.dll下載_解決OPCDAAuto.dll丟失問(wèn)題 OPCDAAuto.dll是微軟vc組件的一個(gè)重要dll文件,缺少它可能會(huì)造成部分軟件或游戲無(wú)法正常運(yùn)行。當(dāng)系統(tǒng)提示“沒(méi)有找到OPCDAAuto.dll”或“丟失OPCDAAuto.dll”等類似錯(cuò)誤信息 dll文件修復(fù)方法:1、解壓下載的文件。2、復(fù)制文件“OPCDAAuto.dll”到系統(tǒng)目錄下。3、系統(tǒng)目錄一般為:C:\WINNT\System32 64位系統(tǒng)為C:\Windows\SysWOW64 4、最后點(diǎn)擊開(kāi)始菜單-->運(yùn)行-->輸入regsvr32 OPCDAAuto.dll 后,回車即可解決錯(cuò)誤提示。

圖片圖片

注意:這個(gè)組件在.net core下項(xiàng)目需要是x86下才能正常使用。

一個(gè)例子

圖片圖片

做一個(gè)自定義控件UPanel。

圖片圖片

public partial class UPanel : UserControl
{
    public event Action<string,string> ValueClick;


    public UPanel()
    {
        InitializeComponent();
    }


    protected override void OnInvalidated(InvalidateEventArgs e)
    {
        base.OnInvalidated(e);
        ResetLocation();
    }
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        ResetLocation();
    }


    protected override void OnResize(EventArgs e)
    {
        base.OnResize(e);
        ResetLocation();
        this.Invalidate();
    }


    private void ResetLocation()
    {
        lblTitle.Left = (this.Width - lblTitle.Width) / 2;
        lblValue.Left = (this.pnlMain.Width - lblValue.Width) / 2;
        lblValue.Top = (this.pnlMain.Height - lblValue.Height) / 2;
    }


    public string Title
    {
        get
        {
            return lblTitle.Text;
        }
        set
        {
            lblTitle.Text = value;
        }
    }


    public string Value
    {
        get
        {
            return lblValue.Text;
        }
        set
        {
            lblValue.Text = value;
        }
    }


    private void pnlMain_Click(object sender, EventArgs e)
    {
        valueClick(Value);
    }


    private void lblValue_Click(object sender, EventArgs e)
    {
        valueClick(Value);
    }


    private void valueClick(string value)
    {
        if (ValueClick != null)
        {
            lblValue.Visible = false;
            TextBox txt = new TextBox();
            txt.Multiline = true;
            this.pnlMain.Controls.Add(txt);
            txt.Dock= DockStyle.Fill;
            txt.Focus();
            txt.MouseLeave += (obj, e) =>
            {
                txt.Visible=false;
                lblValue.Visible = true;
                if(value!=txt.Text && txt.Text != "")
                {
                    Value = txt.Text;
                    this.ValueClick(Value, Title);
                }
            };
        }
    }
}

申明一個(gè)Dev類

public class Dev
{
    public Int32 Bom1 { get; set; }
    public string Part1 { get; set; }


    public Int32 Qty1 { get; set; }
    public Int32 Speed1 { get; set; }
    public bool Status1 { get; set; }
    public bool Status2 { get; set; }
    public bool Status3 { get; set; }
    public bool Status4 { get; set; }


    public Int32 Times1 { get; set; }


    public Int32 Weight { get; set; }


    public int OnLine { get; set; } = 0;
    public int Offline { get; set; } = 0;


    public void Status()
        {
            OnLine = 0;
            Offline = 0;
            var properties= this.GetType().GetProperties()
            .Where(x => x.Name.Contains("Status"));
            foreach (var item in properties)
            {
                if ((bool)item.GetValue(this, null))
                {
                    OnLine++;
                }
                else
                {
                    Offline++;
                }
            }
        }


}

OpcDev類

public class OpcModel
{
    public Action<Dev> ReadFinish=null;
    public Dev dev { get; set; } = new Dev();
    OPCServer MyOpcServer;
    OPCGroup MyOpcGroup;
    OPCItem MyOpcItem1;
    OPCItem MyOpcItem2;
    OPCItem MyOpcItem3;
    OPCItem MyOpcItem4;


    OPCItem MyOpcItem5;
    OPCItem MyOpcItem6;
    OPCItem MyOpcItem7;
    OPCItem MyOpcItem8;


    OPCItem MyOpcItem9;
    OPCItem MyOpcItem10;


    //連接初使化
    public bool Connect()
    {
        try
        {
            MyOpcServer = new OPCServer();
            //ProgID是一個(gè)字符串,唯一標(biāo)識(shí)注冊(cè)的真實(shí)OPC數(shù)據(jù)訪問(wèn)服務(wù)器(實(shí)現(xiàn)自定義接口)
            //The Node name can specify another computer to connect using DCOM.
            MyOpcServer.Connect("Kepware.KEPServerEX.V6", "127.0.0.1");


            MyOpcGroup = MyOpcServer.OPCGroups.Add("MyGroup1");
            MyOpcGroup.IsActive = true;
            //是否可以Change事件
            MyOpcGroup.IsSubscribed = true;
            MyOpcGroup.DeadBand = 0;
            MyOpcGroup.UpdateRate = 100;


            MyOpcItem1 = MyOpcGroup.OPCItems.AddItem("Channel1.Dev1.Bom1", 0);
            MyOpcItem2 = MyOpcGroup.OPCItems.AddItem("Channel1.Dev1.Part1", 0);
            MyOpcItem3 = MyOpcGroup.OPCItems.AddItem("Channel1.Dev1.Qty1", 0);
            MyOpcItem4 = MyOpcGroup.OPCItems.AddItem("Channel1.Dev1.Speed1", 0);
            MyOpcItem5 = MyOpcGroup.OPCItems.AddItem("Channel1.Dev1.Status1", 0);
            MyOpcItem6 = MyOpcGroup.OPCItems.AddItem("Channel1.Dev1.Status2", 0);
            MyOpcItem7 = MyOpcGroup.OPCItems.AddItem("Channel1.Dev1.Status3", 0);
            MyOpcItem8 = MyOpcGroup.OPCItems.AddItem("Channel1.Dev1.Status4", 0);
            MyOpcItem9 = MyOpcGroup.OPCItems.AddItem("Channel1.Dev1.Times1", 0);
            MyOpcItem10 = MyOpcGroup.OPCItems.AddItem("Channel1.Dev1.Weight1", 0);


            //異步讀完成
            MyOpcGroup.AsyncReadComplete += MyOpcGroup_AsyncReadComplete;


            return true;
        }
        catch
        {
            return false;
        }
    }


    //同步讀取信息
    public void ReadValue()
    {
        object ItemValues;
        object Qualities;
        object TimeStamps;


        MyOpcItem1.Read(1, out ItemValues, out Qualities, out TimeStamps);
        dev.Bom1 = (Int32)ItemValues;


        MyOpcItem2.Read(1, out ItemValues, out Qualities, out TimeStamps);
        dev.Part1 = ItemValues.ToString();


        MyOpcItem3.Read(1, out ItemValues, out Qualities, out TimeStamps);
        dev.Qty1 = (Int32)ItemValues;


        MyOpcItem4.Read(1, out ItemValues, out Qualities, out TimeStamps);
        dev.Speed1 = (Int32)ItemValues;


        MyOpcItem5.Read(1, out ItemValues, out Qualities, out TimeStamps);
        dev.Status1 = (bool)ItemValues;


        MyOpcItem6.Read(1, out ItemValues, out Qualities, out TimeStamps);
        dev.Status2 = (bool)ItemValues;


        MyOpcItem7.Read(1, out ItemValues, out Qualities, out TimeStamps);
        dev.Status3 = (bool)ItemValues;


        MyOpcItem8.Read(1, out ItemValues, out Qualities, out TimeStamps);
        dev.Status4 = (bool)ItemValues;


        MyOpcItem9.Read(1, out ItemValues, out Qualities, out TimeStamps);
        dev.Times1 = (Int32)ItemValues;


        MyOpcItem10.Read(1, out ItemValues, out Qualities, out TimeStamps);
        dev.Weight = (Int32)ItemValues;


        dev.Status();
    }
    
    //同步寫(xiě)
    public void WriteValue(string title, object value)
    {
        int[] tmp = new int[] { 0, MyOpcItem1.ServerHandle };
        Array serverHandles = (Array)tmp;
        Array Errors;
        int cancelID;
        object[] v = new object[] { "", value };
        Array values = (Array)v;
        MyOpcGroup.SyncWrite(1, ref serverHandles, ref values, out Errors);
        switch (title)
        {
            default:
                break;
        }
    }
}

修改異步寫(xiě)

//同步寫(xiě)
public void WriteValue(string title, object value)
{
    int[] tmp = new int[] { 0, MyOpcItem1.ServerHandle };
    Array serverHandles = (Array)tmp;
    Array Errors;
    int cancelID;
    object[] v = new object[] { "", value };
    Array values = (Array)v;
    MyOpcGroup.SyncWrite(1, ref serverHandles, ref values, out Errors);
    switch (title)
    {
        default:
            break;
    }
}


//異步寫(xiě)
public void WriteValueAsync(string title, object value)
{
    int[] tmp = new int[] { 0, MyOpcItem1.ServerHandle };


    Array serverHandles = (Array)tmp;
    Array Errors;
    int cancelID;
    object[] v = new object[] { "", value };
    Array values = (Array)v;
    MyOpcGroup.AsyncWrite(1, ref serverHandles, ref values
    , out Errors, 1, out cancelID);


    switch (title)
    {
        default:
            break;
    }
}

異步讀

//異步讀
public void ReadValueAsync()
{
    int[] tmp = new int[] { 0, MyOpcItem1.ServerHandle, MyOpcItem2.ServerHandle
    , MyOpcItem3.ServerHandle, MyOpcItem4.ServerHandle, MyOpcItem5.ServerHandle
    , MyOpcItem6.ServerHandle, MyOpcItem7.ServerHandle, MyOpcItem8.ServerHandle
    , MyOpcItem9.ServerHandle, MyOpcItem10.ServerHandle };
    Array serverHandles = (Array)tmp;
    Array Errors;
    int cancelID;
    MyOpcGroup.AsyncRead(10, ref serverHandles, out Errors, 1, out cancelID);
}


//異步讀完成后的回調(diào)
private void MyOpcGroup_AsyncReadComplete(int TransactionID, int NumItems
, ref Array ClientHandles, ref Array ItemValues
, ref Array Qualities, ref Array TimeStamps, ref Array Errors)
{
    dev.Bom1 = (Int32)MyOpcItem1.Value;
    dev.Part1 = MyOpcItem2.Value.ToString();
    dev.Qty1 = (Int32)MyOpcItem3.Value;
    dev.Speed1 = (Int32)MyOpcItem4.Value;
    dev.Status1 = (bool)MyOpcItem5.Value;
    dev.Status2 = (bool)MyOpcItem6.Value;
    dev.Status3 = (bool)MyOpcItem7.Value;
    dev.Status4 = (bool)MyOpcItem8.Value;
    dev.Times1 = (Int32)MyOpcItem9.Value;
    dev.Weight = (Int32)MyOpcItem10.Value;


    if (ReadFinished != null)
    {
        ReadFinished();
    }
}

數(shù)據(jù)改變事件

MyOpcGroup.IsSubscribed = true; //只有為真事件才有效


MyOpcGroup.DataChange += MyOpcGroup_DataChange; //綁定事件


private void MyOpcGroup_DataChange(int TransactionID, int NumItems
, ref Array ClientHandles
, ref Array ItemValues, ref Array Qualities, ref Array TimeStamps)
{
    dev.Bom1 = (Int32)MyOpcItem1.Value;
    dev.Part1 = MyOpcItem2.Value.ToString();
    dev.Qty1 = (Int32)MyOpcItem3.Value;
    dev.Speed1 = (Int32)MyOpcItem4.Value;
    dev.Status1 = (bool)MyOpcItem5.Value;
    dev.Status2 = (bool)MyOpcItem6.Value;
    dev.Status3 = (bool)MyOpcItem7.Value;
    dev.Status4 = (bool)MyOpcItem8.Value;
    dev.Times1 = (Int32)MyOpcItem9.Value;
    dev.Weight = (Int32)MyOpcItem10.Value;
    if (DataChanged != null)
    {
        DataChanged();
    }
}

Opc server 關(guān)閉事件

MyOpcServer.ServerShutDown += MyOpcServer_ServerShutDown;


private void MyOpcServer_ServerShutDown(string Reason)
{
    
}

界面代碼

public partial class FrmMain : Form
    {
        OpcModel opc = new OpcModel();
        System.Timers.Timer timer= new System.Timers.Timer();
        public FrmMain()
        {
            InitializeComponent();
            timer.Interval = 1000;
            timer.Elapsed += Timer_Elapsed;
        }


        private void Timer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
        {
            opc.ReadValueAsync();
        }


        private void Opc_ReadFinished()
        {
            this.Invoke(() =>
            {
                uPanel1.Title = "Bom1";
                uPanel1.Value = opc.dev.Bom1.ToString();


                uPanel2.Title = "Part1";
                uPanel2.Value = opc.dev.Part1.ToString();


                uPanel3.Title = "Qty1";
                uPanel3.Value = opc.dev.Qty1.ToString();


                uPanel4.Title = "Speed1";
                uPanel4.Value = opc.dev.Speed1.ToString();


                uPanel5.Title = "Status1";
                uPanel5.Value = opc.dev.Status1.ToString();


                uPanel6.Title = "Status2";
                uPanel6.Value = opc.dev.Status2.ToString();


                uPanel7.Title = "Status3";
                uPanel7.Value = opc.dev.Status3.ToString();


                uPanel8.Title = "Status4";
                uPanel8.Value = opc.dev.Status4.ToString();


                uPanel9.Title = "Times1";
                uPanel9.Value = opc.dev.Times1.ToString();


                uPanel10.Title = "Weight";
                uPanel10.Value = opc.dev.Weight.ToString();


                uPanel1.Refresh();
                uPanel2.Refresh();
                uPanel3.Refresh();
                uPanel4.Refresh();




                uPanel5.Refresh();
                uPanel6.Refresh();
                uPanel7.Refresh();
                uPanel8.Refresh();
                uPanel9.Refresh();
                uPanel10.Refresh();
            });
        }


        private void btnStart_Click(object sender, EventArgs e)
        {
            opc.Connect();
            opc.ReadFinished += Opc_ReadFinished;
            opc.DataChanged += Opc_DataChanged;
            //timer.Start();
        }


        private void Opc_DataChanged()
        {
            Opc_ReadFinished();
        }


        private void pnlValueClick(string value,string title)
        {
            opc.WriteValueAsync(title, value);
            opc.WriteFinished -= Opc_WriteFinished;
            opc.WriteFinished += Opc_WriteFinished;
        }


        private void Opc_WriteFinished()
        {
            
        }
    }


}
責(zé)任編輯:武曉燕 來(lái)源: 技術(shù)老小子
相關(guān)推薦

2024-10-21 07:05:14

C#特性語(yǔ)言

2024-12-31 00:08:37

C#語(yǔ)言dynamic?

2024-12-23 10:06:45

C#深拷貝技術(shù)

2024-05-17 08:42:52

AttributeMyClass方法

2024-07-03 08:15:39

C#字符串表達(dá)式

2024-01-02 12:05:26

Java并發(fā)編程

2024-02-04 00:00:00

Effect數(shù)據(jù)組件

2022-12-06 07:53:33

MySQL索引B+樹(shù)

2022-07-13 08:16:49

RocketMQRPC日志

2023-03-26 22:31:29

2024-10-16 11:28:42

2022-04-26 08:41:54

JDK動(dòng)態(tài)代理方法

2024-11-06 11:38:59

C#單例模式

2023-03-09 07:38:58

static關(guān)鍵字狀態(tài)

2023-05-18 09:01:11

MBRGPT分區(qū)

2024-10-12 10:25:15

2024-08-12 08:12:38

2024-05-07 07:58:47

C#程序類型

2025-01-09 07:58:42

C#API函數(shù)

2022-11-11 08:29:24

C語(yǔ)言中文字符代碼
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)