使用PLCcom.dll操作西門子系列PLC

来源:https://www.cnblogs.com/gfjin/archive/2017/12/26/8116357.html
-Advertisement-
Play Games

工作中經常需要瞭解plcdb塊的數據!由於工作使用OPC類庫進行通訊,開發,配置,使用都比較麻煩, 特在網上找到一個名為PLCcom.dll的類庫,可以實現PLC讀寫操作,下麵演示C#如何使用PLCcom.dll類庫 首先看一下封裝對PLCcom調用的幫助類: using System;using ...


工作中經常需要瞭解plcdb塊的數據!由於工作使用OPC類庫進行通訊,開發,配置,使用都比較麻煩,

特在網上找到一個名為PLCcom.dll的類庫,可以實現PLC讀寫操作,下麵演示C#如何使用PLCcom.dll類庫

首先看一下封裝對PLCcom調用的幫助類:

using System;
using PLCcom;
using System.Data;
//using System.Windows.Forms;

namespace GetPlcInfo
{
 /// <summary>
 /// Description of PLCReadWriteHelper.
 /// </summary>
 public class PLCReadWriteHelper
 {
  
  #region 變數定義
  private static PLCReadWriteHelper instance=null;//當前類實例
        private ePLCType cpu = ePLCType.S7_300_400_compatibel;//cpu類型
        private string ip = "192.168.150.201";//CpuIP
        private short rack = 0;//機架號
        private short slot = 3;//插槽號
        public TCP_ISO_Device plc = null;//Plc對象
        private const string user = "111";//用戶
        private const string serial = "51135-21193-754111-1111111";//系列號
        public delegate void OnErrorHandler(OnErrorEventArgs e);//發生錯誤委托
        public event OnErrorHandler OnError;//發生錯誤事件
        public delegate void SuccessHandler(SuccessedEventArgs e);//成功委托
        public event SuccessHandler success;//成功事件
        #endregion
        #region 構造函數
        public PLCReadWriteHelper(ePLCType type,string plcip,string plcRack,string plcsolt)
  {
   this.cpu=ePLCType.S7_300_400_compatibel;
   this.ip=plcip;
   this.rack=short.Parse( plcRack );
   this.slot=short.Parse( plcsolt );
   plc=new TCP_ISO_Device(ip,rack,slot,cpu);
         
   authentication.User=user;
   authentication.Serial =serial ;
   
  }
        #endregion
        #region 連接
        public void TestConnect()
        {
         try
         {
         if (instance!=null)
         {
          ConnectResult cr=plc.Connect();
          //連接失敗
   if (!cr.HasConnected)
   {
    if (OnError!=null)
    {
     OnError (new OnErrorEventArgs(string.Format("連接到PLC:{0}時,發生錯誤!{1}",this.ip,cr.Message)));
    }
   }
   //成功!
   else
   {   
    if(success!=null)
    {
     success(new SuccessedEventArgs("PLC"+this.ip+"連接成功!"+cr.Message));
    }
   }
         }
         }
         catch(Exception ex)
         {
          WriteError("連接失敗:"+ex.Message);
         }
        }
        public void disconnect()
        {
            plc.DisConnect();
        }
        #endregion
        #region 獲取時間

        public  DateTime  GetCpuTime()
        {
            if (instance == null)
            {
                instance = GetInstance(ePLCType.Other,"192.168.0.4", "0", "1");
                instance.plc.Connect();
            }
            ReadRequest[] request = new ReadRequest[1];
            request[0] = new ReadRequest();
            request[0].Region = eRegion.DataBlock;
            request[0].StartByte = 0;
            request[0].Len = 37;
            request[0].DB = 10;
         
            ReadResult[] res = plc.read(request);

            if (!res[0].HasWorked)
            {
                WriteError("讀取CPU時間失敗:" + res[0].Message);
                return DateTime.MinValue;
            }
            else
            {
                return res[0].get_DATE_AND_TIME();
            }

        }
        #endregion
        #region 獲得當前類的實例
        /// <summary>
        /// 靜態方法獲得此幫助類的實例
        /// </summary>
        /// <param name="type">cpu類型</param>
        /// <param name="plcip">ip地址</param>
        /// <param name="plcRack">機架號</param>
        /// <param name="plcsolt">插槽號</param>
        /// <returns></returns>
        public static PLCReadWriteHelper GetInstance(ePLCType type,string plcip,string plcRack,string plcsolt)//此處偷了個懶寫了最簡單的單例,此處線程不安全!
        {
            lock (typeof(PLCReadWriteHelper))
            {
                if (instance == null)
                {
                    instance = new PLCReadWriteHelper(type,plcip,plcRack,plcsolt );
                    return instance;
                }
                else
                {
                    return instance;
                }
            }
        }
          #endregion
        #region 讀PLC信息
        public byte[] ReadPLC(int db,int Start,int Length)
        {
         byte[]readbytes=null;
         
         
         try{
           if (this.plc==null)
           {
            plc=new TCP_ISO_Device (ip,rack,slot,cpu);
            plc.Connect();
           }
           ReadRequest[]request=new ReadRequest[1] ;
           request[0]=new ReadRequest ();
           request[0].Region=eRegion.DataBlock;
           request[0].DB=db;
           request[0].StartByte=Start;
           request[0].Len=Length;
           ReadResult[]res=plc.read(request);
           if (!res[0].HasWorked)
           {
            this.plc=null;
            
           }
           readbytes=new byte[res[0].getBufferLen()];
           int index=0;
           while (res[0].dataAvailable())
           {
            readbytes[index++]+=res[0].get_Byte();
            
           }
                plc.DisConnect();
           
           if (success !=null)
           {
            success(new SuccessedEventArgs("讀取CPU信息成功!"));
                    string result = null;
                    foreach(var n in readbytes)
                    {
                        result+=n.ToString()+"|";
                    }
                    if(result!=null)
                    {
                        success(new SuccessedEventArgs(result));
                    }
           }
           return readbytes;
          }
            catch(NullReferenceException) { return null; }
         catch(Exception ex)
         {
               
          WriteError("讀取指定信息錯誤:"+ex.Message);
          return null;
         }
        }
       
       
#endregion       
        #region 寫信息到DB塊
        public WriteResult WritePLC(int db,int Start,byte[]wValue)
        {
         try
         {
          if (plc==null)
          {
           plc=new TCP_ISO_Device (ip,rack,slot,cpu);
           plc.Connect();
          }
          
          WriteRequest[]writes=new WriteRequest[1];
          writes[0]=new WriteRequest ();
          writes[0].Region=eRegion.DataBlock;
          writes[0].DB=db;
          writes[0].StartByte=Start;
          writes[0].addByte(wValue);
          WriteResult[]wrs=plc.write(writes );
          if (wrs[0].HasWorked != true)
                {
                    this.plc = null;
                }

                return wrs[0];
           
         }
         catch (Exception ex)
         {
          WriteError("寫入信息錯誤:"+ex.Message);
          return new WriteResult ();
         }
        }
        
        
#endregion    
  #region 拋出異常
void WriteError(string errmsg)
{
 if (OnError!=null)
          {
  OnError(new OnErrorEventArgs (errmsg));
          }
}
#endregion
  #region byte數組轉換為字
public int[]ConvertToints(byte[]bt)
{
 try
 {
 int []result  = new int[(bt.Length / 2)];
                        for (int ii = 0; ii < result.Length; ii++)
                        {
                    result[ii] = Convert.ToInt16(bt[ii * 2]) * 256 + Convert.ToInt16(bt[ii * 2 + 1]);
                           
                        }
                        return result;
               
 }
 catch(Exception ex)
 {
  WriteError("位元組數組轉換成int數組失敗:"+ex.Message);
  return null;
 }
}

#endregion
        #region 自定義事件類
          /// <summary>
          /// 發生錯誤
          /// </summary>
        public class OnErrorEventArgs
        {
          string errMsg=string.Empty;
         public OnErrorEventArgs(string errmsg)
         {
           this.errMsg=errmsg;
         }
         public string ErrMsg
         {get{return this. errMsg;}
        }
         
        }
        /// <summary>
        /// 成功
        /// </summary>
    public class SuccessedEventArgs
        {
         string errMsg=string.Empty;
         public SuccessedEventArgs(string errmsg)
         {
           this.errMsg=errmsg;
         }
         public string ErrMsg
         {
          get{return this. errMsg;}
         }
  }
        #endregion
        #region  讀取IO

       public  DateTime  GetTime()
        {
          ReadResult rs= plc.GetPLCTime();
          DateTime dt=  rs.get_DATE_AND_TIME();
           
            return dt;
        }
            
           public  void readIO()
        {
            ReadRequest[] re = new ReadRequest[1];
            re[0].Region = eRegion.Input;
            re[0].Bit = 1;
            re[0].StartByte = 253;
            re[0].Len = 1;
           ReadResult []rr= plc.read(re);
       
        if (  rr[0].isBit)
            {
           //  MessageBox.Show(rr[0].Buffer.ToString());
            }
      
        }
      
        #endregion
        public LEDInfoResult GetLEDINFO()
        {
            return plc.GetLEDInfo();
        }
    }

}

下麵看看如何進行調用:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using Gaofajin.LogWrite;
namespace GetPlcInfo
{
    class Program
    {
        static Timer t;
        static TimerCallback tc;
        static int time = 50;
        static PLCReadWriteHelper helper;
        static string last;
      //  public static object TxtLog { get; private set; }

        static void Main(string[] args)
        {

            if(args.Length<=0)
            {
                Console.WriteLine("必須輸入IP地址:");
                return;
            }
            if(args.Length==2)
            {
                int.TryParse(args[1],out time);
            }
            helper=new PLCReadWriteHelper(PLCcom.ePLCType.S7_300_400_compatibel,args[0],"0","2");//此示例演示的PLC為300系列故此處寫死槽號2,機架號0
            helper.OnError+=new PLCReadWriteHelper.OnErrorHandler(error);
            helper.success+=new PLCReadWriteHelper.SuccessHandler(success);
          
            tc=new TimerCallback(getContent);
            t=new Timer(tc,helper,0,time);
            Console.WriteLine("後臺程式捕獲進程運行中!請勿關閉程式!");
            Console.ReadLine();
        }

        private static void success(PLCReadWriteHelper.SuccessedEventArgs e)
        {
            Console.WriteLine(e.ErrMsg);
        }

        private static void error(PLCReadWriteHelper.OnErrorEventArgs e)
        {
            Console.WriteLine(e.ErrMsg);
        }

        private static void getContent(object obj)
        {
            try
            {
                t.Change(-1,-1);
                helper.TestConnect();
                byte[]bts= helper.ReadPLC(53,20,51);
               
                string str = null;
               
             foreach(byte b in bts)
                {
                    str+=byteTostringChar(b).ToString()+"|";
                }
                if(last!=str)
                {
                    TxtLog.WriteLineToTimeFile(str);
                }
                last=str;
               
               
            }
            catch(Exception ex)
            {
                // Console.WriteLine("發生錯誤:"+ex.Message);
            }
            finally
            {
                t.Change(0,time);
            }
        }

        public static char byteTostringChar(byte b)
        {
            return ((Char)b);
        }
    }
}


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Akka本身使用了 來序列化內部消息(比如gossip message)。Akka系統還可以配置自定義序列化機制。 配置conf 預設的,在local actor之間(the same JVM)的消息是不會序列化的。可以通過 配置,來序列化所有消息(local和remote)。序列化所有的消息不回給 ...
  • 本文將從happens-before關係出發,結合ReentranLock源碼,如何用記憶體屏障、CAS操作、LOCK指令實現鎖的功能。 ...
  • 第一次在python中使用OpenCV(cv2),運行時報錯opencv-3.3.1\modules\highgui\src\window.cpp:339: error: (-215) size.width>0 && size.height>0 in function cv::imshow 源碼如下 ...
  • 單鏈表的12種基本操作 ...
  • 文件操作 1,文件路徑:d:\xxxx.txt 絕對路徑:從根目錄到最後 相對路徑:當前目錄下的文件 2,編碼方式:utf-8 3,操作方式:只讀,只寫,追加,讀寫,寫讀...... (1)只讀--r f =open('路徑',mode='r',encoding='編碼方式') content=f. ...
  • 一、OGNL表達式語言 Ognl Object Graphic Navigation Language(對象圖導航語言),它是一種功能強大的表達式語言(Expression Language,簡稱為EL),通過它簡單一致的表達式語法,可以存取對象的任意屬性,調用對象的方法,遍歷整個對象的結構圖,實現 ...
  • 一、開啟註冊表“win鍵+R鍵”並輸入regedit 二、在註冊表項 HKEY_CURRENT_USER\ Software\ Microsoft\ Command Processor 新建一個項,並修改數據為“cd /d C:\”,在/d空格後就是你要的路徑 修改成功是這樣的 ...
  • 描述: 森炊今天沒吃藥很開森,家裡購置的新房就要領鑰匙了,新房裡有一間他自己專用的很寬敞的房間。更讓他高興的是,媽媽昨天對他說:“你的房間需要購買哪些物品,怎麼佈置,你說了算,只要不超過N元錢就行”。今天一早,森炊就開始做預算了,他把想買的物品分為兩類:主件與附件,附件是從屬於某個主件的,下表就是一 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...