TIA Schieberegister variabeler Länge erstellen mit KPT 400 und S7-300

maverickxxll

Level-1
Beiträge
15
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich brauche mal ne Idee wie ich vorgehen kann.
Für eine Konrtrolleinrichtung benötige ich ein Schieberegister das ich in der Länge verändern kann (Über die HMI), da an unterschiedlicher Stelle kontrolliert wird.
Wie setze ich es am besten um, oder womit fange ich am besten an. Habe TIA 11 als Software zur Verfügung

Feste Registerlängen habe ich bisher über MW realisiert.

Gruß Jens
 
Ein boolsches Schieberegister hab' ich hier in SCL für EMZ entworfen:
Code:
[FONT=Courier New]FUNCTION_BLOCK "Boolsches_Schieberegister"

VAR_INPUT
    Start1: BOOL;                               // Startbedingung 1
    Start2: BOOL;                               // Startbedingung 2
    Takt: BOOL;                                 // Impuls-Eingang
    Schritte: INT;                              // Impulszahl bis zur Ausgabe
    Laenge: INT;                                // Ausgabelänge des Impulses in Takten
END_VAR

VAR_OUTPUT
    Ausgabe: BOOL;                              // Impulsausgabe
END_VAR

VAR
    Takt_Old: BOOL;                             // Flankenmerker für Eingang Takt
    Start: BOOL;                                // Startbedingung erfüllt
    Schieberegister: ARRAY [0..500] OF BOOL;    // Boolsches Schieberegister
    Ausgangszaehler: INT;                       // Zähler für Ausgabelänge
END_VAR

VAR_TEMP
    Schieben: BOOL;                             // positive Flanke Eingang Takt
    Index: INT;                                 // Array-Zeiger
END_VAR


    // Schrittbegrenzung
    IF Schritte > 500 THEN
        Schritte := 500;
    END_IF;
    
    // Startbedingung erfüllt?
    IF Start1 AND Start2 THEN
        Start := true;
    END_IF;
    
    // Flankenerkennung Eingang Takt
    Schieben := Takt AND NOT Takt_Old;
    Takt_Old := Takt;
    
    
    // Schieberegister
    IF Schieben THEN
        
        // Register weiterschieben
        FOR Index := Schritte TO 1 BY -1 DO
            Schieberegister [Index] := Schieberegister [Index - 1];  
        END_FOR;
        
        // Startbedingung ins Schieberegister übernehmen
        Schieberegister [0] := Start;
        Start := false;
        
        // Ausgang Schieberegister
        IF Schieberegister [Schritte] THEN
            Ausgangszaehler := Laenge;
        END_IF;
        
        // Ausgabe
        Ausgabe := Ausgangszaehler > 0;
        
        // Zähler Ausgabelänge
        IF Ausgabe THEN
            Ausgangszaehler := Ausgangszaehler - 1;
        END_IF;
        
    END_IF;
    
    
END_FUNCTION_BLOCK[/FONT]

und dann in diesem Thread auf TIA übertragen.


Wenn Du vlt. noch genauer erklärst, was Du machen willst, kann man das sicher leicht anpassen.
Die Startbedingung z.B. wirst Du ja so auf keinen Fall benötigen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Hucki,
danke für deine schnelle antwort. Den Input muss ich erstmal verdauen.
Zur Anwendung

Ich habe eine Maschine die Flaschen mit Etiketten versieht. Vorm Abspenden werden dort an 2 unterschiedlichen Stellen Kontrollen durchgeführt. Sobal eine der Kontrollen negativ ausfällt soll die Flasche mit dem Etikett ausgewiesen werden. Somit brauche ich ein Register für die Kontrollen (hab gerade die Idee das in einer festen Länge zu machen und über eine Vergleich die entsprechende Stelle auf null zu setzen...). DIe kontrollen ändern sich in der Länge zum Übergabepunkt durch die länge des Etiketts, somit variabel, meisten im Bereich zwischen 1 und 16 Takten. Danach muss die Auswertung an ein Laufbandregister übergeben werden das die information bis zur Ausweisung mit führt. Dafür ist dein Register schon mal hervorragend geeignet, da ich die Länge dann einteachen könnte.
Mal sehen was mir einfällt...
Gruß Jens
 
Guten Morgen,

ich habe für die Kontrollen mal was entworfen. Siehe Bilder, Würde das so funktionieren ?
Das Laufbandregister würde ich versuchen über das boolsche Schieberegister zu machen.

Gruß Jens
PLC1.jpgPLC2.jpg
 
Zuletzt bearbeitet:
Hallo zusammen,

wie weit kann man den Array in dem Code vergrößern ? So auf den Wert von ca. 4000 ? Gibt es dafür einschränkungen ?

Gruß Jens
 
Wenn man nicht für die Darstellung z.B. in einem HMI die Daten im Array in der richtigen Reihenfolge haben muss, löst man sowas durch einen Schreib- und Lesezeiger. Bei Lesen oder Schreiben auf die Daten im Schieberegister wird dann nur der Zeiger umgesetzt, und nicht mehr das komplette Array umkopiert. Dann ist es egal ob das Array 10, 100, oder 10000 Einträge hat.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo maverickxxll,
ich habe in meinem neuen Projekt so etwas ähnliches gemacht.
Schau dir mal die SCL Quelle an.

FUNCTION "ERGEB" : Void
TITLE = Ergebnisse registrieren
{ S7_Optimized_Access := 'FALSE' }
//registrieren und löschen von Ergebnissen
VAR_INPUT
START : Bool; // startet das Rotieren der Ergebnisse
RESET : Bool; // löscht den kompletten Speicher
"DB" : Block_DB; // Datenbaustein
LBYTE : Int; // Startbyte Ergebnisse links
RBYTE : Int; // Startbyte Ergebnisse rechts
SBYTE : Int; // Startbyte Status
ANZAHL : Int; // Anzahl der Bytes pro Spur
END_VAR

VAR_OUTPUT
BUSY : Bool; // Baustein ist beschäftigt
END_VAR

VAR_TEMP
X : Int; // Zählvariable
END_VAR


BEGIN
IF #START THEN
#BUSY := TRUE;
FOR #X := (#ANZAHL - 1) TO 0 BY -1 DO
#DB.DB(#LBYTE + #X) := SHR(IN:=#DB.DB(#LBYTE + #X), N:=1);
#DB.DB(#RBYTE + #X) := SHR(IN:=#DB.DB(#RBYTE + #X), N:=1);
#DB.DB(#SBYTE + #X) := SHR(IN:=#DB.DB(#SBYTE + #X), N:=1);
IF #X > 0 THEN
#DB.DX((#LBYTE + #X), 0) := #DB.DX(((#LBYTE + #X) - 1), 7);
#DB.DX((#RBYTE + #X), 0) := #DB.DX(((#RBYTE + #X) - 1), 7);
#DB.DX((#SBYTE + #X), 0) := #DB.DX(((#SBYTE + #X) - 1), 7);
END_IF;
END_FOR;
#BUSY := FALSE;
GOTO Ende;
END_IF;
IF #RESET THEN
#BUSY := TRUE;
FOR #X := (#ANZAHL - 1) TO 0 BY -1 DO
#DB.DB(#LBYTE + #X) := 0;
#DB.DB(#RBYTE + #X) := 0;
#DB.DB(#SBYTE + #X) := 0;
END_FOR;
#BUSY := FALSE;
END_IF;
Ende:
RETURN;
END_FUNCTION

Der Baustein rotiert mit steigender Flanke am "START" einmal alles durch. Am Ende musst du die genaue Stelle im DB wissen die du dann nur noch abfragen oder mit einem Ergebnis setzen musst.
"BUSY" wird TRUE wenn der Baustein läuft. "RESET" löscht alles. Da ich das für drei Spuren mache brauch ich "LBYTE", "RBYTE" und "SBYTE". Du brauchst ja nur eine Spur.
Der Baustein schiebt immer ganze Bytes und kopiert dann Bit7 vom vorhergehenden in Bit0 vom nachfolgenden Byte, so das die Kette einmal von vorn nach hinten verschoben wird.

MfG Peter.
 
Zurück
Oben