Betriebsstunden Optimierung

bayernburn

Level-1
Beiträge
38
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Liebe Leute im SPS Forum,

ich arbeite mit Step7 V5.5 und benutze WinXP.

ich habe derzeit folgendes Problem:
ich muss ein Programm für einen Tank schreiben, indem sich 2 Pumpen befinden. Das Starten/Stoppen einer Pumpe erfolgt über das Niveau.
Ist ja nicht so schwer. Mein Problem allerdings ist, dass laut Pflichtenheft die beiden Pumpen Betriebsstunden optimiert gestartet bzw. gestoppt werden.
Das bedeuted:
Wird im Tank das Niveau Hi erreicht, soll die Pumpe gestartet werden, die weniger Betriebsstunden hat. Fällt das Niveau im Tank unter den Wert Lo, soll diese Pumpe wieder gestoppt werden.
Tritt ein erneutes Hi Nievau auf, muss wieder die Pumpe starten, die weniger Betriebsstunden hat.
Ich wollte mir hierzu einen eigenen FC bauen, der mir die ganze Betriebsstundenoptimierung macht und mir dann ausgibt, welche Pumpe starten soll. Nur leider bekomm ich das nicht so wirklich hin.
Wollte das ganze in SCL Programmieren.

Kann mir da jemand weiterhelfen? Hat jemand von euch schon mal eine Betriebsstundenoptimierung benötigt/gemacht?

MfG
Bayernburn
 
Zuviel Werbung?
-> Hier kostenlos registrieren
o sorry hab mich verschrieben.
ich programmiere nicht in scl sondern in awl.

es hakt an der stelle, wo ich die reihung der pumpen auswerten muss. ich möchte als ausgabe ein bool haben, das mir dann sagt pumpe 1 oder pumpe 2. also für jede pumpe 1 bool als ausgang.
ich werde dann gleich mal einen vorabzug meines programmes reinstellen.
viell. fällt dann das lösen meines problems leichter.
 
Vergleiche doch einfach die Werte der beiden Betriebsstundenzähler.
L BStdZ 1
L BStdZ 2
>=I
= Merker Pumpe 2 starten

L BStdZ 2
L BStdZ 1
>I
= Merker Pumpe 1 starten

Und das ganze dann noch mit dem Füllstand verknüpfen.
 
Vielleicht aber mal mit dem Verfasser des Pflichtenheftes sprechen.
Wir haben derartige "Schaltungen" zu Hauf wieder ausgebaut weil zum Zeitpunkt wo Pumpe A ganz kaputt war, Pumpe B schon ziemlich kaputt war.
Diese scheinbare "Betriebsstunden Optimierung" stellt sich öfters (nicht immer) als ganz schlecht heraus.
Besser ist es einen Vorwahlschalter zu haben, der eine Pumpe bevorzugt, die andere Pumpe wird dann und wann (zB jeder 10te Start) auch benutzt, damit diese nicht einrostet.

Gruß
Karl
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Vielen Dank erstmal für die schnellen Antworten.
So einfach wie das fuss beschreibt ist das leider nicht.

Der Baustein soll auch lt. meinem Chef so ausgelegt werden, dass 7 Aggregate gleichzeitig überprüpft werden können. Es soll also so sein, dass der Basutein die Betriebsstunden vergleicht und auch überprüft ob das Aggregat bereit ist (kein Fehler) oder ob es bereits läuft.
Hier mal der Baustein, so wie er bis jetzt aussieht.
Ich habe im Moment das ganze nur mal für 2 Antriebe "realisiert", weil ich der Meinung bin, wenn die Sortierung und Auswahl für 2 Antriebe funktioniert, kann ich den Code dann auf 7 erweitern.
Wie man unten im Code sehen kann, übergebe ich die Betriebsstunden und die Aggregatsnummmer (1,2,...) an lokale Daten.
Vor der Reihung wird auch bereits überprüft, ob das Aggregat läuft oder nicht bereit ist.
Ist ein Aggregat nicht bereit oder läuft es bereits, werden in die Lokaldaten temporär hohe Stunden eingetragen um diese zurück zu reihen.
Mein Problem ist jetzt nur, dass ich nicht weiß wie ich auf meine Ausgänge (Bool) meinen Befehl 1 bzw. 0 je nach Sortierung bekomme.
z.b. Pumpe 1 hat 5 Stunden
Pumpe 2 hat 2 Stunden
Somit soll Pumpe 2 einschalten und ich hätte gerne eine 1 bei meiner InOut Variable "DevOn2".

Code:
//=============================================================================
// New Hoop Check program with inputs.
// With this function max. 5 devices can be switched on by checking the operating hours.
// There are several inputs used to signalize the status of the device, ....
//=============================================================================
//This subroutine will check the selected couples of devices for availability.
//At this state the check includes locked status, manual status, alarm condition,
//switching and hours of the selected devices.
//used bits:
//M  xxx.6 -hoop lock
//FC225
FUNCTION "HoopCheck" : VOID
 TITLE =Hours of Operation Checker
 KNOW_HOW_PROTECT
 AUTHOR  :RRRbyMB
 FAMILY  :OH_Ch
 NAME    :HoopCheck
 VERSION :1.0

  VAR_INPUT
   Activ     :INT;                // How many devices to check
   Active1     :BOOL;                // "One" if device is used for OH optimization, "Zero" if not
   AutoRdy1     :BOOL;                // Auto Ready for Device#1
   Running1     :BOOL;                // Running signal for Device#1
   Hours1     :DINT;                // Operating hours for Device#1      
   Active2     :BOOL;                // "One" if device is used for OH optimization, "Zero" if not
   AutoRdy2     :BOOL;                // Auto Ready for Device#2
   Running2     :BOOL;                // Running signal for Device#2
   Hours2     :DINT;                // Operating hours for Device#2         
  END_VAR

  VAR_IN_OUT
   DevOn1     :BOOL;                // On signal for Device#1
   DevOn2     :BOOL;                // On signal for Device#2   
  END_VAR
   
  VAR_TEMP
   DeviceNo       :WORD;
   DeviceMode     :BYTE;
   MaxDevice      :BYTE;
   RunDevice      :BYTE;
   LoopCounter    :BYTE;
   InLoopCounter  :BYTE;
   OutLoopCounter :BYTE;
   Index          :WORD;
   DeviceStop     :BOOL;
  END_VAR

  BEGIN
  NETWORK
       L    "DataDB";
       T    Index;
       AUF  DB [Index];

       L    0;                          // +++ init array
       T    LD 210;                     // LW210-LW237    operating hours device 1-7
       T    LD 214;
       T    LD 218;
       T    LD 222;
       T    LD 226;
       T    LD 230;
       T    LD 234;
       T    LD 238;
       T    LD 242;
       T    LD 246;
       T    LD 250;
       T    LW 252;
       L    #Activ;
       T    LW 252;
    
// min. 2 devices to check    
       U(;
       L    1;
       L    #Activ;
       <=I;
       )       
       SPB LFIL;
       
// 2 devices       
       U(;
       L    2;
       L    #Activ;
       ==I;
       )
       SPBN DEV3;
       L    #Hours1;
       T    LD 210;
       
       L    1;
       T    LW 214;    
       
       L    #Hours2;
       T    LD 216; 

       L    2;
       T    LW 220;             
       SPA    LFIL;
// 3 devices       
DEV3:  U(;
       L    3;
       L    #Activ;
       ==I;
       )
       SPBN DEV4;
       L    #Hours1;
       T    LD 210;
       
       L    #Hours2;
       T    LD 216;       
       SPA    LFIL;
// 4 devices       
DEV4:  U(;
       L    4;
       L    #Activ;
       ==I;
       )
       SPBN DEV5;
       L    #Hours1;
       T    LD 210;
       
       L    #Hours2;
       T    LD 216;       
       SPA    LFIL;
// 5 devices       
DEV5:  U(;
       L    5;
       L    #Activ;
       ==I;
       )
       SPBN DEV6;
       L    #Hours1;
       T    LD 210;
       
       L    #Hours2;
       T    LD 216;       
       SPA    LFIL;
// 6 devices       
DEV6:  U(;
       L    6;
       L    #Activ;
       ==I;
       )
       SPBN DEV6;
       L    #Hours1;
       T    LD 210;
       
       L    #Hours2;
       T    LD 216;       
       SPA    LFIL;
// 7 devices       
DEV7:  U(;
       L    7;
       L    #Activ;
       ==I;
       )
       SPBN LFIL;
       L    #Hours1;
       T    LD 210;
       
       L    #Hours2;
       T    LD 216;       
       SPA    LFIL;                                   
       
                                        // --------------------------------
  LFIL:L    #Activ;                     // +++ max aggregate
       T    #MaxDevice;
                                        // --------------------------------
  MEND:L    MaxDevice;                  // max aggregate counter
         L    1;
         <=I    ;
         BEB    ;
         
         L    0;                          // +++ check auto/alarm
       T    RunDevice;                  // running counter
       L    MaxDevice;
       T    LoopCounter;
       
// Device 1 Check
  LCH1:UN    #Running1;                    // Running signal for Device#1
       SPB  NOR1;
       L    RunDevice;
       INC  1;                          // running counter
       T    RunDevice;
       L    2147483640;                 // running
  NOR1:U    #AutoRdy1                    // Auto Ready for Device#1
         U    DBX 12.7;
       SPB  NOA1;
       L    2147483641;                 // AutoReady
  NOA1:UN   #Active1                    // "One" if device is used for OH optimization, "Zero" if not
       SPB  NON1;
       L    2147483642;                 // Not Active
  NON1:T    LD 210;                     // hours

// Device 2 Check
  LCH2:UN    #Running2;                    // Running signal for Device#1
       SPB  NOR2;
       L    RunDevice;
       INC  1;                          // running counter
       T    RunDevice;
       L    2147483640;                 // running
  NOR2:U    #AutoRdy2                    // Auto Ready for Device#1
         U    DBX 12.7;
       SPB  NOA2;
       L    2147483641;                 // AutoReady
  NOA2:UN   #Active2                    // "One" if device is used for OH optimization, "Zero" if not
       SPB  NON2;
       L    2147483642;                 // Not Active
  NON2:T    LD 216;                     // hours

                                        // --------------------------------
       L    MaxDevice;                  // +++ sort array
       DEC  1;
       T    OutLoopCounter;
  OLOP:L    MaxDevice;                  // +++ outer loop
       DEC  1;
       T    InLoopCounter;              // inner loop counter
       LAR1 P#204.0;                    // start -4 (== 1 step)
       TAR1 AR2;                        // hour pointer == array pointer
       +AR2 P#6.0;                      // hour pointer (next place)
  ILOP:L    0;                          // +++ inner loop
       L    InLoopCounter;
       >=I;
       SPB  IEND;
       DEC  1;
       T    InLoopCounter;              // inner loop counter
       +AR1 P#6.0;
       +AR2 P#6.0;
       L    LD [AR1, P#0.0];            // pointer
       L    LD [AR2, P#0.0];            // pointer +1
       <=D    ;
       SPB  ILOP;
       L    LD [AR1,P#0.0];             // +++ change array Operating Hours
       L    LD [AR2,P#0.0];
       T    LD [AR1,P#0.0];
       TAK;
       T    LD [AR2,P#0.0];

       L    LW [AR1,P#4.0];             // +++ change array ID No
       L    LW [AR2,P#4.0];
       T    LW [AR1,P#4.0];
       TAK;
       T    LW [AR2,P#4.0];
       SPA  ILOP;
  IEND:L    OutLoopCounter;             // outer loop counter
       DEC  1;
       T    OutLoopCounter;
       L    0;
       L    OutLoopCounter;
       <I;
       SPB  OLOP;

                                       // --------------------------------
 CBEF: LAR1 P#214.0;                    // +++ lock/unlock aggregate
       L    LW 252;                     // active
       L    RunDevice;
       ==I;                             // active = running
       L    0;
       SPB  LLOI;
       L    1;
  LLOI:T    DeviceMode;
       L    1;                          // init loop counter
       T    LoopCounter;
  LLOC:L    LoopCounter;
       L    DeviceMode;                 // activ aggregate
       <=I;
       SPB  RES;
       U(;
       LW     [AR1,P#0.0];
       L    1;
       ==I;
       );
       SPBN MOT2;
       U    "One";
       S    #DevOn1;                    // On signal for Device#1
       SPA    COM;
       
MOT2:  U(;
       LW     [AR1,P#0.0];
       L    2;
       ==I;
       );
       SPBN COM;
       U    "One";
       S    #DevOn2;                    // On signal for Device#2
             
  SPA  COM;
  RES:U(;
       LW     [AR1,P#0.0];
       L    1;
       ==I;
       );
       SPB MO12;
       U    "One";
       R    #DevOn1;                    // On signal for Device#1
       SPA    COM;
       
MO12:  U(;
       LW     [AR1,P#0.0];
       L    2;
       ==I;
       );
       SPB COM;
       U    "One";
       R    #DevOn2;
       
  COM:+AR1 P#6.0;                      // inc pointer array

       L    LoopCounter;
       INC  1;
       T    LoopCounter;
       L    MaxDevice;
       <=I;
       SPB  LLOC;

END_FUNCTION
 
Hallo,
also erstmal solltest du dir abgewöhnen, die Lokalvariablen absolut zu adressieren - da blickst du irgendwann nicht mehr durch und irgend ein symbolischer Mechanismus würde dir da auch in die Quere kommen. Wenn du eine TEMP-Variable benutzen möchtest dann benenne sie auch und verwende in der Folge die Benennung (also die Variable symbolisch).
Dann hast du dir einen FC erstellt. Das ist zwar OK nur solltest du beachten, dass der sich nichts "merken" kann.
Ansonsten ist es aber genau so, wie Fuss es schon schreibt. Du mußt, wenn die Pumpen laufen, deren Betriebszeit aufaddieren und kannst diese Werte dann auch genau so vergleichen, wie von Fuss dargestellt.
Wenn es hier aber um 7 Pumpen geht dann wäre es vielleicht auch schon sinnig, es mittels einer Schleife zu verabeiten und da wären wir dann m.E. ganz schnell bei SCL ...

Die Funktionalität deines Codes habe ich mir sonst weiter nicht angeschaut und kann dazu im moment auch keine Aussage machen ...

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo hucki,

wow, danke für den echt tollen link.
Hatte mir jetzt auch schon was in scl überlegt.
Habe aber jetzt deinen Link gesehen und mir das Programm kurz angeschaut.
Werde mal schauen, ob das für alle Anforderungen für mich reicht oder ob ich noch was dazu bauen muss (z.b. Störumschaltung).
Vielen Dank erstmal.

Melde mich dann wieder, wenn ich neue Erkenntnisse habe.
 
So,
zu allererst möchte ich mich auf diesem Weg noch einmal recht herzlich bei huki bedanken, der mir den entscheidenden Link gegeben hat.
Ich habe den Baustein an meine Bedürfnise angepasst und erweitert.
Folgende Änderungen wurde vorgenommen:
- es können bis zu 7 Aggregate angesteuert werden
- es wurden anstatt der fixen Merkerbereiche IN und Out-Variablen definiert
- die Bertriebsstunden werden direkt übergeben und nicht wie im Baustein aufsummiert
- es wurde eine automatische Störumschaltung integriert --> d.h. tritt bei einem Aggregat ein Fehler auf, wird das nävhste betriebsbereite Aggregat mit den wenigsten Stunden dazu geschaltet.

Sollte jemand Interesse an diesem Baustein haben, bitte einfach mit mir Kontakt aufnehmen.
Ich lasse dieses Thema noch eine Zeit lang geöffnet, falls doch noch weitere Fragen oder ev. auch Verbeserungen hinzukommen.

Gruß
 
Also erstmal ist das Programm nicht von mir, sondern von Zotos. Ihm gebührt also der Dank.
Ich fand die Vorgehensweise aber einfach nachvollzieh- und vor allem anpassbar. Deshalb hatte ich mir das gemerkt.

Wenn es Dir nichts ausmacht, poste doch Deinen angepassten Baustein (vlt. als Quelle) hier oder unter Zotos Beitrag für andere Suchende.
Ist einfacher als PN oder ähnliches. Und über ein Danke für seinen Upload freut Zotos sich bestimmt auch.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo hucki,

OK, ich werde mich bei Zoto bedanken.
Anbei das Projekt mit meinem Baustein. Es ist das gleiche Projekt das Zoto online gestellt hat, nur ergänzt mit meinem neuen Baustein. Mein Baustein ist der FC500 und ist nicht als Quelle abgelegt.
Sollte dazu jemand Fragen haben, kann man mich gerne kontaktieren. :ROFLMAO:

Gruß

Anhang anzeigen Motorpen1.zip
 
Zurück
Oben