TIA PLC-Datentyp rücksetzen d.h. alle Bits auf 0 setzen

Bitschieber

Level-1
Beiträge
15
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
kennt jemand eine Möglichkeit, ein Datenwort in einem DB, das über einen PLC-Datentyp programmiert ist auf 0 zu setzen bzw. alle Bits zurückzusetzen,
ohne jedoch für sämtliche Bits ein Rücksetze Bit zu programmieren.
Es soll keine absolute Adressierung angewendet werden. Nur symbolische Programmierung.

Also nicht: L 0
T DBx.DBWx ( nicht absolut, nur symbolisch )

Danke und Gruß
 
Du hast uns noch nicht verraten welche Steuerung, 300/400 oder 1200/1500?
Bei der ersteren wäre es z.B. SFC21-FILL.

Bei der 1200/1500 geht zum Beispiel recht einfach wenn man eine leere Struktur des selben Typs hat und dann diese einfach per MOVE auf die zu löschende
kopiert.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo und Danke für die rasche Antwort.
Habe eine CPU 1511.
Das mit dem leeren Datentyp habe ich auch schon gemacht.
Ist halt leidig, dass man hier für jeden Datentyp einen 2.ten, leeren anlegen muss.
( Wegen der Übersicht).
Trotzdem besten Dank
 
Du könntest evtl einen Slice-Zugriff nutzen.
Hier hast du die Möglichkeit auf einzelne Bits, Byte,... einer symbolischen Variable zuzugreifen.

Bsp.:
L 0
T "DB_Name".StrukturName.VarName.%W0 // alle Bits von Wort 0 zurücksetzen

geht auch mit:
.%X0 // Bit
.%B0 // Byte
.%W0 // Word
.%D0 // DWord
 
Hallo,
bekomme es mit der Slice-Funktion auch nicht hin. Alles rot. TIA kann/kennt das nicht.
Also zur Erklärung:
Habe einen PLC-Datentyp mit 16 Bool. Den will ich auf einen Rutsch zu -0- setzen.

Absolute Adressierung:
L 0
T DB51.DBW150
Kein Problem. Ist zwar gelb hinterlegt, aber's geht.

Aber symbolisch, ???

Gruss Uli
 
Da es in dem neuen "optimierten" TIA nicht mehr sicher ist, daß Struktur-Member auch tatsächlich hintereinander im Speicher liegen, ist es auch nicht möglich, den von der Struktur belegten Speicher als Byte/Word/Doppelword... symbolisch anzusprechen.

Zum Nullsetzen aller Struktur-Member kann man nur
  • jeden Struktur-Member einzeln symbolisch ansprechen, sprich: man muß jedes einzelne Bit einzeln auf 0 setzen (bei Bool-Array geht das auch in einer Schleife)
  • oder man kopiert auf die Struktur eine andere Struktur, wo alle Member (Bits) bereits auf 0 sind
  • oder man zwingt die Struktur auf einen Speicherplatz, wo garantiert ist, daß die einzelnen Struktur-Member hintereinander liegen, und spricht den Speicherplatz dann Byte/Word/Doppelword-weise strukturiert an --> mittels AT, was aber nur sehr eingeschränkt geht und ein anschließendes Kopieren auf die Zielstruktur erfordert

Die einfachste und effizienteste Methode ist tatsächlich das Kopieren einer zweiten vorbereiteten Struktur mit alles 0 auf die Zielstruktur.

Harald
 
Hierzu nochmal eine Frage,...
kann ich nicht auch viel einfacher mit FILL_BLK einen Bereich in einer Struktur/Array/UDT zurücksetzen?
Ich gebe dann bei "IN" ein 0-Bit an, bei "COUNT" z.B. 8 um ein Byte zurück zu setzen und bei "OUT" das 1. Bit das zurück gesetzt werden soll.
Müsste doch funktionieren? Merkert zumindest in der Umgebung nicht.
 
Also nicht: L 0
T DBx.DBWx ( nicht absolut, nur symbolisch )

Und noch eine Frage:
Würde o.g. überhaupt sicher funktionieren?
Soweit ich weis ordnet TIA die Variablen in den DB's bei 1500er ja neu.
Heisst ich kann nicht sicher sein, dass die entsprechenden Variablen zurückgesetzt werden, und nicht andere, wenn ich sie absolut anspreche, oder?

Wäre euch für Hilfe sehr dankbar... bei uns wird sehr oft im Programm mit der Funktion "RESET" (300er) ein Bool-Bereich im DB zurück gesetzt.
Zb: DB300.DBB1, oder DB350 DBW4.

Mit der 1500er finde ich aktuell keine Variante das umzusetzen:
- RESET_BF funktioniert nur bei Arrays -> ungeschickt wenn die Variablen verschiedene Namen haben sollen
- FILL_BLK nimmt auch Struct/UDTs allerdings hab ich dann das Problem, dass hierdurch immer nur 2 Byte belegt werden. Ich muss aber häufig nur 1 Byte zurück setzen.
Eigentlich möchte ich die nachfolgende Adressierung in allen DB's beibehalten.
- Gibt es Möglichkeiten wenn ich im DB kein Struct, UDT oder Array verwenden möchte?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich muss nochmal Fragen:

1500er:

Code:
L 0 
T DB300.DBB15

Damit Bit DB300.DBX15.0-7 zurück zu setzen funktioniert nach wie vor korrekt, richtig?
Man muss nur darauf achten, dass man weiterhin ohne "Optimierter Bausteinzugriff" arbeitet, oder?
Das selbe gilt dann für die gleiche Methode mit MOVE-Baustein in KOP?

Aber gibt es bei der 1500er kein Möglichkeit mehr dies auch ohne Warnung hinzubekommen???
Also wenn man die Bool-Variablen nicht in einem Array, UDT oder Struct hat?
Kann ich kein DB Adressbereich absolut beschreiben, ohne Warnung?! :/
 
Das mit dem leeren Datentyp habe ich auch schon gemacht.
Ist halt leidig, dass man hier für jeden Datentyp einen 2.ten, leeren anlegen muss.

Wieso? Einfach im FB eine Variable "#Löschen" vom Typ "UDT" im Temp Bereich anlegen.
Optimierter Bausteinzugriff gewährleistet dann, dass die Daten im UDT mit deren jeweiligen Datentyp Spezifischen Default Werten belegt werden.
Bool: false, Dint: 0 usw...
 
Danke, man muß aber trotzdem für jeden Datentyp eine Variable #Löschen erzeugen, da die Strukturen der Datentypen ja unterschiedlich sind.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke, man muß aber trotzdem für jeden Datentyp eine Variable #Löschen erzeugen, da die Strukturen der Datentypen ja unterschiedlich sind.
Was ja der Leserlichkeit förderlich ist.
Ich möchte ja klar erkennen wo ich meine Rezeptur
Code:
DATA.Rezept := #LöschenRezeptur;
oder einen einzelnen Datensatz aus dem Rezept lösche.
Code:
DATA.Rezept.Datensatz[i] := #LöschenDatensatz;
Die Variable kostet ja nix...
 
Serialize / Deserialize

Mit der Funktion Serialize / Deserialize stze ich meine Bitfelder auf 0.

Anleitung:
Text in eine Datei mit der Erweiterung .scl packen. Dann Einfügen mit PLC -> Programmbausteine -> Externe Quellen -> Neue externe Datei hinzufügen. Dann nur noch mit "Bausteine aus Quelle generieren" Bausteine erzeugen.


Code:
FUNCTION "fc_BufferAufNull_V15.0.2" : Void
TITLE = Störung/Warnung
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : sf
VERSION : 0.1
   VAR_OUTPUT 
      ob_Error : Bool;   // Error with Varriant Input
   END_VAR

   VAR_IN_OUT 
      iov_Buffer : Variant;
   END_VAR

   VAR_TEMP 
      tempBufferSize : DInt;
      tempCounter : DInt;
      tempVariable1ToBytes : Array[1..#MAX_LENGTH] of Byte;
      tempDeserializeRet : Int;
      tempSerializeRet : Int;
   END_VAR

   VAR CONSTANT 
      MAX_LENGTH : Int := 100;
   END_VAR


BEGIN
    // Ist Varriant passend?
    IF CountOfElements(#iov_Buffer) < #MAX_LENGTH THEN
        //Alle Bits auf Null
        #tempBufferSize := 0;
        #tempSerializeRet := Serialize(SRC_VARIABLE := #iov_Buffer, DEST_ARRAY => #tempVariable1ToBytes, POS := #tempBufferSize);
        #tempCounter := 1;
        WHILE #tempCounter <= #tempBufferSize DO
            #tempVariable1ToBytes[#tempCounter] := 0;
            #tempCounter := #tempCounter + 1;
        END_WHILE;
        #tempBufferSize := 0;
        #tempDeserializeRet := Deserialize(SRC_ARRAY := #tempVariable1ToBytes, DEST_VARIABLE => #iov_Buffer, POS := #tempBufferSize);
    ELSE
        #ob_Error := true;
    END_IF;
END_FUNCTION

Getestet mit Tia 14.1 und 15 unter 1200 und 1500.
 
Hallo und ganz GROSSES DANKE,
hast Dir ja mächtig Arbeit gemacht.
Leider dürfen wir für unsere Projekte kein SCL verwenden ( Kundenvorgabe ).
Nur FUP oder wenns gar nicht geht AWL, aber niemals SCL.
Nochmals bestenDank und Gruss
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo und ganz GROSSES DANKE,
hast Dir ja mächtig Arbeit gemacht.
Leider dürfen wir für unsere Projekte kein SCL verwenden ( Kundenvorgabe ).
Nur FUP oder wenns gar nicht geht AWL, aber niemals SCL.
Nochmals bestenDank und Gruss

Niemals SCL? :eek: Es gibt schon komische Kunden :)
 
Hierzu nochmal eine Frage,...
kann ich nicht auch viel einfacher mit FILL_BLK einen Bereich in einer Struktur/Array/UDT zurücksetzen?
Ich gebe dann bei "IN" ein 0-Bit an, bei "COUNT" z.B. 8 um ein Byte zurück zu setzen und bei "OUT" das 1. Bit das zurück gesetzt werden soll.
Müsste doch funktionieren? Merkert zumindest in der Umgebung nicht.

Kann mir hierzu jemand was sagen? Funktioniert der FILL_BLK dazu sauber?
 
Zurück
Oben