成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C# Opcda 應用詳解,你學會了嗎?

開發 前端
OPC的出現正是為了解決這些問題。它采用一種簡單的接口標準,允許不同的供應商設備和應用程序之間進行數據交換。通過使用OPC,應用程序可以自由地組合不同的設備和應用程序,從而實現更加靈活、高效和經濟的工業自動化系統。

OPC,一句話DA用的越來越少了。全稱OLE For Process Control,是一種工業標準,旨在解決不同供應商設備與應用程序之間的接口標準化問題。隨著工業自動化和控制系統的不斷發展,各種設備和應用程序不斷涌現,其之間的通信變得越來越復雜。傳統的設備和應用程序之間的通信主要依靠編程和調試,但這種方式效率低下、不靈活、成本高,也限制了應用程序的自由組合和開發。

OPC的出現正是為了解決這些問題。它采用一種簡單的接口標準,允許不同的供應商設備和應用程序之間進行數據交換。通過使用OPC,應用程序可以自由地組合不同的設備和應用程序,從而實現更加靈活、高效和經濟的工業自動化系統。

OPC標準包括一組接口規范和協議,可以被用于不同類型的設備和應用程序。OPC的接口規范包括以下幾個部分:OPC控制器規范、OPC數據服務規范、OPC應用程序接口規范和OPC數據傳輸規范。這些規范提供了一種通用的接口,允許設備和應用程序之間進行數據交換。OPC的協議主要包括基于協議的和基于消息的兩種方式。

基于協議的方式是通過協議規范定義的消息格式進行通信。每個設備和應用程序都可以使用OPC協議生成自己的消息格式,從而實現與其他設備和應用程序的通信?;谙⒌姆绞絼t是通過定義消息的格式和目的地來進行通信。消息可以通過OPC服務器進行傳輸,服務器可以是本地的或者遠程的。

OPC標準的實現依賴于OPC基金會,該基金會是一個非營利性的組織,致力于推廣和發展OPC標準?;饡撠熅S護OPC標準,開發新的規范和協議,提供技術支持和培訓等服務。OPC基金會的成員包括各種設備和應用程序的供應商、系統集成商、工程師和用戶。

利用驅動器的系統連接

圖片圖片

利用 OPC 控制的系統組成

圖片圖片

OPC 的分層結構

OPC 對象中最上層的對象是 OPC 服務器,一個 OPC 服務器中可以設置一個以上的 OPC 組。OPC 服務器常對應于某種特定的控制設備,如 DCS 以及 PLC 等。

OPC 組是可以進行數據訪問的多個 OPC 標簽的集合,OPC 應用程序可以將需要的數據分組進行批量讀取,也可以以組為單位啟動或者停止數據訪問。此外,OPC 組還提供組內 OPC 標簽數據變化時向 OPC 應用程序通知的事件。

圖片圖片

OPC 與 OPC UA

OPC DA 與 OPC UA 都是 OPC 協議的標準:

OPC 是一種通過微軟 COM/DCOM 技術來實現自動化控制的協定,采用 C/S 架構。開發人員只需要按照 OPC 的標準編寫 OPC-Client 訪問 OPC-Server 進行讀寫操作即可實現與硬件設備的通信。OPC 的協定中包括:

DA (Data Access):訪問數據的主要規范;

A&E (Alarm and Event):基于事件提供 Client 端訂閱,事件觸發后 Server 主動提交數據;

HDA (History Data Access):歷史數據訪問;

OPC UA 是 OPC 協議的新版,其不再依賴于 COM/DCOM 技術,這意味著其具有跨平臺性,不再局限于 Windows 系統。OPC UA 提供了可靠的通信機制,接口簡單一致。

先用KepServerEx 做個防真環境

模擬數據配制

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

隨機變化型

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

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

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

OPCDA

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

圖片圖片

注意:這個組件在.net core下項目需要是x86下才能正常使用。

一個例子

圖片圖片

做一個自定義控件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);
                }
            };
        }
    }
}

申明一個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是一個字符串,唯一標識注冊的真實OPC數據訪問服務器(實現自定義接口)
            //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();
    }
    
    //同步寫
    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;
        }
    }
}

修改異步寫

//同步寫
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;
    }
}


//異步寫
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);
}


//異步讀完成后的回調
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();
    }
}

數據改變事件

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 關閉事件

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()
        {
            
        }
    }


}
責任編輯:武曉燕 來源: 技術老小子
相關推薦

2024-10-21 07:05:14

C#特性語言

2024-12-31 00:08:37

C#語言dynamic?

2024-12-23 10:06:45

C#深拷貝技術

2024-05-17 08:42:52

AttributeMyClass方法

2024-02-04 00:00:00

Effect數據組件

2024-07-03 08:15:39

C#字符串表達式

2024-01-02 12:05:26

Java并發編程

2022-12-06 07:53:33

MySQL索引B+樹

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動態代理方法

2024-11-06 11:38:59

C#單例模式

2024-01-19 08:25:38

死鎖Java通信

2023-07-26 13:11:21

ChatGPT平臺工具

2023-01-10 08:43:15

定義DDD架構

2022-11-11 08:29:24

C語言中文字符代碼

2025-01-09 07:58:42

C#API函數

2023-03-09 07:38:58

static關鍵字狀態

2024-08-12 08:12:38

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人欧美一区二区三区在线观看 | 久久久精品视频一区二区三区 | 日韩精品一区二区三区 | 亚洲aⅴ| 日韩欧美三级在线 | 男女激情网站免费 | 午夜视频网站 | 日韩av手机在线观看 | 国产蜜臀97一区二区三区 | 欧美一区在线视频 | 999久久久久久久久6666 | 久久国产精品视频 | 在线免费看黄 | 国产精品免费高清 | 欧美不卡一区二区三区 | 天堂资源最新在线 | 日本一区二区高清视频 | 国产欧美在线视频 | 一级国产精品一级国产精品片 | 久久国产精品91 | 色综合一区二区 | 欧美亚洲国产一区二区三区 | 另类在线 | 免费一级片 | 99久久精品免费看国产四区 | 日韩中文电影 | 久久人人爽人人爽 | 中文字幕国产视频 | a视频在线观看 | 一级全黄少妇性色生活免费看 | 视频一区二区中文字幕 | 久久高清 | 99精品久久久久 | xxx国产精品视频 | 免费看片在线播放 | 成人国产精品久久 | 国产高清一区二区 | 免费看的av | 亚洲精品一区二区三区蜜桃久 | 成人黄色在线视频 | 波多野结衣先锋影音 |