Quick Start (PLC / UDP)

Das Beispiel implementiert einen „Echo-Dienst“: Hierbei wird auf einem Port (Standard: 10000) ein UDP Server gestartet. Wenn dieser ein UDP Paket empfängt, sendet er den Inhalt zurück an den Absender (mit gleicher IP und gleichem Port).

Das Beispiel ist auch als Download Sample 02 verfügbar. Der Download enthält zusätzlich zum Quick Start hier erweiterten Code, der jedoch an der Funktionalität selber nichts ändert.

Implementierung des UDP Echo Servers in einem PLC Projekt

Eine TwinCAT Solution wurde erzeugt
1. Wenn noch kein PLC Projekt in der TwinCAT Solution vorhanden ist, müssen Sie dieses anlegen.
2. Es wird ein Funktionsblock erzeugt, der das Interface „ITcIoUdpProtocolRecv“ implementiert. Hierdurch wird eine Methode erzeugt, die aufgerufen wird, falls UDP Pakete eintreffen.
Per Rechts-Klick auf den Knoten „POU“ im PLC Projekt können Sie im Popup Namen vergeben „SampleUdpEchoServer“, und „Implements“ per Haken aktivieren sowie das genannte Interface durch den Button „…“ auswählen:
Quick Start (PLC / UDP) 1:

Der Deklarationsteil des Funktionsbausteins erhält in der Deklaration einige Variablen:

3. Der Deklarationsteil wird somit angelegt:
{attribute 'c++_compatible'}
FUNCTION_BLOCK SampleUdpEchoServer IMPLEMENTS ITcIoUdpProtocolRecv
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
    {attribute 'TcInitSymbol'}
    oid:              OTCID;
    ipUdp:            ITcIoUdpProtocol;
    nUdpPort:         UINT := 10000;
    nReceivedPakets:  UINT;
    hrInit :          HRESULT;
    hrSend :          HRESULT;
END_VAR

Der Rumpf des Funktionsbausteins muss die CheckReceive() Methode des TCP/UDP RT Moduls aufgerufen werden.

4. Der Rumpf wird somit angelegt:
IF ipUdp <> 0 THEN
    ipUdp.CheckReceived();
END_IF

Die durch die Implementierung des Interfaces angelegte Methode “ReceiveData” wird durch das „CheckReceived“ mehrfach aufgerufen werden: Für jedes zwischenzeitlich empfangene Paket ein Aufruf.

5. Die Methode besitzt sowohl Absender-Informationen wie auch Daten als Eingangsparameter. In diesem Beispiel wird als Reaktion auf ein eintreffendes Paket das Paket (mit vertauschtem Absender/Empfänger) durch die „SendData“ Methode wieder rückgesendet. Die Implementierung erfolgt folgendermaßen:
nReceivedPakets := nReceivedPakets+1;
IF ipUdp <> 0 THEN
    hrSend := ipUdp.SendData(ipAddr, udpSrcPort, udpDestPort, nData, pData, TRUE, 0); // send data back
END_IF

Beim Starten und Beenden muss aus der konfigurierten OID eine Referenz auf das „UdpProtocol“ Interface gesetzt werden; entsprechende Freigaben sind beim Runterfahren zu erledigen.

6. Der Baustein benötigt hierfür die Methoden „FB_init“ „FB_reinit“ und „FB_exit“, welche Sie durch einen Rechts-Click auf den Baustein „Add…“ Methode anlegen:
Quick Start (PLC / UDP) 2:

Die passenden Signaturen werden dabei automatisch generiert, sodass nur der eigentliche Rumpf realisiert werden muss. Wichtig ist dabei insbesondere der „RegisterReceiver“ Aufruf, der einen UDP Port zum Empfang öffnet.

7. In der „FB_init“ Methode werden zwei lokale Variablen benötigt:
VAR
    ipSrv: ITComObjectServer;
END_VAR
8. Die Implementierung der „FB_init“ Methode erfolgt folgenderweise:
IF NOT bInCopyCode THEN // no online change
IF ipUdp = 0 AND oid <> 0 THEN
hrInit := FW_ObjMgr_GetObjectInstance(oid:=oid, iid:=TC_GLOBAL_IID_LIST.IID_ITcIoUdpProtocol, pipUnk:=ADR(ipUdp) );
IF SUCCEEDED(hrInit) THEN
IF SUCCEEDED(ipUdp.RegisterReceiver(nUdpPort, THIS^)) THEN //open port
FB_init := TRUE;
ELSE
FB_init := FALSE;
FW_SafeRelease(ADR(ipUdp));
END_IF
END_IF
ELSIF oid = 0 THEN
FB_init := FALSE;
hrInit := ERR_INVALID_PARAM;
END_IF
END_IF

In der „FB_reinit“ Methode, die beim OnlineChange ausgeführt wird, muss dem TCP/UDP RT Objekt die neue Adresse für die Callbacks mitgeteilt werden.

9. Die Implementierung der „FB_reinit“ Methode erfolgt folgenderweise:
IF (ipUdp <> 0) THEN 
ipUdp.RegisterReceiver(nUdpPort, THIS^);
FB_reinit := TRUE;
END_IF

Beim Herunterfahren (aber nicht beim OnlineChange vgl. bInCopyCode) muss der Port entsprechend wieder geschlossen werden.

10. Die Implementierung der „FB_exit“ Methode erfolgt folgenderweise:
IF (NOT bInCopyCode AND ipUdp <> 0) THEN //Shutdown
     ipUdp.UnregisterReceiver(nUdpPort);
    FW_SafeRelease(ADR(ipUdp));
     FB_exit := TRUE;
ELSE
     FB_exit := FALSE;
END_IF
11. Abschließend muss der Funktionsbaustein noch aufgerufen werden:
PROGRAM MAIN
VAR
        udp1 : SampleUdpEchoServer;
END_VAR

udp1();

“TCP/UDP RT” Modul Konfiguration

Hinweis

Variablennamen

Hier werden Variablennamen in Bezug auf TCP verwendet. Diese sind entsprechend zu ersetzen.

1. Legen Sie das „TCP/UDP RT“ Modul unterhalb des RT-Ethernet-Adapters an, indem Sie „Add Object(s)…“ im Context-Menü anwählen.
Quick Start (PLC / UDP) 3:
2. Dann wählen Sie das „TCP/UDP RT“ Modul aus:
Quick Start (PLC / UDP) 4:
Das TCP/UDP RT Objekt wird unterhalb des Adapters angelegt.
Quick Start (PLC / UDP) 5:
3. Parametrieren Sie die zuvor angelegte Instanz des Moduls (hier: Modul1) unter „Interface Pointer“ „TcpProt“ mit der OID des angelegten „TCP/UDP RT“ Objekts: Quick Start (PLC / UDP) 6:
4. Bei PLC Projekten ist diese Konfiguration ebenso an der Instanz vorzunehmen, hier jedoch unter dem Reiter „Symbol Initialization“:
Quick Start (PLC / UDP) 7:
Damit ist die Konfiguration abgeschlossen
Quick Start (PLC / UDP) 8:

Verbindungsabbruch durch Betriebssystem bei Promiscuous Mode

Wenn an dem RT-Ethernet Adapter im Tab „Adapter“ der Promiscuous Mode eingeschaltet ist, werden eintreffende TCP Verbindungsaufbauten durch das Betriebssystem abgebrochen, da dieses einen im TCP/UDP RT Objekt geöffneten Port nicht kennt.

Testing

Nachdem die Konfiguration aktiviert wurde, kann mittels des UDP Sample Clients ein UDP Paket zu der PLC gesendet werden. Es kann beobachtet werden, dass jeder Aufruf den Zähler erhöht. Der Client zeigt die zurückgesendeten Pakete im oberen Bereich an.

Quick Start (PLC / UDP) 9:
Quick Start (PLC / UDP) 10:

Keine lokale Kommunikation

Der UDP Sample Client muss auf einem anderen Rechner laufen als die PLC mit dem TCP/UDP RT Objekt, denn es ist keine lokale Kommunikation von dem Windows Betriebssystem in die Echtzeit möglich.
Möglich ist alternativ die Verwendung eines „Loop-Kabels“, welches 2 Netzwerk-Ports verbindet. Der UDP Sample Client kann durch die Auswahl der Quelle (Dropdown „Source“) veranlasst werden einen spezifischen Port zu verwenden.