# Ping Netzwerkadressen



## christoph.87 (24 März 2017)

Hallo Comunity,

ich versuche seit einer weile über SysSockPing eine IP adresse im Hiemnetzwerk anzupingen, leider mag das bis jetzt nicht wirklich. Im Netzt habe ich zwar schon ein paar Anhaltspunkte gefunden, aber nichts in Codesys V3.
Im Endefekt will ich am Schluss nur ein True oder Fals haben wenn die Adesse erreicbar ist.

Hoffe hier kann mir jmd helfen.
Danke schonmal. 
MfG Chris


----------



## Azrael666 (25 März 2017)

```
FUNCTION_BLOCK TCP_Check
VAR_INPUT
    TimeOut        : UDINT;            (*TimeOut*)
END_VAR
VAR_OUTPUT
    IP1_NA        : BOOL;                (*Zielsystem 1 nicht erreichbar*)
    IP2_NA        : BOOL;                (*Zielsystem 2 nicht erreichbar*)
    IP3_NA        : BOOL;                (*Zielsystem 3 nicht erreichbar*)
    IP4_NA        : BOOL;                (*Zielsystem 4 nicht erreichbar*)
END_VAR
VAR
    IPAdress_1    : STRING[15];        (*Zielsystem 1 IP-Adresse*)
    IPAdress_2    : STRING[15];        (*Zielsystem 2 IP-Adresse*)
    IPAdress_3    : STRING[15];        (*Zielsystem 3 IP-Adresse*)
    IPAdress_4    : STRING[15];        (*Zielsystem 4 IP-Adresse*)
    ReplyTime_1    : UDINT;            (*Antwortzeit*)
    ReplyTime_2    : UDINT;            (*Antwortzeit*)
    ReplyTime_3    : UDINT;            (*Antwortzeit*)
    ReplyTime_4    : UDINT;            (*Antwortzeit*)
    ANF_CHECK     : TON;
    
    (*Variablen VISU*)
    IP1_NA_VISU : DWORD;
    IP2_NA_VISU : DWORD;
    IP3_NA_VISU : DWORD;
    IP4_NA_VISU : DWORD;            
END_VAR
```


```
(*Prüfintervall*)
IF LEN(IPAdress_1) <> 0 OR
    LEN(IPAdress_2) <> 0 OR
    LEN(IPAdress_3) <> 0 OR
    LEN(IPAdress_4) <> 0 THEN
ANF_CHECK (IN:= NOT ANF_CHECK.Q , PT:=T#2000MS);
END_IF;


(*PING Prüfung der einzelnen Teilnehmer*)
IF LEN(IPAdress_1) <> 0 AND ANF_CHECK.Q THEN
SysSockPing(szIPAddress:=IPAdress_1, ulTimeout:=TimeOut , pulReplyTime:=ADR(ReplyTime_1));
    IF ReplyTime_1 >= TimeOut THEN
    IP1_NA := TRUE;
    ELSE IP1_NA := FALSE;
    END_IF;
END_IF;


IF LEN(IPAdress_2) <> 0 AND ANF_CHECK.Q THEN
SysSockPing(szIPAddress:=IPAdress_2, ulTimeout:=TimeOut , pulReplyTime:=ADR(ReplyTime_2));
    IF ReplyTime_2 >= TimeOut THEN
    IP2_NA := TRUE;
    ELSE IP2_NA := FALSE;
    END_IF;
END_IF;


IF LEN(IPAdress_3) <> 0 AND ANF_CHECK.Q THEN
SysSockPing(szIPAddress:=IPAdress_3, ulTimeout:=TimeOut , pulReplyTime:=ADR(ReplyTime_3));
    IF ReplyTime_3 >= TimeOut THEN
    IP3_NA := TRUE;
    ELSE IP3_NA := FALSE;
    END_IF;
END_IF;


IF LEN(IPAdress_4) <> 0 AND ANF_CHECK.Q THEN
SysSockPing(szIPAddress:=IPAdress_4, ulTimeout:=TimeOut , pulReplyTime:=ADR(ReplyTime_4));
    IF ReplyTime_4 >= TimeOut THEN
    IP4_NA := TRUE;
    ELSE IP4_NA := FALSE;
    END_IF;
END_IF;


(*VISU*)
IF IP1_NA THEN
    IP1_NA_VISU := gvl.dwAlarm;
    ELSE IP1_NA_VISU := gvl.dwGreen;
END_IF;
IF LEN(IPAdress_1) = 0 THEN
    IP1_NA_VISU := gvl.dwGrey;
END_IF;


IF IP2_NA THEN
    IP2_NA_VISU := gvl.dwAlarm;
    ELSE IP2_NA_VISU := gvl.dwGreen;
END_IF;
IF LEN(IPAdress_2) = 0 THEN
    IP2_NA_VISU := gvl.dwGrey;
END_IF;


IF IP3_NA THEN
    IP3_NA_VISU := gvl.dwAlarm;
    ELSE IP3_NA_VISU := gvl.dwGreen;
END_IF;
IF LEN(IPAdress_3) = 0 THEN
    IP3_NA_VISU := gvl.dwGrey;
END_IF;


IF IP4_NA THEN
    IP4_NA_VISU := gvl.dwAlarm;
    ELSE IP4_NA_VISU := gvl.dwGreen;
END_IF;
IF LEN(IPAdress_4) = 0 THEN
    IP4_NA_VISU := gvl.dwGrey;
END_IF;
```


----------



## Nandi0710 (3 Februar 2018)

Das läuft bei mir ganz und gar nicht :/ ich bekomme den Fehler "C0046: Bezeichner 'Ping' nicht definiert" und "C0035: Progammname, Funktion oder Funktionsbausteininstanz an Stelle von 'Ping' erwartet


----------



## oliver.tonn (3 Februar 2018)

Nandi0710 schrieb:


> Das läuft bei mir ganz und gar nicht :/ ich bekomme den Fehler "C0046: Bezeichner 'Ping' nicht definiert" und "C0035: Progammname, Funktion oder Funktionsbausteininstanz an Stelle von 'Ping' erwartet


Dann hast Du aber nicht das Beispiel von Azrael666 verwendet oder Dich vertippt, denn bei seinem Beispiel gibt es nichts nur mit Ping. Stell mal das Programm das diese Fehler beim Übersetzen ausgibt hier rein, mal sehen.

Von irgendwas mit Internetzugang gesendet


----------



## Nandi0710 (3 Februar 2018)

Fehler wahrscheinlich gefunden. Kann das sein das ein neuer Baustein kreiirt wird? Entschuldigt die blöden Fragen ich bin Anfänger :/

Kurz zur Geschichte meines Projektes:

Das ganze soll ein System werden das Spannungen von 8-250V AC/DC messen wird mir verschiedenen Messwandlern, Es sollen 2 Relaiskarten geschalten werden eine mit 8 und eine mit 16 Ausgängen und eben dioe Verfügbarkeit von 12 IP Adressen darstellen. Dazu sollen einige Fehlerzustände aufgezeigt werden. Das ganze wird dann in einem Fahrzeug verbaut das die Einsatzleitung vor Ort darstellt.

Ich bedanke mich jetzt schon bei allen Helfern


```
PROGRAM POU
FUNCTION_BLOCK TCP_Check
VAR_INPUT
    TimeOut        : UDINT;            (*TimeOut*)
END_VAR
VAR_OUTPUT
    IP1_NA        : BOOL;                (*Zielsystem 1 nicht erreichbar*)
    IP2_NA        : BOOL;                (*Zielsystem 2 nicht erreichbar*)
    IP3_NA        : BOOL;                (*Zielsystem 3 nicht erreichbar*)
    IP4_NA        : BOOL;                (*Zielsystem 4 nicht erreichbar*)
END_VAR
VAR
    IPAdress_1    : STRING[15];        (*Zielsystem 1 IP-Adresse*)
    IPAdress_2    : STRING[15];        (*Zielsystem 2 IP-Adresse*)
    IPAdress_3    : STRING[15];        (*Zielsystem 3 IP-Adresse*)
    IPAdress_4    : STRING[15];        (*Zielsystem 4 IP-Adresse*)
    ReplyTime_1    : UDINT;            (*Antwortzeit*)
    ReplyTime_2    : UDINT;            (*Antwortzeit*)
    ReplyTime_3    : UDINT;            (*Antwortzeit*)
    ReplyTime_4    : UDINT;            (*Antwortzeit*)
    ANF_CHECK     : TON;
    
    (*Variablen VISU*)
    IP1_NA_VISU : DWORD;
    IP2_NA_VISU : DWORD;
    IP3_NA_VISU : DWORD;
    IP4_NA_VISU : DWORD;            
END_VAR
```


```
IF LEN(IPAdress_1) <> 0 OR
    LEN(IPAdress_2) <> 0 OR
    LEN(IPAdress_3) <> 0 OR
    LEN(IPAdress_4) <> 0 THEN
ANF_CHECK (IN:= NOT ANF_CHECK.Q , PT:=T#2000MS);
END_IF;


(*PING Prüfung der einzelnen Teilnehmer*)
IF LEN(IPAdress_1) <> 0 AND ANF_CHECK.Q THEN
SysSockPing(szIPAddress:=IPAdress_1, ulTimeout:=TimeOut , pulReplyTime:=ADR(ReplyTime_1));
    IF ReplyTime_1 >= TimeOut THEN
    IP1_NA := TRUE;
    ELSE IP1_NA := FALSE;
    END_IF;
END_IF;


IF LEN(IPAdress_2) <> 0 AND ANF_CHECK.Q THEN
SysSockPing(szIPAddress:=IPAdress_2, ulTimeout:=TimeOut , pulReplyTime:=ADR(ReplyTime_2));
    IF ReplyTime_2 >= TimeOut THEN
    IP2_NA := TRUE;
    ELSE IP2_NA := FALSE;
    END_IF;
END_IF;


IF LEN(IPAdress_3) <> 0 AND ANF_CHECK.Q THEN
SysSockPing(szIPAddress:=IPAdress_3, ulTimeout:=TimeOut , pulReplyTime:=ADR(ReplyTime_3));
    IF ReplyTime_3 >= TimeOut THEN
    IP3_NA := TRUE;
    ELSE IP3_NA := FALSE;
    END_IF;
END_IF;


IF LEN(IPAdress_4) <> 0 AND ANF_CHECK.Q THEN
SysSockPing(szIPAddress:=IPAdress_4, ulTimeout:=TimeOut , pulReplyTime:=ADR(ReplyTime_4));
    IF ReplyTime_4 >= TimeOut THEN
    IP4_NA := TRUE;
    ELSE IP4_NA := FALSE;
    END_IF;
END_IF;


(*VISU*)
IF IP1_NA THEN
    IP1_NA_VISU := gvl.dwAlarm;
    ELSE IP1_NA_VISU := gvl.dwGreen;
END_IF;
IF LEN(IPAdress_1) = 0 THEN
    IP1_NA_VISU := gvl.dwGrey;
END_IF;


IF IP2_NA THEN
    IP2_NA_VISU := gvl.dwAlarm;
    ELSE IP2_NA_VISU := gvl.dwGreen;
END_IF;
IF LEN(IPAdress_2) = 0 THEN
    IP2_NA_VISU := gvl.dwGrey;
END_IF;


IF IP3_NA THEN
    IP3_NA_VISU := gvl.dwAlarm;
    ELSE IP3_NA_VISU := gvl.dwGreen;
END_IF;
IF LEN(IPAdress_3) = 0 THEN
    IP3_NA_VISU := gvl.dwGrey;
END_IF;


IF IP4_NA THEN
    IP4_NA_VISU := gvl.dwAlarm;
    ELSE IP4_NA_VISU := gvl.dwGreen;
END_IF;
IF LEN(IPAdress_4) = 0 THEN
    IP4_NA_VISU := gvl.dwGrey;
END_IF;
```


----------



## oliver.tonn (4 Februar 2018)

Bei der Gelegenheit, wo kommt denn die Funktion SysSockPing her? Ich finde die bei TwinCAT nicht.
Nachtrag: Vergiss es, geht ja um Codesys direkt.

Von irgendwas mit Internetzugang gesendet


----------



## oliver.tonn (4 Februar 2018)

Was mit gerade auffällt, SysSockPing wird ein Fumktionsbaustein sein und keine Funktion, in Deinem CFC Beispiel nutzt Du den FB aber als wär es eine Funktion, es fehlt oben über der Box der Instanzname, sprich Du hast im Deklarationsteil keine Instanz für den FB deklariert.

Von irgendwas mit Internetzugang gesendet


----------



## Nandi0710 (6 Februar 2018)

Ich komm einfach nicht weiter :/ oder ich bin einfach zu doof...

wo muss ich diese Codes einfügen? an welchen stellen gebe ich meine IP-Adressen ein? und wie rufe ich diese Funktionen auf?

ich erstelle eine neue POU -> dort füge ich den unteren Code ein das er mir die Variablen erzeugt? oder kopiere ich die Variablen so wie oben geschrieben dorhin? 

danach gehe ich in mein Main Task und rufe dort den soeben erstellten Baustein/Funktion auf? 

oder stehe ich da jetzt voll auf dem Schlauch? hat jemand ein Funktionierendes Beispiel das ich mal etwas bildlich vor den Augen habe?

Besten Dank schon mal


----------



## Azrael666 (7 Februar 2018)

Du musst meinen Code als POU - Funktionsbaustein erstellen und diesen POU dann in einer Funktion aufrufen.

1. Erstelle einen neuen POU als Funktionsbaustein (ST) mit beliebigem Namen
2. Code in diesen neuen Funktionsbaustein einfügen
3. Neue POU erstellen als Funktion (KOP) mit beliebigem Namen
4. Funktionsbaustein (ST) in der Funktion (KOP) als Instanz aufrufen und Ein-/Ausgänge beschalten bzw. Interne Variablen beschreiben.
5. Funktion (KOP) im zyklischen Haupttask aufrufen

PS: alles unter (*VISU*) im Code, kannst du weglassen, das sind nur Elemente denen ich Farben zugeordnet habe um sie in einer Visualisierung darzustellen.

oder du legst dir eine "Globale Variablenliste" an mit dem Namen Gvl und kopierst diesen Code dort hinein 


```
{attribute 'qualified_only'}
VAR_GLOBAL
   (*globale VISU-Farben*)
    dwBlue    : DWORD := 16#FF0000FF; //Blue, highly opaque
    dwGreen    : DWORD := 16#FF00FF00; //Green, highly opaque
    dwYellow: DWORD := 16#FFFFFF00; //Yellow, highly opaque
    dwGrey     : DWORD := 16#88888888; //Grey, semitransparent
    dwBlack : DWORD := 16#88000000; //Black, semitransparent
    dwAlarm    : DWORD := 16#FFFF0000; //Red, highly opaque
    dwWhite : DWORD := 16#FFFFFFFF;    //White
END_VAR
```

*PPS: Es muss natürlich auch die Bibliothek "Syssocket" in das Projekt eingebunden sein (ist standardmäßig bei Codesys mit dabei)!*


----------



## Nandi0710 (7 Februar 2018)

Vielen Herzlichen Danke Azreal666, ich bin wie gesagt absoluter Neuling auf dem Terant

Soweit hab ich es )) nur habe ich jetzt noch den Fehler SysSockPing nicht definiert


----------



## Nandi0710 (7 Februar 2018)

sollte vorhanden sein?

Nachtrag--> Bibliothek war nicht vorhanden da ich irrtümlich dachte der vorhandene aus RDP reicht aus.

Danke für die Hilfe


----------



## Azrael666 (7 Februar 2018)

ja da musst du noch die Syssocket Bibliothek einbinden. Einfach in dem Projekt die Bibliothek öffnen, auf neue Bibliothek einfügen gehen und nach der "Syssocket" suchen.


----------



## Nandi0710 (7 Februar 2018)

und siehe  manchmal sollte man einfach nicht zu kompliziert denken. 

Ich hätte da aber gleich noch eine Frage wie bekommt man die 3 Farben in einer Visualisierung dargestellt? DWORD kann ich ja nicht in der Visu darstellen lassen?


----------



## Azrael666 (7 Februar 2018)

Doch, du kannst bei jedem Element, wenn es um Farben geht (z.b. Hintergrundfarbe) das DWORD als Variable zuordnen. Dann ändert sich z.b. der Hintergrund je nachdem welcher Wert in dem DWORD steht.

Beispiel:
Textelement -> Farbvariablen -> Normalzustand -> Füllfarbe

dort kommt dann z.b. die Variable "IP1_NA_VISU" rein und dann würde sich das Feld je nach Zustand der Variable Rot, Grün oder Grau werden


----------



## Nandi0710 (7 Februar 2018)

Dann scheint es so, als habe ich doch noch einen Fehler in meiner Schaltung. --> Ping (Funktionsbaustein) muss für den Zugriff instanziert werden. 

Der Baustein funktioniert, die Funktion ist auch beschalten und der aufruf der Funktion erfolgt im PLC_PRG


----------



## Azrael666 (7 Februar 2018)

Ja, Funktionsbausteine werden in der Regel instanziert aufgerufen. Wenn du den Baustein im KOP einfügst sollte er dich nach dem Instanznamen fragen


----------



## Nandi0710 (7 Februar 2018)

vorher stand oben im Var block Ping_0ING;

er sollte es doch aufrufen?


----------



## oliver.tonn (7 Februar 2018)

Dann ersetz das DWORD wieder durch Ping und alles ist gut.

Von irgendwas mit Internetzugang gesendet


----------



## Nandi0710 (7 Februar 2018)

hab ich auch schon nur macht er da auch nix.


----------



## oliver.tonn (7 Februar 2018)

Das kann auch nicht gehen. POU ist von Dir als Funktion angelegt worden, da Ping ein FB ist und über mehrere Zyklen läuft kannst Du ihn nicht in einer Funktion einsetzen. Und POU musst Du natürlich auch in einem anderen FB oder Programm dann aufrufen von alleine wird das nicht ausgeführt..


----------



## Nandi0710 (7 Februar 2018)

Azrael666 schrieb:


> Du musst meinen Code als POU - Funktionsbaustein erstellen und diesen POU dann in einer Funktion aufrufen.
> 
> 1. Erstelle einen neuen POU als Funktionsbaustein (ST) mit beliebigem Namen
> 2. Code in diesen neuen Funktionsbaustein einfügen
> ...





Dann hab ich den part falsch verstanden


----------



## oliver.tonn (7 Februar 2018)

Hast Du nicht, Azrael666 liegt falsch, Ping darf nicht in einer Funktion aufgerufen werden. Funktionen verlieren Ihre Werte beim Beenden wieder, für FBs in Funktionen bedeutet dies, dass sich diese so verhalten als würden sie zum ersten mal gestartet, deswegen funktionieren Flankenbausteine in Funktionen z.B. auch nicht, da der vorherige Wert des Signals nie gespeichert wird.


----------



## Nandi0710 (7 Februar 2018)

Jetzt schaut die Welt bissl anders aus. DANKE


----------



## Nandi0710 (7 Februar 2018)

Wenn ich euch nochmal belästigen darf :/. 

Alles funktioniert soweit super Ping wird ausgeführt alle werte kommen sauber zurück und werden auch richtig virtualisiert. Jetzt kommt die rafinesse dazu: ich habe eine Virtualisierung mit dem einem Punkt Einstellungen, dort ist zu jeder IP ein Button hinterlegt der bei klicken den INPUT für Ping liefert. Sprich ich will falls nötig die IP Adresse ändern können bzw. erst einmal einen Fixen Wert haben der beim Laden bereits da ist. 

kurzes Beispiel zum Verständniss: 
Virtualisierung --> Einstellungen --> IP-Adressen --> Gerät 1-12 --> Klick auf Gerät 1 öffnet sich ein Num-Pad mit aktuellen Wert (in meinem Fall "" da ich nicht weis wie ich einen konstanten Wert hinterlege) --> Adresse ändern--> OK--> Adresse wird als String an Baustein gegeben. Nun nach Neustart der Runtime sollte der zuletzt verwendete Wert hier aber drin bleiben oder den Standardwert lesen. 

Hintergrund der Geschichte ist. Das ganze läuft in einem Einsatzleitwagen im Roten Kreuz bei dem von 3 Punkten der Status und die Bedienung des Fahrzeuges vonstatten gehen kann und soll. Die Pings helfen hier dem benutzer der kein Computerfreak ist zu sehen ob alles so läuft wie es laufen soll. Eigentliher Punkt ist es 3 Adressen ändern zu können die drin bleiben sollen da diese bei jedem Einsatz eine neue IP zugewiesen bekommen können oder die alte weiter verwendet werden kann.

Danke für eure Mithilfe


----------



## oliver.tonn (8 Februar 2018)

Na das ist doch eine der leichteren Übungen. :wink:
Einer Variable weist Du bei der Instanzierung so einen Wert zu:

```
IPAdress_1 : STRING[15] := '192.168.2.1';
```
Bei den Buttons musst Du in der Visualisierung unter Eingabekonfiguration das für Dich passende Ereignis auswählen, als Aktion wählst Du dann ST-Code ausführen aus und als Code machst Du dann eine Variablenzuweisung, allerdings musst Du den kompletten Pfad angeben wo die Variable steht. Nehmen wir mal an Dein oberstes Programm heißt Main und in diesem gibt es eine Instanz eines FBs mit dem Instanznamen "IP_Handling" in dem die zu ändernde Variable 'IPAdress_1' steht, dann sähe die auszuführende ST-Zeile so aus:

```
MAIN.IP_Handling.IPAdress_1 := '192.168.2.2'
```
Von diesem Button machst Du jetzt noch zwei Kopien und änderst Die IP entsprechend.
Wenn Du dann mal Lust hast, kannst Du in einer späteren Version, falls die IP als String angegeben wird, ja eine globale Variable (String Array) anlegen, die dann persistent/retain ist, also Ihren Wert nach dem Ausschalten nicht verliert. Über eine andere oder die Selbe Visu-Seite kannst Du in die einzelnen Elemente des Arrays dann individuell eine IP eintragen, dann wird das Ganze noch flexibler. Bei den Buttons wird dann in der ST-Zeile keine feste IP, sondern jeweils ein Element des Arrays angegeben.


----------



## Azrael666 (8 Februar 2018)

oliver.tonn schrieb:


> Hast Du nicht, Azrael666 liegt falsch, Ping darf nicht in einer Funktion aufgerufen werden. Funktionen verlieren Ihre Werte beim Beenden wieder, für FBs in Funktionen bedeutet dies, dass sich diese so verhalten als würden sie zum ersten mal gestartet, deswegen funktionieren Flankenbausteine in Funktionen z.B. auch nicht, da der vorherige Wert des Signals nie gespeichert wird.



Da muss ich leider widersprechen. Man kann eine Funktionsbaustein sehr wohl in einer Funktion aufrufen (das Flanken nicht in einer Funktion gehen sollen ist mir auch neu). 
Hier ein Bild wie es aussehen sollte :


----------



## oliver.tonn (8 Februar 2018)

Azrael666 schrieb:


> Da muss ich leider widersprechen. Man kann eine Funktionsbaustein sehr wohl in einer Funktion aufrufen (das Flanken nicht in einer Funktion gehen sollen ist mir auch neu).


Da hast Du mich missverstanden, ich meinte nicht, dass es nicht geht, sondern das es meistens nicht sinnvoll ist. Eine Funktion startet bei jedem Aufruf quasi jungfräulich und weiß nichts mehr von vorherigen Aufrufen, das hat auch Auswirkungen auf in einer Funktion verwendete FBs. In einer Funktion aufgerufene FBs verhalten sich bei jedem Aufruf so, als würden sie das erste Mal aufgerufen und das Selbe gilt für ihre internen Werte, diese haben bei jedem Aufruf wieder Ihre Initialisierungswerte, weswegen, wie von mir erwähnt, z.B. ein Flankenbaustein-FB, in einer Funktion nicht funktioniert. Wie sich das mit FBs verhält die Firmwarefunktionen aufrufen können vermutlich nur die Entwickler sagen, da kann es sein, dass auch FBs die mehrere Zyklen brauchen funktionieren. Sollen bestimmte Variablen oder FBs ihre Werte behalten müssten sie in einer Funktion im Bereich VAR_STAT deklariert werden.


----------



## oliver.tonn (8 Februar 2018)

Da ich ja viel behaupten kann folgt hier mal der Beweis, dass die Verwendung von FBs in Funktionen nicht unbedingt eine der besten Ideen ist. Da ich auf den Code vom originalen R_TRIG FB keinen Zugriff habe, habe ich kurz meinen eigenen geschrieben. Dieser sieht so aus:

```
FUNCTION_BLOCK FB_RTRIG
VAR_INPUT
    CLK            : BOOL;
END_VAR
VAR_OUTPUT
    Q            : BOOL;
END_VAR
VAR
    b_OldValue    : BOOL := FALSE;
END_VAR


Q := CLK AND (CLK XOR b_OldValue);
b_OldValue := CLK;
```

Hier ein Screenshot beim ersten Aufruf dieses FBs wo CLK TRUE ist. Der Baustein ist komplett durchgelaufen.


Hier einer vom zweiten Aufruf.


Wie Du deutlich erkennen kannst ist b_OldValue wieder auf FALSE, weil das sein Initialisierungswert ist, damit würde Q wieder auf TRUE gehen oder besser formuliert, auf TRUE bleiben.

Nachtrag:
Hier mal der selbe FB aus einem FB aufgerufen. Der erste Durchlauf ist noch gleich.


Beim Zweiten ist dann aber ein Unterschied. Hier behält b_OldValue seinen Wert


und Q geht beim zweiten Durchlauf wieder auf FALSE.


----------



## Azrael666 (8 Februar 2018)

Finde ich irgendwie unlogisch. Der Hauptablauftask ansich ist ja schon eine Funktion. Das würde ja bedeuten, dass die SPS am Ende eines Zyklus sämtliche Variablenwerte auf die Initialwerte setzen würde.


----------



## PN/DP (8 Februar 2018)

oliver.tonn schrieb:


> Da ich ja viel behaupten kann folgt hier mal der Beweis, dass die Verwendung von FBs in Funktionen nicht unbedingt eine der besten Ideen ist.


Ob ein FB sich erwartungsgemäß verhält (mit "Gedächtnis" über mehrere Aufrufe) hängt nicht davon ab, ob er aus einem FB oder aus einer Function aufgerufen wird, sondern davon, wo die Instanz liegt. In Deinem "Beweis" für das nicht-funktionieren hast Du nicht gezeigt, wo die beobachtete FB_RTRIG-Instanz deklariert ist. So wie Du in Deinem Beitrag #25 eine String-Variable global in Main deklariert hast kannst Du auch eine FB_RTRIG-Instanz global anlegen und wenn die Function diese globale Instanz aufruft, dann funktioniert die auch korrekt (ohne neu initialisieren bei jedem Aufruf).

Damit eine Function sich was merken kann, kann man ihr ein "externes Gedächtnis" via VAR_INOUT mitgeben. Ich weiß jetzt nicht, ob man in Codesys per INOUT auch Instanzen von FB übergeben kann (oder Referenzen auf FB-Instanzen per INPUT oder INOUT), doch wenn das geht, dann könntest Du auch eine (globale oder in einem FB deklarierte) FB_RTRIG-Instanz an die Function übergeben - dann würde die trotz Aufruf aus einer Function korrekt funktionieren.

Übrigens, eine Flankenerkennung muß man nicht so umständlich programmieren, man kann auch einfach "umgangssprachlich" schreiben:

```
Q := CLK AND NOT b_OldValue;
b_OldValue := CLK;
```

Harald


----------



## oliver.tonn (8 Februar 2018)

Hallo Harald,


PN/DP schrieb:


> Ob ein FB sich erwartungsgemäß verhält (mit "Gedächtnis" über mehrere Aufrufe) hängt nicht davon ab, ob er aus einem FB oder aus einer Function aufgerufen wird, sondern davon, wo die Instanz liegt. In Deinem "Beweis" für das nicht-funktionieren hast Du nicht gezeigt, wo die beobachtete FB_RTRIG-Instanz deklariert ist. So wie Du in Deinem Beitrag #25 eine String-Variable global in Main deklariert hast kannst Du auch eine FB_RTRIG-Instanz global anlegen und wenn die Function diese globale Instanz aufruft, dann funktioniert die auch korrekt (ohne neu initialisieren bei jedem Aufruf).
> 
> Damit eine Function sich was merken kann, kann man ihr ein "externes Gedächtnis" via VAR_INOUT mitgeben. Ich weiß jetzt nicht, ob man in Codesys per INOUT auch Instanzen von FB übergeben kann (oder Referenzen auf FB-Instanzen per INPUT oder INOUT), doch wenn das geht, dann könntest Du auch eine (globale oder in einem FB deklarierte) FB_RTRIG-Instanz an die Function übergeben - dann würde die trotz Aufruf aus einer Function korrekt funktionieren.


Stimmt, dass hatte ich vergessen zu erwähnen. Die Deklaration ist jeweils in einer Funktion und einem Funktionsbaustein erfolgt. Übrigens VAR_STAT kann auch helfen den Gedächtnissverlust zu vermeiden.


PN/DP schrieb:


> Übrigens, eine Flankenerkennung muß man nicht so umständlich programmieren, man kann auch einfach "umgangssprachlich" schreiben:
> 
> ```
> Q := CLK AND NOT b_OldValue;
> ...


Ach Mann, gönn mir doch meine umständliche Lösung. Aber Du hast recht, dass ist eine meiner Schwächen, ich denke manchmal einfach zu kompliziert und übersehe das Naheliegende.



Azrael666 schrieb:


> Finde ich irgendwie unlogisch. Der Hauptablauftask ansich ist ja schon eine Funktion. Das würde ja bedeuten, dass die SPS am Ende eines Zyklus sämtliche Variablenwerte auf die Initialwerte setzen würde.


@Azrael666: Da liegst Du leider wieder falsch, das was die Task aufruft ist keine Funktion, sondern ein Programm, zu erkennen (zumindest bei TwinCAT) an der Abkürzung PRG, eine Funktion hätte FUN.


----------



## Nandi0710 (8 Februar 2018)

Alos ich wollte hier jetzt keinen Streit anfangen  
Danke oliver.thonn funktioniert natürlich bestens. 

Hat einer von euch erfahrung mit dieser Variable bzw. Funktion? 
	
	



```
CASE iState OF

    0:    (*set the timezone information
          this gc_tziTimeZoneCET variable includes the date for switch to summer and winter time and the
          bias for the timezone for the Central European EU countries*)
        SetTimeZoneInformation(xExecute:= TRUE, tziInfo:= DTU.GlobalConstants.gc_tziTimeZoneCET);
        IF SetTimeZoneInformation.xDone THEN
            SetTimeZoneInformation(xExecute:= FALSE);
            iState:= 1;
        END_IF
        IF SetTimeZoneInformation.xError THEN
            SetTimeZoneInformation(xExecute:= FALSE);
            iState:= 32767;
        END_IF
```

Ich muss dort doch irgendwo den +1 hinzufügen können


----------



## Azrael666 (8 Februar 2018)

@ oliver.tonn

upsela, da hab ich ein bischen Siemenswelt mit Codesys vermischt. Mit Funktion meinte ich natürlich eine Codesys-PRG, bei Siemens gibts ja FCs ohne Gedächnis und FBs mit Instanz-DBs.

Der Funktionsblock wird natürlich nicht in einem Codesys-Funktionsbaustein aufgerufen, sondern in einem Codesys-Programbaustein.

Sry, da hab ich n bischen was durcheinandergewirbelt.


----------



## oliver.tonn (8 Februar 2018)

Kein Problem, kommt vor, aus einem Programm heraus klappt dein Vorschlag dann ja auch.


----------



## oliver.tonn (8 Februar 2018)

Nandi0710 schrieb:


> Hat einer von euch erfahrung mit dieser Variable bzw. Funktion?
> 
> 
> 
> ...


Wofür willst Du wo +1 hinzufügen/addieren?


----------



## tom_vg (27 Februar 2018)

Hallo,

Ich probiere einmahl die frage in Deutsche sprache. 

Ich brauche die Somachine 4.3 (codesys based) software und habe in dieses version eine lib syssocket mit die function 'SysSockPing'.

Jetzt functioniert das immer bekommen ich neur die wert 1.



Hello Everyone,

I have the library in my software with the SysSockPing function. I've installed this but when i try to ping to other devices then i allways get a 1 as respond even if the client o r the ip in the network is unused. 

Anyone with a remark, information?


----------

