Performing a device scan
A device scan detects the connected hardware and adds it to the I/O configuration. The scan is triggered on the I/O node via ProduceXml(false). This call implicitly starts the scan and returns the detected devices synchronously as XML. The devices are then read from the XML file, created individually using CreateChild, and their addresses are set using ConsumeXml. In the final step, a box scan on each device loads the subordinate terminals.
Requirements
- A TwinCAT solution is open, and a DTE connection is active.
ITcSysManagerwas initialized as a COM object in an STA thread.- TwinCAT is in Config mode.
- The hardware is connected and turned on.
C# sample: scanning using ProduceXml as a complete workflow
If the scan is to run on a remote target system, the target NetID must first be set via SetTargetNetId. This step is not necessary when running the application locally. ProduceXml(false) returns the detected devices under the path TreeItem/DeviceGrpDef/FoundDevices/Device. For each device node, the values ItemSubType and AddressInfo are read; the device is created using CreateChild, and its address is set using ConsumeXml. Finally, ScanBoxes loads the terminals for each device.
ITcSysManager3 systemManager = /* ... */;
systemManager.SetTargetNetId("1.2.3.4.5.6"); // remote target (omit for local)
ITcSmTreeItem ioDevicesItem = systemManager.LookupTreeItem("TIID");
// ProduceXml(false) triggers an implicit ScanDevices and returns found devices
string scannedXml = ioDevicesItem.ProduceXml(false);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(scannedXml);
// Extract found devices from XML
XmlNodeList xmlDeviceList =
xmlDoc.SelectNodes("TreeItem/DeviceGrpDef/FoundDevices/Device");
List<ITcSmTreeItem> devices = new List<ITcSmTreeItem>();
int deviceCount = 0;
foreach (XmlNode node in xmlDeviceList)
{
int itemSubType = int.Parse(node.SelectSingleNode("ItemSubType").InnerText);
XmlNode xmlAddress = node.SelectSingleNode("AddressInfo");
// Create device in I/O configuration
ITcSmTreeItem device = ioDevicesItem.CreateChild(
string.Format("Device_{0}", ++deviceCount),
itemSubType,
string.Empty,
null);
// Apply address parameters from AddressInfo node
string xml = string.Format(
"<TreeItem><DeviceDef>{0}</DeviceDef></TreeItem>",
xmlAddress.OuterXml);
device.ConsumeXml(xml);
devices.Add(device);
}
// Scan boxes/terminals for each found device
foreach (ITcSmTreeItem device in devices)
{
string xml = "<TreeItem><DeviceDef><ScanBoxes>1</ScanBoxes></DeviceDef></TreeItem>";
try
{
device.ConsumeXml(xml);
}
catch (Exception ex)
{
Console.WriteLine("Warning: {0}", ex.Message);
}
foreach (ITcSmTreeItem box in device)
{
Console.WriteLine(box.Name);
}
}
PowerShell sample
$ioDevicesItem = $systemManager.LookupTreeItem("TIID")
# ProduceXml(false) triggers an implicit ScanDevices and returns found devices
$scannedXml = $ioDevicesItem.ProduceXml($false)
[xml]$xmlDoc = $scannedXml
$xmlDeviceList = $xmlDoc.SelectNodes("TreeItem/DeviceGrpDef/FoundDevices/Device")
$devices = @()
$deviceCount = 0
foreach ($node in $xmlDeviceList) {
$itemSubType = [int]$node.SelectSingleNode("ItemSubType").InnerText
$xmlAddress = $node.SelectSingleNode("AddressInfo")
$deviceCount++
# Create device in I/O configuration
$device = $ioDevicesItem.CreateChild("Device_$deviceCount", $itemSubType, "", $null)
# Apply address parameters from AddressInfo node
$xml = "<TreeItem><DeviceDef>$($xmlAddress.OuterXml)</DeviceDef></TreeItem>"
$device.ConsumeXml($xml)
$devices += $device
}
# Scan boxes/terminals for each found device
foreach ($device in $devices) {
try {
$device.ConsumeXml("<TreeItem><DeviceDef><ScanBoxes>1</ScanBoxes></DeviceDef></TreeItem>")
} catch {
Write-Warning $_.Exception.Message
}
}
Special feature of CX/K-bus devices for the CX9020 and KL terminals
For CX controllers with a K-bus interface, an explicit ReloadDevices must be called on the I/O node before the box scan. Without this step, ScanBoxes will not return any results for these devices. Calling ReloadDevices forces the driver to rescan the connected hardware.
ITcSmTreeItem ioDevicesItem = systemManager.LookupTreeItem("TIID");
try
{
ioDevicesItem.ConsumeXml(
"<TreeItem><DeviceGrpDef><ReloadDevices>true</ReloadDevices></DeviceGrpDef></TreeItem>");
}
catch (Exception ex)
{
Console.WriteLine("Warning: {0}", ex.Message);
}
// Afterwards run the regular scan via ProduceXml(false) (see above)
![]() |
|
