Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Seite 4 von 5 ErsteErste ... 2345 LetzteLetzte
Ergebnis 31 bis 40 von 48

Thema: Nie mehr als zwei Ausgänge setzen können.

  1. #31
    Registriert seit
    27.06.2009
    Ort
    am Nordharz
    Beiträge
    3.717
    Danke
    443
    Erhielt 920 Danke für 740 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Ich hab' mich da jetzt selbst mal in SCL (von S7 V5.5, weil ich da Arrays mit Konstanten deklarieren kann ) 'ran gesetzt.
    Auf der "großen" SPS ist das Ganze wirklich etwas einfacher, vor allem wenn ich an die Erweiterung der LOGO!-Aufgabe von 4 auf 5 Ein-/Ausgänge denke.


    Zitat Zitat von bkizilkaya Beitrag anzeigen
    wie würdest du es machen kannst du mir ein Beispielcode aufzeigen?
    Ich denke, da sich bkizilkaya schon intensiv mit der sich selbst gestellten Aufgabe beschäftigt und auch einen eigenen Lösungsweg fast fertig hat, ist es auch in dieser Phase schon legitim, meine Variante als solche zu posten.
    ( Warum glaub' ich eigentlich, mich dafür rechtfertigen zu müssen? )

    Ich habe mir 2 FBs erstellt.
    Der erste FB "X_aus_N" enthält die eigentliche Aufgabe, wobei die Ein- und Ausgänge der Einfachheit halber jeweils als Array's deklariert sind:
    Code:
    FUNCTION_BLOCK "X_aus_N"
    
    CONST
        N:=  5;                                                                 // Anzahl Ein-/Ausgänge
        XS:= 2;                                                                 // Standard-Anzahl max. eingeschalteter Ausgänge
    END_CONST
    
    VAR_INPUT
        IN:     ARRAY [1 .. N] OF BOOL;                                         // Neuer Zustand der Eingänge
        X:      INT;                                                            // Anzahl max. eingeschalteter Ausgänge
    END_VAR
    
    VAR_OUTPUT
        OUT:    ARRAY [1 .. N] OF BOOL;                                         // Ausgänge
    END_VAR
    
    VAR
        IN_OLD: ARRAY [1 .. N] OF BOOL;                                         // letzter Zustand der Eingänge
        ORDER:  ARRAY [1 .. N] OF INT;                                          // Speicher für Einschaltreihenfolge
    END_VAR
    
    VAR_TEMP
        i:      INT;                                                            // Hilfsvariable Schleife Ein-/Ausgänge
        j:      INT;                                                            // Hilfsvariable Schleife Reihenfolgespeicher
    END_VAR
    
    
    
        // Eingänge auf Zustandsänderungen prüfen:
        FOR i:= 1 TO N BY 1 DO                                                  // Alle Eingänge der Reihe nach prüfen
            IF IN[i] AND NOT IN_OLD[i] THEN                                     //      Wenn positive Flanke des Eingangs
                FOR j:=  1 TO N BY 1 DO                                         //      dann Reihenfolgespeicher von unten an durchsuchen
                    IF ORDER[j] = 0 THEN                                        //              Wenn Reihenfolgefeld noch leer
                        ORDER[j]:= i;                                           //              dann Nummer des Eingangs eintragen
                        EXIT;                                                   //                   und Schleife abbrechen
                    END_IF;
                END_FOR;                                                        //           nächstes Speicherfeld
            ELSIF IN_OLD[i] AND NOT IN[i] THEN                                  //      sonst wenn negative Flanke des Eingangs
                FOR j:= 1 TO N BY 1 DO                                          //      dann Reihenfolgespeicher von unten an durchsuchen
                    IF ORDER[j] = i THEN                                        //              Wenn Eintrag des Eingangs gefunden,
                        ORDER[j]:= 0;                                           //              dann Eintrag löschen
                        EXIT;                                                   //                   und Schleife verlassen (und Stelle merken)
                    END_IF;
                END_FOR;                                                        //           nächstes Speicherfeld
                // Ggf. alles Folgende 1 Stelle nach unten schieben
                IF j < N THEN                                                   //           Wenn Eintrag nicht im letzten Speicherfeld
                    FOR j:= j TO N - 1 BY 1 DO                                  //           dann vom Feld des Eintrags bis zum vorletzten Feld
                            ORDER[j]:= ORDER[j+1];                              //                   Inhalt vom Speicherfeld drüber kopieren
                    END_FOR;                                                    //                nächstes Speicherfeld
                    ORDER[N]:= 0;                                               //                letztes Speicherfeld Eintrag löschen
                END_IF;
            END_IF;
            IN_OLD[i]:= IN[i];                                                  //      Zustand des Eingangs für nächsten Zyklus speichern
        END_FOR;
        
        // alle Ausgänge rücksetzen
        FOR i:= 1 TO N BY 1 DO
            OUT[i]:= false;                                                     // alle Ausgänge rücksetzen
        END_FOR;
        
        // Anzahl X (max. eingeschalteter Ausgänge) ggf. korrigieren
        X:= SEL ( G:= X < 1 OR X > N, IN0:= X, IN1:= XS);                       // Wenn X innerhalb 1 und Maximum, dann verwenden
        
        // max. Anzahl Ausgänge setzen
        FOR i:= 1 TO X BY 1 DO
            OUT[ ORDER[i] ]:= true;                                             // max. gewünschte Anzahl Ausgänge setzen
        END_FOR;
        
    
    END_FUNCTION_BLOCK
    Der 2. FB "IN_OUT_to_Array" steckt mir die Ein- und Ausgänge jeweils in ein Array bzw. holt sie wieder raus. Dabei kann jeweils ein Startbyte angegeben werden, von dem mit Bit 0 begonnen wird. So konnte ich schön variabel mit den beiden rumspielen, ohne immer den Code an x Stellen anpassen zu müssen:
    Code:
    FUNCTION_BLOCK "IN_OUT_to_Array"
    
    CONST
        N:= 5;                                                                  // Anzahl Ein-/Ausgänge
    END_CONST
    
    VAR_INPUT
        S_IN:  INT;                                                             // Startbyte der Eingänge
        S_OUT: INT;                                                             // Startbyte der Ausgänge
        X: INT;                                                                 // Anzahl max. eingeschalteter Ausgänge
    END_VAR
    
    VAR
        IN:  ARRAY [1..N] OF BOOL;                                              // Array der Eingänge für "X_aus_N"
        X_N: "X_aus_N";                                                         // FB "X_aus_N" als Multiinstanz
    END_VAR
    
    VAR_TEMP
        i: INT;                                                                 // Hilfsvariable
    END_VAR
    
    
        // Eingänge ins Array
        FOR i:= 1 TO N  BY 1 DO
            IN[i] := E[ S_IN + ( i - 1 ) / 8 , ( i - 1 ) MOD 8 ];               // Eingang ( Byte, Bit ) ins Array eintragen
        END_FOR;
        
        // "X_aus_N" aufrufen
        X_N ( IN:= IN, X:= X );
        
        // Ausgänge aus Array übernehmen
        FOR i:= 1 TO N  BY 1 DO
            A[ S_OUT + ( i - 1 ) / 8 , ( i - 1 ) MOD 8 ]:= X_N.OUT[i];          // Ausgang ( Byte, Bit ) aus Array übernehmen
        END_FOR;
        
    END_FUNCTION_BLOCK
    Wie einfach es doch sein kann, aus 5 Eingängen 8, 16 oder x machen zu können.
    Und dann noch die Anzahl der max. eingeschalteten Ausgänge sogar im lfd. Betrieb ändern.
    Geändert von hucki (10.01.2014 um 00:04 Uhr) Grund: Die Ein-/Ausgänge von den gespielten 16 auf die geforderten 5 zurückgesetzt

  2. #32
    Registriert seit
    03.09.2013
    Beiträge
    93
    Danke
    1
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Danke hucki ich werde es mir heute oder morgen anschauen
    Gruss

  3. #33
    Registriert seit
    03.09.2013
    Beiträge
    93
    Danke
    1
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Hallo hucki

    Ich habe jetzt dein Code an mich angepasst und getestet und habe festgestellt wenn du zum Beispiel schalter 1 2 3 aktiv hast in dieser Reihenfolge und ich zum beispiel schalter 2 deaktiviere dann hallt passiert halt ganz komisches. Dann ist keiner in der Reihenfolge!
    Mein Code:

    Code:
    // Schalter_Flanek abspeichern
    #Schalter_zustand[1] := #schalter_1;
    #Schalter_zustand[2] := #schalter_2;
    #Schalter_zustand[3] := #schalter_3;
    #Schalter_zustand[4] := #schalter_4;
    #Schalter_zustand[5] := #schalter_5;
    
    
    
    
    // Eingänge aus Zustandsänderung prüfen
    FOR #i := 1 TO 5 BY 1 DO
      IF #Schalter_zustand[#i] AND NOT #Schalter_Zustand_OLD[#i] THEN
        FOR #j:= 1 TO 5 BY 1 DO
          IF #ORDER[#j] = 0 THEN
            #ORDER[#j] := #i;
            EXIT;
          END_IF;
        END_FOR;      
      ELSIF #Schalter_Zustand_OLD[#i] AND NOT #Schalter_zustand[#i] THEN
        FOR #j := 1 TO 5 BY 1 DO
          IF #ORDER[#j] = #i THEN
            #ORDER[#j] := 0;
            EXIT;
          END_IF;
        END_FOR;
        IF #j < 5 THEN
          FOR #j := 1 TO 5 BY 1 DO
            #ORDER[#j] := #ORDER[#j + 1];
          END_FOR;
          #ORDER[5] := 0;
        END_IF;
      END_IF;
        #Schalter_Zustand_OLD[#i] := #Schalter_zustand[#i];
    END_FOR;
    
    
    // reseten
    IF "reset" THEN
    FOR #k := 1 TO 5 BY 1 DO
      #ORDER[#k] := 0;
    END_FOR;
    END_IF;

  4. #34
    Registriert seit
    03.09.2013
    Beiträge
    93
    Danke
    1
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Es funktioniert habe das vorzeichen vertauscht

    Danke viel mal

  5. #35
    Registriert seit
    27.06.2009
    Ort
    am Nordharz
    Beiträge
    3.717
    Danke
    443
    Erhielt 920 Danke für 740 Beiträge

    Standard

    Du hast einen Logik- und Progammfehler im Code:
    Zitat Zitat von bkizilkaya Beitrag anzeigen
    Mein Code:
    Code:
    ...
      ELSIF #Schalter_Zustand_OLD[#i] AND NOT #Schalter_zustand[#i] THEN
        FOR #j := 1 TO 5 BY 1 DO
          IF #ORDER[#j] = #i THEN
            #ORDER[#j] := 0;
            EXIT;
          END_IF;
        END_FOR;
        IF #j < 5 THEN
    
       // FOR #j := 1 TO 5 BY 1 DO     -->
    // hier darf nicht an Stelle 1 des Arrays begonnen werden, sondern dort,
    // wo die vorige Schleife nach dem Löschen des Inhalts abgebrochen wurde.
    // Die Stelle steht in der Variable #j  -> Jetzt werden auch Stellen verschoben,
    // vor denen gar nichts gelöscht wurde und die erste Stelle geht z.B. immer verloren,
    // wenn eine spätere Stelle gelöscht wird!
    
    // Außerdem darf die Schleife auch nur bis zur vorletzten Stelle des Array's gehen,
    // weil sonst bei "#j + 1" eine Bereichsüberschreitung stattfindet!
    
    // Richtig: 
          FOR #j := #j TO 4 BY 1 DO
     
           #ORDER[#j] := #ORDER[#j + 1];
          END_FOR;
          #ORDER[5] := 0;
        END_IF;
      END_IF;
        #Schalter_Zustand_OLD[#i] := #Schalter_zustand[#i];
    END_FOR;
    ...
    Die Zuweisungen für die Ausgänge sind nur nicht gepostet?



    Für so wiederkehrende Zahlen, wie hier bei Dir die 5 (Ausgänge), sollte man immer wenigstens Konstanten deklarieren. Wenn Du später mal die Anzahl der Ausgänge verändern willst, musst Du so nur an einer Stelle ändern und nicht das ganze Programm durchsuchen.
    In der äußeren FOR-Schleife für die Kontrolle der Eingange sind allein schon 6 Verwendungsstellen. Da wird bei späteren Änderungen schnell mal was übersehen.

    Bei TIA muss man dann allerdings bei solchen Änderungen noch zusätzlich die Array-Deklarationen anpassen. Das ist bei Classic definitiv besser!

  6. Folgender Benutzer sagt Danke zu hucki für den nützlichen Beitrag:

    vollmi (10.01.2014)

  7. #36
    Registriert seit
    06.10.2004
    Ort
    Kopenhagen.
    Beiträge
    4.626
    Danke
    377
    Erhielt 801 Danke für 642 Beiträge

    Standard

    Hallo hucki.

    Wie deklariert man Konstanten in Classic ? Und als Bereiche für Arrays verwendet ?
    Das wurde mich interessieren.
    Hatte gedacht das diese Funktionalität gibt es gar nicht.
    Jesper M. Pedersen

  8. #37
    Registriert seit
    27.06.2009
    Ort
    am Nordharz
    Beiträge
    3.717
    Danke
    443
    Erhielt 920 Danke für 740 Beiträge

    Standard

    Zitat Zitat von JesperMP Beitrag anzeigen
    Hallo hucki.

    Wie deklariert man Konstanten in Classic ? Und als Bereiche für Arrays verwendet ?
    Das wurde mich interessieren.
    Hatte gedacht das diese Funktionalität gibt es gar nicht.
    Äh... , so wie oben in meinem Code?
    Zitat Zitat von hucki Beitrag anzeigen
    ...
    Code:
    FUNCTION_BLOCK "X_aus_N"
    
    CONST
        N:=  5;                                                                 // Anzahl Ein-/Ausgänge
        XS:= 2;                                                                 // Standard-Anzahl max. eingeschalteter Ausgänge
    END_CONST
    
    VAR_INPUT
        IN:     ARRAY [1 .. N] OF BOOL;                                         // Neuer Zustand der Eingänge
        X:      INT;                                                            // Anzahl max. eingeschalteter Ausgänge
    END_VAR
    
    VAR_OUTPUT
        OUT:    ARRAY [1 .. N] OF BOOL;                                         // Ausgänge
    END_VAR
    
    ...
    ...



  9. Folgender Benutzer sagt Danke zu hucki für den nützlichen Beitrag:

    JesperMP (10.01.2014)

  10. #38
    Registriert seit
    27.06.2009
    Ort
    am Nordharz
    Beiträge
    3.717
    Danke
    443
    Erhielt 920 Danke für 740 Beiträge

    Standard

    PS: Es gehen damit auch solch nette Sachen (aus der "4 gewinnt"-Sache):
    Code:
    CONST
        Spalten:= 7;                                                                    // Anzahl Spalten
        Zeilen := 6;                                                                    // Anzahl Zeilen
    END_CONST
    
    VAR
        SPIELFELD:   ARRAY [1 .. Spalten, 1 .. Zeilen] OF INT;                          // Spielfeld               (7 Spalten,  6 Zeilen)
        SPIELZUEGE:  ARRAY [1 .. Spalten * Zeilen, 0 .. 3] OF INT;                      // Speicher Spielzüge (max. 7 Spalten x 6 Zeilen = 42 Spielzüge,
    ...

  11. #39
    Registriert seit
    06.10.2004
    Ort
    Kopenhagen.
    Beiträge
    4.626
    Danke
    377
    Erhielt 801 Danke für 642 Beiträge

    Standard

    Danke hucki.

    Das ist ein Super tip.
    CONST und END_CONST sind gar nicht zu finden in den Online Hilfe zu SCL !
    edit: Doch es gibt, aber ist nur etwas versteckt.

    Und mein Hans Berger Buch über SCL hat auch keine Informationen darüber.
    Aber nach eine kleine test scheint es tatsäglich zu funktionieren.

    Weil du so kundig bist, weist du ob man auch globale Konstanten deklarieren kann ?
    Geändert von JesperMP (10.01.2014 um 16:10 Uhr)
    Jesper M. Pedersen

  12. #40
    Registriert seit
    27.06.2009
    Ort
    am Nordharz
    Beiträge
    3.717
    Danke
    443
    Erhielt 920 Danke für 740 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    1. Hast Du das PS noch gesehen?
    Nicht das es durch Deinen Post untergegangen ist.

    2. ich bin da gar nicht so kundig, wie Du vlt. gerade glaubst. Aber ich glaube, es ist möglich. In TIA nur noch global. Allerdings kann man in TIA die Arrays leider nicht mit Konstanten deklarieren.

    3. SCL-Anleitung für S7 V5.5 von Siemens. Da hatte ich das drin gelesen.

Ähnliche Themen

  1. Step 5 Ausgänge setzen/rücksetzen
    Von hoffi im Forum Simatic
    Antworten: 4
    Letzter Beitrag: 07.01.2014, 12:22
  2. Antworten: 5
    Letzter Beitrag: 08.10.2013, 09:47
  3. Ausgänge im EG können nicht angesteuert werden
    Von antares24 im Forum Simatic
    Antworten: 14
    Letzter Beitrag: 07.05.2012, 20:27
  4. Antworten: 5
    Letzter Beitrag: 09.03.2010, 08:20
  5. Antworten: 10
    Letzter Beitrag: 28.04.2008, 22:17

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •