Symbol initialization and retain variables
Symbol initialization and *Retain variables are two different mechanisms for persistent data storage in TwinCAT PLC projects. Using the Automation Interface, both can be read from the PLC instance via ProduceXml. Initialization values can also be set using ConsumeXml.
Requirements
- TwinCAT XAE is installed and started.
- A DTE connection to the target instance is active.
ITcSysManageris initialized in an STA thread.- A PLC project containing a PLC instance exists in the solution.
Symbol initialization
Variables can be marked in the PLC code using the {attribute 'TcInitSymbol'} pragma. TwinCAT then provides XML access to the initialization values via the Automation Interface. This feature is available starting with TwinCAT Build 4024.17.
PLC declaration
VAR
{attribute 'TcInitSymbol'}
nCount : INT;
END_VAR
Read initialization values (C#)
// Look up PLC instance (under TIPC^<ProjectName>^<InstanceName>)
ITcSmTreeItem plcInstance = sysManager.LookupTreeItem(@"TIPC^PLC1^PLC1 Instance");
// Read symbol initialization values
string initXml = plcInstance.ProduceXml();
// The XML contains <InitSymbolValues> for all variables marked with {attribute 'TcInitSymbol'}
Sample XML (ProduceXml output)
<TreeItem>
<TcModuleInstance>
<Module>
<InitSymbolValues>
<Value>
<Name>MAIN.nRem1</Name>
<Value>0</Value>
</Value>
</InitSymbolValues>
</Module>
</TcModuleInstance>
</TreeItem>
Set initialization value (ConsumeXml, C#)
string setInitXml = @"<TreeItem>
<Instance>
<SymbolInit>
<Symbol>
<Name>MAIN.nInitValue</Name>
<Value>42</Value>
</Symbol>
</SymbolInit>
</Instance>
</TreeItem>";
plcInstance.ConsumeXml(setInitXml);
Retain variables
![]() | Access to retain variables via the Automation Interface is read-only. |
Retain variables are declared in the PLC code using the VAR RETAIN section and retain their values even after the PLC is restarted.
PLC declaration
PROGRAM MAIN
VAR
END_VAR
VAR RETAIN
nRem1 : INT;
END_VAR
Sample XML (ProduceXml output from the PLC instance)
<TreeItem>
<TcModuleInstance>
<Module>
<DataAreas>
<DataArea>
<AreaNo AreaType="RetainSrc" CreateSymbols="true">4</AreaNo>
<Name>PlcTask Retains</Name>
<ContextId>0</ContextId>
<ByteSize>11534336</ByteSize>
<Symbol>
<Name>MAIN.nRem1</Name>
<Comment><![CDATA[{attribute 'TcInitSymbol'}]]></Comment>
<BitSize>16</BitSize>
<BaseType GUID="{18071995-0000-0000-0000-000000000006}">INT</BaseType>
<BitOffs>3096576</BitOffs>
</Symbol>
<Symbol>
<Name>myProg.nRemain</Name>
<BitSize>16</BitSize>
<BaseType GUID="{18071995-0000-0000-0000-000000000006}">INT</BaseType>
<BitOffs>3137088</BitOffs>
</Symbol>
</DataArea>
</DataAreas>
</Module>
</TcModuleInstance>
</TreeItem>
<TreeItem>
<TcModuleInstance>
<Module>
<RetainDataMappings>
<RetainDataMapping AreaNo="4" OTCID="#x03020001"/>
</RetainDataMappings>
</Module>
</TcModuleInstance>
</TreeItem>
