Anfängerfrage - Zugriff auf statische Variablen von FBs

FrankTheTank

Level-1
Beiträge
41
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo allerseits!

Ich verstehe nicht ganz, wie das mit dem Variablenzugriff auf statische Variablen, die ich in FBs eingeführt habe, funktioniert.

Ich habe einen FB, der so aussieht:

Code:
FUNCTION_BLOCK FB70
   VAR_INPUT
   E2.5 : BOOL;
   E3.0 : BOOL;
   END_VAR

   VAR
   s1_prev_state : BOOL := 0;
   s2_prev_state : BOOL := 0;
   s1_pos_edge : BOOL;
   s2_pos_edge : BOOL;
   END_VAR

s1_pos_edge := E2.5 & NOT s1_prev_state;
s2_pos_edge := E3.0 & NOT s2_prev_state;

...

END_FUNCTION_BLOCK
In der Doku hab ich folgendes gefunden:
Von anderen Bausteinen aus können Sie die Variable durch indizierten Zugriff ansprechen, z.B. DBx.variable.

Ich möchte nun in einer Funktion (FC80) auf "s1_pos_edge" zugreifen. Wie mache ich das? Ich hab ja nur einen FB angelegt, aber keinen DB? Wird das automatisch gemacht?

Würde denn
Code:
IF DB70.s1_pos_edge = 1
   THEN (* irgendwas machen *)
END_IF
funktionieren?

mfg,
Frank
 
Code:
IF DB70.s1_pos_edge = 1
   THEN (* irgendwas machen *)
END_IF
funktionieren?

mfg,
Frank

Genau so. Wobei DB70 der instanzdb ist.

Deinen FB musst du aber mit einem call aufrufen, also z.B. call deinfb, instanzdb (z.B. DB70)

Dann wird auch der DB70 automatisch generiert.

Anzumerken ist noch das es unschön ist auf statische Variablen extern zuzugreifen. Für externe zugriffe hat Siemens die Schnittstelle erfunden.
Und Absolute Adressen musst du nicht bei VAR_INPUT Deklarieren, das funktioniert so nicht.

mfG René
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Okay, das mit den absoluten Adressen ist behoben. Das Programm funktioniert jetzt auch.

Inwiefern ist der Zugriff auf statische Variablen "unschön"? Meinst du mit Schnittstelle, dass "VAR_OUTPUT" verwenden soll?
 
Inwiefern ist der Zugriff auf statische Variablen "unschön"? Meinst du mit Schnittstelle, dass "VAR_OUTPUT" verwenden soll?

Das war so gemeint, dass man auf die Variable von extern zugreifen kann, indem man (woanders) die absolute Adresse der Variablen im Instanz-DB angibt. (z.B. DB70.dbx...) Das geht dann nur so lange gut, wie der Instanz-DB unverändert bleibt. Sobald die Schnittstelle des Bausteins verändert wird, rutschen die Adressen durch und der absolute Zugriff adressiert möglicherweise etwas ganz anderes...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Sobald die Schnittstelle des Bausteins verändert wird, rutschen die Adressen durch und der absolute Zugriff adressiert möglicherweise etwas ganz anderes...

Man kann natürlich auch konsequent alles symbolisch machen. Den Vorrang auf Symbolisch umstellen. Jeden externen zugriff auf den IDB öffnen dass die geänderte Zuweisung erkannt wird speichern und erneut herunterladen.

Ich bevorzuge übergänge über die schnittstelle nach draussen. Und wenn dafür etwas mehr speicher verbraucht wird. Ich finde es übersichtlicher.
 
Da gab es schon mal eine sehr "angeregte" Diskussion über den externen Zugriff auf den IDB...
Meine bescheidene Sichtweise ist übrigens ebenso wie die von René: Wenn Zugriffe gemacht werden sollen, dann über die Schnittstelle des FB.
 
Man kann natürlich auch konsequent alles symbolisch machen. Den Vorrang auf Symbolisch umstellen. Jeden externen zugriff auf den IDB öffnen dass die geänderte Zuweisung erkannt wird speichern und erneut herunterladen.
Was genau bedeutet "symbolischer Zugriff"?

Sowas?
Code:
IF DB70.s1_pos_edge = 1
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Was genau bedeutet "symbolischer Zugriff"?

Sowas?
Code:
IF DB70.s1_pos_edge = 1

Das ist ein teilsymbolischer zugriff, das funktioniert eh nur in SCL
Hier adressierst du den DB Absolut und die Stelle im DB dann Symbolisch.

Spielt also keine Rolle sobald du die SCL Quelle übersetzt wird dem Zugriff die absolute Adresse zugewiesen.

In AWL isses dann anders, da wird die eingabe dann direkt in eine absolute Adresse umgewandelt und du musst dann händisch die Adresse überall anpassen sollte sich am DB irgendwas verschieben.


Wenn der DB aber einen symbolischen Namen hat (Symbolliste oder Rechtsklick -> Objekteigenschaften auf den DB im Projektmanager) dann kannst du ihn so ansprechen
U SymbolvonDB.s1_pos_edge

oder

IF SymbolvonDB.s1_pos_edge = TRUE THEN

mfG René
 
Okay, Werte möchte ich nun per Schnittstelle ändern. Leider liefert mir das beim Übersetzen Fehlermeldungen. Ich kann allerdings keinen Fehler erkennen.

Code:
FUNCTION_BLOCK FB71
VAR
    currentState : INT := 1;
END_VAR

CASE currentState OF
   1: currentState := FC81; [COLOR=Red]// ungültiger oder fehlender Funktionstyp[/COLOR]
   2: ...
END_CASE;

END_FUNCTION_BLOCK;


FUNCTION FC81 : INT
VAR_OUTPUT
   nextState : INT;
END_VAR

(* Motor anschalten *)
A10.6 := 1;
nextState := 2;
END_FUNCTION[COLOR=Black]; [COLOR=Red]// Der Rückgabewert der Funktion ist nicht gesetzt[/COLOR][/COLOR]
 
für letztere Fehlermeldung musst du ja den Rückgabewert der Funktion irgendwie zuweisen. z.B. so

Code:
FC81 := 1;
Warum erster Fehler kommt, weiss ich nicht, mache das nie so.

Ich nehme aber an FC81 gibts noch nicht weil du ihn nicht übersetzen konntest.

mfG René
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hm, dann habe ich das ganze wohl doch noch nicht so ganz verstanden.

Worin unterscheiden sich jetzt Rückgabewert einer Funktion und "VAR_OUTPUT" genau?

Wie mache ich das am besten ("schönsten", "richtigsten"), wenn ich im FB71 die Variable "currentState" von FC81 aus verändern möchte?
 
z.B. So.

Code:
FUNCTION_BLOCK FB71
VAR
    currentState : INT := 1;
END_VAR

CASE currentState OF
   1: currentState := FC81; 
   2: ...
END_CASE;

END_FUNCTION_BLOCK;


FUNCTION FC81 : INT
VAR_OUTPUT
   nextState : INT; // wird zur zeit nicht verwendet, könnte also aus Output gelöscht werden.
END_VAR

(* Motor anschalten *)
A10.6 := 1;
 FC81 := 2; // Rückgabewert des FC81
END_FUNCTION;

VAR_OUTPUT nutzt du wenn dir nur ein Rückgabewert nicht ausreicht.

Du kannst die Funktion auch so bauen: FUNCTION FC81 : VOID
Dann musst du keinen rückgabewert Angeben oder kannst nur diese nutzen welche du in VAR_OUTPUT deklarierst.

mfG René
 
Zuletzt bearbeitet:
Wie würde denn so ein Konstrukt mit "VAR_OUTPUT" aussehen?
Also wenn ich in FC81
Code:
...
VAR_OUTPUT
   meineVariable1 : INT := 12;
   meineVariable2 : INT := 13;
END_VAR
...
stehen habe und nun "meineVariable1/2" einer anderen Variable in FB71 zuweisen möchte?

Die Fehler mit der Zuweisung tauchen nun nicht mehr auf. Übersetzen mag er das Programm trotzdem nicht:
Code:
FUNCTION_BLOCK FB71
VAR
    currentState : INT := 1;
END_VAR

CASE currentState OF
   1: currentState := FC81; [COLOR=Red]// Ungültiger Datentyp[/COLOR]
   2: ...
END_CASE;

END_FUNCTION_BLOCK;


FUNCTION FC81 : INT

(* Motor anschalten *)
A10.6 := 1;
FC81 := 2; // Rückgabewert des FC81
END_FUNCTION;
Hat jemand eine Idee, woran das liegen könnte?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Code:
   1: currentState := FC81[COLOR=Red]()[/COLOR]; 
   2: ...
END_CASE;


Das ist essentiell. sorry vorher nicht drauf geachtet.

Ansonsten würde ich es so machen. Dann ist alles in der Schnittstelle deklariert und du kannst frei drauf zugreifen und man kommt sogar noch draus.

Code:
FUNCTION_BLOCK FB71
VAR
    currentState : INT := 1;
    meinFC  : FC81; // deklaration des FC

END_VAR

meinFC();
FC81();

CASE currentState OF
   1: currentState := meinFC.meineVariable1;  // entweder so
   2: currentState := FC81.meineVariable2;  // oder so
END_CASE;

END_FUNCTION_BLOCK;


FUNCTION FC81 : VOID
VAR_OUTPUT
   meineVariable1 : INT;
   meineVariable2 : INT;
END_VAR

(* Motor anschalten *)
A10.6 := 1;
 meineVariable1 := 2; // Rückgabewert des FC81
END_FUNCTION;
 
Zuletzt bearbeitet:
Zurück
Oben