TIA S7-1200 Tagesproduktionszähler

Horschd

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

ich programmier eine kleine Prüfstation. Das Prüfprogramm ist fast fertig.

Nun kamen die Sonderwünsche, da häng ich gerade.
Es sind Zähler gefordert, welche die geprüften Werkstücke zählen und die Werkstücke die OK waren.
Es soll insgesammt 10 Speicherplätze geben, die täglich automatisch wechseln. Es soll 10 Arbeitstage gespeichert werden können.

Wenn alle Speicherplätze belegt sind muss der Meister kommen, sich die Werte abschreiben und mindestens einen, nicht unbedingt den ersten, Speicherplatz löschen.
Das Programm soll automatisch den ersten freien Speicherplatz beschreiben. Natürlich mit Datum.

Ich habe ein kleines Farbpanel mit Profinetschnittstelle (genauen Typ hab ich gerade vergessen.)

Könnt ihr mir bei den Zähler helfen?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Code:
    #counter_Platz_belegt := 0;
    
    FOR #count_01 := 0 TO 18 BY 2 DO
         
        IF DB8.DBw[#count_01] <> 0 THEN
            #counter_Platz_belegt := 1;
            
        END_IF;
    END_FOR;

Ich sitze immer noch an der Problematik und brauch eure Hilfe. Wieso lässt sich das Codestück nicht in SCL kompilieren?
 
Code:
        IF [COLOR=#ff0000]%[/COLOR]DB8.[COLOR=#ff0000]DW([/COLOR]#count_01[COLOR=#ff0000])[/COLOR] <> 0 THEN

So muss das aussehen, wenn du auf ein Wort zugreifen willst.

mfG René

Edit: ich würde aber auf absolute Zugriffe verzichten. Und gerade in TIA Das Zeug mit Strukturen und Arrays lösen. Einfacher und TIA kümmert sich um die Zugriffe.
 
Zuletzt bearbeitet:
danke für die Antwort. das %DB8.DW ist rot unterstrichen.

Beim %DB8 steht "ungültiger Funktionsname"
Beim Punkt steht "ungültiger Aufruf eines Funktionsbaustein '%DB8.DW' "
Beim DW steht "ungültige Adresse 'DW' "

An was dachtest du, wie ich viele Elemente gut Überprüfen kann?
Array wäre ne möglichkeit. Aber dann muss ich die ganzen variablen in der Visu neu machen, oder?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hast du gesehen das da Runde und keine Eckigen klammern verwendet werden? Unterschied Step7/TIA.

Für Arrays deklariert man in der Visu ja auch ein Array. Also eigentlich nur eine Variable. Das meinte ich mit Strukturiert programmieren. Wenn man da Strukturen und Arrays und kombinationen davon aufs HMI bringt, kann man die Variablendeklaration enorm zusammenstreichen.

mfG René
 
Code:
IF %DB8.Dw(#count_01) <> 0 THEN

Ja die runden Klammern hatte ich geändert.

Mal ne dumme Frage, oben wollte ich mit nem Pointer auf den Speichererech zeigen, welchen ich vergleichen wollte.
Da ich eine große Zahl von Variablen habe, wollte ich in der Schleife, einfach die Zugriffadresse inkementieren.
Habe ich jetzt den sinn von Pointer falsch verstanden?
 
Nein das funktioniert grundsätzlich schon so. Allerdings Pointern geht nur in nicht optimierten Bausteinen. Man muss wissen was man zählt. etc.

So als kleines Beispiel wie du anfangen könntest.
Code:
FUNCTION_BLOCK "FehlerSpeicher"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      Fehler : Bool;
   END_VAR


   VAR_IN_OUT 
      Speicher : Array[0..10] of Struct
         Fehlerzahl : DInt;
         Datum {OriginalPartName := 'DTL'; LibVersion := '1.0'} : DTL;
      END_STRUCT;
   END_VAR


   VAR 
      AktSpeicher : Int;
      keinSpeicher : Bool;
      R_TRIG_Instance {OriginalPartName := 'R_TRIG_1500'; LibVersion := '1.0'} : R_TRIG;
   END_VAR


   VAR_TEMP 
      Datum {OriginalPartName := 'DTL'; LibVersion := '1.0'} : DTL;
      status : Int;
      index : Int;
   END_VAR




BEGIN
    
    #status := RD_LOC_T(#Datum);
    #R_TRIG_Instance(CLK:=#Fehler);
    
    
    
    // Aktueller Tag vorhanden?
    FOR #index := 0 TO 10 DO
        #keinSpeicher := false; // kein Speicher zurücksetzen 
        IF #Speicher[#index].Datum.DAY = #Datum.DAY THEN // Schauen ob akueller Wochentag schon vorhanden
            #AktSpeicher := #index;
        ELSIF #Speicher[#index].Datum.DAY = 0 THEN // Wenn Wochentag nicht vorhanden, erste Stelle mit 0 Suchen
            #AktSpeicher := #index;
            #Speicher[#index].Datum := #Datum;
        ELSE // Wenn kein leerer Speicherplatz dann Fehler werfen.
            #keinSpeicher := true;
        END_IF;
    END_FOR;
    
    // Wenn fehler Zähler des aktuellen speichers hochzählen
    IF #R_TRIG_Instance.Q AND NOT #keinSpeicher THEN
        #Speicher[#AktSpeicher].Fehlerzahl := #Speicher[#AktSpeicher].Fehlerzahl + 1;
    END_IF;
    
END_FUNCTION_BLOCK

Natürlich ungetestet und sehr einfach.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke für das Beispiel.

Ich habe ein paar Fragen dazu:
-Was ist R_Trig_Instance ?
-Wie schaffst du es ( #status := RD_LOC_T(#Datum);) die DTL Variable (#Datum) in eine Integer zu speichern? DTL ist doch 12 Byte groß.Oder was möchtest du damit bewzecken?

und ein paarallgemeine Fragen.
Wie spricht man eine DB Speicherstelle Symbolisch an?
Sind die # für Symbolische Adressierung oder noch für mehr?
was ist ein opimierter Baustein?
 
R_Trig ist in der Bibliothek unter Bitverknüpfungen. Da ich das grad unter ner 1500er zusammengestückelt hab. Verweist er auf deren Bibliothek. Einfach schnell rausnehmen und neu deklarieren.

Datum ist vom Typ DTL. DTL wird von TIA gleich als Struktur mit Unterelementen wie Datum.DAY (für Tag im Monat) angelegt. Und den kann man in einem Integer speichern.

Die # werden in TIA als Symbolische Adressierung verwendet. "Datum" ist vielleicht ein schlechter Variablenname Versuch das zu ersetzen gegen was das nicht als Keyword in TIA erkannt wird.

mfG René
 
Ich steh gerade auf dem großem SCL Schlauch.

Was muss isch schreiben, wenn ich eine Integer Variable im DB Symbolisch verwenden will?

Wenn ich mit %DB8.xxx bringt es nur Fehler. Und wenn ich mit DB_Zaehlstand.xxx komme wird es auch nicht besser.
 
-Wie schaffst du es ( #status := RD_LOC_T(#Datum); ) die DTL Variable (#Datum) in eine Integer zu speichern? DTL ist doch 12 Byte groß.Oder was möchtest du damit bewzecken?
Schau Dir mal die Hilfe zur Anweisung RD_LOC_T an. Die Anweisung hat einen Rückgabewert (RET_VAL) zur Signalisierung von Fehlern. Dieser Rückgabewert wird der Int-Variable "status" zugewiesen. Die Lokalzeit wird in den DTL "Datum" geschrieben.


was ist ein opimierter Baustein?
Schau mal in die Hilfe > Index nach "Optimierter Zugriff" und in den Programmierleitfaden Kapitel "Optimierte Bausteine"

Kurz gefasst: Bei Bausteinen mit "optimiertem Zugriff" verteilt der Compiler die deklarierten Variablen nicht in der Reihenfolge wie deklariert, sondern nach Gusto angeblich nach Größe sortiert in einer viel "optimaleren" Anordnung im DB (weil Durchschnitts-Programmierer ja gedankenlos und verschwenderisch programmieren ;)). Dadurch kann man aus der Reihenfolge der Deklaration nicht mehr auf die Adresse der Variablen schließen. Der Compiler verhindert auch alle Versuche, die Adresse der Variablen anzusprechen (z.B. durch indirekte Adressierung). Achtung: Auch zusammenhängend deklarierte Strukturen werden auseinandergepflückt "optimal" im DB angeordnet. Selbst wenn man von einer Variable die Adresse wüßte, kann man nicht auf die Adresse der nächsten Variable schließen. In Bausteinen mit "optimiertem Zugriff" kann man nur noch indizierbare Elemente (Arrays) indirekt ansprechen. Direktes oder indirektes Ansprechen von Speicheradressen und hoffen, damit eine bestimmte Variable zu treffen, ist nicht mehr möglich. Merke: bei S7-1200/1500 programmiere am besten vollsymbolisch ohne jeden Adressbezug.

Siehe auch hier:
Wie können Sie in STEP 7 (TIA Portal) für die S7-1200/S7-1500 effizient und performant programmieren?
Programmierleitfaden und Programmierstyleguide für S7-1200 und S7-1500

Harald
 
Zurück
Oben