Vorstellung und erste Frage Umschalter/Vergleicher 1-Byte-Werte

Mein Beispiel von oben, mit 'ner einfachen (Zähl-) Rampe zum Ausdimmen:
Code:
[FONT=Courier New]FUNCTION_BLOCK DMX_Treppe


CONST
    Stufen:= 26;                                                              // Anzahl Stufen
    Neben :=  3;                                                              // benachbarte Stufen
    Rampe := 10;                                                              // Zyklen, um Istwert zu dekrementieren
END_CONST

VAR_INPUT
    Stufe     : ARRAY [1..Stufen] OF BOOL;                                    // Belegungserkennung Stufe
END_VAR

VAR_IN_OUT
    DMX_Soll  : ARRAY [1..Stufen] OF BYTE;                                    // Sollvorgabe  für DMX
    DMX_Ist   : ARRAY [1..Stufen] OF BYTE;                                    // Byte-Ausgabe für DMX
END_VAR

VAR
    DMX_Rampe : ARRAY [1..Stufen] OF INT;                                     // Zähler für Ausdimmen
END_VAR

VAR_TEMP
    Dimm      : ARRAY [0..Neben]  OF BYTE;                                    // Dimmstufen
    i         : INT;                                                          // Index-Variable benachbarte Stufen
    z         : INT;                                                          // Index-Variable Stufen
END_VAR

    
    // Dimmstufen festlegen
    Dimm[0]:= 255;                                                            // Dimmstufe 0 = 100% = 255 
    Dimm[1]:= 179;                                                            // Dimmstufe 1 =  70% = 179 
    Dimm[2]:= 102;                                                            // Dimmstufe 2 =  40% = 102 
    Dimm[3]:=  25;                                                            // Dimmstufe 3 =  10% =  25 
    
  
    // Treppenstufen abfragen und DMX-Sollwerte zuweisen
    FOR z:= 1 TO Stufen BY 1 DO                                               // Schleife über alle Stufen
        DMX_Soll[z]:= 0;                                                      //   DMX-Wert für Stufe zurücksetzen
        FOR i:= 0 TO Neben BY 1 DO                                            //   Schleife über benachbarte Stufen
            IF Stufe[ SEL(G:= z + i > Stufen, IN0:= z + i, IN1:= z) ] OR      // Wenn Stufe i höher  (wenn existent, sonst eigene) oder
               Stufe[ SEL(G:= z - i < 1,      IN0:= z - i, IN1:= z) ]         //      Stufe i tiefer (wenn existent, sonst eigene) belegt
            THEN                                                              //     Befehle bei belegter Stufe:
                DMX_Soll[z]:= Dimm[i];                                        //       DMX-Byte entspechend Abstand zu belegter Stufe zuweisen
                EXIT;                                                         //       Schleife über benachbarte Stufen vorzeitig verlassen
            END_IF;                                                           //     Ende Befehle bei belegter Stufe
        END_FOR;                                                              //   Ende Schleife über benachbarte Stufen
    END_FOR;                                                                  // Ende Schleife über alle Stufen
    
    
    // Istwert-Anpassung
    FOR z:= 1 TO Stufen BY 1 DO                                               // Schleife über alle Stufen
        IF BYTE_TO_INT( DMX_Soll[z] ) < BYTE_TO_INT( DMX_Ist[z] )             //   Vergleich Soll- und Istwert
        THEN                                                                  //   Befehle bei kleiner:
            DMX_Rampe[z]:= DMX_Rampe[z] + 1;                                  //     Rampe inkrementieren 
            CASE DMX_Rampe[z] OF                                              //     Prüfung Rampenwert:
            1:     DMX_Ist[z]:= INT_TO_BYTE( BYTE_TO_INT( DMX_Ist[z] ) - 1 ); //     = 1:    [/FONT]Istwert dekrementieren[FONT=Courier New]
            Rampe: DMX_Rampe[z]:= 0;                                          //     = Ende: Rampe rücksetzen
            END_CASE;                                                         //     Ende Prüfung Rampenwert
        ELSE                                                                  //   Befehle sonst:
            DMX_Ist[z]:= DMX_Soll[z];                                         //      Istwert direkt vom Sollwert übernehmen
            DMX_Rampe[z]:= 0;                                                 //      Rampe rücksetzen
        END_IF;                                                               //   Ende Vergleich
    END_FOR;                                                                  // Ende Schleife über alle Stufen


END_FUNCTION_BLOCK[/FONT]
Der Endwert der Rampe geht unter SCL bei CASE nur mit Konstante.
Besser wäre aber 'ne Variable. Vlt. geht das ja bei CoDeSys. Ansonsten z.B. von CASE auf IF..ELSIF ausweichen.

Wie bereits weiter oben gesagt, Einschalten ohne Rampe, nur Ausdimmen. Sieht beim Begehen bestimmt besser aus, als Hochdimmen.


PS: Hab' gerad gemerkt, das der Zähler für die Rampe abhanden ist. So bestimmt nur die Zykluslänge die Rampe.
* Noch mal vorkram *
* So, wieder drin *
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Zum Vergleich - mit variabler Rampe:
Code:
[FONT=courier new]FUNCTION_BLOCK DMX_Treppe


CONST
    Stufen:= 26;                                                              // Anzahl Stufen
    Neben :=  3;                                                              // benachbarte Stufen
END_CONST

VAR_INPUT
    Stufe     : ARRAY [1..Stufen] OF BOOL;                                    // Belegungserkennung Stufe
    Rampe     : INT:= 10;                                                     // Zyklen, um Istwert zu dekrementieren
END_VAR

VAR_IN_OUT
    DMX_Soll  : ARRAY [1..Stufen] OF BYTE;                                    // Sollvorgabe  für DMX
    DMX_Ist   : ARRAY [1..Stufen] OF BYTE;                                    // Byte-Ausgabe für DMX
END_VAR

VAR
    DMX_Rampe : ARRAY [1..Stufen] OF INT;                                     // Zähler für Ausdimmen
END_VAR

VAR_TEMP
    Dimm      : ARRAY [0..Neben]  OF BYTE;                                    // Dimmstufen
    i         : INT;                                                          // Index-Variable benachbarte Stufen
    z         : INT;                                                          // Index-Variable Stufen
END_VAR

    
    // Dimmstufen festlegen
    Dimm[0]:= 255;                                                            // Dimmstufe 0 = 100% = 255 
    Dimm[1]:= 179;                                                            // Dimmstufe 1 =  70% = 179 
    Dimm[2]:= 102;                                                            // Dimmstufe 2 =  40% = 102 
    Dimm[3]:=  25;                                                            // Dimmstufe 3 =  10% =  25 
    
  
    // Treppenstufen abfragen und DMX-Sollwerte zuweisen
    FOR z:= 1 TO Stufen BY 1 DO                                               // Schleife über alle Stufen
        DMX_Soll[z]:= 0;                                                      //   DMX-Wert für Stufe zurücksetzen
        FOR i:= 0 TO Neben BY 1 DO                                            //   Schleife über benachbarte Stufen
            IF Stufe[ SEL(G:= z + i > Stufen, IN0:= z + i, IN1:= z) ] OR      // Wenn Stufe i höher  (wenn existent, sonst eigene) oder
               Stufe[ SEL(G:= z - i < 1,      IN0:= z - i, IN1:= z) ]         //      Stufe i tiefer (wenn existent, sonst eigene) belegt
            THEN                                                              //     Befehle bei belegter Stufe:
                DMX_Soll[z]:= Dimm[i];                                        //       DMX-Byte entspechend Abstand zu belegter Stufe zuweisen
                EXIT;                                                         //       Schleife über benachbarte Stufen vorzeitig verlassen
            END_IF;                                                           //     Ende Befehle bei belegter Stufe
        END_FOR;                                                              //   Ende Schleife über benachbarte Stufen
    END_FOR;                                                                  // Ende Schleife über alle Stufen
    
    
    // Istwert-Anpassung
    FOR z:= 1 TO Stufen BY 1 DO                                               // Schleife über alle Stufen
        IF BYTE_TO_INT( DMX_Soll[z] ) < BYTE_TO_INT( DMX_Ist[z] )             //   Vergleich Soll- und Istwert
        THEN                                                                  //   Befehle bei kleiner:
            IF DMX_Rampe[z] <= 0                                              //     Vergleich Rampenwert
            THEN                                                              //     Befehle bei 0:
                DMX_Ist[z]:= INT_TO_BYTE( BYTE_TO_INT( DMX_Ist[z] ) - 1 );    //       Istwert dekrementieren
                DMX_Rampe[z]:= Rampe;                                         //       Rampe auf Maxwert setzen
            END_IF;                                                           //     Ende Vergleich Rampenwert
            DMX_Rampe[z]:= DMX_Rampe[z] - 1;                                  //     Rampe dekrementieren 
        ELSE                                                                  //   Befehle sonst:
            DMX_Ist[z]:= DMX_Soll[z];                                         //      Istwert direkt vom Sollwert übernehmen
            DMX_Rampe[z]:= 0;                                                 //      Rampe rücksetzen
        END_IF;                                                               //   Ende Vergleich
    END_FOR;                                                                  // Ende Schleife über alle Stufen


END_FUNCTION_BLOCK[/FONT]
 
WOW! Da hast Du extra eine Nachtschicht eingelegt...

Super, vielen Dank!
Läuft auch soweit, aber da ich gerade über 500 km von der Treppe entfernt bin und somit keine Lichttastersignale hier habe, wollte ich mir schnell per TON diese Signale simulieren. Aber TON weigert sich partout, Q nach der Zeit PT auf TRUE zu schalten. D.h. der Timer läuft erst garnicht an.

Beim Nachgucken in der Simulation bin ich auch auf .M und .StartTime gestoßen, die ich in der Hilfe und auch im Handbuch nicht dokumentiert finde. Die beiden bleiben auch auf FALSE, bzw. T#0ms, auch wenn IN = TRUE ist (siehe Anhänge).

Wo liegt der Hund begraben? :O
 

Anhänge

  • TON_1.jpg
    TON_1.jpg
    52,4 KB · Aufrufe: 6
  • DI_Start force.jpg
    DI_Start force.jpg
    74,3 KB · Aufrufe: 13
So, ich hab das dann gestern Abend mal, ohne große Hoffnung eigentlich, auf der Wago getestet. Und siehe da..., Timer läuft!

Kann mir jemand erklären, warum TON auf der Steuerung läuft, in der Simulation jedoch nicht?
 
Zurück
Oben