Usage guide
Recommended entry points
| API | Use |
|---|---|
SlmpConnectionOptions |
Holds host, profile, port, transport, timeout, target, and monitoring timer settings. |
SlmpClientFactory.OpenAndConnectAsync |
Opens a connected QueuedSlmpClient from SlmpConnectionOptions. |
ReadTypedAsync |
Reads one typed scalar such as D100 as U, S, D, L, or F. |
WriteTypedAsync |
Writes one typed scalar. |
ReadNamedAsync |
Reads a mixed snapshot of named addresses. |
WriteNamedAsync |
Writes a named set of values. |
ReadWordsSingleRequestAsync / ReadDWordsSingleRequestAsync |
Reads one contiguous block in one protocol request. |
ReadWordsChunkedAsync / ReadDWordsChunkedAsync |
Reads an explicitly chunked contiguous block. |
WriteBitInWordAsync |
Sets or clears one bit in a word device. |
PollAsync |
Repeats a named snapshot on an async interval. |
SlmpAddress |
Parses, formats, and normalizes SLMP address text. |
Connection
using System;
using PlcComm.Slmp;
var options = new SlmpConnectionOptions("192.168.250.100", SlmpPlcProfile.IqR)
{
Port = 1025,
Timeout = TimeSpan.FromSeconds(3),
Transport = SlmpTransportMode.Tcp,
Target = new SlmpTargetAddress(Station: 0xFF, ModuleIo: 0x03FF),
MonitoringTimer = 0x0010,
};
await using var client = await SlmpClientFactory.OpenAndConnectAsync(options);
Console.WriteLine($"{client.FrameType} {client.CompatibilityMode}");
Read a single value
| Type suffix | .NET value | PLC size |
|---|---|---|
U |
ushort |
1 word |
S |
short |
1 word |
D |
uint |
2 words |
L |
int |
2 words |
F |
float |
2 words |
using System;
using PlcComm.Slmp;
var options = new SlmpConnectionOptions("192.168.250.100", SlmpPlcProfile.IqR)
{
Port = 1025,
};
await using var client = await SlmpClientFactory.OpenAndConnectAsync(options);
var value = await client.ReadTypedAsync("D100", "U");
Console.WriteLine($"D100 = {value}");
Write a single value
using System;
using PlcComm.Slmp;
var options = new SlmpConnectionOptions("192.168.250.100", SlmpPlcProfile.IqR)
{
Port = 1025,
};
await using var client = await SlmpClientFactory.OpenAndConnectAsync(options);
await client.WriteTypedAsync("D100", "U", (ushort)123);
Console.WriteLine("Wrote D100.");
Named snapshot
using System;
using PlcComm.Slmp;
var options = new SlmpConnectionOptions("192.168.250.100", SlmpPlcProfile.IqR)
{
Port = 1025,
};
await using var client = await SlmpClientFactory.OpenAndConnectAsync(options);
var snapshot = await client.ReadNamedAsync(["D100", "D200:F", "D300:L", "D50.3"]);
foreach (var (address, value) in snapshot)
{
Console.WriteLine($"{address} = {value}");
}
Block reads
using System;
using PlcComm.Slmp;
var options = new SlmpConnectionOptions("192.168.250.100", SlmpPlcProfile.IqR)
{
Port = 1025,
};
await using var client = await SlmpClientFactory.OpenAndConnectAsync(options);
ushort[] words = await client.ReadWordsSingleRequestAsync("D0", 10);
uint[] dwords = await client.ReadDWordsSingleRequestAsync("D200", 4);
ushort[] chunkedWords = await client.ReadWordsChunkedAsync("D1000", 1000, maxWordsPerRequest: 480);
uint[] chunkedDwords = await client.ReadDWordsChunkedAsync("D2000", 200, maxDwordsPerRequest: 240);
Console.WriteLine($"words={words.Length}, dwords={dwords.Length}");
Console.WriteLine($"chunked words={chunkedWords.Length}, chunked dwords={chunkedDwords.Length}");
Bit in word
Use WriteBitInWordAsync when a PLC stores flags inside a word. Use .n notation such as D50.3 when reading the same bit in a named snapshot.
using System;
using PlcComm.Slmp;
var options = new SlmpConnectionOptions("192.168.250.100", SlmpPlcProfile.IqR)
{
Port = 1025,
};
await using var client = await SlmpClientFactory.OpenAndConnectAsync(options);
await client.WriteBitInWordAsync("D50", bitIndex: 3, value: true);
var snapshot = await client.ReadNamedAsync(["D50.3"]);
Console.WriteLine($"D50.3 = {snapshot["D50.3"]}");
Polling
using System;
using System.Threading;
using PlcComm.Slmp;
var options = new SlmpConnectionOptions("192.168.250.100", SlmpPlcProfile.IqR)
{
Port = 1025,
};
await using var client = await SlmpClientFactory.OpenAndConnectAsync(options);
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
await foreach (var snapshot in client.PollAsync(["D100", "D200:F", "D50.3"], TimeSpan.FromSeconds(1), cts.Token))
{
Console.WriteLine($"D100 = {snapshot["D100"]}");
}
Device range catalog
ReadDeviceRangeCatalogAsync reads live device range bounds from your PLC after you connect with an explicit PLC profile. It does not auto-discover the profile.
using System;
using System.Linq;
using PlcComm.Slmp;
var options = new SlmpConnectionOptions("192.168.250.100", SlmpPlcProfile.IqR)
{
Port = 1025,
};
await using var client = await SlmpClientFactory.OpenAndConnectAsync(options);
var catalog = await client.ReadDeviceRangeCatalogAsync();
var row = catalog.Entries.First(entry => entry.Device == "D");
Console.WriteLine($"{row.Device}: supported={row.Supported}, range={row.AddressRange}");
Long device families
LTN, LSTN, LCN, and LZ are 32-bit families. Always use :D or :L in named addresses, or pass D or L as the ReadTypedAsync / WriteTypedAsync dtype.
using System;
using PlcComm.Slmp;
var options = new SlmpConnectionOptions("192.168.250.100", SlmpPlcProfile.IqR)
{
Port = 1025,
};
await using var client = await SlmpClientFactory.OpenAndConnectAsync(options);
var current = await client.ReadTypedAsync("LTN0", "D");
var snapshot = await client.ReadNamedAsync(["LTN0:D", "LSTN0:L", "LCN0:D", "LZ0:L"]);
Console.WriteLine($"LTN0 = {current}");
Console.WriteLine($"LCN0:D = {snapshot["LCN0:D"]}");
Caution: Plain word access to
LTN,LSTN,LCN, andLZis rejected by the library.
Address reference
| Form | Example | Meaning |
|---|---|---|
| Plain word | D100 |
Unsigned 16-bit word by default. |
| Plain bit | M1000 |
Boolean bit value. |
:U |
D100:U |
Unsigned 16-bit word. |
:S |
D100:S |
Signed 16-bit word. |
:D |
D200:D |
Unsigned 32-bit value. |
:L |
D200:L |
Signed 32-bit value. |
:F |
D200:F |
Float32 value. |
.n |
D50.3 |
Bit n inside one word, where n is hexadecimal 0 to F. |