wie gehe ich da ran?

xinix

Level-1
Beiträge
46
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin moin,

fange ja gerade erst mit ST an und benötige mal ne einschätzung zu folgenden Szenario:

Ich frage einen Zustand ( START oder BETRIEB ) zweier Tanks, je nach den Füllständen meiner Teichanlage ab. Sind beide Tanks leer, dann soll sie START Sequenz eingeleitet werden.

Da sich der Zustand zu Sequenz währen dieser ändert, würde ich nach meiner Logik ein eine Variable setzen, und erst am ende der Sequenz wieder zurücksetzten. Wäre das eine Lösung oder gibt es was besseres?

Nach der Abfrage und wahl der Sequenz, muss ich ja entweder an eine bestimmte Stelle im Programm springen, oder ein anderes Programm aufrufen. Was macht mehr sinn, und wie geht das? Gibt es sowas wie goto? oder wie eine Sprung in FUP?

Wäre um ein Beispiel sehr dankbar!

Gruß
 
Für Sequenzen setzt ich oft die Case-Struktur ein:
http://infosys.beckhoff.com/content/1031/tcplccontrol/html/tcplcctrl_statement_case.htm?id=12175

Da kannst du Schritte machen, und selber "Weiterschaltbedingungen" definieren. Sprünge habe ich noch nie in ST gebraucht!

Leider habe ich gerade kein passenden Beispiel parat, aber unten mal ein kleiner Auswahlbaustein in einer Case, es geht um eine Lüftungsklappe...

Code:
    CASE iNr OF
    
        0: (* NOP *)
        ;

        10: (* Klappe öffnen *)
            bAusgang_Motor := TRUE;
            IF (bSensorIsOpen) THEN
            bAusgang_Motor := FALSE;
            bDoKlappe_Auf := FALSE;
            iNr := 0;
            END_IF

        20:    (* Klappe Schliessen *)
            bAusgang_Motor := TRUE;
            IF (bSensorIsClose) THEN
            bAusgang_Motor := FALSE;
            bDoKlappe_Zu := FALSE;
            iNr := 0;
            END_IF
    END_CASE
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Naja ohne Hardware kann man dir schlecht helfen. Wenn du 2 Fühler hast machste ne 2-punkt Regelung. Hast du Analoge Werte machst du halt ne If schleife mit real werten oder was auch immer. Aber so in die Glaskugel geschaut kann man dir nicht "richtig" helfen.
 
Hallo Dante, mir geht es eigenlich erst einmal um das grundsätzliche, nicht auf eine bestimmte Hardware bezogen, da ich es erst einmal verstehen möchte.

Also ich frage zunächst den Zustand ab, ob beide tanks leer sind. Wenn beide Tanks leer sind soll eine Starsequenz eingeleitet werden. Sind beide Tanks jeweils mit mehr als 25% gefüllt wird die Betriebssequenz eingeleitet.

Diese Start- und Betriebssequenz birgt aber auch wider eine Rehe von Messungen und Abfragen und Regelungen. Die Startsequenz ist auf die Betriebszeit von einer Strunde festgelegt. Nach dieser Stunde soll dann die Betriebssequenz eingeleitet werden die ähnlich der Startsequenz arbeite aber ein par kleine änderungen mit sich bringt.

Das auswerten der Fühler und das Steuern der Pumpen ist soweit kein problem.
 
Hallo,

eigentlich hast du mit deiner Beschreibung bereits das Programm schon fast geschrieben.

Im Prinzip brauchst du nur noch Zeile für Zeile in Codeys übersetzen.

Beispiel:

Tank1_viertelvoll:=(Messwert1>33);
Tank2_viertelvoll:=(Messwert2>38); (*Falls der Tank andere Maße hat*)

If Tank1_Leer=True and Tank2_leer=true then Sequenz_Start:=true;end_if

If Tank1_viertelvoll=True and Tank2_viertelvoll then
Sequenz_Start:=False;
Sequenz_Regeln:=True;
end_if



Ist jetzt nur mal ein einfaches Beispiel.

MfG CAS
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Habs ihm schon komplett geschrieben :D

Hier die exportierte Version: (mit seinen Angaben gemacht ohne Sicherheit das die Pumpen trocken laufen oder so)


Code:
(* @NESTEDCOMMENTS := 'Yes' *)
(* @PATH := '' *)
(* @SYMFILEFLAGS := '2048' *)
FUNCTION_BLOCK FB_Pumpensteuerung
VAR_INPUT
    nTank_1: INT;
    nTank_2: INT;
END_VAR
VAR_OUTPUT
    nPumpeTank_1: BOOL;
    nPumpeFilterung: BOOL;
    bPumpeTeichzulauf: BOOL;
    bUmspuelung: BOOL;
    bTeichfuellung: BOOL;
END_VAR
VAR
    bInit: BOOL;        (*Startvorgang*)
    TOF_Filterung: TOF;
    F_TRIG_Filterung: F_TRIG;
    bBetrieb: BOOL;
    R_TRIG_Betrieb: R_TRIG;
    TOF_betrieb: TOF;
    F_TRIG_Betrieb: F_TRIG;
END_VAR
(* @END_DECLARATION := '0' *)
(*
#############################
#                            #
#    Pumpensteuerung            #
#    Teichanlage V1.0            #
#                            #
#############################
*)

(*
###########################    Startvorgang
*)

IF nTank_1<100 AND nTank_2<100 AND F_TRIG_Filterung.Q=FALSE AND bBetrieb=FALSE THEN
    bInit=TRUE;
ELSIF F_TRIG_Filterung.Q=TRUE THEN
    binit=FALSE;
END_IF;

(*
###########################    Wasser umwaelzen | reinigen
*)

IF bInit=TRUE THEN            (*Startvorgang*)

    IF nTank_1<800 THEN
        nPumpeTank_1:=TRUE;
    ELSE
        nPumpeTank_1:=FALSE;
    END_IF;


    TOF_Filterung(IN:=nPumpeTank_1 , PT:=T#60m , Q=> , ET=> );    (*1 Stunde zur Filterung*)
    F_TRIG_Filterung(CLK:=TOF_Filterung.Q , Q=> );                (*Fallende Flanke vom Timer setzt initialschritt zurueck*)

    IF nTank_1>500 AND TOF_Filterung.Q THEN
        nPumpeFilterung:=TRUE;
    ELSE
        nPumpeFilterung:=FALSE;
    END_IF;

(*
###########################    Wasser umspuelen
*)

    IF nTank_2>nTank_1 AND TOF_Filterung.Q THEN
        bPumpeTeichzulauf:=TRUE;
        bUmspuelung:=TRUE;
    ELSE
        bPumpeTeichzulauf:=FALSE;
        bUmspuelung:=FALSE;
    END_IF;

END_IF;

(*
###########################    Betrieb
*)

IF binit=FALSE AND nTank_1<100 AND nTank_2<100 THEN
    bBetrieb:=TRUE;
ELSIF F_TRIG_Betrieb=TRUE THEN
    bBetrieb:=FALSE;
END_IF;

IF bBetrieb=TRUE THEN

    R_TRIG_Betrieb(CLK:=bBetrieb , Q=> );
    TOF_Betrieb(IN:=R_TRIG_Betrieb.Q OR F_TRIG_Betrieb.Q, PT:=t#180m , Q=> , ET=> );    (*3 Stunden Intervall*)
    F_TRIG_Betrieb(CLK:=TOF_Betrieb.Q , Q=> );

    IF F_TRIG_Betrieb.Q=TRUE THEN
        IF nTank_2>200 THEN
            bPumpeTeichzulauf:=TRUE;
            bTeichfuellung:=TRUE;
        ELSE
            bPumpeTeichzulauf:=FALSE;
            bTeichfuellung:=FALSE;
        END_IF;

        IF nTank_2>800 THEN
            nPumpeFilterung:=TRUE;
            nPumpeTank_1:=TRUE;
        ELSE
            nPumpeFilterung:=FALSE;
            nPumpeTank_1:=FALSE;
        END_IF;
    END_IF;

END_IF;
END_FUNCTION_BLOCK
 
also wenn man das so liest, könnte man glatt glauben, dass Codesys keinen KOP oder FUP kann :p

Gruß
Dieter
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Es soll auch schon ein Hammer in der Uhrmacherwerkstatt gesichtet worden sein :ROFLMAO:

Um bei deinem Vergleich zu bleiben:
Hier wurde der Schmiedehammer rausgeholt :)

Fehlt nur noch die Modellierung auf Basis von Zustandsautomaten.

Gruß
Dieter
 
du kannst die Aufgabe ja sehr gerne mal in FUB oder KOP machen und wir schauen was übersichtlichert wird :).
 
Code:
IF Bedingung
THEN
   Ergebnis:=True;
ELSE
   Ergebnis:=False;
END_IF;

Ergebnis:=Bedingung;

Natürlich lassen sich solche Steuerungsfunktionen in kombinatorischer Logik einfacher darstellen, dazu braucht man noch nicht mal FUP oder KOP. Aber muss man das? Das Programm von Dante zeigt sehr gut, wie sich die Denkweise beim Programmieren mit ST langsam aber sicher zum "Wenn-Dann" entwickelt. Und sobald auch nur ein wenig speichernde Logik hinzukommt, ist das in meinen Augen auch besser verständlich. Wenn jemand seinen gesamten Programmierstil in diese Richtung entwickelt, sehe ich das deshalb nicht negativ.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Um bei deinem Vergleich zu bleiben:
Hier wurde der Schmiedehammer rausgeholt :)

Fehlt nur noch die Modellierung auf Basis von Zustandsautomaten.

Gruß
Dieter

Also erst einmal vielen Dank für die unterstützenden Threads! Scheinbar wurde übersehen, dass ich am Anfang ausdrücklich nach der Hilfe in ST und nicht nach FUP oder KOP fragte. Dante hat sich überdurchschnittlich ins Zeug gelegt mir durch Sein Beispiel mal einen Einblick zu geben, wie soetwas aussehen kann. Dafür bin ich Ihn sehr dankbar.

Sicherlicht ist es ähnlich dem Arztbesuch. Jeder Arzt stellt eine andere Diagnose. Mir hat's auf jeden fall Geholfen Dr. Dante!

Gruß
 
Natürlich lassen sich solche Steuerungsfunktionen in kombinatorischer Logik einfacher darstellen, dazu braucht man noch nicht mal FUP oder KOP. Aber muss man das?

Gegen
Code:
Ergebnis:=Bedingung;
habe ich gar nicht einzuwenden. Ist nichts anderes als KOP oder FUP.

Bei
Code:
IF Bedingung
THEN
   Ergebnis:=True;
ELSE
   Ergebnis:=False;
END_IF;
geht bei vielen in der Praxis oft der Überblick verloren und es entsteht schnell Spaghetti-Code. Ganz beliebt sind hier Betriebsartenwechsel, Manuelle Eingriffe, Not-Halt und ähnliches.
Viele Programmierer (besonders solche aus der PC-Ecke) vergessen hier, dass Anlagen und Benutzer manchmal ein "Eigenleben" haben.

Gruß
Dieter
 
Das Programm von Dante zeigt sehr gut, wie sich die Denkweise beim Programmieren mit ST langsam aber sicher zum "Wenn-Dann" entwickelt. Und sobald auch nur ein wenig speichernde Logik hinzukommt, ist das in meinen Augen auch besser verständlich. Wenn jemand seinen gesamten Programmierstil in diese Richtung entwickelt, sehe ich das deshalb nicht negativ.
Was ich besonders an dieser Wenn-Dann-Denke und Wenn-Dann-Programmierung (inklusive übermäßigem Gebrauch von Flanken) hasse, ist, daß dadurch fast zwangsläufig bedingte Ausgangszuweisungen an -zig Stellen im Programm gemacht werden. Wenn dann wie bei dante noch nicht einmal für ALLE möglichen Anlagenzustände eine Reaktion ausprogrammiert ist, dann gibt es Anlagenzustände ohne aktive Ausgangszuweisung. Die Ausgänge bleiben so, wie sie durch irgendeine Vorgeschichte "zufällig" stehen.

Wenn in solchen Programmen dann auch noch "ein wenig speichernde Logik" hinzukommt, dann wird das Verhälten des Programms in der Regel nicht verständlicher, sondern zeitweise unvorhersagbar.

Die typische Reaktion der Wenn-Dann-Programmierer bei zutagetreten der "unmöglichen" Anlagenzustände ist, noch eine spezielle Wenn-Dann-Reaktion hinterher-zu-programmieren und später noch eine und noch eine ... das Programm besteht dann irgendwann aus 80% Ausnahmereaktionen und nur noch 20% "gewollter Code". Ich sage in solchen Fällen immer: Es gibt 1000 Krankheiten, aber nur eine Gesundheit.

@dante
Kannst Du auf Anhieb genau sagen, was die Pumpen in Deinem Programm machen, wenn z.B. binit=FALSE und bBetrieb=FALSE oder im anderen Fall binit=TRUE und bBetrieb=TRUE sind? (Sag jetzt nicht, daß beide Fälle in Deinem Programm niemals vorkommen können).

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Was ich besonders an dieser Wenn-Dann-Denke und Wenn-Dann-Programmierung (inklusive übermäßigem Gebrauch von Flanken) hasse, ist, daß dadurch fast zwangsläufig bedingte Ausgangszuweisungen an -zig Stellen im Programm gemacht werden. Wenn dann wie bei dante noch nicht einmal für ALLE möglichen Anlagenzustände eine Reaktion ausprogrammiert ist, dann gibt es Anlagenzustände ohne aktive Ausgangszuweisung. Die Ausgänge bleiben so, wie sie durch irgendeine Vorgeschichte "zufällig" stehen.

Wenn in solchen Programmen dann auch noch "ein wenig speichernde Logik" hinzukommt, dann wird das Verhälten des Programms in der Regel nicht verständlicher, sondern zeitweise unvorhersagbar.

Die typische Reaktion der Wenn-Dann-Programmierer bei zutagetreten der "unmöglichen" Anlagenzustände ist, noch eine spezielle Wenn-Dann-Reaktion hinterher-zu-programmieren und später noch eine und noch eine ... das Programm besteht dann irgendwann aus 80% Ausnahmereaktionen und nur noch 20% "gewollter Code". Ich sage in solchen Fällen immer: Es gibt 1000 Krankheiten, aber nur eine Gesundheit.

Dazu kann nur eins kommen : *ACK*

@dante
Kannst Du auf Anhieb genau sagen, was die Pumpen in Deinem Programm machen, wenn z.B. binit=FALSE und bBetrieb=FALSE oder im anderen Fall binit=TRUE und bBetrieb=TRUE sind? (Sag jetzt nicht, daß beide Fälle in Deinem Programm niemals vorkommen können).

Harald

Frag doch bitte nicht nach was nicht ausprogrammiert ist. ;)

Der Schmiedehammer, wie jemand schon geschrieben hat, ist eben doch nicht immer das richtige Werkzeug.

Warum alles mit Gewalt in ein Korsett pressen?


bike
 
Um mich auch noch in diese Diskussion mit ein zu bringen:

Ich verwende oft CASE für solche Sachen, dann ist das ganze Wenn-Dann etc. nur in der Auswahl der Einsprungstelle, die Anweisungen sind in der Struktur gut aufgehoben. Zudem kann ohne grosser Aufwand die Verriegelun realisiert werden.
 
Um mich auch noch in diese Diskussion mit ein zu bringen:

Ich verwende oft CASE für solche Sachen, dann ist das ganze Wenn-Dann etc. nur in der Auswahl der Einsprungstelle, die Anweisungen sind in der Struktur gut aufgehoben. Zudem kann ohne grosser Aufwand die Verriegelun realisiert werden.

Wenn du dann unkontrolliert aus der Schleife fällst, hast du ggF auch Ausgänge oder andere Variablen so, wie du diese nicht willst.

Egal wie. bei all den bedingten Abarbeitungen ist viel Aufwand zu tun, um nicht irgend etwas seltsames auf den Weg zu bringen.


bike
 
PN/DP schrieb:
Was ich besonders an dieser Wenn-Dann-Denke und Wenn-Dann-Programmierung (inklusive übermäßigem Gebrauch von Flanken) hasse, ist, daß dadurch fast zwangsläufig bedingte Ausgangszuweisungen an -zig Stellen im Programm gemacht werden.
PN/DP schrieb:
Die typische Reaktion der Wenn-Dann-Programmierer bei zutagetreten der "unmöglichen" Anlagenzustände ist, noch eine spezielle Wenn-Dann-Reaktion hinterher-zu-programmieren und später noch eine und noch eine

Wenn schon die erste Version eines Programms so geschrieben ist oder später noch jede Menge Verriegelungen nachgetragen werden müssen, hat man ganz klar seine Hausaufgaben nicht gemacht. Das hat für mich aber nichts mit der grundsätzlichen Denk- und Vorgehensweise beim Programmieren zu tun.
 
Wenn schon die erste Version eines Programms so geschrieben ist oder später noch jede Menge Verriegelungen nachgetragen werden müssen, hat man ganz klar seine Hausaufgaben nicht gemacht. Das hat für mich aber nichts mit der grundsätzlichen Denk- und Vorgehensweise beim Programmieren zu tun.

Wenn ich dich richtig verstanden habe, weißt du zu Beginn schon alle Eventualitäten, die sich bei der Programmierung und Inbetriebnahme ergeben?

Respekt!


bike
 
Zurück
Oben