[Tutorial] Communication between Unity and Simence PLC

Development platform: Unity 2021
Dependent DLL: S7.NET
Programming language: CSharp 6.0 or above

I. Introduction


  Unity involves a wide range of application industries. In the direction of industry, there is a certain direction of involvement and in-depth. In addition to building data dashboards and other content, there will also be the need to simulate physical equipment for virtual twinning needs to be resolved. As SIMATIC (Siemens) is one of the industrial communications, it is the focus of this article to understand how to implement communication in CSharp.

2. Understand | Dependent Library Objects: S7.NET


insert image description here


Restrictions: Only run under Unity CSharp configuration 2.0 Framework.
Download Link: GitHub-S7.NET
Development Documentation: WiKi-S7.NET

  For Unity, referencing the S7.NET method requires importing S7.NET.DLL or all program files in the DLL to the Unity Assets directory before it can be used. As shown in the picture above: we only need to import the S7.NET folder into Unity. Or generate S7.NET.DLL under the Plugins folder under the import directory.

3. Understand | PLC DB database


insert image description here

The PLC DB database writes or reads data   according to " Database - Data Type - Data Offset ". This description is somewhat abstract, with S7.NET reading a single sample data. For example, the red box in the above figure: Get the data of the Int data type under the PLC data [DB160], and the value is 104.0.

PLC.Read("DB160.DBW104.0");
  1. Get DB library always sticks to "DB" + library number
  2. To get the offset value, always stick to "DB" + data type + offset value.
    insert image description here
    Note: PLC.Read(string content)the read defaults to decimal .

  For some cases where the data itself is large, some PLC engineers in charge of the data will choose to split the data for batch storage. For example: Real data is similar to float precision data class in CSharp.

  • In Unity development, data related to precision (such as displacement and rotation axis data) is often split into high and low hexadecimal storage.

4. It is not recommended to use the Read method for data reading


  Analysis PLC.Read(string plc)can understand that it creates an DataItemobject according to the string combination content, which is used for PLC DB block data access. Note: is created . Each timed request must create a local variable before it can be accessed. It is not advisable to read from high frequency as the premise, and as string plcthe amount increases, there will be delays in reading and so on.

public override void OnUpdateData()
{
    
    
	Data.J1 = float.Parse($"{
      
      PLC.Read("DB110.DBW20.0")}");
	Data.J2 = float.Parse($"{
      
      PLC.Read("DB110.DBW22.0")}");
	Data.J3 = float.Parse($"{
      
      PLC.Read("DB110.DBW24.0")}");
	Data.J4 = float.Parse($"{
      
      PLC.Read("DB110.DBW26.0")}");	

	Data.机械夹爪原位 = ConvertUtils.GetBool(PLC.Read("DB110.DBW100.0"), 1);
	Data.机械夹爪动位 = ConvertUtils.GetBool(PLC.Read("DB110.DBW110.0"), 7);
	
	Data.顶升气缸原位 = ConvertUtils.GetBool(PLC.Read("DB110.DBW100.0"), 2); 
	Data.顶升气缸东位 = ConvertUtils.GetBool(PLC.Read("DB110.DBW100.0"), 3); 

	Data.滚筒进料阻挡原位 = ConvertUtils.GetBool(PLC.Read("DB110.DBW110.0"), 2); 
	Data.滚筒进料阻挡动位 = ConvertUtils.GetBool(PLC.Read("DB110.DBW110.0"), 4);

	//.....更多其他数据
}

  The most clear historical memory is that the mechanical axis of a bottom cover installation machine has 4-axis axis value data, mechanical gripper status data, belt status data, jacking|blocking cylinder and other component data. The synchronous mechanical axis data should be updated at a time of 100ms, but when 13 devices synchronously request PLC DB data, it takes 7s to complete a data request. Obviously, PLC reading is blocked. (Using multi-threaded request data in the design is stretched for me in multi-threaded optimization)

  So, considering that there is a request for the same DB block offset data in each request, I set up a local variable to read. For example:

public override void OnUpdateData()
{
    
    
	var theDB20 = PLC.Read("DB110.DBW20.0");
	var theDB22 = PLC.Read("DB110.DBW22.0");
	//...
	var theDB100 = PLC.Read("DB110.DBW100.0");

	Data.J1 = float.Parse($"{
      
      theDB20}");
	//...
	Data.顶升气缸原位 = ConvertUtils.GetBool(theDB100, 2); 
	Data.顶升气缸东位 = ConvertUtils.GetBool(theDB100, 3); 
	//...
}
  • Using local variables as an alternative reduces the update frequency from 7s to 3 - 4s when all 13 devices are running. For projects of different scales, the frequency changes to different degrees, but compared with repeated use, PLC.Read(string plc)there is significant improvement. But in essence, the immediate goal is still not achieved.

  Therefore, PLC.Read(string plc)knowing the string parsing rules is inevitable. Through the source code, you can understand the data class that is finally parsed DataIteminto for the request. And refer to the method that can be PLC.ReadMultibleVars(List<DataItem> data)understood , which is used to obtain the specified offset data under a DB block. Obtaining all data in one visit is obviously less stressful and more applicable than obtaining multiple data in multiple visits. So combine PLC.Read(string plc)to create DataItem instance. Using static fields and attributes instead of string to access DB is the optimal solution (currently)

private static DataItem VarDB20 = new DataItem()
{
    
    
    DataType = DataType.DataBlock,
    VarType = VarType.Bit,
    DB = 110,
    StartByteAdr = 20,
    BitAdr = 0,
    Count = 1,
    Value = new object()
};

public static List<DataItem> Datas = new List<DataItem>() {
    
     VarDB20 }
  • DataType.DataBlock: PLC connection data type is DB block
  • VarType:type of data. Reference "DBW" "DBB" "DBX" "DBD"
  • DB: DB block number. For example, "DB110.DBW20.0" points to 110 BD block
  • StartByteAdr :Offset. For example "DB110.DBW20.0" points to an offset of 20 (20 decimal places in 20.0)
  • BitAdr :address. For example "DB110.DBW20.0" points to an offset of 0 (0 after the decimal point in 20.0)
  • Count: Fetch number (the default is 1, unless otherwise specified)
  • Value: store the data value to be read or written in PLC. (decimal)
public override void OnUpdateData()
{
    
    
	PLC.ReadMultibleVars(Datas);
	
	Data.J1 = float.Parse($"{
      
      VarDB20.Value}");
	//...
	Data.顶升气缸原位 = ConvertUtils.GetBool(VarDB100.Value, 2); 
	Data.顶升气缸东位 = ConvertUtils.GetBool(VarDB100.Value, 3); 
	//...
}

  In case of PLC.ReadMultibleVars(List<DataItem> data)optimized , the read pressure is reduced again, so that the simulated performance of the actual mechanical axis is almost lag-free from the actual performance. Note: When the data all point to the same DB block, using this method is optimal for reading and writing (currently).

5. About data type conversion


  Same as each programming language, its data types also include string/booland other data types, but the difference is Realthe data type. (In fact, it is double/floatthe kind of floating point number). To read this type of data, you need to use the DBD type to read. Fortunately, the conversion method is provided in S7:

(uShort.Parse($"{
      
      PLC.Read("DB110.DBW100.0")}")).ConvertToFloat()

Guess you like

Origin blog.csdn.net/qq_51026638/article/details/129334007