PLC Data Type
Each program works with data. There are different types of data to match real-world problems. For example, a counter machine counts a number of objects (that can be 0 to n), on the other hand, if we want to read pressure values from a pressure sensor that can be for example -20.5 bar to 200.01 bar. In this section, we go through the different data types and it’s upper and lower range.
We shall consider all data types described in the IEC 61131-3 standard.
=> BOOL data type:
BOOL constants are the truth values TRUE (1) and FALSE (0).
If we treat INT as a 32-bit value, then we can have a problem to write over ADS. For example, If we treat short to INT type which is 32-bit in Windows then we shall have a mismatch that causes a problem in Visual Studio that may be difficult to remember.
short iclwValue = 0; //if we write int icwValue = 0; will cause problem in ADS
try
{
iclwValue = Int16.Parse(textBoxTargetCLW.Text);
}
catch (Exception){}
if (plc.IsPLCConnected)
{
object data = iclwValue;
plc.WriteValue("MAIN.MachineType", data);
=> REAL/LREAL Type:
=>STRING Type:
A variable of data type STRING can accept any string. The size specification for the memory space allocation in the declaration refers to characters and is enclosed by round or square brackets. If no size is specified, TwinCAT assumes 80 characters by default.
As a rule, TwinCAT does not limit the string length, but the string function only processes lengths between 1 and 255! If a variable is initialized with a string that is too long for the data type of the variable, TwinCAT truncates the string from the right.
The memory space required for a STRING variable is always 1 byte per character + 1 additional byte, e.g. 81 bytes for a “STRING[80]” declaration.
Example: String declaration with 35 characters
sVar : STRING(35) := ‘This is a String’;
=> WSTRING Type:
Unlike the data type STRING (ASCII), the data type WSTRING is interpreted in Unicode format. With WSTRING, a length of 10 means that the length of the WSTRING can occupy a maximum of 10 WORDs. In Unicode, however, for some characters several WORDs are required for encoding a character, so that the number of characters does not have to correspond to the length of the WSTRING (10 in this case).
Example:
wsVar : WSTRING := “This is a WString”;
Reading data type and set to PLC variable
This has been used in our PLC testing module. For example we have declared the following DINT type in PLC. We want to write 16000 to the variable pressureRawValue, how we do that.
pressureRawValue AT%I*: DINT := 0; (*myanalog defaultvalue 16000*)
Here are the tips for most type. item is the variable info loaded by using ADS.
var resultString = Regex.Match(item.Comment, @"\d+").Value;
var vv = Convert.ToInt32(resultString);
if (item.Type.StartsWith("DINT") == true)
{
item.Datatype = DataType.INT32;
if (item.Comment.Contains("defaultvalue"))
{
object oo = vv;
oo = (int)vv;
WriteValue(item.Name, oo);
}
}
if (item.Type.StartsWith("WORD") == true)
{
item.Datatype = DataType.UINT16;
if (item.Comment.Contains("defaultvalue"))
{
object oo = vv;
oo = (ushort)vv;
WriteValue(item.Name, oo);
}
}
if (item.Type.IndexOf("BOOL") >=0)
{
item.Datatype = DataType.UINT8;
if (item.Comment.Contains("defaultvalue"))
{
object oo = vv;
oo = (byte)vv;
WriteValue(item.Name, oo);
}
}
if (item.Type.IndexOf("DWORD") >=0)
{
item.Datatype = DataType.UINT32;
if (item.Comment.Contains("defaultvalue"))
{
object oo = vv;
oo = (uint)vv;
WriteValue(item.Name, oo);
}
}
if (item.Type.StartsWith("INT") == true)
{
item.Datatype = DataType.INT16;
if (item.Comment.Contains("defaultvalue"))
{
object oo = vv;
oo = (short)vv;
WriteValue(item.Name, oo);
}
}
if (item.Type.StartsWith("DINT") == true)
{
item.Datatype = DataType.INT32;
if (item.Comment.Contains("defaultvalue"))
{
object oo = vv;
oo = (int)vv;
WriteValue(item.Name, oo);
}
}
if (item.Type.StartsWith("LINT") == true)
{
item.Datatype = DataType.INT64;
if (item.Comment.Contains("defaultvalue"))
{
object oo = vv;
oo = (long)vv;
WriteValue(item.Name, oo);
}
}
if (item.Type.IndexOf("USINT") >=0)
{
item.Datatype = DataType.UINT8;
if (item.Comment.Contains("defaultvalue"))
{
object oo = vv;
oo = (byte)vv;
WriteValue(item.Name, oo);
}
}
if (item.Type.IndexOf("UINT") >=0)
{
item.Datatype = DataType.UINT16;
if (item.Comment.Contains("defaultvalue"))
{
object oo = vv;
oo = (ushort)vv;
WriteValue(item.Name, oo);
}
}
if (item.Type.IndexOf("UDINT") >=0)
{
item.Datatype = DataType.UINT32;
if (item.Comment.Contains("defaultvalue"))
{
object oo = vv;
oo = (uint)vv;
WriteValue(item.Name, oo);
}
}
if (item.Type.IndexOf("ULINT") >=0)
{
item.Datatype = DataType.UINT64;
if (item.Comment.Contains("defaultvalue"))
{
object oo = vv;
oo = (ulong)vv;
WriteValue(item.Name, oo);
}
}
if (item.Type.StartsWith("REAL") == true)
{
item.Datatype = DataType.FLOAT;
if (item.Comment.Contains("defaultvalue"))
{
object oo = vv;
oo = (float)vv;
WriteValue(item.Name, oo);
}
}
if (item.Type.IndexOf("LREAL") >=0)
{
item.Datatype = DataType.DOUBLE;
if (item.Comment.Contains("defaultvalue"))
{
object oo = vv;
oo = (double)vv;
WriteValue(item.Name, oo);
}
}
Tips
Tips 01:
Windows data type and size are different in TwinCAT structured text. This causes problems, especially when we write data over ADS in C#. Here is an example, we have declared a variable in the Windows program as the following
int myWinInt = 200;
object rawValue = myWinInt ;
client.WriteAny(handle, rawValue); // This will throw an exception "parameter size not correct" if the variable in PLC is declared as INT type.
myPLCIntType : INT := 0; //Declared in PLC
Solution:
Make sure the data size in PLC is equal to or higher than the size of the Windows variable, the above case can be solved in the following way.
int myWinInt = 200; // 4 bytes in Windows
myPLCIntType : DINT := 0; // 4 bytes in PLC
OR
short myWinInt = 200; // 2 bytes in Windows
myPLCIntType : INT := 0; // 2 bytes in PLC
What next?
Download the sample from the link given above.
Next, let’s try to understand PLC data type at https://www.hemelix.com/plc/structured-text-memory-management/
Ask questions related to Hemelix sample code and design at Google group https://groups.google.com/g/hemelix