精华内容
下载资源
问答
  • C#与PLC通讯

    2021-02-02 11:39:03
    最近因为工作的原因用到了西门子PLC,在使用过程中一直在思考上位机和PLC的通讯问题,后来上网查了一下,找到了一个专门针对S7开发的一个.net库–《S7netPlus》,PLC通讯方法比较多,所以也是在不断地学习中,以下...

    最近因为工作的原因用到了西门子PLC,在使用过程中一直在思考上位机和PLC的通讯问题,后来上网查了一下,找到了一个专门针对S7开发的一个.net库–《S7netPlus》,PLC通讯方法比较多,所以也是在不断地学习中,以下内容如有不足之处,望大神予以指教。

    公司设备一直都用的PLC做下端设备的控制,但是目前都没有专职做上位机的,而我之前对PLC又接触的比较少,做起来还是比较难的。。

    查找了一堆资料后,终于找到了这个.net库,在大致学习了一下之后,总结了一下,当作自己的学习笔记。

    一、开发环境准备

    最近因为疫情的影响,只能呆在总公司混日子,手里没有设备,只能用博图的仿真器来测试通讯,需要安装的软件包括:

    TIA Protal(博图)&S7-PLCSIM

    西门子针对于PLC专门开发的一款编程软件,相信各位肯定比我熟悉这个软件了,这里就不作过多介绍了,同时提供了S7系列的仿真软件S7-PLCSIM,这里我们就用这两个设备仿真PLC设备来测试S7NETPlus库的通讯。
    在这里插入图片描述

    博图V15.1

    在这里插入图片描述

    S7-PLCSIM

    NetToPLCSIM

    在这里插入图片描述

    这个软件是用于将西门子的PLCsim映射到网络内,如果之前没有用过这个软件,建议按照后面的操作来,否则很容易出现Start server之后还是连不上仿真器。

    二、开发测试

    PLC配置

    1、在组态好的PLC设备属性中,找到“防护与安全”–>“连接机制”中,勾选“允许来自远程对象的PUT/GET通信访问”;

    在这里插入图片描述

    2、新建DB块,同时将该DB快属性中的“优化块的访问取消”;

    在这里插入图片描述

    3、在新建的DB块中新增一些数据,完成后点击编译计算偏移量。

    在这里插入图片描述

    4、以上步骤完成后,点击开始仿真,将工程下载到仿真器中;

    在这里插入图片描述

    NetToPLCSIM配置

    1、打开软件后,点击Add增加设备

    2、在弹出的窗口中,Network IP Address中填入本地回环IP“127.0.0.1”(如果你是在两台设备中测试,首先保证两台设备在同一个内网中,该处IP就可以设置为运行仿真环境的IP了)

    在这里插入图片描述

    3、Plcsim IP Address中,点击后面两个点,选择软件自己识别出来的仿真器地址;

    在这里插入图片描述

    4、Plcsim Rack/Slot中Rack为机架号,Slot为插槽号,这两个可以在PLC的设备组态属性->项目信息中找到

    配置完成后点击完成,这时候就可以点击Start Server开启服务了。

    在这里插入图片描述

    上面的操作一定要按照以上的步骤一步一步完成,否则很容易出现即使点Start Server显示状态为running,但是实际连接仍然连不上的情况。

    另外需要注意的是,可能在打开NetToPLCSim的时候,会弹出“Port 102 is in use!”的警告,如果遇到这个情况,点击是,之后在将PLCSIM关掉重新启动一下就可以了。
    在这里插入图片描述

    创建连接

    配置连接

    这里使用的是S7-1215的模块,所以CpuType选择S71200,IP地址使用回环地址“127.0.0.1”,机架号和插槽号在PLC工程中查。

    using S7.Net;
    
    Plc plc = new Plc(CpuType.S71200, "127.0.0.1", 0, 1);		
    

    配置完成后,使用Open()来打开,在最早的一个版本中,Open有返回值,可以通过返回值获取 ErrorCode 和 ErrorMessage,我目前使用的是最新版0.8.1.0,没有返回值,所以用try…catch来接收异常

    try
    {
    	plc.Open();
    }
    catch(Exception)
    {
    	Console.WriteLine($"连接到PLC设备失败:IsConnect = {plc.IsConnected},IsAvailable={plc.IsAvailable}");
    	return;
    }
    

    连接是否成功,可以用IsConnected去判断一下。

    访问数据块

    连接成功后,我们就可以去访问PLC的数据块了,访问数据块,我们先尝试一下读取数据块

    读取单个数据–Read

    这里主要用到了DBX,DBW,DBD读取数据,其他的各位可以在查一下PLC的资料

    /*
    方法:public object Read(string variable)
    入参:读取数据地址
    出参:Object类型数据,可强制类型转换
    */
    var db1Bool1 = plc.Read("DB1.DBX0.0");
    Console.WriteLine("DB1.DBX0.0:" + db1Bool1);
    
    bool db1Bool2 = (bool)plc.Read("DB1.DBX0.1");
    Console.WriteLine("DB1.DBX0.1:" + db1Bool2);
    
    int IntVariable = (ushort)plc.Read("DB1.DBW2.0");
    Console.WriteLine("DB1.DBW2.0:" + IntVariable);
    
    float RealVariable = ((uint)plc.Read("DB1.DBD4.0")).ConvertToFloat();
    Console.WriteLine("DB1.DBD4.0:" + RealVariable);
    
    var dIntVariable = (uint)plc.Read("DB1.DBD8.0");
    Console.WriteLine("DB1.DBD8.0: " + dIntVariable);
    
    var dWordVariable = (uint)plc.Read("DB1.DBD12.0");
    Console.WriteLine("DB1.DBD12.0: " + Convert.ToString(dWordVariable, 16));
    
    var wordVariable = (ushort)plc.Read("DB1.DBW16.0");
    Console.WriteLine("DB1.DBW16.0: " + Convert.ToString(wordVariable,16));
    

    在这里插入图片描述

    读取批量数据块–ReadBytes
    /*
    方法:public byte[] ReadBytes(DataType dataType, int db, int startByteAdr, int count)
    入参:
    	1、DataType数据类型,可选择从DB块或者Memory中读取;
    	2、db:1:DataBlock=1,Memory=0;
    	3、startByteAdr:起始地址,即DB块的起始偏移量;
    	4、count:读取大小,该大小由读取的DB块的最后一个数据的偏移量和大小决定,这里最后一个字节WordVariable偏移量为16,数据类型为word,2个字节,因此此次读取为16+2=18个字节。
    出参:Byte[],这里Byte[]的大小必然和count的大小是相同的,
    */
    //读取数据选择从DB块中读取,db设置为1,起始地址为0,读取18个字节
    var bytes = plc.ReadBytes(DataType.DataBlock, 1, 0, 18);
    //取字节0中的第0位
    var db1Bool1 = bytes[0].SelectBit(0);
    Console.WriteLine("DB1.DBX0.0:" + db1Bool1);
    //取字节0中的第1位
    bool db1Bool2 = bytes[0].SelectBit(1); ;
    Console.WriteLine("DB1.DBX0.1:" + db1Bool2);
    //跳到字节2并连续取两个字节数据
    int IntVariable = S7.Net.Types.Int.FromByteArray(bytes.Skip(2).Take(2).ToArray());
    Console.WriteLine("DB1.DBW2.0:" + IntVariable);
    //...
    double RealVariable = S7.Net.Types.Real.FromByteArray(bytes.Skip(4).Take(4).ToArray());
    Console.WriteLine("DB1.DBD4.0:" + RealVariable);
    //...
    int dIntVariable = S7.Net.Types.DInt.FromByteArray(bytes.Skip(8).Take(4).ToArray());
    Console.WriteLine("DB1.DBD8.0: " + dIntVariable);
    //...
    uint dWordVariable = S7.Net.Types.DWord.FromByteArray(bytes.Skip(12).Take(4).ToArray());
    Console.WriteLine("DB1.DBD12.0: " + Convert.ToString(dWordVariable, 16));
    //...
    ushort wordVariable = S7.Net.Types.Word.FromByteArray(bytes.Skip(16).Take(2).ToArray());
    Console.WriteLine("DB1.DBW16.0: " + Convert.ToString(wordVariable, 16));
    

    在这里插入图片描述

    写入单个数据–Write
    /*
    方法:public void Write(string variable, object value)
    入参:
    	1、string variable:写入地址
    	2、object value,写入数据
    */
    plc.Write("DB1.DBX0.0", true);
    plc.Write("DB1.DBD12.0", 123457);
    

    在这里插入图片描述

    写入多个数据–WriteBytes
    /*
    public void WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value)
    用法如同ReadBytes,这里就不在写例程了,有兴趣的可以自己研究一下
    */
    

    关闭连接

    在通讯完之后,千万不要忘了关闭通讯链路哈,这里使用Close来关闭。

     plc.Close();
    

    以上内容都是在学习中,中间有很多内容还不完善,后续的内容在学习过程中会不断增加,如有更好的解决方案,欢迎留言一起探讨。

    展开全文
  • C#与PLC通讯源码MC协议,程序包含界面和源码,同时还有简单说明和PLC断开设置,PLC设置,若有不明白的可以一起研究研究
  • C#与PLC通讯.rar

    2019-08-31 17:40:04
    C#与三菱、松下PLC串口通讯实例经过测试了。能够读取写入PLC各种类型的寄存器和IO
  • C#与PLC通讯,modbus-RTU,c#做从站,比如我想用PLC读C#中D0的值,怎么在C#中把值赋进D0
  • C#与PLC通讯读写.rar

    2019-12-17 15:00:23
    c#通过MX component连接三菱PLC源代码,实际测试过了,运行OK C#程序读取三菱PLC内部寄存器的值和写入寄存器的值 输出端的读写,输入端的读取
  • 各位仁兄,有没有人知道关于C#与三菱/欧母龙 PLC通讯的书籍或文章,或博客,特别是与PLC通讯时数据效率处理的好方法,本人现在与PLC通讯,软件数据都有延时和缓慢。 (搜索过了,都没找到想要的...很是无奈,无助)
  • C#上位机与PLC通讯流程,上位机与下位机的通讯格式,数据包解析
  • C#实现与PLC通讯

    热门讨论 2012-03-15 17:17:13
    C#实现与西门子PLC串行通讯,分析了PLC与PC的数据格式的差异,然后给出了PC与PLC之间的串行通讯协议和通讯流程
  • C#与西门子PLC通讯

    万次阅读 2019-09-10 18:28:37
    C#与西门子PLC通讯S7NetPLC设置C#程序 S7Net PLC在工业自动化领域是常用的控制器,一般在和上位机界面通讯时,经常使用组态软件。以西门子PLC为例,上位机可以使用西门子的WINCC。但是,当面对需求比较多样化的需求...

    C#与西门子PLC通讯

    S7Net

    PLC在工业自动化领域是常用的控制器,一般在和上位机界面通讯时,经常使用组态软件。以西门子PLC为例,上位机可以使用西门子的WINCC。但是,当面对需求比较多样化的需求时,WINCC难以胜任。而且,作为量产的标准化产品,WINCC授权的费用一笔不小的成本。 S7.Net .dll 是应用在 .NET平台上和西门子PLC通讯的一个动态库。大家可以到GitHub中直接去下载,或者直接搜索“S7.Net .dll”也可以找到下载的链接。文章最后也会给出链接。
    目前该动态库支持的西门子PLC类型有S7-200,S7-300,S7-400,S7-1200,S7-1500,基本涵盖了西门子所有的PLC产品。该库可以直接读写PLC中的全局DB块,作为通讯的接口。 下面对需要的一些函数以及数据类型做简单说明。
    构造函数:cpu 为枚举类型,代表PLC类型。ip 为PLC地址,需要和PLC组态的地址一致,同时,和通讯的PC IP地址应在同一局域网段。rack 为导轨号,slot 为插槽号,均可在TIA PLC 硬件组态处获得。
    如下图,ip=“192.168.0.5”。
    IP地址
    如下图,rack为0,slot为1。
    在这里插入图片描述

    public Plc(CpuType cpu, string ip, short rack, short slot);
    public enum CpuType
    {
            S7200 = 0,
            S7300 = 10,
            S7400 = 20,
            S71200 = 30,
            S71500 = 40
     }
    

    获取是否连接成功:

    public bool IsConnected { get; }
    

    连接PLC:

    public void Open();
    public Task OpenAsync();
    

    该类库提供了两个用于PLC连接的函数,区别在于第二个为异步连接,在请求连接的过程中,不会导致线程阻塞。我个人比较喜欢第二种方式。
    按位写操作:参数db代表访问的DB块编号,如下图所示UISendInt编号为3,UIReadInt编号为4。
    在这里插入图片描述
    startByteAdr是在数据块内以字节为单位的起始地址,可以传入0。bitAdr 为需要操作的位的偏移地址(以startByteAdr为基准),value 为写入的值。
    dataType为枚举类型,我们操作的是数据块,传入DataBlock。

    public void WriteBit(DataType dataType, int db, int startByteAdr, int bitAdr, bool value);
    public enum DataType
    {
         Counter = 28,
         Timer = 29,
         Input = 129,
         Output = 130,
         Memory = 131,
         DataBlock = 132
     }
    

    按字节读:count代表读的字节数量。在进行按字节读写时,对于8位的单字节变量来说没有任何问题。但是对于多字节比如在PLC中16位I的INT类型,需要注意大小端问题。在西门子PLC中以大端模式存储数据,但是在Intel的X86架构的PC上,确是以小端模式。所以,在从PLC读取一个INT类型的变量,需要将读取回来的字节数组高低字节调换,后面C#程序中会有详细的实现代码。

    public byte[] ReadBytes(DataType dataType, int db, int startByteAdr, int count);
    

    按字节写:value代表将要传输的数据转换成的字节数组,如果要操作一个INT变量,需要提前将高低字节调换,后面C#程序中会有详细的实现代码。

    public void WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value);
    

    PLC设置

    实现外部程序可以访问操作DB块,需要对PLC部分做一些设置。首先对于要读取或者访问的DB块,要将优化的块访问取消,默认为勾选的,选中块右击选择属性。
    在这里插入图片描述
    同时还要在硬件组态中,设置防护与安全中的连接机制。将“允许来自远程对象的PUT/GET访问”勾选。如下图:
    在这里插入图片描述

    C#程序

    在C#上位机软件中,对通讯类库的函数做一个简单的包装,以方便我们使用。首先新建一个类S7,在项目中需要引用S7.NET,并在该类中包含命名空间。

    using S7.Net;
    

    定义一个Plc类型变量plc,并定义该类的构造函数和析构函数:

    Plc plc;
    public S7(S7DataType.CpuType cpuType,string ip,Int16 rack,Int16 slot)
    {
        plc = new Plc((CpuType)cpuType,ip, rack,slot);
    }
    
    ~S7()
    {
        this.plc.Close();
    }
    

    定义连接函数以及关闭函数:

    public void OpenAsync()
    {
           this.plc.OpenAsync();
     }
    
    public void Close()
    {
        this.plc.Close();
    }
    

    定义读写函数:之所以加lock,是因为在应用中数据通讯很有可能在不同的线程去操作,比如单独开一个线程定时从PLC更新数据。

    public byte[] PlcReadBytes(int db, int startByteAdr=0, int count=1)
    {
          try
          {
              lock (this)
              {
                  return this.plc.ReadBytes(DataType.DataBlock, db, startByteAdr, count);
              }
          }
          catch
          {
              return new byte[2];
          }
         
      }
      
    public void PlcWriteBytes(int db, byte[] value, int startByteAdr = 0)
    {
            lock (this)
            {
                this.plc.WriteBytes(DataType.DataBlock, db, startByteAdr, value);
            }    
    } 
    
    public void PlcWriteBit(int db, int bitAdr, bool value, S7DataType.DataType dataType = 
    S7DataType.DataType.DataBlock)
     {
         int temp1 = bitAdr / 8;
         int temp2 = bitAdr % 8;
         lock (this)
         {
             this.plc.WriteBit((DataType)dataType, db, temp1, temp2, value);
         }
     }
    

    定义字节和Int16类型之间的转换函数(需要进行高低字节转换):

    public static byte[] Int16ToBytes(Int16 data)
     {
          byte[] temp = new byte[2];
          temp[0] =(byte) (data >> 8);
          temp[1] = (byte)(data);
          return temp;
      }
    
    public static Int16 BytesToInt16(byte[] bytes)
     {
          Int16 temp;
          temp =(Int16)( bytes[0] << 8 | bytes[1]);
          return temp;
      }
    

    S7.NET.dll 下载链接:
    https://download.csdn.net/download/m0_37763193/11721737

    展开全文
  • c#三菱plc通讯demo

    2018-09-14 01:01:41
    c#开发的一个三菱plc型号fx3u通讯的一个demo,网口通讯,支持多连接。
  • C#与三菱PLC通讯

    2018-11-15 16:22:41
    该文件为个人开发的C#上位机软件,通过三菱的AcUtlType控件三菱PLC进行通讯,对单个或多个16位、32位数据寄存器进行读写,对单个或多个中间继电器进行读写。
  • C#与三菱PLC通讯.rar

    2019-09-28 14:40:12
    上位机用C#与三菱FX PLC通讯,联机测试的PLC型号为FX2N-40MT
  • 使用C#与三菱PLC通讯

    2021-02-11 21:14:34
    使用C#与三菱PLC通讯一、三菱PLC驱动程序安装 一、三菱PLC驱动程序安装

    一、三菱PLC驱动程序安装

    编写上位机程序与三菱PLC进行通讯,首先应该下载驱动安装程序,程序安装之后可以首先对PLC进行测试,如果通讯功能正常,说明硬件配置无误,可以参照安装目录下的示例代码编写程序。
    三菱驱动程序在三菱官网即可下载,下载地址为https://www.mitsubishielectric-fa.cn/
    进入官网后点击上方菜单栏中的资料中心,然后选择控制器——可编程控制器——软件,进入软件下载界面。
    在这里插入图片描述
    在软件下载界面选择GX Works3 及 MX Component两个软件(下载需要注册及登录三菱官网
    ),其中GX Works3提供了PLC编程的可视化界面,而MX Component提供了PLC连接的配置工具及示例代码。在安装MX Component过程中如遇到错误,可上网查询解决方法也可以在解压之后的安装包里的Manual文件夹内浏览安装说明文档,查找错误解决方法。安装过程中需要输入序列号,安装序列号为:117-610768844。在这里插入图片描述

    二、建立PLC连接与关闭连接

    在MX Component程序安装目录下可以找到MX_PLC_Samples文件夹,文件夹内有VBA、Vb、Vc、C#语言编写的示例代码,其中Vcs.NET——Sample2010文件夹内为C#语言编写的示例代码。
    打开示例代码可以发现,建立PLC连接共有两种方式,分别为ActProgType连接和ActUtlType连接。
    ActUtlType连接需要先使用Communication Setup Utility程序(在开始菜单程序目录下),以管理员身份运行,预先建立一个PLC连接,并设置LogicalStationNumber,详情见三菱PLC(FX5U)与C#通信说明。建立连接后,再使用代码进行连接,示例代码如下:

                        using AxActUtlTypeLib;
                        ...
                        AxActUtlType axActUtlType1 = new AxActUtlType();
                        axActUtlType1.ActLogicalStationNumber = 0;//0为LogicalStationNumber
                        int returnCode = axActUtlType1.Open();//返回类型为int类型
                        if (returnCode == 0)
                        {
                            MessageBox.Show("连接成功");
                            return;
                        }
                        else
                        {
                            MessageBox.Show("连接错误");
                            return;
                        }
    

    ActProgType连接不需要预先进行Communication Setup Utility程序进行设置,连接也不需要LogicalStationNumber参数,但需要在代码中设置连接类型,并且根据连接类型设置一些参数,例如计算机与PLC通过串口连接,那么需要设置串口号等,如果通过网线连接,那么需要设置IP地址、连接模块等参数。
    以网线连接、连接模块为CPU_FX5为例,示例代码如下:

                        using AxActProgTypeLib;
                        ...
                        AxActProgType axActProgType1 = new AxActProgType();
                        axActProgType1.ActUnitType = 0x2001;//Connect module:CPU module(FX5)
                        axActProgType1.ActProtocolType = 0x0005;//PC side I/F:Ethernet board
                        axActProgType1.ActHostAddress = value01;//IPAddress
                        int returnCode = axActProgType1.Open();
                        if (returnCode == 0)
                        {
                            MessageBox.Show("连接成功");
                            return;
                        }
                        else
                        {
                            MessageBox.Show("连接错误");
                            return;
                        }
    

    关闭连接示例代码如下:

                        int returnCode = axActProgType1.Close();
                        if (returnCode == 0)
                        {
                            MessageBox.Show("连接已断开");
                            return;
                        }
                        else
                        {
                            MessageBox.Show("断开连接时发生错误");
                            return;
                        }
                        returnCode = axActUtlType1.Close();
                        if (returnCode == 0)
                        {
                            MessageBox.Show("连接已断开");
                            return;
                        }
                        else
                        {
                            MessageBox.Show("断开连接时发生错误");
                            return;
                        }
    

    三、读写PLC数据

    读取PLC的软元件数据的函数共有四种,分别为
    1、int ReadDeviceBlock(string szDevice, int lSize, out int lplData);
    2、int ReadDeviceBlock2(string szDevice, int lSize, out short lpsData);
    3、int ReadDeviceRandom(string szDeviceList, int lSize, out int lplData);
    4、int ReadDeviceRandom2(string szDeviceList, int lSize, out short lpsData);
    其中1与2函数读取的数据位数不同,所以输出类型也不同,3与4同理。而写入PLC数据的函数也共有四种,与四种读取函数相对应,这里不再一一列举,下面给出ActProgType类型读写PLC数据的示例代码:

    short Result=0;
    int iReturnCode = axActProgType1.ReadDeviceBlock2("E0",1, out Result);
    if (iReturnCode == 0)
    {
          MessageBox.Show(Result.ToString());
    }
    short Data=100;
    iReturnCode = axActProgType1.WriteDeviceBlock2("E0",1, ref Data);
    if (iReturnCode == 0)
    {
          MessageBox.Show("写入成功");
    }
    

    参考文档

    三菱PLC(FX5U)与C#通信说明
    C# 通过网络和三菱的PLC通信
    【MX Component】三菱自带网口与上位机通讯实例全过程图解
    上位机通过c#调用MX component实现与三菱PLC通讯。附源代码

    展开全文
  • C#与各种PLC通讯测试

    2019-01-09 16:08:40
    用来测试各种品牌PLC与上位机的通讯PLC端无需进行任何程序操作和编写
  • c#与PLC通过SocketTcp通讯代码

    热门讨论 2013-07-01 09:29:37
    c#与PLC通过SocketTcp通讯代码.仅通讯部分,不包含协议解析
  • 本程序通过编程口三菱FX系列PLC进行通讯(FX-3GA-40MT测试没有问题),以读取PLC内各软元件数据……程序只做了部分软元件的处理,若要处理所有软元件可以此为基础进行相应的二次开发。本软件开源只为服务更多工控...
  • 如下图,rack为0,slot为1。 public Plc(CpuType cpu, string ip, short rack, short slot);public enum CpuType{S7200 = 0,S7300 = 10,S7400 = 20,S71200 = 30,S71500 = 40}123456789获取是否连接成功:p...

    S7Net

    如下图,ip=“192.168.0.5”。

    0a420f7d74bba407d2e69b9cbdf06156.png

    如下图,rack为0,slot为1。

    bd73e1fafc7f2afcd730214ba55e6b72.png

    public Plc(CpuType cpu, string ip, short rack, short slot);

    public enum CpuType

    {

    S7200 = 0,

    S7300 = 10,

    S7400 = 20,

    S71200 = 30,

    S71500 = 40

    }1

    2

    3

    4

    5

    6

    7

    8

    9

    获取是否连接成功:

    public bool IsConnected { get; }1

    连接PLC:

    public void Open();

    public Task OpenAsync();1

    2

    该类库提供了两个用于PLC连接的函数,区别在于第二个为异步连接,在请求连接的过程中,不会导致线程阻塞。我个人比较喜欢第二种方式。按位写操作:参数db代表访问的DB块编号,如下图所示UISendInt编号为3,UIReadInt编号为4。

    458fe4108549ef1c3584177133b02999.png

    public void WriteBit(DataType dataType, int db, int startByteAdr, int bitAdr, bool value);

    public enum DataType

    {

    Counter = 28,

    Timer = 29,

    Input = 129,

    Output = 130,

    Memory = 131,

    DataBlock = 132

    }1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    按字节读:count代表读的字节数量。在进行按字节读写时,对于8位的单字节变量来说没有任何问题。但是对于多字节比如在PLC中16位I的INT类型,需要注意大小端问题。在西门子PLC中以大端模式存储数据,但是在Intel的X86架构的PC上,确是以小端模式。所以,在从PLC读取一个INT类型的变量,需要将读取回来的字节数组高低字节调换,后面C#程序中会有详细的实现代码。

    public byte[] ReadBytes(DataType dataType, int db, int startByteAdr, int count);1

    按字节写:value代表将要传输的数据转换成的字节数组,如果要操作一个INT变量,需要提前将高低字节调换,后面C#程序中会有详细的实现代码。

    public void WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value);1

    PLC设置

    实现外部程序可以访问操作DB块,需要对PLC部分做一些设置。首先对于要读取或者访问的DB块,要将优化的块访问取消,默认为勾选的,选中块右击选择属性。

    ff7aeed5a41ce71991423bdbb682837a.png

    同时还要在硬件组态中,设置防护与安全中的连接机制。将“允许来自远程对象的PUT/GET访问”勾选。如下图:

    9dd774ef531ed84ac6b9ec692138b218.png

    C#程序

    在C#上位机软件中,对通讯类库的函数做一个简单的包装,以方便我们使用。首先新建一个类S7,在项目中需要引用S7.NET,并在该类中包含命名空间。

    using S7.Net;1

    定义一个Plc类型变量plc,并定义该类的构造函数和析构函数:

    Plc plc;

    public S7(S7DataType.CpuType cpuType,string ip,Int16 rack,Int16 slot)

    {

    plc = new Plc((CpuType)cpuType,ip, rack,slot);

    }

    ~S7()

    {

    this.plc.Close();

    }1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    定义连接函数以及关闭函数:

    public void OpenAsync()

    {

    this.plc.OpenAsync();

    }

    public void Close()

    {

    this.plc.Close();

    }1

    2

    3

    4

    5

    6

    7

    8

    9

    定义读写函数:之所以加lock,是因为在应用中数据通讯很有可能在不同的线程去操作,比如单独开一个线程定时从PLC更新数据。

    public byte[] PlcReadBytes(int db, int startByteAdr=0, int count=1)

    {

    try

    {

    lock (this)

    {

    return this.plc.ReadBytes(DataType.DataBlock, db, startByteAdr, count);

    }

    }

    catch

    {

    return new byte[2];

    }

    }

    public void PlcWriteBytes(int db, byte[] value, int startByteAdr = 0)

    {

    lock (this)

    {

    this.plc.WriteBytes(DataType.DataBlock, db, startByteAdr, value);

    }

    }

    public void PlcWriteBit(int db, int bitAdr, bool value, S7DataType.DataType dataType =

    S7DataType.DataType.DataBlock)

    {

    int temp1 = bitAdr / 8;

    int temp2 = bitAdr % 8;

    lock (this)

    {

    this.plc.WriteBit((DataType)dataType, db, temp1, temp2, value);

    }

    }1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    定义字节和Int16类型之间的转换函数(需要进行高低字节转换):

    public static byte[] Int16ToBytes(Int16 data)

    {

    byte[] temp = new byte[2];

    temp[0] =(byte) (data >> 8);

    temp[1] = (byte)(data);

    return temp;

    }

    public static Int16 BytesToInt16(byte[] bytes)

    {

    Int16 temp;

    temp =(Int16)( bytes[0] << 8 | bytes[1]);

    return temp;

    }

    7855208f5dcbceebb4ce53a7cfb6ceb9.png

    《精彩回顾》

    1、

    2、

    3、

    4、

    5、

    6、

    7、

    8、

    9、

    文章来源:综合网络,如有侵权,联系删除。

    b0da137add31fb1cc2c53b9d47e51145.png

    点分享

    点点赞

    点在看

    展开全文
  • } } #endregion #region 读取三菱PLC数据 private void btnReadX_ButtonClick(object Sender) { txtResultView.Text = melsec.ReadBool(txtReadX.Text.Trim(), 1).Content[0] .ToString(); } private void btnReadY...
  • c#与三菱PLC通讯读写实例

    热门讨论 2015-08-16 14:55:37
    c#与三菱FX2N系列PLC进行COM口通讯进行配置,实现数据读写

空空如也

空空如也

1 2 3 4 5 ... 15
收藏数 285
精华内容 114
关键字:

c#与plc通讯

c# 订阅