Step 7 SCL-Code: Falsche Ausgabe bei der Simulation!!!

DMA&JC

Level-1
Beiträge
11
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,
ich habe das untere SCL-Code geschrieben. Beim Simulieren ergibt mir Pumpe1_Ein 1 TRUE, wenn ich z.B Fuellstand1 = 11.0 setze und Valve1_Auf = FALSE. Ich habe erwartet, dass Pumpe1_Ein = FALSE für Valve1_Auf = FALSE. Was mache ich Falch???

CODE:
FUNCTION_BLOCK Wasserquelle
//Deklaration und Initialisierung
VAR_INPUT //Eingansparameter
//Start : BOOL := FALSE;
//Stop : BOOL := FALSE;
Fuellstand1 : REAL := 0.0;
Fuellstand2 : REAL := 0.0;
FuellDigit1 : REAL := 0.0;
FuellDigit2 : REAL := 0.0;
Valve1_Auf : BOOL := FALSE;
Valve2_Auf : BOOL := FALSE;
Valve3_Auf : BOOL := FALSE;
Valve4_Auf : BOOL := FALSE;


END_VAR

VAR //Durchgansparameter
Fullst_Voll_1 : BOOL := FALSE;
Fullst_Voll_2 : BOOL := FALSE;
Fullst_Leer_1 : BOOL := FALSE;
Fullst_Leer_2 : BOOL := FALSE;
Pumpe1_Ein : BOOL := FALSE;
Pumpe2_Ein : BOOL := FALSE;
Pumpe3_Ein : BOOL := FALSE;
Pumpe4_Ein : BOOL := FALSE;


END_VAR

VAR_OUTPUT//Ausgansparameter
Aufbe_laueft : BOOL := FALSE;
SB1_Befu : BOOL := FALSE;
SB2_Befu : BOOL := FALSE;
SB1_Ent : BOOL := FALSE;
SB2_Ent : BOOL := FALSE;
END_VAR

BEGIN

//Funktion Füllstand Voll
IF ABS(Fuellstand1) >=100 THEN
Fullst_Voll_1 := TRUE;
ELSE
Fullst_Voll_1 := FALSE;
END_IF;

//Funktion Pumpe 1 Ein
Pumpe1_Ein := Valve1_Auf AND (NOT Fullst_Voll_1);

//Funktion Befüllen
SB1_Befu := Pumpe1_Ein;

//Funktion Füllstand Leer 1
IF ABS(Fuellstand1) <=10 THEN
Fullst_Leer_1 := TRUE;
ELSE
Fullst_Leer_1 := FALSE;
END_IF;
//Funktion Pumpe 2 Ein
Pumpe2_Ein := Valve2_Auf AND (NOT Fullst_Leer_1);

//Funktion Entleeren
SB1_Ent := Pumpe2_Ein;

//Funktion Füllstand Voll 2
IF ABS(Fuellstand2) >=100 THEN
Fullst_Voll_2 := TRUE;
ELSE
Fullst_Voll_2 := FALSE;
END_IF;

//Funktion Pumpe 3 Ein
Pumpe3_Ein := Valve3_Auf AND (NOT Fullst_Voll_2);

//Funktion Befüllen
SB2_Befu := Pumpe3_Ein;

//Funktion Füllstand Leer 2
IF ABS(Fuellstand2) <=10 THEN
Fullst_Leer_2 := TRUE;
ELSE
Fullst_Leer_2 := FALSE;
END_IF;

//Funktion Pumpe 4 Ein
Pumpe4_Ein := Valve4_Auf AND (NOT Fullst_Leer_2);

//Funktion Entleeren
SB2_Ent := Pumpe4_Ein;

Aufbe_laueft := SB1_Ent OR SB2_Ent;

END_FUNCTION_BLOCK

ORGANIZATION_BLOCK OB1

VAR_TEMP
Info : ARRAY[0..19] OF BYTE;
END_VAR

BEGIN

SB1_Befu := Pumpe1_Ein;
SB2_Befu := Pumpe3_Ein;
SB1_Ent := Pumpe2_Ein;
SB2_Ent := Pumpe4_Ein;
Aufbe_laueft := SB1_Ent OR SB2_Ent;

END_ORGANIZATION_BLOCK
 
Du hast anscheinend mehrere Variablen die Pumpe1_Ein heißen? (einmal eine globale Variable und einmal eine lokale Variable in einem FB (im STAT-Bereich))
Im OB1 liest Du die globale Variable (der wird nirgendwo was zugewiesen) und in dem FB Wasserquelle beschreibst Du die lokale Variable der FB-Instanz. Allerdings wird anscheinend Dein FB gar nicht aufgerufen. Oder wo macht Dein Programm das?

Du müsstest eine Instanz des FB anlegen (Instanz-DB) und dann im OB1 die Instanz aufrufen und könntest danach die lokale Variable der FB-Instanz lesen (*):
Code:
//im OB1:

Wasserquelle.Instanzname(...);

SB1_Befu := Instanzname.Pumpe1_Ein;

(*) Der Zugriff auf FB-interne lokale Variablen von außen ist schlechter Programmierstil.
Oder Du änderst "VAR //Durchgansparameter" zu "VAR_IN_OUT //Durchgangsparameter"

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Habe versucht, mir einen Überblick über den Code zu verschaffen.
Habe dazu die VariablenDeklarationen und Initialisierungen weggelassen.
Stattdessen die INPUT-Variablen grün, die OUTPUT-Variablen rot und die übrigen im FB blau dargestellt.
Die ausführbaren Anweisungen habe ich teils umformuliert und ein wenig umsortiert, die Kommentare nach rechts geschoben.
Das ist das Ergebnis:
Code:
FUNCTION_BLOCK Wasserquelle
BEGIN
    [COLOR=#0000cd]Fullst_Voll_1[/COLOR] := ABS([B][COLOR=#008000]Fuellstand1[/COLOR][/B]) >= 100.0;          //Funktion Füllstand Voll 1
    [COLOR=#0000cd]Fullst_Voll_2[/COLOR] := ABS([B][COLOR=#008000]Fuellstand2[/COLOR][/B]) >= 100.0;          //Funktion Füllstand Voll 2
    [COLOR=#0000cd]Fullst_Leer_1[/COLOR] := ABS([B][COLOR=#008000]Fuellstand1[/COLOR][/B]) <= 10.0;           //Funktion Füllstand Leer 1
    [COLOR=#0000cd]Fullst_Leer_2[/COLOR] := ABS([B][COLOR=#008000]Fuellstand2[/COLOR][/B]) <= 10.0;           //Funktion Füllstand Leer 2

    [COLOR=#0000cd]Pumpe1_Ein[/COLOR] := [COLOR=#008000][B]Valve1_Auf[/B][/COLOR] AND (NOT [COLOR=#0000cd]Fullst_Voll_1[/COLOR]);    //Funktion Pumpe 1 Ein
    [COLOR=#0000ff]Pumpe2_Ein[/COLOR] := [B][COLOR=#008000]Valve2_Auf[/COLOR][/B] AND (NOT [COLOR=#0000cd]Fullst_Leer_1[/COLOR]);    //Funktion Pumpe 2 Ein
    [COLOR=#0000ff]Pumpe3_Ein[/COLOR] := [B][COLOR=#008000]Valve3_Auf[/COLOR][/B] AND (NOT [COLOR=#0000cd]Fullst_Voll_2[/COLOR]);    //Funktion Pumpe 3 Ein
    [COLOR=#0000ff]Pumpe4_Ein[/COLOR] := [B][COLOR=#008000]Valve4_Auf[/COLOR][/B] AND (NOT [COLOR=#0000cd]Fullst_Leer_2[/COLOR]);    //Funktion Pumpe 4 Ein

    [B][COLOR=#ff0000]SB1_Befu[/COLOR][/B] := [COLOR=#0000ff]Pumpe1_Ein[/COLOR];                              //Funktion Befüllen
    [COLOR=#ff0000][B]SB2_Befu[/B][/COLOR] := [COLOR=#0000ff]Pumpe3_Ein[/COLOR];                              //Funktion Befüllen
    [COLOR=#ff0000][B]SB1_Ent [/B][/COLOR]:= [COLOR=#0000ff]Pumpe2_Ein[/COLOR];                               //Funktion Entleeren
    [B][COLOR=#ff0000]SB2_Ent[/COLOR][/B] := [COLOR=#0000ff]Pumpe4_Ein[/COLOR];                               //Funktion Entleeren
    [COLOR=#ff0000][B]Aufbe_laueft[/B][/COLOR] := [COLOR=#ff0000][B]SB1_Ent[/B][/COLOR] OR [COLOR=#ff0000][B]SB2_Ent[/B][/COLOR];
END_FUNCTION_BLOCK

ORGANIZATION_BLOCK OB1
BEGIN
     SB1_Befu := Pumpe1_Ein;
     SB2_Befu := Pumpe3_Ein;
     SB1_Ent := Pumpe2_Ein;
     SB2_Ent := Pumpe4_Ein;
     Aufbe_laueft := SB1_Ent OR SB2_Ent;
END_ORGANIZATION_BLOCK
Am liebsten hätte ich noch die Variablen Pumpe1_Ein ... Pumpe4_Ein eliminiert, die nichts anderes darstellen als die Variablen SB1_Befu ... SB2_Ent.
Aber so sieht man sofort, dass die einzigen ausführbaren Anweisungen des OB1 die letzten 5 Anweisungen des FB wiederholen - mit gleichnamigen, jedoch ausserhalb des FB nicht deklarierten Variablen.
Die restlichen blauen Variablen (HilfsVariablen, die jeweils nur einmal abgefragt werden) wären auch noch verzichtbar (Geschmackssache).
Dann bliebe vom FB noch übrig (habe wieder die Deklarationen/Initialisierungen geschlabbert):
Code:
[FONT=courier new][COLOR=#222222][LEFT][COLOR=#222222]FUNCTION_BLOCK Wasserquelle[/COLOR]
[COLOR=#222222]BEGIN[/COLOR]
[/LEFT]
[/COLOR][/FONT][COLOR=#222222][FONT=Verdana][FONT=courier new][B][COLOR=#ff0000][COLOR=#ff0000]    SB1_Befu [/COLOR][/COLOR][/B][COLOR=#222222]:= [/COLOR][COLOR=#008000][COLOR=#008000][B]Valve1_Auf [/B][/COLOR][/COLOR][COLOR=#222222]AND NOT ([/COLOR][COLOR=#222222]ABS([/COLOR][B][COLOR=#008000][COLOR=#008000]Fuellstand1[/COLOR][/COLOR][/B][COLOR=#222222]) >= 100.0[/COLOR][COLOR=#222222]);  //Funktion Pumpe 1 Ein (Befüllen)[/COLOR]
[/FONT][LEFT][LEFT][FONT=courier new][COLOR=#222222][COLOR=#ff0000][COLOR=#ff0000][B]    SB1_Ent  [/B][/COLOR][/COLOR][/COLOR][COLOR=#222222]:= [/COLOR][B][COLOR=#008000][COLOR=#008000]Valve2_Auf [/COLOR][/COLOR][/B][COLOR=#222222]AND NOT ([/COLOR][COLOR=#222222]ABS([/COLOR][B][COLOR=#008000][COLOR=#008000]Fuellstand1[/COLOR][/COLOR][/B][COLOR=#222222]) <= 10.0[/COLOR][COLOR=#222222]);   //Funktion Pumpe 2 Ein (Entleeren)[/COLOR]
[/FONT][/LEFT]
[FONT=courier new]    [COLOR=#ff0000][COLOR=#ff0000][B]SB2_Befu [/B][/COLOR][/COLOR][COLOR=#222222]:= [/COLOR][B][COLOR=#008000][COLOR=#008000]Valve3_Auf [/COLOR][/COLOR][/B][COLOR=#222222]AND NOT ([/COLOR][COLOR=#222222]ABS([/COLOR][B][COLOR=#008000][COLOR=#008000]Fuellstand2[/COLOR][/COLOR][/B][COLOR=#222222]) >= 100.0[/COLOR][COLOR=#222222]);  //Funktion Pumpe 3 Ein (Befüllen)[/COLOR]
    [B][COLOR=#ff0000][COLOR=#ff0000]SB2_Ent  [/COLOR][/COLOR][/B][COLOR=#222222]:= [/COLOR][B][COLOR=#008000][COLOR=#008000]Valve4_Auf [/COLOR][/COLOR][/B][COLOR=#222222]AND NOT ([/COLOR][COLOR=#222222]ABS([/COLOR][B][COLOR=#008000][COLOR=#008000]Fuellstand2[/COLOR][/COLOR][/B][COLOR=#222222]) <= 10.0[/COLOR][COLOR=#222222]);   //Funktion Pumpe 4 Ein (Entleeren)[/COLOR]

[/FONT][FONT=courier new][COLOR=#ff0000][COLOR=#ff0000]    [B]Aufbe_laueft [/B][/COLOR][/COLOR][COLOR=#222222]:=  [/COLOR][COLOR=#ff0000][COLOR=#ff0000][B]SB1_Ent [/B][/COLOR][/COLOR][COLOR=#222222]OR [/COLOR][COLOR=#ff0000][COLOR=#ff0000][B]SB2_Ent[/B][/COLOR][/COLOR][COLOR=#222222];[/COLOR]
[COLOR=#222222]END_FUNCTION_BLOCK[/COLOR][/FONT][/LEFT]
[/FONT][/COLOR]
Die ABS-Funktionen sind vermutlich auch entbehrlich?
Ansonsten ... siehe Haralds Beitrag.​
 
Zuletzt bearbeitet:
Zurück
Oben