Read/Write primitive values
Reading writing Values from ADS Devices is the most essential part of the communication API. There are several options for communication with your application.
- Accessing by IndexGroup / IndexOffset
- Symbolic access by instance path and optionally use handles for the symbol
- Holding the overall Symbolic information in the SymbolLoader and use easy access via symbol objects.
- Usage the symbolic interface ITcAdsSymbol when complete SymbolLoading by SymbolLoaders is not appropriate.
- Reading / Writing values as .NET managed Types (primitive types or compound primitive types called ANY_TYPES), or complex dynamic types typesafe generated at runtime.
The following section shows the different scenarios as code snippets.
HowTo Read/Write Values
Read/Write AnyType by IndexGroup/IndexOffset (asynchronously)
using (AdsClient client = new AdsClient())
{
CancellationToken cancel = CancellationToken.None;
uint valueToRead = 0;
uint valueToWrite = 42;
client.Connect(AmsNetId.Local, 851);
ResultWrite resultWrite = await client.WriteAnyAsync(0x4020, 0x0, valueToWrite,cancel);
bool succeeded = resultWrite.Succeeded;
ResultValue<uint> resultRead = await client.ReadAnyAsync<uint>(0x4020, 0x0, cancel);
if(resultRead.Succeeded)
{
valueToRead = (uint)resultRead.Value;
}
}
Read/Write AnyType by IndexGroup/IndexOffset (synchronously)
using (AdsClient client = new AdsClient())
{
uint valueToRead = 0;
uint valueToWrite = 42;
client.Connect(AmsNetId.Local, 851);
client.WriteAny(0x4020, 0x0, valueToWrite);
valueToRead = (uint)client.ReadAny(0x4020, 0x0, typeof(uint));
}
Read/Write AnyType by variable handle (asynchronously)
using (AdsClient client = new AdsClient())
{
CancellationToken cancel = CancellationToken.None;
uint varHandle = 0;
client.Connect(AmsNetId.Local, 851);
uint valueToRead = 0;
uint valueToWrite = 42;
ResultHandle resultHandle = await client.CreateVariableHandleAsync("MAIN.nCounter", cancel);
varHandle = resultHandle.Handle;
if (resultHandle.Succeeded)
{
try
{
ResultWrite resultWrite = await client.WriteAnyAsync(varHandle, valueToWrite, cancel);
ResultValue<uint> resultRead = await client.ReadAnyAsync<uint>(varHandle, cancel);
if (resultRead.Succeeded)
valueToRead = resultRead.Value;
}
finally
{
// Unregister VarHandle after Use
ResultAds result = await client.DeleteVariableHandleAsync(varHandle,cancel);
}
}
}
Read/Write AnyType by variable handle (synchronously)
using (AdsClient client = new AdsClient())
{
uint varHandle = 0;
client.Connect(AmsNetId.Local, 851);
try
{
uint valueToRead = 0;
uint valueToWrite = 42;
varHandle = client.CreateVariableHandle("MAIN.nCounter");
client.WriteAny(varHandle, valueToWrite);
valueToRead = (uint)client.ReadAny(varHandle, typeof(uint));
}
finally
{
// Unregister VarHandle after Use
client.DeleteVariableHandle(varHandle);
}
}
Read/Write AnyType by instance/symbol path (asynchronously)
using (AdsClient client = new AdsClient())
{
CancellationToken cancel = CancellationToken.None;
uint valueToRead = 0;
uint valueToWrite = 42;
client.Connect(AmsNetId.Local, 851);
ResultWrite resultWrite = await client.WriteValueAsync("MAIN.nCounter", valueToWrite, cancel);
ResultValue<uint> resultRead = await client.ReadValueAsync<uint>("MAIN.nCounter",cancel);
if (resultRead.Succeeded)
valueToRead = resultRead.Value;
}
Read/Write AnyType by instance/symbol path (synchronously)
using (AdsClient client = new AdsClient())
{
uint valueToRead = 0;
uint valueToWrite = 42;
client.Connect(AmsNetId.Local, 851);
client.WriteValue("MAIN.nCounter", valueToWrite);
valueToRead = (uint)client.ReadValue("MAIN.nCounter", typeof(uint));
}
Read/Write AnyType by IAdsSymbol (asynchronously)
using (AdsClient client = new AdsClient())
{
CancellationToken cancel = CancellationToken.None;
uint valueToRead = 0;
uint valueToWrite = 42;
client.Connect(AmsNetId.Local, 851);
ResultValue<IAdsSymbol> resultSymbol = await client.ReadSymbolAsync("MAIN.nCounter",cancel);
if (resultSymbol.Succeeded)
{
ResultWrite resultWrite = await client.WriteValueAsync(resultSymbol.Value, valueToWrite, cancel);
bool succeeded = resultWrite.Succeeded;
ResultValue<uint> resultValue = await client.ReadValueAsync<uint>(resultSymbol.Value,cancel);
if (resultValue.Succeeded)
valueToRead = resultValue.Value;
}
}
Read/Write AnyType by IAdsSymbol (synchronously)
using (AdsClient client = new AdsClient())
{
uint valueToRead = 0;
uint valueToWrite = 42;
client.Connect(AmsNetId.Local, 851);
IAdsSymbol symbol = client.ReadSymbol("MAIN.nCounter");
client.WriteValue(symbol, valueToWrite);
valueToRead = (uint)client.ReadValue(symbol);
}
Read/Write AnyType by SymbolBrowser (asynchronously)
using (AdsClient client = new AdsClient())
{
CancellationToken cancel = CancellationToken.None;
uint valueToRead = 0;
uint valueToWrite = 42;
client.Connect(AmsNetId.Local, 851);
// Load all Symbols + DataTypes
ISymbolLoader loader = SymbolLoaderFactory.Create(client, SymbolLoaderSettings.Default);
ResultSymbols resultSymbols = await loader.GetSymbolsAsync(cancel);
if (resultSymbols.Succeeded)
{
Symbol symbol = (Symbol)resultSymbols.Symbols["MAIN.nCounter"];
// Works for ALL Primitive 'ANY TYPES' Symbols
ResultWriteAccess resultWrite = await symbol.WriteValueAsync(valueToWrite, cancel);
ResultReadValueAccess resultRead = await symbol.ReadValueAsync(cancel);
if (resultRead.Succeeded)
valueToRead = (uint)resultRead.Value;
// Simple filtering of Symbols
Regex filterExpression = new Regex(pattern: @"^MAIN.*"); // Everything that starts with "MAIN"
// FilterFunction that filters for the InstancePath
Func<ISymbol, bool> filter = s => filterExpression.IsMatch(s.InstancePath);
SymbolIterator iterator = new SymbolIterator(symbols: resultSymbols.Symbols, recurse: true, selector: filter);
foreach (ISymbol filteredSymbol in iterator)
{
Console.WriteLine(filteredSymbol.InstancePath);
}
}
}
Read/Write AnyType by SymbolBrowser (synchronously)
using (AdsClient client = new AdsClient())
{
uint valueToRead = 0;
uint valueToWrite = 42;
client.Connect(AmsNetId.Local, 851);
// Load all Symbols + DataTypes
ISymbolLoader loader = SymbolLoaderFactory.Create(client, SymbolLoaderSettings.Default);
Symbol symbol = (Symbol)loader.Symbols["MAIN.nCounter"];
// Works for ALL Primitive 'ANY TYPES' Symbols
symbol.WriteValue(valueToWrite);
valueToRead = (uint)symbol.ReadValue();
// Simple filtering of Symbols
Regex filterExpression = new Regex(pattern: @"^MAIN.*"); // Everything that starts with "MAIN"
// FilterFunction that filters for the InstancePath
Func<ISymbol, bool> filter = s => filterExpression.IsMatch(s.InstancePath);
SymbolIterator iterator = new SymbolIterator(symbols: loader.Symbols, recurse: true, selector: filter);
foreach (ISymbol filteredSymbol in iterator)
{
Console.WriteLine(filteredSymbol.InstancePath);
}
}
Read/Write dynamic types by SymbolBrowser (asynchronously)
using (AdsClient client = new AdsClient())
{
CancellationToken cancel = CancellationToken.None;
uint valueToRead = 0;
uint valueToWrite = 42;
client.Connect(AmsNetId.Local, 851);
// Load all Symbols + DataTypes
// Primitive Parts will be automatically resolved to .NET Primitive types.
IDynamicSymbolLoader loader = (IDynamicSymbolLoader)SymbolLoaderFactory.Create(client, SymbolLoaderSettings.DefaultDynamic);
//dynamic symbols = loader.SymbolsDynamic;
ResultDynamicSymbols resultSymbols = await loader.GetDynamicSymbolsAsync(cancel);
if (resultSymbols.Succeeded)
{
dynamic symbols = resultSymbols.Symbols; // Symbols collection with 'dynamic' access.
dynamic main = symbols.Main; // Get the 'dynamic' main FB as Property
// Use typed object to use InfoTips instead of 'dynamic'
DynamicSymbol nCounter = main.nCounter;
// or to be fullDynamic
dynamic nCounter2 = main.nCounter;
// Works for ALL sorts of types (not restricted to ANY_TYPE basing primitive types)
ResultWriteAccess resultWrite = await nCounter.WriteValueAsync(valueToWrite,cancel);
ResultReadValueAccess resultRead = await nCounter.ReadValueAsync(cancel);
if (resultRead.Succeeded)
{
// Because the PLC value is defined as UDINT (32-Bit)
// We get back an already Marshalled UInt32 here ...
valueToRead = (uint)resultRead.Value;
}
}
}
Read/Write dynamic types by SymbolBrowser (synchronously)
using (AdsClient client = new AdsClient())
{
uint valueToRead = 0;
uint valueToWrite = 42;
client.Connect(AmsNetId.Local, 851);
// Load all Symbols + DataTypes
// Primitive Parts will be automatically resolved to .NET Primitive types.
IDynamicSymbolLoader loader = (IDynamicSymbolLoader)SymbolLoaderFactory.Create(client, SymbolLoaderSettings.DefaultDynamic);
dynamic symbols = loader.SymbolsDynamic;
dynamic main = symbols.Main;
// Use typed object to use InfoTips
DynamicSymbol nCounter = main.nCounter;
// or to be fullDynamic
//dynamic nCounter = main.nCounter;
// Works for ALL sorts of types (not restricted to ANY_TYPE basing primitive types)
nCounter.WriteValue(valueToWrite);
valueToRead = (uint)nCounter.ReadValue();
}