When creating TwinCAT software I’ve come across a use case where I want to print out and store the actual version of the project that the program resides in. This can be pretty neat when you do version control, and for instance create a release of your program and want this information available somewhere in the output of the program. I’ve had this scenario when we had a project that was continuously updated. The test/integration team needed constant bug fixes/new software releases. As a software engineer I needed to keep track of what version the test/integration team were actually running at a specific time. By updating the version number in the project information I was being able to log the actual running version of the software in a database, which is important to know when going back to fault trace any strange behavior in a particular test.
The actual information is available under “Project” ->”<Name of project> properties” in Visual Studio 2015.
This will give you the following:
Now, how do you access this from PLC-code? To start with, for libraries this is easy and is actually documented in the Beckhoff documentation. Here you are supposed to use the type “ST_LibVersion“, and Beckhoff documentation explicitly states “Each library contains a global structure of this data type.” This struct type provides the following data:
TYPE ST_LibVersion : STRUCT iMajor : UINT; iMinor : UINT; iBuild : UINT; iRevision : UINT; sVersion : STRING(23); END_STRUCT END_TYPE
For instance, if you need access to the version of the commonly used “TC2_Standard“-library:
VAR sVersion : STRING(23); END_VAR
sVersion := stLibVersion_Tc2_Standard;
“stLibVersion_Tc2_Standard” is defined as a constant global variable in the project library. In this case it will for instance give you the string ‘18.104.22.168’.
Now, what if you want to include the version of your running program (not library!) that you have defined in your project properties? Because your program is not a library this constant global variable is not available per default as in library projects. What you need to do is to click “Add” next to “POUs for property access” under the project properties.
This will create the folder “Project Information” and the three functions “F_GetCompany()”, “F_GetTitle()” and F_GetVersion()” in your project. Opening F_GetVersion() gives the following:
Perfect, a function returning a “ST_LibVersion” structure holding the Major/Minor/Build/Revision numbers! Even though the “ST_LibVersion” in itself holds a String(23), for some reason this is not included in the call to F_GetVersion (at least not in TwinCAT 3.1.4020.28). Whether this is a bug or not is unknown to me. If you update the project information, this function automatically gets updated with the correct numbers! Now that we have access to this information by calling this function in our own program, we can easily convert this to a string by a mixture of UDINT_TO_STRING and CONCAT.
VAR sVersion : STRING(23); stProgramVersion : ST_LibVersion; END_VAR
stProgramVersion := F_GetVersion(); sVersion := CONCAT(UDINT_TO_STRING(stProgramVersion.iMajor), '.'); sVersion := CONCAT(sVersion, UDINT_TO_STRING(stProgramVersion.iMinor)); sVersion := CONCAT(sVersion, '.'); sVersion := CONCAT(sVersion, UDINT_TO_STRING(stProgramVersion.iBuild)); sVersion := CONCAT(sVersion, '.'); sVersion := CONCAT(sVersion, UDINT_TO_STRING(stProgramVersion.iRevision));
Running this code gives the end result: