zoukankan      html  css  js  c++  java
  • 使用PLCcom.dll操作西门子系列PLC

    工作中经常需要了解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);
            }
        }
    }

  • 相关阅读:
    Vim配置及使用技巧
    终端提示符的配置
    Archlinux下i3wm与urxvt的配置
    Linux压缩命令
    Archlinux无线联网教程
    Archlinux安装和使用技巧
    Linux下硬盘分区
    Linux挂载
    Android中pullToRefresh使用
    SVN服务器搭建和使用教程
  • 原文地址:https://www.cnblogs.com/gfjin/p/8116357.html
Copyright © 2011-2022 走看看