Zwei Pumpenpaare abwechselnd + 1 Pumpe bei hohen Wasseraufkommen

Zuviel Werbung?
-> Hier kostenlos registrieren
Verdammt!!!

Ab Beitrag 15 ist es ein anderes Projekt!!!

Vielleicht sollte da ein Moderator zwei Threads raus machen?
Das ist jetzt eigentlich auch egal ... im Grunde passt es ja noch "ein bisschen" zum Ursprungsthema und vor Allem aber zur Überschrift ... 8)
 
Zu deiner Schrittkette :
Ob es so gut oder nicht gut ist kann ich jetzt so nicht beurteilen - das wird dann aber sicherlich dein Test ergeben.
Was du dir ggf. noch überlegen solltest ist, die Schrittnummern nicht im 1er-Schritt zu vergeben - lieber so, wie für bei den "guten alten" Basic-Programmen - also 10er oder ggf. 5er Schritte. Der Vorteil ist, dass du einfacher einen eventuell mal notwendigen Zwischenschritt an der richtigen Position einfügen kannst (da hast du dann ggf. mal einen 1er Schritt).
Mit den Timern wirst du sicherlich mit IEC-Timern arbeiten (?) - wäre jedenfalls sinnig. Denk dran, dass deinen Bools, die du an den Q des Timers hängst auch statische Variablen sein müssen ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Durch das tolle Forum und Google bin ich auf ein Thread gestoßen wo die Schrittnummern als Konstanten hinterlegt ist,
so kann man immer recht Simple ändern. In der Tat habe ich den Parallellauf Nachträglich eingeführt daher die Schrittnummer 70.

Genau die Frage habe ich mit gestellt, soll ich in den Timern TON oder IEC als statische Variable instanziieren.
Also IEC Timer vielen Dank.

Ich verstehe nicht was du mit Bools die an den Ausgängen des Timers angehengt werden, meinst.
 
Ich verstehe nicht was du mit Bools die an den Ausgängen des Timers angehengt werden, meinst.
Naja ... du weißt ja sicherlich, dass die IEC-Timer ganz generell nicht bedingt aufgerufen werden wollen (also nicht in den SELECT einbauen oder eine IF-Abfrage. Nun musst (oder willst) du die Meldung, dass der Timer abgelaufen ist ja irgendwie an die Schrittkette übergeben ... das wäre dann z.B. dein "Revision_Zeit" - das sollte dann ein STAT am Timer.Q sein ...

Das mit den Schrittnummern als Konstanten (vor Allem wenn die dann nicht "Schritt_xyz" oder so heissen) ist natürlich auch sinnig. Leider ist Siemens hier noch nicht so weit wie z.B. Beckhoff - da geht das noch ein bisschen schöner ...
 
Alles klar vielen Dank, jetzt fehlt mir nur noch das setzen der richtigen Pumpen, Also welche Pumpe jetzt dran ist.
Irgendwie sehe ich nicht den Wald vor lauter Bäumen nicht mehr...
 
Irgendwie sehe ich nicht den Wald vor lauter Bäumen nicht mehr...
Dann beschreib uns doch mal Deine Bäume so, dass wir einen klareren Blick darauf erhalten können.
"Welche Pumpe jetzt dran ist" hat ja zwei Bedeutungen:
- welche Pumpe ist dran mit eingeschaltet werden
und, wenn mehrere Pumpen laufen,
- welche Pumpe ist dran mit abgeschaltet werden.

Welche Kriterien hast Du (in Deiner "PumpenTabelle" also in Deinem array of struct) dafür, welche Pumpe ...
- nicht zur Verfügung steht
- bevorzugt eingeschaltet werden soll
- bevorzugt abgeschaltet werden soll
- ggfs mit welcher anderen Pumpe "verheiratet" ist
?

Allgemeiner Tipp:
Tabelle entsprechend den Prioritäten und AusschlussKriterien sortieren. Weil nach unterschiedlichen Kriterien unterschiedlich sortiert werden soll, belässt man die Tabelle unsortiert und fügt Spalten hinzu, die Indizes auf die Zeilen der "festen" TabellenSpalten enthalten. Nur diese IndexSpalten werden dann sortiert.
 
ICh hab das jetzt mal so gemacht:

Für Kritik und Verbesserung bin ich offen.

Code:
REGION Pumpen Schalten
    
    REGION Nächster Pumpensatz
        // Nächsten Pumpensatz bestimmen
        #tempNächsterSatz := #statAktiverSatz;
        FOR #statLaufvariable := 1 TO #tempAnzahlPumpen DO
            
            // inkrementieren
            #tempNächsterSatz += 1;
            
            // Limitieren
            IF #tempNächsterSatz > #tempAnzahlPumpen THEN
                #tempNächsterSatz := 1;
            END_IF;
            
            IF #pumpen[#tempNächsterSatz].status.bereit THEN
                // wenn Pumpe bereit, dann als nächste bzw. für den Parallelbetrieb vormerken und Schleife verlassen 
                #statNächsterSatz := #tempNächsterSatz;
                EXIT;
            END_IF;
        END_FOR;
    END_REGION 
    
    REGION Satzwechsel 
        // Positive Flanke generieren, nach der Nachlaufzeit oder dem Reversieren für den Satzwelsel
        #statFTriggVorgang(CLK := (#statSchritkette.Schritte.nachlaufzeit AND NOT #tempAnforderungReversierung)
                           OR (#statSchritkette.Schritte.reversionNachAbpumpen AND #tempAnforderungReversierung));
        
        // Negative Flanke nach der Abschaltung durch Laufzeit oder Fehler
        #statRTriggAbschaltung(CLK := #statSchritkette.Schritte.pauseNachAbschaltung);
        
        // Anforderung nächster Satz setzen
        #statAnforderungNächsterSatz := #statRTriggAbschaltung.Q OR #statFTriggVorgang.Q;
        
        // Satzwechsel
        IF #statAnforderungNächsterSatz THEN
            #statAktiverSatz := #statNächsterSatz;
        END_IF;
    END_REGION ;
    
    REGION Pumpenfreigaben
        // erste Pumpe einschalten
        #pumpen[#statAktiverSatz].autoEin := #statSchritkette.Schritte.abpumpen
        OR #statSchritkette.Schritte.parallelbetrieb
        OR #statSchritkette.Schritte.nachlaufzeit;
        
        IF #Einstellungen.Parallelbetrieb THEN
            // zusätzliche Pumpe einschalten
            #statParallSatz := #statNächsterSatz;
            #pumpen[#statParallSatz].autoEin := #statSchritkette.Schritte.parallelbetrieb OR #statSchritkette.Schritte.nachlaufzeit;
        END_IF;
        
        // erste Pumpe reversieren
        #pumpen[#statAktiverSatz].autoRev := #statSchritkette.Schritte.reversionVorAbpumpen OR #statSchritkette.Schritte.reversionNachAbpumpen;
    END_REGION
END_REGION
 
Weil, es ja mehr als 2 Pumpen sein können, und sagen wir Pumpe 1 ist aktiver Satz und Pumpe 2 nicht bereit, weil gewartet wird oder gestört ist.
Dann muss ja Pumpe 3 einsetzen. wie ich das realisier ohne eine Schleife keine Ahnung...
 
So, wie du aktuell die Schleife hast, läuft sie immer. Schau dir deinen Code-Schnipsel mal genau an ...

Was du beschreibst ist ja eine Suche nach der nächsten Pumpe - das darf nur einmal und auf Anforderung geschehen. Wenn du aber tatsächlich nur max. 3 Pumpen an den Start bringst dann kannst du das genauso über einen IF-ELSE_IF-Abfrage machen - das ist dann auch nicht mehr Aufwand (und für dich vielleicht auch einfacher umzusetzen ...
 
Und der nächste Satz ist auch für den Parallelbetrieb.

ich finde aber nicht den Fehler den du meinst?

der Aktive Satz wird doch nur bei hier gesetzt:

Code:
 // Satzwechsel
        IF #statAnforderungNächsterSatz THEN
            #statAktiverSatz := #statNächsterSatz;
        END_IF;
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich meinte das hier :
Code:
       FOR #statLaufvariable := 1 TO #tempAnzahlPumpen DO
            
            // inkrementieren
            #tempNächsterSatz += 1;   [COLOR=#ff0000]// <= hier wird munter durch-inkrementiert, und zwar sogar die aktuelle Nummer wird dabei nicht ausgespart ...[/COLOR]
            
            // Limitieren
            IF #tempNächsterSatz > #tempAnzahlPumpen THEN
                #tempNächsterSatz := 1;
            END_IF;
            
            [COLOR=#ff0000]// dieser Teil macht vielleicht Sinn - aber ggf, auch eher so, wie ich geschrieben habe ...[/COLOR]
            IF #pumpen[#tempNächsterSatz].status.bereit THEN
                // wenn Pumpe bereit, dann als nächste bzw. für den Parallelbetrieb vormerken und Schleife verlassen 
                #statNächsterSatz := #tempNächsterSatz;
                EXIT;
            END_IF;
        END_FOR;
 
Aber die aktuelle Nummer ist doch tempNächsterSatz, die wird im 1. Durchlauf inkrementiert, damit die aktuelle Pumpe nicht ausgewählt wird.

Die erste, welche gefunden wird gesetzt als nächste Pumpe. Die aktuelle Pumpe hat den Status bereit nicht! Also kann diese auch nicht ausgewählt werden als nächste Pumpe.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Sorry ich raff das nicht,

vor der Schleife wird die Temp Variable zum druchlaufen der Schleife doch mit der Zahl des aktiven Satzes initialisiert. Muss ja auch jeder zyklus, da es doch eine Temp Variable ist.

Code:
// Nächsten Pumpensatz bestimmen
        #tempNächsterSatz := #statAktiverSatz;
        FOR #statLaufvariable := 1 TO #tempAnzahlPumpen DO

Ich glaube ich stehe auf dem Schlauch ;)
 
Wie lang ist der geschätze Zyklus deiner SPS ? 10 ms ? 20 ms ?
In dieser Zeit läuft deine Schleife ein Mal durch. Die Bereit-Meldung, auf die du reagierst, wird sich nicht während des Durchlaufs der Schleife verändern sondern nur davor (oder danach - egal wie du es siehst). Denk immer dran : Zyklische Programmbearbeitung ...! Der Durchlauf, den du da skizzierst hast, wird also im Zyklus stattfinden und somit immer das gleiche (oder kein) Ergebnis bringen.
Aber du kannst es ja auch einfach ausprobieren ... ;)
 
Wie würdest du es denn anders machen? Oder anders gefragt, wie würdest du sicher stellen, dass die Schleife nur einmal ausgeführt wird? Das auch in den Trigger Bedingung für die Anforderung?

Alle meine Programme laufen die schleifen jeden Zyklus. Was ist wenn sich der bereit Status ändert wie kann man das abfangen und durch iterrieren?

Mit if else wusste ich nicht wie ich ein dynamisches Array Durchlauf
 
Zurück
Oben