Communication between Siemens PLC and Unity3D丨PROFINET communication

foreword

I have wanted to do this kind of communication for too long, and it was not officially completed until February 21. At the beginning, I thought that if Siemens 1200 series and Unity could communicate, then many experiments could be done in virtual simulation. In the future The interface of the upper computer will also be richer than the traditional one. Nowadays, the industrial control industry and the IT industry are inseparable, and the similarity is getting higher and higher. I tried several communication methods here and there, and finally found the most appropriate communication method with the help of my teacher.
This article is about the communication between the physical PLC and Unity. If there is no physical PLC, you can refer to my previous blog post about the PROFINET communication simulation (virtual communication) between the upper computer and Siemens Portal TIA . This blog post describes how to configure PLCsim and use PlCsim instead The entity PLC communicates.

In particular, the communication method described below has been successfully debugged on my computer. If you encounter special circumstances, please handle it specially. Welcome everyone to contact me, and we will learn together.

Protocol

The communication protocol between PLC and Unity uses ModbusTCP communication, and
there are roughly two points to be done on the Siemens side

  1. Check the communication protection and other options of the project
  2. Write a part of the ModbusTCP code, I think the purpose of this is to allow external access.

On the Unity side, it is necessary to import a C# Dll library——S7.Net. This library is used to write Winform applications. Because they are all written in C#, it can also be used directly when imported into Unity.

Details of communication establishment

Notice! ! ! The computer running Portal, the computer running Unity, and the Siemens PLC need to be on the same network segment, that is, the first three digits of the IP address are the same.
1. Settings of Siemens Portal

  1. According to the S7.Net official document, the attribute should be configured
    as mentioned in the official document (in order to avoid my description is not clear enough, the original text is placed below, there are three settings, the first point is that it will only be used when accessing the DB block It is not necessary to do this when accessing the M register. The next two points must be done.)
S7 1200/1500 Notes
An external equipment can access to S71200/1500 CPU using the S7 “base” 
protocol, only working as an HMI, i.e. only basic data transfer are allowed.
All other PG operations (control/directory/etc..) must follow the extended protocol, 
not (yet) covered by Snap7.
Particularly to access a DB in S71500 some additional setting plc-side are needed.
1. Only global DBs can be accessed.
2. The optimized block access must be turned off.
3. The access level must be “full” and the “connection mechanism” must allow 
GET/PUT.
Let’s see these settings in TIA Portal V12
DB property
Select the DB in the left pane under “Program blocks” and press Alt-Enter (or in 
the contextual menu select “Properties…”)
Uncheck Optimized block access, by default it’s checked

(Here, the option to optimize block access needs to be turned off for the data block to be accessed.)
insert image description here

Protection
Select the CPU project in the left pane and press Alt-Enter (or in the contextual 
menu select “Properties…”)
In the item Protection, select “Full access” and Check “Permit access with PUT/GET 
….” as in figure.

(There are two settings here, one is to adjust the access level in the protection to: Full access; the other is to allow PUT/GET connection)
insert image description here2. Write the communication code,
select the MB_Server block in the communication-other-ModbusTCP on the right
insert image description here
and put it in It can be written, and the details are shown in the following two figures. (The meaning of the specific parameters will not be repeated here. If you have any questions, please refer to the Portal Information System.) insert image description hereinsert image description here
2. Communication settings on the Unity side

  1. Create a new Plugins folder under the Assets folder of the Unity project file, and put S7.Net.dll and other files into the
    Dll library of S7.net and the manual has been uploaded. If you need it, you can pick it up yourself
    insert image description here
    . There are two points to note here: First, I don't know whether this file will affect the project, so it is put together. (The .meta file is automatically generated after importing into Unity. You can use this to confirm whether it can be used in the project.) The
    insert image description here
    second point is that the online S7.Net library is a folder, but there are three versions of the S7.Net library , you only need to save one, otherwise Unity will recognize confusion.
    Of course, if you only get insert image description here
    these two files, you will not have the above two points to pay attention to.
  2. After importing the Dll library, you can create a new C# script in the project for code writing.
    The following is my source code, and I will mark the important points in the form of comments.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using S7.Net; 					 //首先一定是using
using System;
using UnityEngine.UI;
using System.Threading;

public class PLC : MonoBehaviour
{
    Plc PLC1 = new Plc(CpuType.S71200, "192.168.0.1", 0, 1);		
    //在这里对Plc这类进行新建,public Plc(CpuType cpu, string ip, Int16 rack, Int16 slot),这个函数是对连接的Plc进行一个访问初始化
    //需要的参数有PLC类型、IP地址、插槽号、机架号。其中后两项在博途CPU属性中可以查到。

    public InputField InputIP;
    public Text InputSet;

    Thread PLCLink;

    public Text Error;

    public GameObject FluidC;
    public byte HighSet;

    public byte result;
    public double RealSet;
    public byte ReadValve;

    public ushort intValve;

    float UnityHigh;
    // Start is called before the first frame update
    void Start()
    {
    }

    public void BtnOpen()
    {
        
        try
        {
            PLC1 = new Plc(CpuType.S71200, InputIP.text, 0, 1);  //这里的是做了一个外部设置IP地址的操作
            PLC1.Open();
            //打开与PLC的连接是有两种方式,一个是Open();另一个是OpenAsync(),两者之间的功能是一样的,前者可以返回错误信息,比较适合初学者。

            if (PLC1.IsConnected)   //判断是否连接
            {

                Debug.Log("Plc is Connected");
                Error.text = "Plc is Connected";

                PLCLink = new Thread(LinkThread);
                PLCLink.Start();                    //这里我是想做一个阶段性的中断,所以选用另起线程,将查询和写入PLC的功能放入新的线程,数据处理在主线程。用来防止线程卡死。
            }
            else
            {
                Error.text = "PLC 连接不成功,请检查IP地址、机架、插槽等是否正确";
            }
        }
        catch (Exception ex)
        {
            Debug.Log(ex);
            Error.text = ex + "";
            throw;
        }
    }

    public void BtnClose()
    {
        try
        {
            PLC1.Close();     //关闭与PLC的连接
        }
        catch (Exception ex)
        {
            Debug.Log(ex);
            Error.text = ex + "";
            throw;
        }
    }

    public void BtnRead()
    {
        //复位按键
        try
        {
            PLC1.Write("M0.0", true);  //我做的是Unity上的仿真PID所以需要一个复位按键。
            PLC1.Write("M0.0", false);
        }
        catch (Exception ex)
        {
            Debug.Log(ex);
            Error.text = ex + "";
            throw;
        }
    }
    
    public void LinkThread()
    {
        while (true)
        {
            if (PLC1.IsConnected)
            {
                RealSet = Convert.ToDouble(PLC1.Read("DB3.DBD0"));  
                //读取PLC的值,这边我还没有做的很满意,大家可以根据S7.Net的说明书和自己的意图来写合适的代码
                result = (byte)PLC1.Read("MB103");
                intValve = (ushort)PLC1.Read("DB3.DBW12");
                Debug.Log(intValve);
                Thread.Sleep(100);
            }
        }
    }

    private void OnApplicationQuit()
    {
        BtnClose();
    }

    // Update is called once per frame
    void Update()
    {
        UnityHigh = FluidC.GetComponent<FluidControl>().OutPutHigh;
        InputSet.text = result + "";
    }
}

At this point, the communication between the two parties has been completed, and the rest is data processing. When I am satisfied next time, I will write an article for everyone to read.

The two main problems encountered during

  1. S7.Net.PlcException: Unable to write data to the transport connection: An existing connection was forcibly closed by the remote host.

  2. Index exceeds array bounds.
    Both of my problems occurred when the read and write operations could not be performed after the connection was successful.
    A brief summary of the inspection steps

  3. Ping the IP address of the PLC. If the ping fails, there are many possibilities. It is not in the same network segment, and the PLC is not properly set up to protect external access (please refer to 1. Settings on the Siemens Portal) and so on.

  4. If it can be pinged, please check whether the communication code of the PLC is wrong. Usually the first question will appear here.

  5. The second problem may be that the accessed block does not exist or the address does not have a defined number.

Summarize

This article only writes the words of my family. There are not many problems encountered, so it will not be the most comprehensive. I hope that you can discuss with me the strange problems you encounter.

Guess you like

Origin blog.csdn.net/qq_44879321/article/details/121140520