# Beckhoff Controller für TCP/IP



## Thomas_v2.1 (15 Januar 2010)

Hallo,
kann mir jemand sagen, mit welchen Beckhoff Controllern ich eine nackte TCP-Verbindung (TCP-Client) aufbauen kann, bzw. wo die möglichen Protokolle aufgelistet sind?

Es gibt die TCP/IP-Server Bibliothek (kostenpflichtig) die nur auf Windows CE basierenden Geräten zu funktionieren scheint. Ist das mit den kleineren Buscontrollern BCxxxx nicht möglich?


----------



## Feldbus (20 Januar 2010)

BC9050, BC9020, BC9120, BX9000...die können das aber nur für sehr wenig und für langsame Kommunikation geeignet schau mal in die Doku...

alle CXe können das, aber nur wenn man ein Supplemnet kauft. TCP/IP Server, kann auch als Client arbeiten, muss man aber nach-kaufen bzw. -installieren.

Gruß


----------



## Thomas_v2.1 (31 Januar 2010)

Ich habe jetzt einen BC9120 mit dem TCP/IP-Kommunikation funktioniert.
Die Bausteine dazu sind in der TcBaseBX9000.lib.

Nun sind mit beim programmieren folgende "spezielle" Eigenschaften der Bausteine in dieser Bibliothek aufgefallen:

* FB_IpStartSession
Der Baustein hat einen Parameter tTimeout. In der Hilfe von Beckhoff steht:
"tTimeout: Zeit nach der abgebrochen werden soll."

Was dort nicht steht:
1. Das ist die Timeoutzeit nach der eine bestehende Verbindung abgebrochen wird wenn keine Daten ausgetauscht werden
2. Die Zeit ist nach oben hin auf 60 Sekunden begrenzt. Wenn größere Werte parametriert werden wird trotzdem nach 60s abgebrochen
3. Wenn ich T#0s parametriere wird die Verbindung dauerhaft aufrecht erhalten


* FB_IpOpen
1. Der Baustein hat anscheinend einen internen Timeout der auf ca. 11s eingestellt ist. Also angenommen ich möchte eine Verbindung aufbauen, auf der Gegenstelle ist niemand, wechselt busy auf false und error geht auf true.
Wenn ich mir z.B. eine eigene Timeoutfunktion mache die schneller abbricht, und dann die Session mit dem FB_IpEndSession beende, hängt sich der FB_IpOpen irgendwie weg. Zumindest lässt sich die ganze TCP-Kommunikation nur durch einen Reset der Steuerung wieder aktivieren.


Würd mich mal interessieren ob da andere Leute die gleichen Erfahrungen gemacht haben, oder ob diese von Beckhoff eine Glaskugel mitgeliefert bekommen haben.
Leider hat Beckhoff kein Forum wo man denen das mal unter die Nase reiben könnte.


----------



## caret (12 Februar 2010)

Thomas_v2.1 schrieb:


> * FB_IpOpen
> 1. Der Baustein hat anscheinend einen internen Timeout der auf ca. 11s eingestellt ist. Also angenommen ich möchte eine Verbindung aufbauen, auf der Gegenstelle ist niemand, wechselt busy auf false und error geht auf true.
> Wenn ich mir z.B. eine eigene Timeoutfunktion mache die schneller abbricht, und dann die Session mit dem FB_IpEndSession beende, hängt sich der FB_IpOpen irgendwie weg. Zumindest lässt sich die ganze TCP-Kommunikation nur durch einen Reset der Steuerung wieder aktivieren.


Machst du bei deinem Timeout auch einen Aufruf von FB_IpOpen mit bStart:=FALSE um den Baustein zu reseten bevor du die Session schliesst?


----------



## Thomas_v2.1 (12 Februar 2010)

caret schrieb:


> Machst du bei deinem Timeout auch einen Aufruf von FB_IpOpen mit bStart:=FALSE um den Baustein zu reseten bevor du die Session schliesst?



Hallo,
ja, habe ich. Direkt vor End-Session mache ich generell:

```
FB_IpOpen(bStart := FALSE);
FB_IpEndSession(
	bStart:= TRUE,
	iSession:= FB_IpStartSession.iSession,
	bBusy=> ,
	bError=> ,
	iErrorId=>
);
```
Ist dir da etwas in der Richtung bekannt, bzw. hast du das mit einem eigenen Timeout laufen?


----------



## trinitaucher (12 Februar 2010)

Und du bist auch sicher, dass der FB_IoOpen direkt nach dem Aufruf fertig ist?
Vielleicht solltest du einen zyklus warten oder generell Busy oder Done oder was der Baustein sonst so bietet abfragen.


----------



## Thomas_v2.1 (12 Februar 2010)

trinitaucher schrieb:


> Und du bist auch sicher, dass der FB_IoOpen direkt nach dem Aufruf fertig ist?
> Vielleicht solltest du einen zyklus warten oder generell Busy oder Done oder was der Baustein sonst so bietet abfragen.



Ja, Busy und Error etc. fange ich ja ab, aber wie geschrieben dauert das bis zum Timeout gemessene 11s. So wie es aussieht muss ich auf jeden Fall warten bis der IpOpen von selber fertig ist.

Ich hänge meinen Baustein einfach mal an.
Es soll eine Implementation des IPCONTROL2 Bausteines aus der Oscat Network-Bibliothek werden. Wenn man den Connect-Timeout über den Zähler rausnimmt klappt das auch, nur dann muss man immer diese 11s warten. Aktuelle Tests laufen damit auf einem BC9120.


----------



## trinitaucher (12 Februar 2010)

Im Netz finde ich leider keine Doku zu der Lib. 

Ich würde aber zunächst versuchen auszuschließen, dass du ein Problem durch die Ausführung des FBs bekommst.
Mir fällt bei deinem Code auf, dass alle FB-Aufrufe bei dir an Bedingungen geknüft sind, z.B. in der Art:

```
IF bBool THEN
  myFb(In := ...);
END_IF
```
Wenn die Bedingung nicht erfüllt ist, wir der FB nicht ausgeführt. Auch die Aufrufe unter CASE-Bedingungen sind evtl. problematisch.
Braucht eine Abarbeitung länger als einen Zyklus, ist es gerade bei externen Ereignissen leicht möglich in Timeouts zu laufen.

In deinem Programm...

```
SM_END_SESSION:            (* 16#50 *)
    FB_IpOpen(bStart := FALSE);
    FB_IpEndSession(
        bStart:= TRUE,
        iSession:= FB_IpStartSession.iSession,
        bBusy=> ,
        bError=> ,
        iErrorId=>
    );
```
...fragst du das bBusy übrigens nicht ab, bevor du F_IpEndSession aufrufst.
Z.B. so:

```
SM_END_SESSION:            (* 16#50 *)
    FB_IpOpen(bStart := FALSE);
    IF NOT FB_IpOpen.bBusy THEN
       FB_IpEndSession.bStart := TRUE;
    END_IF
    FB_IpEndSession(
        iSession:= FB_IpStartSession.iSession,
        bBusy=> ,
        bError=> ,
        iErrorId=>
    );
```
Oder bleibt Busy bis zum Ablauf der 11s auf TRUE?

Mein Tipp:
Aufrufe generell bedingungsunabhängig machen und im Code ausschließlich mit den Ein- und Ausgängen der FBs arbeiten. Dann wird der Code auch etwas übersichtlicher.


```
IF bBool THEN
   myFb.In := TRUE;
ELSE
   myFb.In := FALSE;
END:IF

IF myFb.Err THEN
   myFb.In := FALSE;
END_IF

myFb();  (*ein einziger FB-Aufruf pro Zyklus, bedingungsunabhängig! *)
```


----------



## Thomas_v2.1 (12 Februar 2010)

trinitaucher schrieb:


> Im Netz finde ich leider keine Doku zu der Lib.



Die gibts hier:
http://infosys.beckhoff.com/espanol...0/html/bt_tcbasebx9000_socket_fb_overview.htm



trinitaucher schrieb:


> Ich würde aber zunächst versuchen auszuschließen, dass du ein Problem durch die Ausführung des FBs bekommst.
> Mir fällt bei deinem Code auf, dass alle FB-Aufrufe bei dir an Bedingungen geknüft sind, z.B. in der Art:
> 
> ```
> ...



Eigentlich sollte die Statemachine so vollständig sein dass ein definierter Ablauf vollzogen wird. Darum muss jeder Schritt die Weiterschaltbedingungen exakt auswerten, und dann sollte es keine unbestimmten Zustände geben. 
Vielleicht ist auch das genau das Problem bei dem was ich mit dem FB_IpOpen mache: nämlich ich warte nicht auf sein Ergebnis sondern würge ihn mit meinem eigenen Timeout vorher ab.
Evtl. muss ich das dann eben so hinnehmen wie es ist. Es wäre aber von Vorteil, wenn das Verhalten in der Dokumentation vollständig beschrieben wäre, denn die Send/Receive Bausteine kann ich ja abwürgen.



trinitaucher schrieb:


> ...fragst du das bBusy übrigens nicht ab, bevor du F_IpEndSession aufrufst.
> 
> Oder bleibt Busy bis zum Ablauf der 11s auf TRUE?



Ja, Busy bleibt bis zu Timeout des Bausteins auf true. Beim Baustein-internen Timeout geht dann busy auf false und error auf true.



trinitaucher schrieb:


> Mein Tipp:
> Aufrufe generell bedingungsunabhängig machen und im Code ausschließlich mit den Ein- und Ausgängen der FBs arbeiten. Dann wird der Code auch etwas übersichtlicher.



Naja, das ist eine Geschmacksfrage. Die Vorgehensweise mit dem "generell allen Code ausführen" ist wieder so eine SPS-Programmier-Spezialität, auf die in der restlichen Programmierwelt seltsamerweise verzichtet werden kann.


----------

