Zwei Pumpenpaare abwechselnd + 1 Pumpe bei hohen Wasseraufkommen

mista

Level-2
Beiträge
108
Reaktionspunkte
6
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo liebe Leute,

ich stehe mal wieder vor einer Herausforderung.

Ich muss eine Pumpensteuerung entwickeln die folgende Kriterien Erfüllen muss:

  • 2 Pumpenpaare mit je 2 Pumpen
  • Behälter wird ab einem Niveau geleert, ein Pumpenpaar lauft an
  • ist ein Anderes Niveau unterschritten gehen die Pumpen des Pumpenpaar aus
  • Ist das Wasservorkommen zu hoch und Niveau 3 wird erreicht lauft eine weitere Pumpe des jeweiligen anderen Pumpenpaares an, welche die weinigsten Betriebsstunden aufweist.
  • Bis ein Niveau erreicht wird wo die Dritte Pumpe ausschaltet.
  • Wenn eine Pumpe aus geht, darf sie erst wieder anspringen nach einer einstellbaren Zeit wieder anlaufen.
  • Eine Störumschaltung der Pumpenpaare soll natürlich auch implementiert werden.
  • Tia 15 Update 4
  • Vorzugsweise in FUP wenn nicht geht in SCL, KEIN AWL.

In SCL würde ich mir das zusammen frickeln können, aber nicht in FUP.
Da es nicht zusammen gefrickelt werden soll, sondern auch gut Wartbar hoffe ich, auf kreativen Input hier, denn ich weiß nicht so recht wie ich anfangen soll.

Klar Nach Betriebsstunden, sortieren, und wenn eine Pumpe gesperrt ist eine hohe Zahl eintragen in dem Sortierarray. Aber das fühlt sich für mich nicht nach leicht wartbar an.
Pumpenbausteine muss ich auch selber Programmieren.

Vielleicht könnt ihr mir ja ein wenig Helfen, oder Links geben, wie eine Pumpenfolge zu Programmieren ist.

Vielen Dank, und bleibt gesund.
 
Na, vielleicht solltest du uns erst einmal weiterhelfen.

In dem du uns erst einmal mitteilst, welcher Steuerungstyp und welche Software.
 
Ich muss eine Pumpensteuerung entwickeln die folgende Kriterien Erfüllen muss:

  • 2 Pumpenpaare mit je 2 Pumpen
  • Behälter wird ab einem Niveau geleert, ein Pumpenpaar lauft an
  • ist ein Anderes Niveau unterschritten gehen die Pumpen des Pumpenpaar aus
  • Ist das Wasservorkommen zu hoch und Niveau 3 wird erreicht lauft eine weitere Pumpe des jeweiligen anderen Pumpenpaares an, welche die weinigsten Betriebsstunden aufweist.
  • Bis ein Niveau erreicht wird wo die Dritte Pumpe ausschaltet.
  • Wenn eine Pumpe aus geht, darf sie erst wieder anspringen nach einer einstellbaren Zeit wieder anlaufen.
  • Eine Störumschaltung der Pumpenpaare soll natürlich auch implementiert werden.
  • Tia 15 Update 4
  • Vorzugsweise in FUP wenn nicht geht in SCL, KEIN AWL.
Kenne die Anlage ja nicht, scheint mir logisch aber nicht schlüssig.

Sind die Pumpen(paare) in ihrer Leistung identisch?
Zumindest scheinen sie wohl einzeln ansteuerbar zu sein - warum soll dann immer gleich ein Pumpenpaar eingeschaltet werden, anstatt kontinuierlich zuschaltend? Oder sind das Doppelpumpen?

Wir haben das bislang so gelöst, dass für jede Pumpe die Betriebsstunden erfasst wurden; bei Tageswechsel wurde die Priorität der Pumpen in Abhängigkeit der Betriebsstunden neu verteilt - was Pumpe 1,2 usw. ist. Pumpen mit aktiver Störung wurden dann zwar in die Reihe einsortiert, jedoch in der Ansteuerung in der Priorität "übersprungen" - war die Störung behoben, lief die Pumpe in der angedachten Sortierung mit.

Wenn man die Wahl zwischen FUP und SCL hat, ist ein SCL-Code meiner Ansicht für dergleichen wesentlich wartbarer als FUP.
 
Für die Zu-/Abschaltung nach Betriebsdauer hat Zotos mal ein FUP-Beispiel für Classic gepostet -> Motorenpendel
Eine Abwandlung dieses Beispiels mit zusätzlicher Laufzeitüberwachung und Wiederanlaufsperre für TIA SCL findest Du hier -> Pumpenpendel

Dazu dann noch die Zu-/Abschaltung nach Niveau (Anzahl der benötigten Pumpen).
Die sollte ja nicht mehr den riesen Aufwand darstellen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das wäre dann mein Erster Versuch:

Code:
REGION Initialisierung
    // Niveuau Reinigungsbetrieb
    IF #Reinigungsbetrieb THEN
        #tempNiveau1 := #einstellungen.Niveaus.Reinigungsbetrieb.Niveau_1;
        #tempNiveau2 := #einstellungen.Niveaus.Reinigungsbetrieb.Niveau_2;
        #tempNiveau3 := #einstellungen.Niveaus.Reinigungsbetrieb.Niveau_3;
        #tempNiveau4 := #einstellungen.Niveaus.Reinigungsbetrieb.Niveau_4;
        #tempNiveau5 := #einstellungen.Niveaus.Reinigungsbetrieb.Niveau_5;
    ELSE
        #tempNiveau1 := #einstellungen.Niveaus.Normalbetrieb.Niveau_1;
        #tempNiveau2 := #einstellungen.Niveaus.Normalbetrieb.Niveau_2;
        #tempNiveau3 := #einstellungen.Niveaus.Normalbetrieb.Niveau_3;
        #tempNiveau4 := #einstellungen.Niveaus.Normalbetrieb.Niveau_4;
        #tempNiveau5 := #einstellungen.Niveaus.Normalbetrieb.Niveau_5;
    END_IF;
END_REGION


REGION Freigaben nach Niveau
    // Niveau Freigaben
    IF #Füllstand > #tempNiveau1 THEN
        #tempAnforderungNormal := true;
    END_IF;
    
    IF #Füllstand < #tempNiveau1 THEN
        #tempAnforderungNormal := false;
    END_IF;
    
    // Anforderung dritte Pumpe
    IF NOT #Reinigungsbetrieb AND #Füllstand > #tempNiveau4 THEN
        #tempDrittePumpe := true;
    END_IF;
    
    IF #tempDrittePumpe AND #Füllstand < #tempNiveau2 THEN
        #tempDrittePumpe := false;
    END_IF;
END_REGION


REGION Automatikbetrieb
    // Einschalten wenn keine Pumpenpaar läuft und Anforderung
    IF #tempAnforderungNormal THEN
        IF NOT #statPumpenpaar1EIN AND NOT #statPumpenpaar2EIN THEN
            IF #statPumpenpaar1EIN OR (NOT #Pumpen[1].Status.Aktiv OR NOT #Pumpen[2].Status.Aktiv) THEN
                #statPumpenpaar2EIN := TRUE;
                #stat_LetztesPumpenpaar := 2;
                
            ELSIF #stat_LetztesPumpenpaar = 2 OR (NOT #Pumpen[3].Status.Aktiv OR NOT #Pumpen[4].Status.Aktiv) THEN
                #statPumpenpaar1EIN := TRUE;
                #stat_LetztesPumpenpaar :=1;
            END_IF;
        END_IF;
    ELSE
        #statPumpenpaar1EIN := FALSE;
        #statPumpenpaar2EIN := FALSE;
    END_IF;
    
    IF #statPumpenpaar1EIN THEN
        #Pumpen[1].Status.Lauft := true;
        #Pumpen[2].Status.Lauft := true;
        #Pumpen[3].Status.Lauft := false;
        #Pumpen[4].Status.Lauft := false;
        #statStart := 3;
        #statEnd := 4;
    ELSIF #statPumpenpaar2EIN THEN
        #Pumpen[3].Status.Lauft := true;
        #Pumpen[4].Status.Lauft := True;
        #Pumpen[1].Status.Lauft := FALSE;
        #Pumpen[2].Status.Lauft := FALSE;
        #statStart := 1;
        #statEnd := 2;
    END_IF;
    
    IF #tempDrittePumpe THEN
        IF NOT #statDrittePumpeEIN THEN
            FOR #temp_i := #statStart TO #statEnd BY 1 DO
                IF #Pumpen[#temp_i].Status.Modus = 2 // Modus Auto
                    AND #Pumpen[#temp_i].Betriebstunden < #tempAktuelleLaufzeit
                THEN
                    #tempAktuelleLaufzeit := #Pumpen[#temp_i].Betriebstunden;
                    #tempSelekiertePumpe := INT_TO_USINT(#temp_i);
                END_IF;
            END_FOR;
            IF #tempSelekiertePumpe >= 1 THEN
                #Pumpen[#tempSelekiertePumpe].Status.Lauft := true;
                #statDrittePumpeEIN := true;
            ELSE
                //Fehler keine Pumpe verfügbar!
                ;
            END_IF;
        END_IF;
    ELSE
        #statDrittePumpeEIN := FALSE;
        #Pumpen[#statStart].Status.Lauft := false;
        #Pumpen[#statEnd].Status.Lauft := false;
    END_IF;
    
END_REGION

Nicht so dynamisch wie das Pumpenpendel und simpler
 
Warum sind die ganzen Niveauvorgaben z.B. eigentlich keine Arrays?
Würde doch noch Einiges vereinfachen:
Code:
REGION Initialisierung
     // Niveau Reinigungsbetrieb

     #tempNiveau := SEL(G := #Reinigungsbetrieb, IN0 := #einstellungen.Niveaus.Normalbetrieb; IN1 := #einstellungen.Niveaus.Reinigungsbetrieb);

END_REGION

...
 
Na weil ich die SEL Funktion vorher nicht kannte.

Die Zykluszeit über RT_INFO(); benutze ich um die Sperrzeit abzuziehen. Doch in der TIA Simulation kommen mir Sekunden Fast wie Minuten?
Beim Pumpenpendel nutzt du den für die Betriebsstunden, kann ich das so übernehmen?
Also die Zykluszeit addieren auf die Gesamtlaufzeit solange ich eine Betriebsrückmeldung der Pumpe bekomme und dann irgendwie (x 3600000000) in Stunden Umrechen?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Warum sind die ganzen Niveauvorgaben z.B. eigentlich keine Arrays?
Na weil ich die SEL Funktion vorher nicht kannte.
Die Arrays haben ja nix mit der SEL-Funktion zu tun. Die Zuweisungen funktionieren mit IF genauso.
Man kann halt das komplette Array auch an einem Stück übergeben, statt jedes Feld einzeln.
Das trifft auch für gleich aufgebaute STRUCTs/UDTs zu.


Das SEL ist dann eher so 'ne "Marotte" von mir, für nur eine Auswahlzuweisung kein IF...THEN...ELSE zu verwenden, weil ich persönlich es mit dieser einzelnen direkten Zuweisung lesbarer finde.
Der kompilierte Code wird dann vermutlich eh' wieder für beide Varianten sehr ähnlich aussehen.
 
Die Zykluszeit über RT_INFO(); benutze ich um die Sperrzeit abzuziehen. Doch in der TIA Simulation kommen mir Sekunden Fast wie Minuten?
Beim Pumpenpendel nutzt du den für die Betriebsstunden, kann ich das so übernehmen?
Also die Zykluszeit addieren auf die Gesamtlaufzeit solange ich eine Betriebsrückmeldung der Pumpe bekomme und dann irgendwie (x 3600000000) in Stunden Umrechen?
Welchen MODE und OB gibst Du für RT_INFO an?

Wenn ich mich richtig erinnere, hatte ich das damals auf 'ner realen S7-1500 laufen lassen.
Deswegen hatte ich für den MODE auch die 25 verwendet, obwohl in der Hilfe eigentlich was von 1 stand. Mit der 1 hab' ich komischerweise keine Zeiten erhalten.

Bei mir funktionierte der Betriebszähler jedenfalls so.
LTIME hatte ich damals der Einfachheit halber gewählt.
Für Anzeigen gibt's dann ja noch Konverter, die aus der LTIME was für Menschen Lesbares machen.
 
Mode 25 für letzte Zykluszeit und OB 1 für die Abfrage.

Ja genau so einen Konverter, wie machst du den?

Ich hab ein weg mit ms aber nicht mit ns.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
T_CONV hat einiges an Möglichkeiten.

Ich persönlich ziehe mir meist zum Anzeigen auch nur die vollen Stunden aus der LTIME, also LTIME_TO_LINT und dann Division durch 3.600.000.000.000 (1h = 60m x 60s x 1.000ms x 1.000µs x 1.000ns).



PS:
Also in meiner Simu laufen die Sekunden (Division nur durch 1.000.000.000) recht "normal" und nicht wie Minuten.
Und mein Tablet ist bereits über 6 Jahre alt.
 
Zuletzt bearbeitet:
Für die BEtriebsstunden mache ich das so:

Code:
IF #Rückmeldung_betrieb THEN    #statGesamtLaufzeit += #Zykluszeit;
    #tempTimeToINT := LTIME_TO_LINT(#statGesamtLaufzeit);
    #HMI_Pumpe.Betriebsdaten.Betriebstunden := LINT_TO_REAL(#tempTimeToINT / 3600000000000);
END_IF;

Für die Sperrzeit so:
sperrzeit.PNG
 
Wozu brauchst Du denn bei den Betriebsstunden einen REAL?
DINT oder sogar INT sollten doch vollkommen ausreichen.
(REAL ist übrigens auch noch ungenauer als DINT, weil 8 Bits für die Kommaverschiebung weggehen.)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Und Monatlich grüßt das Murmeltier...

Neue Aufgabe,

und wieder stehe ich da mit lauter ???? in meinem Kopf.

Bitte sagt mir, wie man an solchen Pumpensteuerung rann geht. Am besten so einfach wie möglich zu verstehen, wenn ein anderer über den Code ließt. Und einfach umzusetzen.

Folgendes Szenario, 2 Motoren, 3 Motoren oder 2x2 Motoren

in den ersten 2 Fällen:
  • läuft bei einer Bedingung 1 Motor bis Abschaltbedingung kommt oder durch die Laufzeitkontrolle abschaltet.
  • Bei einer andere Bedingung startet zusätzlich ein weiter Motor, dann gibt es für beide keine Laufzeitkontrolle.
  • die 2. Pumpe läuft bis eine Abschaltbedingung erfüllt ist.

Beim 2x2 ist es so, dass es 2 Paare gibt.
  • dabei schalte bei Anforderung, P1 ein nach einer Verzögerung P2,
  • beim Ausschalten erst P2 dann P1.
  • Beim nächsten Start soll P3 und P4 starten.
  • Auch hier soll es eine Laufzeitkontrolle geben.

Generell gilt: Bei Abschaltung durch Laufzeit, soll es eine Pause geben, wann erst der nächste Motor oder Motorpaar einschalten darf.

Und um das noch ein wenig zu verkomplizieren, soll es auch nach X Anlaufen für eine Y Zeit in den Linkslauf gehen. und das einstellbar nach einem Motorlauf oder davor wenn die Bedinung wieder erfüllt ist.

Natürlich soll es auch Stör Umschaltungen geben etc.

Ja ich habe mir das Motorpendel angeschaut auch das Beispiel von @hucki.

Ich habe ein Laufendes Programm allerdings werden Freigaben und Bedingungen so oft geschrieben, dass es unübersichtlich ist wo was passiert.
Aktuell ist es so, das nach der Initialisierung der Zeiten die Zustände kommen, welche aber weiter unten erst definiert werden. Also für mich persönlich nicht leserlich und Wartungsfreundlich.

Ich möchte auch kein fertiges Programm nur einen Pseudo Code, für die Aufteilung wo ihr was machen würdet, bzw. wie ihr das aufteilen würdet. Würdet ihr drei Funktionen machen oder Alle drei Fälle in einer Funktion unterkriegen. Fall 1 und 2 kann durch dynamische Anzahl von Motoren Array leicht zusammen gefasst werden. Beim dritten Fall würde ich mit Modulo arbeiten weil es immer ein Paar sein muss.

Den Trick mit der Zykluszeit für die Betriebsstunden finde ich genial, allerdings benötige ich eine Fließkommazahl, Also kein DINT mehr sondern, Real oder LReal wenn man von LTIME konvertiert?

Wie würdet ihr euch ds aufschreiben, skizieren um es dann zu Programmieren? gibt es im Netz Tutorial wo man die Herangehensweise lernt? ich bin für alles offen auch für Privatstuden über SKYPE etc.
Gibt es da vielleicht Desingpattern die man immer wieder anwendet?
 
Hallo,
es hört sich für mich erstmal grundsätzlich nach einem Ablauf an - denk hier doch mal, gerade wegen Nachvollziehbarkeit, über eine Schrittkette nach.
Ich habe aber dein erstes Scenario nicht wirklich verstanden ...

Gruß
Larry
 
Szeneario bei 2 bis 3 Motoren.

1. Bedingung erfüllt dann // Startbedining für 1. Motor

Starte Motor 1

2. Bedingung erfüllt dann // Startbeding für den Parallelbetrieb

Starte den zweiten Motor

2. Abschaltbeding erfüllt dann
Stoppe 2. Motor

1. Abschaltbeding erfüllt dann

stoppe ersten Motor

Und dann nach dem Prinzip
1,2,1,2 bzw. 1+2 im Parallelbetrieb
oder 1,2,3, bzw. 1+2, 2+3, 3+1 im Parallelbetrieb

1. Bedingung erffült dann // Startbedining für 1. Motor

starte 2. Motor

usw.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Na ... da hast du doch dann schon deine Schrittkette ... 8)
Und so ähnlich würde es dann für das 2. Szenario ja auch aussehen ...

Weißt du das umzusetzen ...?

Gruß
Larry
 
Meinst Du echt eine Schrittkette? :confused:

Was wäre der Initialschritt? Wie würdest du das durchwechseln der Motoren gewährleisten?

Den Linkslauf und das Automatische Abschalten nach einer Zeit und dann auch noch die Pausenzeit.

Schrittketten habe ich eigentlich bei Fördertechnik gedacht nicht bei Verfahrenstechnik. Nur so klar ist es viel Strukturierter...

Ansonsten Ja hab mal was mit Schritten gemacht und würde es jetzt so machen:


Code:
Intialschritt = Keine Ahnung

Wenn Bedingung Erfüllt, dann                                                                              möglicher Paralleler Schrittketten Strang:                                      Wenn 2. Motor angefodert (und Schritt 1 ist aber schon Zurück gesetzt )

Schritt 1 = Starte Motor der an der Reihe ist.                                                                            Schritt 3 = Starte 2.Motor

Wenn Ausshaltbedinngung erreicht worden, und Schritt 1 aktiv ist dann:                                     Wenn Ausschaltbedinung erreicht worden und Schritt 3 dann 

Schritt 2 = Rücksetze Schritt 1, Starte Nachlaufzeit                                               2. Motor aus                                                 Schalte Motor 2 aus und Rücksetze Schritt 3

IRgendiwie So..

Jetzt habe ich durch google gesehen, dass Du hier mal eine Schrittkette mit Hilfe von INT und ein SWITCH CASE Anweisung empfohlen hast.
 
Zuletzt bearbeitet:
Na klar - Schrittkette ...!!!
Du musst dir nur klar darüber sein was wann passieren soll.
Ne Schritt kette ist nicht grundsätzlich nur für Fördertechnik - es ist eigentlich immer dann sinnig wenn es ein ABLAUF ist und der möglichst mehr als 2 Schritte hat. In deinem Fall, bei dem ich allerdings die Zuschalt- und Abschaltbedingungen für die Motore noch nicht so richtig verinnerlicht habe :

Initialschritt = hier warte die Schrittkette (auch nach dem Start der SPS oder der Betriebsart) auf deren Start bzw. Freigabe

Versuch einfach noch einmal deinen Ablauf zu beschreiben - ich bastel dir dann daraus die Schrittkette ...

Gruß
Larry
 
Zurück
Oben