Zurück zur Startseite

OPC UA in MFC: Integration von open62541

Der Artikel beschreibt die technische Implementierung eines OPC UA-Clients in einer MFC-Anwendung in C++ mit open62541. Abgedeckt sind Verbindung zu Siemens S7-Controllern, Einrichten von Abonnements, Sicherheit, Arbeiten mit SQL Server und Besonderheiten der Integration in die Windows GUI.

OPC UA in MFC: Technischer Leitfaden für Entwickler
Advertisement 728x90

OPC UA in MFC-Anwendungen: Integration von open62541 für industrielle SCADA unter Windows

Industrielle Automatisierungssysteme verlassen zunehmend monolithische, proprietäre SCADA-Lösungen zugunsten flexibler, sicherer und plattformübergreifender OPC-UA-basierter Plattformen. In diesem Kontext stellt die Entwicklung eines leichten SCADA-Systems auf Basis der Microsoft Foundation Classes (MFC) mit open62541-Integration eine technisch sinnvolle Wahl für mittelständische Unternehmen dar – insbesondere wenn Kompatibilität mit bestehenden Windows-Infrastrukturen sowie strenge Latenzanforderungen bei der Kommunikation mit Siemens S7-1200/S7-1500-Steuerungen erforderlich sind.

Architektonischer Wandel: Von proprietärer SCADA zu OPC-UA-gesteuerter Integration

Traditionelle SCADA-Plattformen (WinCC, InTouch, EcoStruxure) basieren auf geschlossenen Protokollen und Herstellerabhängigkeit. Ihre Bereitstellung erfordert Lizenzierung, umfangreiche Konfiguration und führt häufig zu überladenen Softwareinstallationen – Setup-Pakete können bis zu 20 GB groß sein, obwohl nur 15–20 % der Funktionalität tatsächlich genutzt werden. Für kleine und mittlere Unternehmen ist dies wirtschaftlich nicht vertretbar.

OPC UA adressiert drei systemische Herausforderungen:

Google AdInline article slot
  • Interoperabilität: Ein einheitlicher Adressraum (NodeId), typisierte Variablen und ein einziges Abonnement-Mechanismus ermöglichen die Datenaggregation von Geräten verschiedener Hersteller ohne Zwischengateways.
  • Sicherheit out-of-the-box: Unterstützung für X.509-Zertifikate, Sicherheitsrichtlinien (None, Basic128Rsa15, Basic256Sha256) sowie Verschlüsselung und Authentifizierung auf Protokollebene.
  • Flexibilität bei der Bereitstellung: Clients können native Windows-Anwendungen (MFC/Win32), Webdienste oder Microservices sein, die auf Linux laufen – ohne Änderungen an der Serverlogik.

In der industriellen Praxis bedeutet dies, teure SCADA-Systeme durch maßgeschneiderte Lösungen zu ersetzen, die direkt über OPC UA mit Steuerungen verbunden sind, sich in SQL Server zur Speicherung von Rezepten und historischen Daten integrieren und Fernüberwachung über Diagramme und Anlagenstatusanzeigen ermöglichen.

Integration von open62541 in MFC: Technische Merkmale und Einschränkungen

open62541 ist eine C99-konforme, abhängigkeitsfreie Open-Source-Bibliothek, die für Embedded- und Desktopsysteme konzipiert wurde. Ihre Verwendung in einem MFC-Projekt setzt mehrere Bedingungen voraus:

  • Das Projekt muss im /MD-Modus kompiliert werden (dynamische Verknüpfung mit CRT), da open62541 auf der Standard-C-Bibliothek basiert.
  • Bei Verwendung sicherer Richtlinien ist eine explizite Initialisierung des TLS/SSL-Stapels erforderlich – unter Windows erfolgt dies über Wincrypt.h und CryptInitialize().
  • Alle Objekte wie UA_Client, UA_CreateSubscriptionRequest und UA_MonitoredItemCreateRequest müssen manuell verwaltet werden: Speicherzuweisung, Aufruf von UA_Client_disconnect() und Freigabe mit UA_Client_delete().

Eine kritische Einschränkung ist das Fehlen eines integrierten Thread-Pools. In einer MFC-Anwendung mit GUI-Thread müssen alle Aufrufe von UA_Client_* in einem separaten Worker-Thread (AfxBeginThread) oder über PostMessage/WM_USER ausgeführt werden, um eine Blockierung der Benutzeroberfläche zu vermeiden. Ein direkter Aufruf von UA_Client_connect() in CMainFrame::OnInitialUpdate() würde das Fenster einfrieren lassen.

Google AdInline article slot

Implementierung von Verbindung und Abonnement in C++/MFC

Die Funktion CMainFrame::ConnectCPUOnline() zeigt einen minimal tragfähigen Szenario für die Verbindung mit einem OPC-UA-Server. Sie initialisiert den Client, konfiguriert die Einstellungen und stellt die Verbindung her. Wichtige Punkte sind:

  • Die Verwendung von UA_String_fromChars() zur Konvertierung von CT2A-Strings in UA_String – eine zwingende Voraussetzung der open62541-API.
  • Die Einstellung von cc->securityMode = UA_MESSAGESECURITYMODE_NONE ist nur in isolierten Netzwerken akzeptabel; in realen Projekten muss UA_MESSAGESECURITYMODE_SIGNANDENCRYPT gewählt und Zertifikate über UA_ClientConfig_setDefaultEncryption() geladen werden.
  • Logging auf der Ebene UA_LOGLEVEL_ERROR bietet das optimale Gleichgewicht zwischen Diagnose und Performance in der Produktion.

Nach der Verbindung wird ein Abonnement erstellt und Monitoring-Items konfiguriert. Nachfolgend ein Ausschnitt, wie ein Abonnement erstellt und das erste Tag hinzugefügt wird:

// Erstellung eines Abonnements
UA_CreateSubscriptionRequest request = UA_CreateSubscriptionRequest_default();
request.requestedPublishingInterval = 500.0; // ms
request.requestedMaxKeepAliveCount = 10;
request.requestedLifetimeCount = 30;

UA_CreateSubscriptionResponse response = UA_Client_Subscriptions_create(
    StrCPUADR[iAdr].g_clientOnline, request, NULL, NULL, NULL);

if (response.responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
    return false;
}
StrCPUADR[iAdr].g_subscriptionId = response.subscriptionId;

// Konfiguration des Monitors für das Tag
UA_MonitoredItemCreateRequest monRequest = UA_MonitoredItemCreateRequest_default();
monRequest.itemToMonitor.nodeId = UA_NODEID_NUMERIC(0, StrDBINI[i].iIDUA);
monRequest.itemToMonitor.attributeId = UA_ATTRIBUTEID_VALUE;
monRequest.monitoringMode = UA_MONITORINGMODE_REPORTING;

UA_MonitoredItemCreateResult monResponse = UA_Client_MonitoredItems_createSingle(
    StrCPUADR[iAdr].g_clientOnline,
    StrCPUADR[iAdr].g_subscriptionId,
    &monRequest);

Beachten Sie, dass iIDUA die NodeId des Controllers ist, die aus der Datenbank stammt (z. B. ns=2;s=Channel1.Device1.Tag1). Sie muss exakt mit dem Adressraum des Servers übereinstimmen. Fehler in der NodeId führen zwar zu UA_STATUSCODE_BADNODEIDUNKNOWN, aber nicht zum Absturz – daher ist die Überprüfung von monResponse.statusCode unerlässlich.

Google AdInline article slot

Arbeit mit Daten: Vom Lesen bis zum Logging in SQL Server

Das System verwendet drei zentrale Strukturen zur Datenverwaltung:

  • StrDBCP – Konfiguration für Verbindungen zu Steuerungen: IP-Adresse, Online-/Offline-Status, Pointer auf UA_Client*, Abonnement-ID und ein arrayValue-Puffer für den Empfang von Werten.
  • StrDBINI – Metadaten zu Tags: iIDUA (NodeId), iTYPEID (Datentyp: UA_TYPES_INT32, UA_TYPES_DOUBLE, UA_TYPES_BOOLEAN) und ein bSaveDb-Flag für das Logging.
  • StrDBVAL – Historische Wertetabelle mit Zeitstempeln, CTime, iNOMEQ, iItem und iVal.

Die Logik zur Aktualisierung der Werte wird in der Callback-Funktion UA_Client_DataChangeNotification implementiert. Wenn ein neuer Wert empfangen wird:

  • Überprüfung des iTYPEID und sicheres Casten des Typs mit UA_Variant_getScalarCopy().
  • Schreiben in arrayValue[i] unter Berücksichtigung von sizearray.
  • Wenn bSaveDb == true, Formulierung einer parametrisierten INSERT-Anweisung in SQL Server via CDatabase::ExecuteSQL().

Wichtig: Alle Operationen an arrayValue müssen durch eine kritische Section (CCriticalSection) geschützt werden, da die Daten aus einem Hintergrundthread kommen, während der GUI-Thread sie gleichzeitig für die Diagrammrenderung anfordern kann.

Was wirklich zählt

  • OPC UA in einer MFC-Anwendung erfordert die manuelle Verwaltung des Lebenszyklus von UA_Client: Initialisierung → Verbindung → Abonnement → Lesen → Abmeldung → Trennung → Löschung.
  • Sicherheit ist kein Optional: SECURITYPOLICY_NONE ist nur in Testumgebungen akzeptabel; in industriellen Netzwerken sind X.509-Zertifikate und SIGNANDENCRYPT obligatorisch.
  • open62541 bietet keine asynchronen APIs für die Windows-GUI – alle Netzwerkoperationen müssen in einem separaten Thread durchgeführt und anschließend über PostMessage synchronisiert werden.
  • Die Strukturen StrDBCP, StrDBINI und StrDBVAL bilden eine Abstraktionsschicht über OPC UA, die es ermöglicht, zwischen verschiedenen Steuerungen zu wechseln, ohne die Datenverarbeitungslogik zu ändern.
  • Die Unterstützung von Siemens S7-1200/S7-1500 erfordert das Aktivieren des OPC-UA-Servers in der Controller-Firmware sowie die korrekte Konfiguration der User Access Control (UAC) in TIA Portal.

— Editorial Team

Advertisement 728x90

Weiterlesen