Auswahlkriterium Betriebsstunden

Zuviel Werbung?
-> Hier kostenlos registrieren
Zottel schrieb:
rs-plc-aa schrieb:
Hallo,

da bin ich gerade dabei...

Ich hab dann mal



gegen

Code:
      L     0
      L     "Module_soll"
      ==I   
      SPB   nene                        // ... oder auch nicht ...
...

So ist es richtiger. War das andere von mir?

Ja... (Hätte theoretisch auch funktionieren müssen nur praktisch halt nicht)


Wohl deshalb weil im 7 Byte des IndexDB die Nummer 4 stand. Das kann ich aber nur aus dem Ergebnis schließen.
Nummer =6 bedeutet: 7.Eintrag im IndexDB = DBB6
Nummer =0 bedeutet: 1.Eintrag im IndexDB = DBB0
Die Byte-Nummer (hier 6) ist mit 8 zu multiplizieren. Das ist einfach eine Vorraussetzung damit der Befehl
Code:
     L     DBB [LD 12]
funktioniert.
Es haben ja schon Leute versucht, "pointer" zu erklären.

Hiermit schon gut genug erklärt...


1. Step7 auch noch "typisierte" Pointer kennt, z.B. P#DB20.DBX0.0, P#E60.0, die eine Information über den Speicherbereich beinhalten.

Ich kannte bisher nur die...

Fazit: der Befehl
Code:
     L     DBB [LD 12]
braucht immer die 8-fache Bytenummer, was zufällig auch die Bit-Nummer ist. Das ist weder vernünftig, noch dem Wesen nach durch den Begriff "Pointer" zu erklären, sondern schlicht eine "Schrulle" der Siemens-Entwickler, mit der man jetzt leben muß.

man muß es eben nur wissen...

Kan der Simulator Einzelschritt?

Ja - werde ich jetzt noch ausprobieren...


Um hier alles gleichzeitig im Auge zu haben sollte man eine Kinoleinwand als Monitor haben...
 
Es haben ja schon Leute versucht, "pointer" zu erklären. Eigentlich finde ich das keine gute Erklärung, weil:
1. Step7 auch noch "typisierte" Pointer kennt, z.B. P#DB20.DBX0.0, P#E60.0, die eine Information über den Speicherbereich beinhalten.
2. Die hier verwendeten Adressen im Gegensatz zu pointern anderer Programmiersprachen stehen: Im Gegenstatz zu Pascal ist Rechnen mit "pointern" erlaubt. Im Gegenstatz zu C wird bei den Berechnungen aber eben nicht die Größe des Zielobjekts automatisch berücksichtigt.

Ich wollte eigentlich gar nicht groß den Begriff "Pointer" erklären, viel mehr ein bischen Licht darauf werfen, weswegen es nötig ist um 8 zu multiplizieren. Das ganze ist ganz gut in Berger erklärt und wenn man das Diagramm auf Seite 338 vor Augen hat, wo die Struktur der Zeiger dargestellt wird, dann kann man klar sehen weswegen es einfacher zu verstehen ist wenn man SLD 3 benutzt (was natürlich funktional dasselbe ist).
 
RMA schrieb:
Ich wollte eigentlich gar nicht groß den Begriff "Pointer" erklären, viel mehr ein bischen Licht darauf werfen, weswegen es nötig ist um 8 zu multiplizieren. Das ganze ist ganz gut in Berger erklärt und wenn man das Diagramm auf Seite 338 vor Augen hat, wo die Struktur der Zeiger dargestellt wird, dann kann man klar sehen weswegen es einfacher zu verstehen ist wenn man SLD 3 benutzt (was natürlich funktional dasselbe ist).

Da hab ich doch gleich mal den Berger (3. Auflage, 2002 ) aufgeschlagen...

Da kommt bei mir aber auf S. 338 etwas von Alarmbehandlung.


Wie heißt denn das Kapitel genau ?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Oops, :oops: war gerade auf dem Weg zurück zu sagen im KOP / FUP Buch, Kap. 24 - Ergänzung zur grafischen Programmierung.

Das AWL Buch hab' ich leider nicht, aber vielleicht findest Du es im Stichwortverzeichniss unter "Zeiger" (mindestens, so ist es im KOP / FUP Buch zu finden).
 
Zottel schrieb:
Kenne leider den Berger nicht.
Kannst Du die Struktur mal eben widergeben?
Ach ja, fand sich ja wahrscheinlich schon im Thread:
Byte.Bit, wobei die hinteren drei Bits für die Bitnummer reseviert sind.
SLD 3 heißt dann "schiebe die Bytenummer in die Bits fürs Byte".

Es ist jedoch recht sinnlos, den Index von L DBB[x] so zu codieren, ohne auch den Zugriff auf ein Byte ab einer beliebigen Bitposition zu implementieren.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

jetzt habe ich es glaube ich schon kapiert...

Ich füge hier mal einen Auschnitt vom Code an an dem ich das nun "extra ausführlich" kommentiert habe.

Wenn die Kommentare stimmen dann müsste ich das kapiert haben.

Code:
      L     #indexDB                    // Index DB Nr. zuweisen
      T     #idbn

      AUF   DB [#idbn]                  // IndexDB aufschlagen
      L     #Nummer                     // Offset laden (DBB in dem das gewünschte Modul steht)
      L     8                           // 8-bit-Einträge 
      *I    
      T     LD    12                    // Inhalt in Temp index kopieren
      L     DBB [LD 12]                 // Modul-Nummer des gewählten DBB aus dem Index lesen

      SPL   tbig                        // wenn Nummer größer als Anzahl Sprungziele ist
      SPA   BM00                        // Sprung nach BM00 wenn Modul-Nummer = 0 war => real #1
      SPA   BM01                        // ...wenn = 1 war => real #2
      SPA   BM02                        // ...wenn = 2 war => real #3
      SPA   BM03                        // ...wenn = 3 war => real #4
      SPA   BM04                        // ...wenn = 4 war => real #5
      SPA   BM05                        // ...wenn = 5 war => real #6
      SPA   BM06                        // ...wenn = 6 war => real #7

tbig: NOP   0
// hier kann eine Störmeldung o.Ä. erzeugt werden...
      SPA   ende

BM00: NOP   0
      UN    "M1_Bereit"                 // betriebsbereit BM0 
      BEB                               // Ende ohne reduzierte Anzahl, kann BM nicht einschalten 
      S     "Modul1_Ein"                // Modul 1 einschalten 
      SPA   END1                        // Ende mit reduzierter Anzahl 

..........

END1: NOP   0           
      L     #Anzahl  
      DEC   1
      T     #Anzahl  // wenn das Modul bereit war und eingeschaltet wurde wird die Anzahl der benötigten um 1 verringert

      BE

Das ganze ist ja nun auch ziemlich komplett.

Angenommen es wird ein Modul eingeschaltet das aber daraufhin nicht gestartet werden kann...

Das einzige was es dann tun muß ist das Bit "Betriebsbereit" zurücksetzen, dann wird beim nächsten durchlauf erkannt daß es nicht mehr verfügbar ist und automatisch das nächst höhere (Stunden) genommen - genial.



Eine Sache überlege ich aber gerade noch:

Um zu vermeiden daß ein eingeschaltetes das gerade einwandfrei läuft abgewählt wird - nur weil es ein anderes (das gerade steht) gerade mit den Stunden überholt hat könnte man noch eine Verriegelung einbauen.

Diese muß dann aber an der Stelle platziert werden bevor alle ausgeschaltet werden.


Ich dachte da mal an folgendes:

Wenn ich mir merke wieviele Module vorher liefen, und dann vergleiche mit der Anzahl was nun laufen soll, und feststelle daß es gleich viele sind -> nichts machen....


Somit wäre zumindest gewährleistet daß wenn gerade 4 Stück laufen sollen - es die selben 4 bleiben - egal was die Stunden sagen.


Wenn dann eine Änderung eintritt wird´s schon schwieriger...

Wenn es weniger sein sollen als vorher wird ja das mit den meisten Stunden weggelassen - dabei kann aber auch schon passieren daß eines das bisher stand auch wieder weniger hat als eines das bisher lief - also Tausch.

Umgekehrt genauso.



Aber zumindest wenn sich nix ändert sollte man auch nix ändern - das geht ja... - oder etwa nicht ?

... da fällt mir doch während ich hier schreibe noch der worst case ein...


Ich zitiere mich mal:

Angenommen es wird ein Modul eingeschaltet das aber daraufhin nicht gestartet werden kann...

Das einzige was es dann tun muß ist das Bit "Betriebsbereit" zurücksetzen, dann wird beim nächsten durchlauf erkannt daß es nicht mehr verfügbar ist und automatisch das nächst höhere (Stunden) genommen - genial.

geht dann aber auch nicht - weil dann davon ausgegangen wird daß das bloße Einschalten ausreichte - aber der Fall daß das Einschalten quasi umsonst war wird dann gar nicht berücksichtigt...


Ich glaube es sollte so bleiben - dann kann eigentlich nix (oder am wenigsten) schief gehen.
 
Müßte jetzt selbst diesen Thread gründlichst lesen, um alles wieder ins Bewußtsein zu holen...
Aber, wenn ich es richtig weiß, war meine Vorstellung:
1. Die Zahl der benötigten BMs ermitteln.
2. Nur wenn sich diese geändert hat, neu sortieren und neu schalten.

Soweit wäre es egal wenn ein E kommt, einer geht und die Zahl gleich bleibt.

Aber 2 Fälle sind doof:

1. Ein E geht, eine Sekunde später kommt wieder einer, es wird 2x sortiert und geschaltet.

2. Es bleiben über sehr lange Zeit drei Eingänge anstehen; aus Gründen der Gerechtigkeit sollen aber mal andere BMs drankommen.

Fall 1 Läßt sich durch einen Zeitverzoegerung lösen: Wenn die neue Zahl der benötigten BMs ungleich der alten Anzahl ist, eine Zeit starten, erst bei Ablauf der Zeit neu sortieren, schalten und benötigte Anzahl als alte speichern.

Fall 2 ließe sich lösen, indem auch bei unveränderter Anzahl der BMs nach Ablauf einer Zeit X die BMs sortiert und geschaltet werden.
Angenommen es wird ein Modul eingeschaltet das aber daraufhin nicht gestartet werden kann...
Das einzige was es dann tun muß ist das Bit "Betriebsbereit" zurücksetzen, dann wird beim nächsten durchlauf erkannt daß es nicht mehr verfügbar ist und automatisch das nächst höhere (Stunden) genommen - genial.

Das mit der Bereitschaft: So wie der Code bis jetzt ist, wird vor Einschalten des BMs die Bereitschaft überprüft. Daß das Einschalten selbst schiefgeht, ist eigentlich durch die allgemeinere Bedingung "Betriebsbereitschaft eines eingeschalteten BMs fällt weg" mit zu erledigen. Diese wird bis jetzt nicht behandelt.


Am Einfachsten dürfte es sein, dann ein Sortieren und Neuverteilen zu erzwingen. Dabei wird dann das nicht bereite BM übergangen.
[/quote]
 
Hallo,

ich habe gerade auch wie verrückt überlegt - jedoch in eine etwas andere Richtung...


Das was jetzt kommt ist definitiv für meinen Fall anzuwenden:


"Fall 2" bräuchte ich genau umgekehrt.


Es sollen die BM´s die schon mal laufen auf jeden Fall weiterlaufen - egal wie lange.


So lange sich die Anzahl vorher - nachher nicht ändert braucht ja nur überwacht zu werden daß die welche mal angefordert wurden auch immer noch laufen.

Dann kommt der Fall Änderung der Anzahl:

Hier sollen ebenfalls vorrangig die weiterlaufen die vorher schon liefen.


Es soll also generell darauf geachtet werden die Ein-Ausschaltvorgänge zu minimieren.


So nun wann ist aber der richtige Moment neu zu sortieren ??

Oder vielleicht nur einen Teil der Liste (ausgenommen von den laufenden) neu zu sortieren...


Das macht mir gerade einen ziemlichen Kopf .
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du kannst es so machen:
Bei Änderungen unterscheiden, ob mehr oder weniger BMs verlangt werden.

Werden es mehr, sortierst du aufsteigend, schaltest nix aus und ein BM ein. Dabei prüfst du auf "betriebsbereit und noch nicht ein".

Werden es weniger, sortierst du absteigend, schaltest nix ein und ein BM aus.
Dabei prüfst du auf "eingeschaltet". Du schaltest also das BM aus, daß die meiste Zeit auf dem Buckel hat und ein ist.

Statt die Sortierrichtung zu wechsel, kannst du auch beim Ausschalten mit dem letzten Element des Index beginnen und rückwärts gehen.
 
Hallo,

ich bin gerade noch feste am tüfteln...

Eines ist aber klar - das letzte Vorhaben hier zu implementieren ist ganz schön knifflig...


Ich habe es nun mal so gemacht (funktioniert allerdings noch nicht richtig):


Bubble Sort geklont, und geändert in aufsteigend - so kann dann bei Bedarf der jeweilige aufgerufen werden...

Dann die An-Abwahl dahingehend geändert daß sie unterscheidet zwischen An- und Abwahl.

Einen weiteren Baustein hinzugefügt der überwacht so lange sich nix ändert ob auch die laufen die laufen sollen (mit Ret-VAL anhand derer dann reagiert werden kann).



Aber irgendwie spielen die Bits gerade ein wenig verrückt, und es tut nicht so wie es soll.


Meine befürchtung ist ein wenig daß der bis dato noch sehr kompakte Code zum aufgeblasenen Monster mutiert :shock:
 
rs-plc-aa schrieb:
Bubble Sort geklont, und geändert in aufsteigend - so kann dann bei Bedarf der jeweilige aufgerufen werden...
Wieso klonen? Ich meine, es ist schon ein Parameter dafür drin!
Meine befürchtung ist ein wenig daß der bis dato noch sehr kompakte Code zum aufgeblasenen Monster mutiert :shock:
Ja eben draum nicht klonen. Mein Vorschlag von gestern vergrößert den Code um weniger als 10 %.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zottel schrieb:
Wieso klonen? Ich meine, es ist schon ein Parameter dafür drin!

Oooops...

jetzt hab ich das doch glatt mißverstanden mit dem Aufruf.

Ich habe Bubble Sort also zwei mal hintereinander gestartet, und die Sortierrichtung vom zweiten Aufruf erhalten....


Zottel schrieb:
//
// OB1 zum Testen des FC16:
//
Code:
      CALL  FC    16
       laenge     :=6
       indexDB    :=10
       datenDB    :=20
       datenLaenge:=32
       AUF_AB     :=FALSE
       INIT_INDEX :=TRUE
      L     DB10.DBB    0
      L     DB10.DBB    1
      L     DB10.DBB    2
      L     DB10.DBB    3
      L     DB10.DBB    4
      L     DB10.DBB    5
      L     DB10.DBB    6

      CALL  FC    16
       laenge     :=6
       indexDB    :=10
       datenDB    :=20
       datenLaenge:=32
       AUF_AB     :=TRUE
       INIT_INDEX :=TRUE
      L     DB10.DBB    0
      L     DB10.DBB    1
      L     DB10.DBB    2
      L     DB10.DBB    3
      L     DB10.DBB    4
      L     DB10.DBB    5
      L     DB10.DBB    6
      BE

wie peinlich...

Darauf habe ich jetzt gar nicht mehr geachtet

wird sofort geändert...

===============================================


Du kannst es so machen:
Bei Änderungen unterscheiden, ob mehr oder weniger BMs verlangt werden.

Werden es mehr, sortierst du aufsteigend, schaltest nix aus und ein BM ein. Dabei prüfst du auf "betriebsbereit und noch nicht ein".

Werden es weniger, sortierst du absteigend, schaltest nix ein und ein BM aus.
Dabei prüfst du auf "eingeschaltet". Du schaltest also das BM aus, daß die meiste Zeit auf dem Buckel hat und ein ist.

Statt die Sortierrichtung zu wechsel, kannst du auch beim Ausschalten mit dem letzten Element des Index beginnen und rückwärts gehen.


Zitat vom Zitat:
Bei Änderungen unterscheiden, ob mehr oder weniger BMs verlangt werden.

Das habe ich versucht mit einem FC zu lösen der abfrägt wieviele BM´s gerade laufen und mit der Zahl der Anforderungen vergleicht.

Bei gleichheit ist der Ret_Val 0 , sind es mehr = 1 und weniger = 2...

Im aufrufenden Baustein werte ich dann den Ret_Val aus...

Bei 0 nichts machen

bei 1 Schalter "Aufsteigend" = 1

bei 2 Schalter "Aufsteigend" = 0


Dann den Index sortieren (entsprechend der Schalterstellung).

Und dann wird´s problematisch.

Schalte ich nun alle aus (wie vorher) habe ich nachher das Problem daß ich die richtigen wieder erwische (die die laufen und weiterlaufen sollen - egal wieviel Stunden...)

Schalte ich keine aus ist´s noch schwieriger...


Werden es mehr, sortierst du aufsteigend, schaltest nix aus und ein BM ein. Dabei prüfst du auf "betriebsbereit und noch nicht ein".


und

Werden es weniger, sortierst du absteigend, schaltest nix ein und ein BM aus.
Dabei prüfst du auf "eingeschaltet". Du schaltest also das BM aus, daß die meiste Zeit auf dem Buckel hat und ein ist.


Das muß ja beides in den An-Abwahl Baustein rein - oder ?

Er muß dann zusätzlich entscheiden (unterscheiden) ob An - oder Abgewählt wird - richtig ?


Ich glaube irgendwie habe ich das Ganze minimal unterschätzt - und das gewaltig :)
 
Hallo,

ich hab so ein änliches Programm vor kurzem geschrieben, dabei geht es um 5 Kompressoren, die den Druck in einem System innerhalb eines bestimmten Wertebereiches halten sollen. Ist der Druck zu gering wird der Kompressor mit den geringsten Betriebstunden zugeschaltet. Ist der Druck zu hoch wird der Kompressor mit den meisten Betriebstunden abgeschaltet. Wenn du willst kann ich es dir mailen, vielleicht hilft dir das weiter??? Kannst mir ja deine emailadresse senden.


Gruß Schibi
 
Hallo,

am Wochenende hatte ich (eigentlich aus der Verzweiflung heraus) eine Idee, die ich hier mal gerne vortragen wollte.


Ich habe mir überlegt ob es nicht einfach ausreichen würde die realen Betribsstundenstände der einzelnen BM´s (die ja über die MS-Kommunikation eingelesen werden) nur dann zu aktualisieren wenn das entsprechende BM nicht läuft.

Das Ergebnis wäre ja dann daß die Stunden der BM´s die laufen, zur Laufzeit nicht "mehr" werden (im Stunden DB zumindest) und die von denen die stehen ja sowieso nicht...


Somit wäre doch gewährleistet daß immer die selben angefordert werden - da die Stunden im DB eingefroren sind.

Wird eines oder mehrere dann abgewählt, werden die Stunden aktualisiert, und wenn diese dann höher sind als die die seither nicht liefen, rutschen diese ja dann im DB (wenn dann) nach hinten (auf keinen Fall nach vorne).

Die, die aber immer noch laufen, bleiben vorne (mit am wenigsten Stunden).

Die Umsetzung war eigentlich schon vorhanden - musste nur ein wenig erweitert werden.

Code:
FC 1 "Stunden DB versorgen":

      SET   
      U     "M1_Laeuft"
      SPB   a001

      L     "BH_Modul_1"
      T     "Stunden".Stunden_Modul1

a001: NOP   0
      U     "M2_Laeuft"
      SPB   a002

      L     "BH_Modul_2"
      T     "Stunden".Stunden_Modul2

a002: NOP   0
      U     "M3_Laeuft"
      SPB   a003

      L     "BH_Modul_3"
      T     "Stunden".Stunden_Modul3

a003: NOP   0
      U     "M4_Laeuft"
      SPB   a004

      L     "BH_Modul_4"
      T     "Stunden".Stunden_Modul4

a004: NOP   0
      U     "M5_Laeuft"
      SPB   a005

      L     "BH_Modul_5"
      T     "Stunden".Stunden_Modul5

a005: NOP   0
      U     "M6_Laeuft"
      SPB   a006

      L     "BH_Modul_6"
      T     "Stunden".Stunden_Modul6

a006: NOP   0
      U     "M7_Laeuft"
      SPB   a007

      L     "BH_Modul_7"
      T     "Stunden".Stunden_Modul7

a007: NOP   0

      BE


Mir ist bis jetzt noch nichts eingefallen was dagegen spricht.


Was meint ihr dazu ?
 
Zurück
Oben