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.

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();
}