C# 构建S7服务器 西门子的虚拟服务器 测试通信 HslCommunication应用

本文将使用一个gitHub开源的组件技术来实现S7服务器的功能,使用的是基于以太网的TCP/IP实现,不须要额外的组件css

github地址:https://github.com/dathlin/HslCommunication      fork      star                 若是喜欢能够star或是fork,还能够打赏支持。git

官网地址:http://www.hslcommunication.cn/         打赏请认准官网github

 

 

 


演示的demo,快速开发,下载demo程序,您能够进行初步的访问的测试,免去了您写测试程序的麻烦,快速实验通信,测试开发软件的操做。数组

下载地址为:HslCommunicationDemo.zip 服务器

演示的服务器截图为:性能

再配合本组件支持的客户端通信、就能够实现自我测试。测试

 

 二者的地址格式是一致的。大数据

服务器端支持4种地址:输入的I0,输出的Q0,中间寄存器M100,DB块,DB1.100ui

 

 

自定义服务器开发


 

实际的场景中,颇有可能你须要的是一个能够测试的demo,当你在开发上位机,SCADA软件,监控软件,历史追述软件的时候,尚未PLC来给你测试,开发,这时候就可使用本demo来实现模拟服务器的功能。spa

固然还有另外一种需求,当你要集成一个服务器到你本身的程序中的时候,就可使用本组件来实现,而要集成一个自定义的服务器将会是很是的简单。

 

1. 安装组件,能够经过下面的指令,或是nuget可视化的客户端来安装

Install-Package HslCommunication

2. 引用命名空间:

using HslCommunication.Profinet.Siemens;
using HslCommunication;

3. 写代码。这个服务器能够是在你的窗体中,固然也能够在你的自定义类中,下面的举例在类中定义(窗体的本质也是类)

        private SiemensS7Server s7NetServer;
        public void S7Start()
        {
            try
            {
                s7NetServer = new SiemensS7Server();
                s7NetServer.ServerStart(102);
            }
            catch(Exception ex)
            {
                Console.Write("Failed:" + HslCommunication.BasicFramework.SoftBasic.GetExceptionMessage(ex));
            }
        }

这样就启动了一个最基本的西门子虚拟服务器了。而后就能够用Hsl组件去读写数据了。端口号是102。

 

4. 服务器操做数据信息,有了上述的例子后,咱们来扩充服务器的功能,好比在服务器端进行读写数据信息。以下的代码举例的通常类型的读写操做说明。

            // 此处以M100寄存器做为示例
            bool bool_M100_0     = s7NetServer.ReadBool("M100.0").Content;
            byte byte_M100       = s7NetServer.ReadByte("M100").Content;         // 读取M100的值
            short short_M100     = s7NetServer.ReadInt16("M100").Content;        // 读取M100-M101组成的字
            ushort ushort_M100   = s7NetServer.ReadUInt16("M100").Content;       // 读取M100-M101组成的无符号的值
            int int_M100         = s7NetServer.ReadInt32("M100").Content;        // 读取M100-M103组成的有符号的数据
            uint uint_M100       = s7NetServer.ReadUInt32("M100").Content;       // 读取M100-M103组成的无符号的值
            float float_M100     = s7NetServer.ReadFloat("M100").Content;        // 读取M100-M103组成的单精度值
            long long_M100       = s7NetServer.ReadInt64("M100").Content;        // 读取M100-M107组成的大数据值
            ulong ulong_M100     = s7NetServer.ReadUInt64("M100").Content;       // 读取M100-M107组成的无符号大数据
            double double_M100   = s7NetServer.ReadDouble("M100").Content;       // 读取M100-M107组成的双精度值
            string string_M100   = s7NetServer.ReadString("M100", 10).Content;   // 读取M100-M109组成的ASCII字符串数据

            // 读取数组
            short[] short_M100_array      = s7NetServer.ReadInt16("M100", 10).Content;      // 读取M100-M101组成的字
            ushort[] ushort_M100_array    = s7NetServer.ReadUInt16("M100", 10).Content;     // 读取M100-M101组成的无符号的值
            int[] int_M100_array          = s7NetServer.ReadInt32("M100", 10).Content;      // 读取M100-M103组成的有符号的数据
            uint[] uint_M100_array        = s7NetServer.ReadUInt32("M100", 10).Content;     // 读取M100-M103组成的无符号的值
            float[] float_M100_array      = s7NetServer.ReadFloat("M100", 10).Content;      // 读取M100-M103组成的单精度值
            long[] long_M100_array        = s7NetServer.ReadInt64("M100", 10).Content;      // 读取M100-M107组成的大数据值
            ulong[] ulong_M100_array      = s7NetServer.ReadUInt64("M100", 10).Content;     // 读取M100-M107组成的无符号大数据
            double[] double_M100_array    = s7NetServer.ReadDouble("M100", 10).Content;     // 读取M100-M107组成的双精度值

基本的写入操做

            // 此处以M100寄存器做为示例
            s7NetServer.Write("M100", true);                       // 写入M100  bool值
            s7NetServer.Write("M100", (byte)123);                  // 写入M100  byte值
            s7NetServer.Write("M100", (short)1234);                // 写入M100  short值
            s7NetServer.Write("M100", (ushort)45678);              // 写入M100  ushort值
            s7NetServer.Write("M100", 1234566);                    // 写入M100  int值
            s7NetServer.Write("M100", (uint)1234566);              // 写入M100  uint值
            s7NetServer.Write("M100", 123.456f);                   // 写入M100  float值
            s7NetServer.Write("M100", 123.456d);                   // 写入M100  double值
            s7NetServer.Write("M100", 123456661235123534L);        // 写入M100  long值
            s7NetServer.Write("M100", 523456661235123534UL);       // 写入M100  ulong值
            s7NetServer.Write("M100", "K123456789");               // 写入M100  string值

            // 读取数组
            s7NetServer.Write("M100", new short[] { 123, 3566, -123 });                                      // 写入M100  short值  ,W3C0,R3C0 效果是同样的
            s7NetServer.Write("M100", new ushort[] { 12242, 42321, 12323 });                                 // 写入M100  ushort值
            s7NetServer.Write("M100", new int[] { 1234312312, 12312312, -1237213 });                         // 写入M100  int值
            s7NetServer.Write("M100", new uint[] { 523123212, 213, 13123 });                                 // 写入M100  uint值
            s7NetServer.Write("M100", new float[] { 123.456f, 35.3f, -675.2f });                             // 写入M100  float值
            s7NetServer.Write("M100", new double[] { 12343.542312d, 213123.123d, -231232.53432d });          // 写入M100  double值
            s7NetServer.Write("M100", new long[] { 1231231242312, 34312312323214, -1283862312631823 });      // 写入M100  long值
            s7NetServer.Write("M100", new ulong[] { 1231231242312, 34312312323214, 9731283862312631823 });   // 写入M100  ulong值

5. 高级读写,所谓的高级的读写,就是读写基础的字节数据,相关的转换须要本身来完成

读数据的例子以下:

            OperateResult<byte[]> read = s7NetServer.Read("M100", 8);
            if (read.IsSuccess)
            {
                float temp   = s7NetServer.ByteTransform.TransInt16(read.Content, 0) / 10f;
                float press  = s7NetServer.ByteTransform.TransInt16(read.Content, 2) / 100f;
                int count    = s7NetServer.ByteTransform.TransInt32(read.Content, 2);

                // do something
            }
            else
            {
                // failed
            }

写数据的例子:

            // 拼凑数据,这样的话,一次通信就完成数据的所有写入
            byte[] buffer = new byte[8];
            s7NetServer.ByteTransform.TransByte((short)1234).CopyTo(buffer, 0);
            s7NetServer.ByteTransform.TransByte((short)2100).CopyTo(buffer, 2);
            s7NetServer.ByteTransform.TransByte(12353423).CopyTo(buffer, 4);

            OperateResult write = s7NetServer.Write("M100", buffer);
            if (write.IsSuccess)
            {
                // success
            }
            else
            {
                // failed
            }

            // 上面的功能等同于三个数据分别写入,下面的方式性能稍微差一点点,几乎看不出来
            // s7NetServer.Write( "M100", (short)1234 );
            // s7NetServer.Write( "M100", (short)2100 );
            // s7NetServer.Write( "M100", 12353423 );

 

6. 服务器的高级操做,日志配置

        public void S7Start2()
        {
            try
            {
                s7NetServer = new SiemensS7Server();
                s7NetServer.LogNet = new HslCommunication.LogNet.LogNetSingle("logs.txt");        // 配置日志信息
                s7NetServer.ServerStart(102);
            }
            catch (Exception ex)
            {
                Console.Write("Failed:" + HslCommunication.BasicFramework.SoftBasic.GetExceptionMessage(ex));
            }
        }

7. 限制客户端的ip地址,下面举例是仅仅容许本机登陆。

        public void S7Start3()
        {
            try
            {
                s7NetServer = new SiemensS7Server();
                s7NetServer.LogNet = new HslCommunication.LogNet.LogNetSingle("logs.txt");        // 配置日志信息
                s7NetServer.SetTrustedIpAddress(new List<string>() { "127.0.0.1" });              // 仅仅限制本机客户端读写
                s7NetServer.ServerStart(102);
            }
            catch (Exception ex)
            {
                Console.Write("Failed:" + HslCommunication.BasicFramework.SoftBasic.GetExceptionMessage(ex));
            }
        }

8. 捕捉数据接收事件,每当客户端进行数据交互的时候,均可以触发事件,而后能够对报文进行分析,好比说,分析出了客户端写入了地址M100的数据,就触发下自定义的操做,在这种状况下就可使用以下的代码

        public void S7Start4()
        {
            try
            {
                s7NetServer = new SiemensS7Server();
                s7NetServer.LogNet = new HslCommunication.LogNet.LogNetSingle("logs.txt");        // 配置日志信息
                s7NetServer.SetTrustedIpAddress(new List<string>() { "127.0.0.1" });              // 仅仅限制本机客户端读写
                s7NetServer.OnDataReceived += S7NetServer_OnDataReceived;
                s7NetServer.ServerStart(102);
            }
            catch (Exception ex)
            {
                Console.Write("Failed:" + HslCommunication.BasicFramework.SoftBasic.GetExceptionMessage(ex));
            }
        }

        private void S7NetServer_OnDataReceived(object sender, byte[] data)
        {
            Console.WriteLine(HslCommunication.BasicFramework.SoftBasic.ByteToHexString(data, ' ')); // 打印客户端发送的数据
        }

9. 示例,举个简单的例子,用来模拟PLC的程序,整个PLC的程序无非是对输入输出进行代码操做,PLC的优点就是实时性,因此咱们能够基于本组件开发一个虚拟化的PLC,可用于简单的模拟,调试,测试操做。

相关文章
相关标签/搜索