Step 7 Störbits erkennen

spirit

Level-1
Beiträge
961
Reaktionspunkte
23
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi,

ich stecke mal wieder etwas fest ... ;)

Habe mal folgenden Code

Code:
      L     MD   200
      INVD  
      L     DB10.DBD   16
      T     MD   200
      UD    
      U     <>0
      FP    M     25.0
      S     A      4.7


Beispiel dazu:

1) DB10.DBX16.4 wird 1 --> A4.7 erhält den Status 1. Das klappt soweit!

2) DB10.DBX16.4 bleibt 1 UND A4.7 wird rückgesetzt!

3) DB10.DBX16.5 wird 1 --> A4.7 soll erneut den Status 1 erhalten. Das klappt aber nicht!


Kann ich das Konstrukt irgendwie umbauen, dass der Ausgang (nach Rücksetzen) bei jeder neuen Störerfassung wieder gesetzt wird?
 
Hallo Spirit,

in deinem Codesnippet ist der Flankenmerker (M25.0) das Problem. Egal, was du mit dem Ausgang 4.7 machst - solange der DB10.DBX16.4 auf True ist bleibt der Flankenmerker auch True und somit würde das Aktiv werden eines weiteren Bits aus dem DBB16 nicht mehr registriert werden.
Du müßtest das also vollkommen anders anfassen und dir zu deinem DBB den Vorgängerstand speichern und mit dem arbeiten.

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

in deinem Codesnippet ist der Flankenmerker (M25.0) das Problem. Egal, was du mit dem Ausgang 4.7 machst - solange der DB10.DBX16.4 auf True ist bleibt der Flankenmerker auch True und somit würde das Aktiv werden eines weiteren Bits aus dem DBB16 nicht mehr registriert werden.
Du müßtest das also vollkommen anders anfassen und dir zu deinem DBB den Vorgängerstand speichern und mit dem arbeiten.

Gruß
Larry

Danke Larry,

ja das hatte ich schon bemerkt - wollte euch nur den ganzen Code servieren ... ;)

Das Problem ist halt nur, ohne FM kann ich den Ausgang nicht rücksetzen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Na oK,

was meint ihr hierzu:

Code:
      L     MD   200
      L     DB10.DBD   16
      <>D   
      S     A 4.7

      L     DB10.DBD   16
      L     MD   200
      INVI  
      UD    
      L     DB10.DBD   16
      T     MD   200

      L     DB10.DBD   16
      L     L#0
      ==D   
      R     A 4.7
 
1) DB10.DBX16.4 wird 1 --> A4.7 erhält den Status 1. Das klappt soweit!

2) DB10.DBX16.4 bleibt 1 UND A4.7 wird rückgesetzt!

3) DB10.DBX16.5 wird 1 --> A4.7 soll erneut den Status 1 erhalten.
Also bei mir funktioniert Dein Code genau so wie von Dir gewünscht. :)
Die Flankenerkennung "FP M25.0" ist zwar unnötig, stört aber auch nicht. Das UD ergibt schon 1-Bits, welche nur 1 Zyklus lang 1 sind: Nur wenn ein 1-Bit in DB10.DBD16 auftaucht, welches im Zyklus vorher 0 war, dann ergibt das UD einen Wert <>0.

Beschreibt eine andere Programmstelle Deine beteiligten Variablen?
Sind die Anweisungen vor Deinem Code VKE-Begrenzend? Schreibe mal "sicherheitshalber" vor die erste Anweisung ein einzelnes CLR oder SET.

Code:
      CLR                               // sicherheitshalber VKE begrenzen

      L     MD   200                    // Zustand der Störbits "vorher"
      INVD
      L     DB10.DBD   16               // Störbits aktuell
      T     MD   200                    // Zustand der Störbits "vorher"
      UD
      U     <>0
//      FP    M     25.0                  // ist unnötig, stört aber auch nicht
      S     A      4.7


      U     M     26.0                  // Quittiertaster
      R     A      4.7

Harald
 
Also bei mir funktioniert Dein Code genau so wie von Dir gewünscht. :)


Code:
      L     MD   200                   
      INVD
      L     DB10.DBD   16               
      T     MD   200                    
      UD
      U     <>0
      S     A      4.7

      U     M     26.0                  
      R     A      4.7

Harald


WOW - ist ja immer interessant, dass andere mit meinem Code besser umgehen können, als ich selber ... :p

Habe nun vor diesem Netzwerk noch etwas geändert und nun klappt es erst einmal!


Da es ja auch noch weitere DBD's gibt, wollte ich das Ganze jetzt mal schön in eine kompakte Schleife packen - ist mir aber noch nicht ganz gelungen; bin soweit gekommen:


Code:
         AUF   "DB10"

         L     P#16.0                     
         T     #pointer_1

         L     4                           
Next: T     #zaehler

        L     DBD [#pointer_1]
        L     L#0
        ==D                               
        SPB   Null                       

        L     MD   200
        INVD  
        L     DBD [#pointer_1]           
        T     MD   200                    
        UD    
        U     <>0
        S     A 4.7

Null:  NOP   0
        L     #pointer_1
        L     P#4.0
        +D                                
        T     #pointer_1
        L     #zaehler
        LOOP  Next

     U   M  26.0                  // Quittiertaster
     R   A  4.7



Das Problem ist nun noch, dass der Ausgang nicht rückgesetzt wird, sobald alle Störbits gleich Null sind.

Könnte ich das in obigen Code irgendwie integrieren?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Dann müßte dein MD200 durch ein DBD[#Pointer_2] ersetzt werden, dass über einen #Pointer_2 adressiert wird, denn der Zwischenspeicher des "alten Standes" kann ja nicht in jeder Schleife das selbe MD200 sein!
Also mußt du (am Besten am selben DB) noch ein paar DBD anhängen, und darin den "alten Stand" speichern. Diesen #Pointer_2 addierst du dann genauso auf, wie du das mit #Pointer_1 machst, nur die Anfangsadresse ist natürlich eine andere.
 
Dann müßte dein MD200 durch ein DBD[#Pointer_2] ersetzt werden, dass über einen #Pointer_2 adressiert wird, denn der Zwischenspeicher des "alten Standes" kann ja nicht in jeder Schleife das selbe MD200 sein!
Also mußt du (am Besten am selben DB) noch ein paar DBD anhängen, und darin den "alten Stand" speichern. Diesen #Pointer_2 addierst du dann genauso auf, wie du das mit #Pointer_1 machst, nur die Anfangsadresse ist natürlich eine andere.

Vielen Dank Ralle!

... mit noch ein paar DBD anhängen verstehe ich so, dass ich z.B. den DB10.DBD20, DB10.DBD24 und DB10.DBD28 im DB10 anhängen soll?

Und dann den MD200 einfach durch den #pointer_2 ersetzen?
 
Ja genau.
Aber Achtung, geht das denn ab DBD20? Du hast doch DBD16 für das erste DBD mit den Bits, dann den Zähler 4, also muß doch dein DB jetzt schon mindestens DBD16,DBD20,DBD24,DBD28 enthalten für die Bits, oder? Dahinter dann die DBD für den "alten Stand" oder ganz ans Ende, wenn der DB noch andere Daten enthält.
 
Ja genau.
Aber Achtung, geht das denn ab DBD20? Du hast doch DBD16 für das erste DBD mit den Bits, dann den Zähler 4, also muß doch dein DB jetzt schon mindestens DBD16,DBD20,DBD24,DBD28 enthalten für die Bits, oder? Dahinter dann die DBD für den "alten Stand" oder ganz ans Ende, wenn der DB noch andere Daten enthält.

Hm, ich glaube ich habe es noch nicht ganz richtig verstanden.

Es sollen z.B. der DB10.DBD16 / DBD20 / DBD24 und DBD28 abgefragt werden. Diese habe ich im DB10 hintereinander stehen. Ganz am Ende ab DBD36 stehen dann vier Einträge um den "alten Stand" zu merken.


Code:
     AUF   "DB10"

        L     P#16.0                      
        T     #pointer_1

        L     P#36.0                     
        T     #pointer_2

        L     4                          
Next: T     #zaehler

        L     DBD [#pointer_1]
        L     L#0
        ==D                             
        SPB   Null   
                     
        L     DBD [#pointer_2]
        INVD  
        L     DBD [#pointer_1]            
        T     DBD [#pointer_2]                 
        UD    
        U     <>0
        S     A 4.7

Null: NOP   0
      L     #pointer_1
      L     P#4.0
      +D                                
      T     #pointer_1

      L     #pointer_2
      L     P#4.0
      +D                                
      T     #pointer_2

      L     #zaehler
      LOOP  Next

      U     "OP_ACK"
      R     A 4.7

Irgendwie will des Ganze aber noch net so wie ich ... etwas stur heute die SPS! ;)


@vierlagig: Die Codes auf der verlinkten Seite sind aber mal wieder ganz anders als meiner - und ich wollte halt meinen weiterentwickeln ...
 
So sollte es eigentlich laufen.
Hast du den DB verlängert und in die SPS geschoben?
Kannst ja mal nicht L 4 für den Zähler machen, sondern L 1 (oder L 0???), dann kannst du das zumindest für das 1. DBD beobachten.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das Problem ist nun noch, dass der Ausgang nicht rückgesetzt wird, sobald alle Störbits gleich Null sind.
Willst Du das wirklich???
Ich meine, es macht keinen Sinn, den Ausgang zurückzusetzen sobald kein Störbit mehr aktiv ist, wenn man vorher umständlich eine Neustörung detektiert und speichert. Dann könnte man nämlich einfach nur alle Stör-DBD ver-Odern und gut ist's.

Du solltest für Dich zunächst mal in Klartext formulieren was Du willst, denn das bestimmt die Logik des Ausgangs. Danach kannst Du dann Deine Schleife basteln.
A) der Ausgang soll signalisieren, wenn irgendeine Störung aktiv ist (Sammelstörung)
B) der Ausgang soll signalisieren, wenn irgendeine Störung aktiv ist oder aktiv war, bis die Signalisierung quittiert wurde (soll nach dem Gehen der letzten Störung nochmal quittiert werden?)
C) der Ausgang soll signalisieren, wenn seit dem letzten Quittieren eine neue Störung dazugekommen ist, bis die Signalisierung quittiert wurde (Neustörung)
D) ?

Code:
// A: Sammelstörung aktiv
StörDW[1] OR StörDW[2] OR ... ---> = Lampe

// B: Sammelstörung speichern bis quittiert
StörDW[1] OR StörDW[2] OR ... ---> S Lampe
Quittiertaster ---> R Lampe

// C: Neustörung speichern bis quittiert
StörDW[1] AND NOT StörDW_vorher[1] OR StörDW[2] AND NOT StörDW_vorher[2] OR ... ---> S Lampe
Quittiertaster ---> R Lampe

Gerne wird auch gemischt: die Lampe leuchtet bei Sammelstörung und blinkt bei Neustörung.
Code:
Lampe := (Sammelstörung AND NOT Neustörung) OR (Neustörung AND Blink)


@vierlagig: Die Codes auf der verlinkten Seite sind aber mal wieder ganz anders als meiner - und ich wollte halt meinen weiterentwickeln ...
Hatten wir das nicht schon kürzlich in einem anderen Thread von Dir für ...zig Meldungen erweitetet?
Ich meine, ich hatte da auch einen Link auf einen Thread gepostet, wie ich Sammelstörung, Neustörung und Störungshupe mit allen Schikanen programmiere.

Harald
 
@Ralle: Es läuft insoweit schon, aber wenn alle Störbits den Status 0 haben, dann wird der Ausgang nicht selbstständig zurückgesetzt! Finde aber in meiner Schleife den Fehler nicht ... :confused:


@Harald: Stimmt, wir hatten schon mal für mich so etwas Ähnliches konstruiert; allerdings mit mehreren Abfragen - also ohne Schleife.

Nun, diese Vorgabe (Ausgang automatisch rücksetzen) ist eine Kundenvorgabe!

Es soll halt wie folgt ablaufen:

Es gibt einen DB10 in dem vier DBD's hintereinander angeordnet sind. DB10.DBD16 - DB10.DBD28

Ferner eine Meldeanzeige, die immer automatisch aufpoppen soll, wenn ein Störungsbit aktiv ist, bzw. ein neues hinzukommt. Störungsbit ist hier vielleicht der falsche Ausdruck, da es eigentlich Betriebsmeldungen (Hinweise für den Benutzer) sind, und keine Alarme!

Also, ein Bit aus dem DB10 wird aktiv --> Meldeanzeige mit Text geht auf. Der Benutzer kann das zur Kenntnis nehmen und über eine Taste die Meldeanzeige (auch bei noch aktivem Störungsbit) wieder ausschalten. Kommt eine neue Meldung hinzu, so poppt die Anzeige erneut auf und wenn sie nicht durch den Benutzer geschlossen wird, so wird sie automatisch geschlossen, wenn keine Meldung (Störungsbit) mehr anliegt.

Dies habe ich nun versucht in meiner Schleife darzustellen. Das Problem ist nun noch, dass die Meldeanzeige eben nicht mehr selbststätig schließt, sobald kein Störungsbit mehr aktiv ist.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

Dies habe ich nun versucht in meiner Schleife darzustellen. Das Problem ist nun noch, dass die Meldeanzeige eben nicht mehr selbststätig schließt, sobald kein Störungsbit mehr aktiv ist.

sieh Dir mal Deine Rücksetzbedingung an. Im Augenblick setzt Du den Ausgang nur mit "OP_ACK" zurück. Du mußt dort zusätzlich prüfen ob alle DBD Null sind.

Gruß
 
Danke für den Hinweis Thruser,

hatte das vorhin schon mal so:

Code:
AUF   "DB10"

        L     P#16.0                      
        T     #pointer_1

        L     P#36.0                     
        T     #pointer_2

        L     4                          
Next:   T     #zaehler

        L     DBD [#pointer_1]
        L     L#0
        ==D                             
        SPB   Null   
                     
        L     DBD [#pointer_2]
        INVD  
        L     DBD [#pointer_1]            
        T     DBD [#pointer_2]                 
        UD    
        U     <>0
        S     A 4.7

Null:   NOP   0
        L     #pointer_1
        L     P#4.0
        +D                                
        T     #pointer_1

        L     #pointer_2
        L     P#4.0
        +D                                
        T     #pointer_2

        L     #zaehler
        LOOP  Next

        O     "OP_ACK"
        O(    
        L     DBD [#pointer_1]
        L     L#0
        ==D   
        )     
        R     A 4.7

Aber irgendwie funzt das alles noch nicht so, wie von mir gewünscht.

Der Code hat ein Eigenleben; einmal klappt es und dann wieder nicht ... ;)

Derzeit wird der Ausgang überhaupt nicht gesetzt, wenn ich z.B. DB10.DBX16.4 setze!


Hier noch die angefügten Zeilen im DB10:

DB.jpg
 
Hallo,

Danke für den Hinweis Thruser, hatte das vorhin schon mal so: Aber irgendwie funzt das alles noch nicht so, wie von mir gewünscht. Der Code hat ein Eigenleben; einmal klappt es und dann wieder nicht ... ;) Derzeit wird der Ausgang überhaupt nicht gesetzt, wenn ich z.B. DB10.DBX16.4 setze!

hier machst Du die Abfrage ja auch nur mit dem letzten DBD, da Du erst nach der Schleife abfragst.

Eventuell solltest Du mit einem Zwischenspeicher (ein DBD) arbeiten.

Den zuerst auf Null setzen.
Dann in die Schleife:Wenn aktueller DBD größer als der Speicher diesen Wert in den Speicher laden.

Am Ende Abfragen, ob Speicher gleich Null dann rücksetzen.

Anderes fällt mir z.Zt. nicht ein. Bin lange raus aus der Siemenprogrammierung mit AWL und Pointern.

Gruß
 
Zurück
Oben