• 在虚拟机中使用NetToPLCSim和PLC相连.


    1,虚拟机...系统Win10...里面安装了VS.

    2,本机...系统Win10...里面安装了博图15.

    3,转换软件:NetToPLCSIM.

    4,本机和虚拟机连接同一个路由器.注意:

    image

    5,设置虚拟机为桥接模式,并且选择连接了路由器的网卡.

    6,网卡设置自动获取IP地址,并且禁止,启用,让网卡获取IP地址.

    本机IP:image

    虚拟机IP:image

    正常情况,两台机器能够互相ping 成功!,则基本准备,网络配置完毕.否则,检查防火墙.我没遇到,就没弄.

    然后打开博图,必须要进行get/put打勾!

      1,设置PLC ip image

    2,GET/PUT 打勾

                      image

    3,模拟的时候,先点击模拟,但是不要下载PLC.


    4,打开Nettoplcsim软件:(其中有 stop server start server 默认即可),注意,一定要先打开这个软件.

    image

    5,打开添加对接画面:点击PLCSIM IP.注意,如果先模拟再添加就不会显示.

    image没有PLC

    6,打开PLC模拟器,并下载PLC 点击 PLCSIM IP:这个很关键,必须它自己跳出来的.选择PLC.

    image

    7,选择 NET IP ADDR:

    image

    8,ok注意 rack和slot选择

    image

    image

    9,在虚拟机的VS里面测试通讯

     internal static void TestS7()
            {
    
    
                Plc plc = new Plc(CpuType.S71200, "192.168.3.62", 0, 1);
                try
                {
                    log("begin open plc");
                    plc.Open();//一个PLC异步函数,注意,异步函数的异常只能通过
                    log("plc is open!");
                }
                catch(Exception e)
                {
                    log(e.Message);
                }
            }

    结果:

    image

    10,尝试读取写入byte[]数组:

      RecipePLC 数据类型具有:(配方)

        一个字符串: string[20] 占用了22个字节.Index0是其大小,应该是22,index1 是实际字符长度.应该是0.现在

       一个step数组:step是一个plc数据类型. 其为30个step元素.

    每个step含有:

    image

    OK,我们先来完成如何读取写入这个结构:

    10.1首先在vs中架构一个PLCSTRING类,因为 string这个类不好投射.


     public class PlcString:IPlcParse
        {
            private readonly byte[] bytes;
            public PlcString() : this(256) { }
            public PlcString(int len )
            {
                bytes = new byte[len];
                bytes[0] = len <= 0xfe ? (byte)len : (byte)0xfe;
    
    
    
            }
            public void SetString(string str)
            {
                int len = bytes.Length;
                if (str != string.Empty)
                {
                    byte[] str_bytes = ASCIIEncoding.ASCII.GetBytes(str);
                    bytes[1] = (byte)str_bytes.Length;
                    str_bytes.CopyTo(bytes, 2);
                }
                else
                {
                    bytes[1] = 0;
    
                }
            }
            public string GetString()
            {
                if (bytes[1] != 0)
                {
                    byte[] strs = new byte[(int)bytes[1]];
                    Buffer.BlockCopy(bytes, 2, strs, 0, (int)bytes[1]);
                    return ASCIIEncoding.ASCII.GetString(strs);
                }
                else
                {
                    return string.Empty;
                }
    
    
            }
    
            public static explicit operator String(PlcString obj)
            {
                return obj.GetString();
            }
    
            public  object FromBytes(byte[] bytes, ref double numBytes)
            {
                numBytes = Math.Ceiling(numBytes);
                if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                    numBytes++;
                Buffer.BlockCopy(bytes, (int)numBytes, this.bytes, 0, this.bytes.Length);
                numBytes += this.bytes.Length;
                return this;
            }
    
            public int GetSize()
            {
                return bytes.Length;
            }
    
            public void ToBytes(byte[] bytes, ref double numBytes)
            {
                numBytes = Math.Ceiling(numBytes);
                if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                    numBytes++;
                Buffer.BlockCopy(this.bytes, 0,bytes, (int)numBytes, this.bytes.Length);
                numBytes += this.bytes.Length;
            }
            public void Display()
            {
                foreach (var x in bytes)
                    Console.Write(" {0:X2}", x);
                Console.WriteLine();
            }
        }

    这个类实现了如下的接口:

     public interface IPlcParse
        {
            void ToBytes(byte[] bytes, ref double numBytes);
            object FromBytes(byte[] bytes, ref double numBytes);
            int GetSize();
        }

    https://gitee.com/mao_qin_bin/s7netplus

    算了,太多了,大家到这个地方下载吧. 注意版权.是我的!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    在原有的S7的基础上更改的实现.(git下来之后,我们再开始下一步)

    下面我们来实现VS中的step步:

    public class Recipe_Step
        {
            public short element1;
            public short element2;
            public short element3;
            public short element4;
            public short element5;
            public short element6;
            public double element7;
            public double element8;
            public double element9;
            public double element10;
            public double element11;
            public double element12;
            public double element13;
            public bool element14;
            public bool element15;
            public short element16;
        }

    image

    1,int--投射成short

    2,real-投射成double

    3,注意大小是64个字节.我们来计算下我们的类的大小.

     public static void demo5()
            {
    
                PlcClassHelper.DisplayObject(new Recipe_Step());
    
    
            }

    结果:

     Recipe_Step : ConsoleApp1.PlcClass.Recipe_Step   Size:44
    
    Class of Recipe_Step
       Int16 : 0   Size:2
       Int16 : 0   Size:2
       Int16 : 0   Size:2
       Int16 : 0   Size:2
       Int16 : 0   Size:2
       Int16 : 0   Size:2
       Double : 0   Size:4
       Double : 0   Size:4
       Double : 0   Size:4
       Double : 0   Size:4
       Double : 0   Size:4
       Double : 0   Size:4
       Double : 0   Size:4
       Boolean : False   Size:2
       Boolean : False   Size:2
       Int16 : 0   Size:2
    

    OK.

    然后再测试下Recipe1:

     public class Recipe
        {
            public static Recipe StaticInstance=new Recipe();
            public PlcString Recipe_Name = new PlcString(20, "");
            public Recipe_Step[] Recipe_Steps = new Recipe_Step[30];
            private Recipe()
            {
                for(var i = 0; i < Recipe_Steps.Length; i++)
                {
                    Recipe_Steps[i] = new Recipe_Step();
                }
            }
        }

    这是PLC数据块(非优化)编译好的

    image

    这是我测试的:

    Recipe : ConsoleApp1.PlcClass.Recipe   Size:1342
    
    Class of Recipe
       PlcString :  String =   Bytes = : 14  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0    Size:22
    
    Array of ConsoleApp1.PlcClass.Recipe_Step[] :
         Recipe_Step : ConsoleApp1.PlcClass.Recipe_Step   Size:44
    
    Class of Recipe_Step
           Int16 : 0   Size:2
           Int16 : 0   Size:2
           Int16 : 0   Size:2
           Int16 : 0   Size:2
           Int16 : 0   Size:2
           Int16 : 0   Size:2
           Double : 0   Size:4
           Double : 0   Size:4
           Double : 0   Size:4
           Double : 0   Size:4
           Double : 0   Size:4
           Double : 0   Size:4
           Double : 0   Size:4
           Boolean : False   Size:2
           Boolean : False   Size:2
           Int16 : 0   Size:2
         Recipe_Step : ConsoleApp1.PlcClass.Recipe_Step   Size:44

    完全正确.下面设定下一些数据并且从PLC的读取:

    10.5 设置PLC数据

    image

    image

    10.6 从PLC读取数据:

    image

    完全一致:

    10.7 将数据写入PLC:

     public static void demo6()
            {
    
                Recipe curRecipe = Recipe.StaticInstance;//引用配方
                Recipe.Initial();
                short t = 0;
                foreach(var step in curRecipe.Recipe_Steps)
                {
                    step.element1 = t++;
                    step.element16 = t++;
    
    
                }
    
    
    
    
    
    
                Plc plc = new Plc(CpuType.S71200, "192.168.3.62", 0, 1);
                try
                {
                    plc.Open();
                    plc.WriteBytes(DataType.DataBlock, 1, 0, PlcClass.ToBytes(curRecipe));
                    PlcClassHelper.DisplayObject(curRecipe);
                }
                catch (PlcException e)
                {
                    Console.WriteLine("Exception'Message is {0},Exception's Errcode is {1}", e.Message, e.ErrorCode.ToString());
                }
                finally
                {
                    plc.Close();
                }
    
            }

    上面的Initial是将staticInstance实列给初始化了.

    查看结果: PLC

    image

    查看结果:VS

    image

  • 相关阅读:
    SQL的四种连接-左外连接、右外连接、内连接、全连接
    查看Linux下端口占用情况的命令
    linux的命令(1)
    xsheell的下载安装初级使用
    日交易,根据权重分配流量的算法,根据权重和交易笔数
    根据权重挑选通道的简单算法
    Java中的String与常量池
    JAVA虚拟机内存分配与回收机制
    JVM 内部运行线程介绍
    AspectJ切入点语法详解
  • 原文地址:https://www.cnblogs.com/frogkiller/p/12346066.html
Copyright © 2020-2023  润新知