# Win CC flex einzelne Bits einer Variable per VBS schreiben



## Hahnus (29 Juni 2010)

Hallo,

ich möchte per VBS einzelne Bits einer Variablen schreiben (Sammelvariable zur Verringerung der notwendigen Powertags).
Hat das schon mal jemand gemacht?

Danke + Gruß
Hahnus


----------



## vierlagig (29 Juni 2010)

da gibt es der möglichkeiten viele, eine einfache:

addition und subtraktion der dezimal werte die durch die binäre stelle repräsentiert werden, also 1,2,4,8,16,32,.......


----------



## Larry Laffer (29 Juni 2010)

Hallo,
ich weiß zwar nicht so genau wo du hinwillst, aber es geht mit maskieren :
	
	



```
if (myWord and &H80) <> 0 then 
   myBit = true 
else 
   myBit = false
end if
```
Gruß
Larry


----------



## Larry Laffer (29 Juni 2010)

@4L:
bist du dir mit deiner Idee da gaaaaanz sicher ...?


----------



## vierlagig (29 Juni 2010)

Larry Laffer schrieb:


> @4L:
> bist du dir mit deiner Idee da gaaaaanz sicher ...?



öhm, lass mich kurz ... ja!

bitmuster: 0101 1101
kann ich mit: 1 + 4 + 8 + 16 + 64 = 93
abbilden.
will ich jetzt 0101 1110 haben, also das 0te bit false, das 1te true, mach ich
93 - 1 + 2 = 94


----------



## Larry Laffer (29 Juni 2010)

OK ... und wie stellst du jetzt (an deinem Beispiel) fest, ob das Bit 2^5 = 32 gesetzt ist ?
wenn (93 - 32) > 0 dann Bit_gesetzt ?


----------



## vierlagig (29 Juni 2010)

Larry Laffer schrieb:


> OK ... und wie stellst du jetzt (an deinem Beispiel) fest, ob das Bit 2^5 = 32 gesetzt ist ?
> wenn (93 - 32) > 0 dann Bit_gesetzt ?



erste frage war ja: setzen ... nicht lesen...

aber um auch dein wissenshunger zu stillen:

93 / 2 = 46 R: 1
46 / 2 = 23 R: 0
23 / 2 = 11 R: 1
11 / 2 = 5  R: 1
 5 / 2 = 2  R: 1
 2 / 2 = 1  R: 0
 1 / 2 = 0  R: 1

das ganze in ner for-schleife in ein temporäres ARRAY [0..7] OF BOOL z.B.


----------



## Larry Laffer (29 Juni 2010)

vierlagig schrieb:


> addition und subtraktion der dezimal werte die durch die binäre stelle repräsentiert werden, also 1,2,4,8,16,32,.......


Was hat das mit dein Divisionsrest-Geschichte zu tun ?

Wenn ich die Frage richtig verstanden habe dann will der TE wissen ob ein bestimmtes (wahrscheinlich sogar vorwählbares) Bit gesetzt ist ...
Ich will jetzt nicht bestreiten, dass dein Weg "Word_to_ARRAY_of_Bool" auch funktioniert - ist vielleicht nur etwas oversized ... und hat nicht so viel mit der ursprünglichen Antwort (siehe oben) zu tun ...

Gruß
Larry


----------



## Perfektionist (29 Juni 2010)

ich sag nur:





Hahnus schrieb:


> ... einzelne Bits einer Variablen *schreiben* ...


aber vermutlich gibt es für 





> zur Verringerung der notwendigen Powertags


noch ganz andere Wege.


----------



## vierlagig (29 Juni 2010)

Larry Laffer schrieb:


> Was hat das mit dein Divisionsrest-Geschichte zu tun ?
> 
> Wenn ich die Frage richtig verstanden habe dann will der TE wissen ob ein bestimmtes (wahrscheinlich sogar vorwählbares) Bit gesetzt ist ...
> Ich will jetzt nicht bestreiten, dass dein Weg "Word_to_ARRAY_of_Bool" auch funktioniert - ist vielleicht nur etwas oversized ... und hat nicht so viel mit der ursprünglichen Antwort (siehe oben) zu tun ...
> ...




ursprung war 





> ich möchte per VBS einzelne Bits einer Variablen schreiben



das heißt, die variable ist als word/dword in der visualisierung angelegt und die steuerung holt sich diese (lesender zugriff!)
um die bits dieses word/dword zu beeinflussen: addition/subtraktion des jeweiligen wertes.

möchte er jetzt lesend aus sicht HMI zugreifen muß er das word/dword zerlegen oder entsprechend deinem vorschlag maskieren ...

ich sehe dein problem nicht!

finde übrigens meine lösung nicht unperformant, da in einem rutsch alle bits verfügbar gemacht werden... bei deiner lösung müssen alle bits einzeln maskiert werden ... hat aber wahrscheinlich auch noch andere vor-/nachteile...


----------



## vierlagig (29 Juni 2010)

Perfektionist schrieb:


> aber vermutlich gibt es für noch ganz andere Wege.



habs jetz grad nicht vor augen, aber gilt ein ARRAY [0..255] OF BOOL nicht auch als ein Powertag?


----------



## Perfektionist (29 Juni 2010)

... das wäre dann sowas wie:
	
	



```
myWord or &H80
myWord and not &H80
```
oder so ähnlich für das Setzen bzw. Rücksetzen eines Bits.


----------



## Perfektionist (29 Juni 2010)

vierlagig schrieb:


> habs jetz grad nicht vor augen, aber gilt ein ARRAY [0..255] OF BOOL nicht auch als ein Powertag?


ich _glaube_, ja.

PS:


MSB schrieb:


> Power-Tag ist eine externe Variable, also eine Zeile in der Variablentabelle, welche auf die Steuerung verweist.
> Sagt aber nichts über die Größe der Variable aus.
> *Ein BOOL ist genau so ein Powertag wie ein ARRAY mit 1000 Werten.*
> 
> ...


----------



## rostiger Nagel (29 Juni 2010)

mmh...ist es bei flex nicht so das ein Array von variabeln
nur ein powetag ist? Wenn es darum gehen sollte, das nur
Geld für eine 128PT lizens da ist. 
Ich glaube das meinte auch der perfekte.


----------



## PN/DP (29 Juni 2010)

In der SPS 32 Bits zu einem Doppelword zum Panel zusammenfassen und am Panel wieder ausmaskieren

```
myBit1 = myDWord and 1
...
myBit31 = myDWord and &H40000000
' kann man auch so schreiben:
SmartTags("myBit32") = SmartTags("myDWord") and &H80000000
```
ist eine gute Idee zum Sparen von Powertags. Ich würde mich aber nicht darauf verlassen, daß dann 
eine "BeiWertänderung"-Aktion an den Panel-lokalen Einzelbits immer korrekt ausgeführt wird bzw. 
die Doppelword-Variable muß dann auf ständig lesen stehen. Oder man muß dafür sorgen, daß überall 
da, wo die Einzelbits benötigt werden, die Doppelword-Variable aus der SPS gelesen wird.


Beim Zusammenfassen von Einzelbits, die vom Panel zur SPS *geschrieben* werden sollen, da habe ich 
leichte Bauchschmerzen, da kann es durch die Kommunikations-Laufzeit haarig werden.

Wenn die SPS auch in das empfangene Doppelword schreibt (z.B. Rücksetzen von Tastenbits), dann 
kann das Bit in der SPS durch die Panel-Zugriffe kurz danach unerwartet wieder gesetzt sein.
Wenn die SPS nicht auf das empfangene Doppelword schreibt, dann gibt es weniger Probleme.

Einzelne Bits in der Doppelwort-Schreibvariable setzen oder löschen kann man z.B. in einem Skript 
durch verknüpfen mit einer Bitmaske (hinein-ORen oder heraus-ANDen), wie der Perfektionist gezeigt
hat. Oder gleich einen Wert 1, 2, 4, 8, 16, 32, ... zuweisen. 
Dies kann aber einen Skript-Stau verursachen, wenn in schneller Folge mehrere Bits in dem Schreib-
Doppelwort verändert werden.
Mehrere unabhängige Bits im Schreib-Doppelwort gleichzeitig ändern geht nur in einem Skript.

Oder man nutzt die Systemfunktionen
* SetzeBitInVariable
* RuecksetzeBitInVariable
* InvertiereBitInVariable

Wegen der Probleme die aus der Kommunikations-Laufzeit resultieren können, schreibt die WCCflex-Onlinehilfe:


> Die Systemfunktion überträgt nach der Änderung des angegebenen Bits die gesamte Variable wieder an die Steuerung. Es wird nicht geprüft, ob sich zwischenzeitlich andere Bits in der Variablen geändert haben. Bediener und Steuerung dürfen auf die angegebene Variable nur lesend zugreifen, bis die Variable wieder an die Steuerung übertragen wurde.
> 
> *Hinweis*
> Verwenden Sie diese Systemfunktion nicht, wenn die Steuerung BOOL-Variablen unterstützt. Verwenden Sie statt dessen die Systemfunktion "SetzeBit".



"Nur lesend zugreifen, bis ..." - woher soll die Steuerung wissen, wann die Variable vom Panel gelesen 
und wann wieder zurückgeschrieben wurde?


Ein ARRAY [0..255] OF BOOL ist zwar nur 1 Powertag, es kann aber auch hier zu Problemen kommen, wenn 
in der SPS auf Bits in dem Array geschrieben wird.
Beim Ändern eines Array-Bits vom Panel wird das komplette Array in die SPS geschrieben und danach wieder 
gelesen. Wenn nun im Panel schon ein weiteres Bit geändert wurde, wird wieder das gesamte Array in die 
SPS geschrieben, mit dem vermeintlich noch gesetzten Bit von der ersten Änderung! Und ohne zwischenzeitlich
von der SPS geänderte Bits.
Das Panel kann man (zumindest unter WinCCflex) nicht zwingen, eine Variable vor dem Schreiben NICHT zu lesen.


Nachteile der Zusammenfassung von Bits in Doppelwörtern oder Arrays of Bool:
- Auf die einzelnen Bits kann nicht mehr "symbolisch" zugegriffen werden. 
- Die Querverweisliste in WCCflex wird unvollständig und unübersichtlich.
- Die meisten WCCflex-Objekte können nicht mit Arrays umgehen, (ich glaube) nur Schalter.
- Auf Bitfeld-Variablen vom Panel darf die SPS nicht schreiben.
- in Panel und SPS unterschiedliche Berechnung, auf welcher Adresse Bit0 ... Bit31 sind

Gruß
Harald


----------



## Hahnus (30 Juni 2010)

Entschuldigung, war beim Zahnarzt und konnte deshalb das  zwischenzeitliche Rätseln, was ich eigentlich tun will, nicht aufklären.

Ich  bekomme ein Textfile (mehrere Zeilen mit einem 200 Byte langen String).  Die einzelne Zeile (der 200Byte-String) steht jeweils für ein Produkt  aus dem Los, das Textfile verkörpert dann das kpl. Los. Das Textfile  hole ich per VBS von einem Server und lege es auch so in der SPS ab.
Während  der Bearbeitung sollte ich nun jeweils die Daten eines Produktes in  Bits und Bytes wandeln, damit ich in der SPS entsprechend bearbeiten  kann. Das könnte ich in der SPS machen, der elegantere Weg wäre  wahrscheinlich ein Script zu schreiben, welches den 200Byte-String  entsprechend zerhackt und zur SPS zurückgibt. Hier ergeben sich doch  relativ viele Bits, die ich in der Visu gern zu einem Wort bzw.  Doppelwort zusammenfassen möchte (Reduzierung Powertags).
D.h.  grundsätzlich schreibt nur die Visu in diesen Datenbereich, die SPS  liest nur --> keine Konflikte.
Die Bits werde ich am Skript-Start  alle initialisieren (auf 0 setzen), danach dann definiert setzen so wie  ich sie brauche. Jetzt muss ich also mal schauen, ob ich eine der  angebotenen Lösungen umsetzen kann.
Mit den Arrays in WinCCF habe ich  noch nicht gearbeitet, auch das schaue ich mir an.

Danke + Gruß
Hahnus


----------



## Larry Laffer (30 Juni 2010)

Hallo,
aus unter Anderem den auch schon von PN/DP genannten Gründen würde ich nicht den String in der Visu zerlegen und die Einzel-Komponenten dann zur SPS zurückschicken. Das Hauptproblem dabei ist, dass du nicht weißt, wann die letzte Einzel-Variable zur SPS zurückgeschrieben und somit für sie verfügbar ist.
Ich würde dir hier doch dazu raten, das Ganze in der SPS zu machen.
Wenn die ganze Routine eher ein Kandidat für ein Script ist, so hast du mit SCL ja diese Möglichkeiten auch in der SPS. Denk mal drüber nach ...

Gruß
Larry


----------



## Hahnus (30 Juni 2010)

@LarryLafer
Das sollte sich doch ganz gut damit bewerksteligen lassen, dass ich ein Testbit aus dem Wort per SPS hochsetze, dann das Skript starte und darauf warte, dass das Visu-Skript dieses rücksetzt --> SPS-Abfrage Testbit = 0 --> Skript fertig und Variablen gültig.
Oder denke ich hier zu einfach?

Danke + Gruß
Hahnus


----------



## Hahnus (30 Juni 2010)

PS an alle:
Ja, ein Array ist nur eine Variable!

Hahnus


----------



## PN/DP (30 Juni 2010)

Hallo Hahnus,

das konsistente Schreiben mehrerer zusammengehöriger Variablen vom Panel zur SPS ist ein typischer Anwendungsfall
für Rezepturen (Datensätze). Die Systemfunktion *SchreibeDatensatzvariablenInSteuerung* (SetDataRecordTagsToPLC)
gibt sogar eine Ende-Meldung, wenn der Datensatz komplett in die Steuerung geschrieben wurde.

Ein Skript-Beispiel für die Anwendung findest Du hier:
konsistent Variablen in SPS schreiben mit Endemeldung

Gruß
Harald

PS: Ein Array ist nur 1 PowerTag.


----------

