WinCC Seltsames Verhalten in VBS Aktion - Bit maskieren funktioniert nicht

Hardy81

Level-2
Beiträge
124
Reaktionspunkte
8
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe in einem Faceplate zum Bildwechsel in einer Zustandsanzeige das folgende VBS-Script drin.

Über die Variable "Statusbits" (32 Bit UINT) möchte ich verschiedene Zustandsanzeigen abhängig vom jeweiligen Bit schalten.
Bit 0 -> Zustandsanzeige1
Bit 1 -> Zustandanzeige 2
usw.

Das Ganze funktioniert bis zum Bit 15. Ab Bit 16 schalten dann 2 Zustandsanzeigen gleichzeitig, obwohl nur ein Bit über die Bitmaske maskiert wird.

Meine Vermutung ist, dass VBS hier an der Stelle (oder auch generell) keine 32 Bit Integer kann. Liege ich hier richtig?


Code:
Function Index_Trigger(ByVal Item)
    Dim Status

' dwStatusbits
' Bit 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
'      |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
'      |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    +-> Überlast Warnung
'      |    |    |    |    |    |    |    |    |    |    |    |    |    |    +------> Überlast Auslösung
'      |    |    |    |    |    |    |    |    |    |    |    |    |    +-----------> Reserve
'      |    |    |    |    |    |    |    |    |    |    |    |    +----------------> Reserve
'      |    |    |    |    |    |    |    |    |    |    |    +---------------------> Reserve
'      |    |    |    |    |    |    |    |    |    |    +--------------------------> Reserve
'      |    |    |    |    |    |    |    |    |    +-------------------------------> Reserve
'      |    |    |    |    |    |    |    |    +------------------------------------> Reserve
'      |    |    |    |    |    |    |    +-----------------------------------------> Reserve         
'      |    |    |    |    |    |    +----------------------------------------------> Reserve                
'      |    |    |    |    |    +---------------------------------------------------> Reserve              
'      |    |    |    |    +--------------------------------------------------------> Reserve                    
'      |    |    |    +-------------------------------------------------------------> Reserve                      
'      |    |    +------------------------------------------------------------------> Reserve                            
'      |    +-----------------------------------------------------------------------> Reserve                                
'      +----------------------------------------------------------------------------> Reserve                                      
'
' Bit 15 | 14 | 13 | 12 | 11 | 10 |  9 |  8 |  7 |  6 |  5 |  4 |  3 |  2 |  1 |  0
'      |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |
'      |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    +-> Leistungsschalter EIN
'      |    |    |    |    |    |    |    |    |    |    |    |    |    |    +------> Leistungsschalter AUS
'      |    |    |    |    |    |    |    |    |    |    |    |    |    +-----------> Leistungsschalter Betriebsstellung
'      |    |    |    |    |    |    |    |    |    |    |    |    +----------------> Leistungsschalter Teststellung
'      |    |    |    |    |    |    |    |    |    |    |    +---------------------> Erdungsschalter EIN                     
'      |    |    |    |    |    |    |    |    |    |    +--------------------------> Erdungsschalter AUS                           
'      |    |    |    |    |    |    |    |    |    +-------------------------------> Schutzauslösung                                
'      |    |    |    |    |    |    |    |    +------------------------------------> Automatenfall 
'      |    |    |    |    |    |    |    +-----------------------------------------> Trafoschutz Warnung                                          
'      |    |    |    |    |    |    +----------------------------------------------> Trafoschutz Auslösung                                               
'      |    |    |    |    |    +---------------------------------------------------> Umschalter ORT                                                    
'      |    |    |    |    +--------------------------------------------------------> Umschalter FERN                                                         
'      |    |    |    +-------------------------------------------------------------> I> Auslösung                                                              
'      |    |    +------------------------------------------------------------------> I>> Auslösung                                                                   
'      |    +-----------------------------------------------------------------------> IE> Vorwärts                                                                        
'      +----------------------------------------------------------------------------> IE> Rückwärts                                                                             
'          

    Const BitMask = &H00010000   '<-- Bit 16 soll ausmaskiert werden Klappt nicht :-(
    
    Status = SmartTags("Statusbits") And BitMask
    
    If Status Then
        Index_Trigger = 2
    Else
        Index_Trigger = 0
    End If
    
End Function
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Jo, geht auch nicht.

Die Zustandsanzeige bei "IE> Rückwärts" liegt auf Bit 15 und wechselt wunderbar.

"Überlast Warnung" liegt auf Bit 16. Immer wenn Bit 16 "1" ist, geht IE> Rückwärts auch auf grün.


Script für Bit 15
Code:
Function Index_Trigger(ByVal Item)
    Dim Status
    Const BitMask = &H00008000
    
    Status = SmartTags("Statusbits") And BitMask
    
    If Status Then
        Index_Trigger = 2
    Else
        Index_Trigger = 0
    End If
    
End Function


Script für Bit 16
Code:
Function Index_Trigger(ByVal Item)
    Dim Status
    Const BitMask = &H00010000 
    
    Status = SmartTags("Statusbits") And BitMask
    
    If Status Then
        Index_Trigger = 2
    Else
        Index_Trigger = 0
    End If
    
End Function

2024-03-12 08_43_51-Window.png
 
Erklär mir doch bitte mal deine Function :
- du hast für 2 unterschiedliche Konstanten dieselbe Function ?
- was macht der Übergabe-Parameter Item, der ja im Script der Function nicht verwendet wird ?
- wie und wo wertest du den Rückgabewert aus ?

und Nachtrag :
- dimensioniere doch deine BitMask mal als LONG ...

und :
- was ist mit Bit 17 ff.
 
Hallo Hardy81,

was hast du überhaupt für eine Visu?
und warum maskierst du was aus um die Bitinformation eines 32Bit Wertes anzuzeigen?

so geht's nicht?
1710230760868.png
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe für jede Zustandsanzeige die gleiche Funktion. Jede Zustandsanzeige hat aber ihre EIGENE Funktion. Sprich, die Funktion gibts es als eigenständige Instanz bei jeder Zustandsanzeige.

Der Übergabeparameter wird direkt aus der Funktion als Rückmeldung an die Eigenschaft der Zustandsanzeige geschrieben. Es ist kein klassisches "return" oder ähnliches notwendig, dass einen Wert zurückliefert Das passiert automatisch. Aus dem Grund wird Index_Trigger bzw Item nicht benutzt.

Biz 17 funktioniert auch nicht. Die restlichen Bits (18 - 31) sind Reserve und werden nicht ausgewertet.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das du an jede Anzeige immer dieselbe Function anbindest (als neue Instanz) sehe ich als fragwürdig an. Wenn dann würde ich eine globale Function hernehmen, ihr den Wunschwert übergeben und die Bitnummer, die ich auswerten will. Von der Function dann den Rückgabewert auswerten - also etwa so (quick and dirty) :
Code:
Function GetBit (Wert, BitNr)

Dim Maske
Maske = 2 ^BitNr
if (Wert and Maske) = Maske the GetBit=1 else GetBit=0

end Function

Nachtrag :
dies würde bei Flex functionieren und bis einschließlich Bit 30 - Bit 31 würde hier auch nicht funktionieren
 
VBS definiert alle Variablen als Variant. Evt. hilft eine definierte Typwandlung

also irgendwas in der Richtung:

Code:
Function Index_Trigger(ByVal Item)
    Dim Status
    Const BitMask = &H00010000
    
    Status = CLng(SmartTags("Statusbits")) And CLng(BitMask)
    
    If Status <> 0 Then
        Index_Trigger = 2
    Else
        Index_Trigger = 0
    End If
    
End Function
 
Wegen der automatischen Datentyp-Verwaltung von VBS sind Bit 15 und Bit 31 immer das Vorzeichenbit, und bei vorzeichenbehafteten Datentypen sind Bit-Verknüpfungen nicht zulässig oder führen zu falschen Ergebnissen, sobald das Bit = 1 ist. Darüber gab es hier im Forum auch schon Diskussionen und Lösungen.
Z.B. das Bit 15 kann man nicht mit Bit-Verknüpfung setzen oder abfragen, sondern muss das arithmetisch lösen, durch addieren oder subtrahieren des Dezimalwertes von &H8000, und Abfragen durch Vergleich, ob der Wert < 0 ist.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@PN/DP : das erklärt aber nicht das Verhalten mit Bit 16 und 17 ...
Dein beschriebenes Problem kannte ich auch tatsächlich erst bei Bit 31 - mit Bit 15 hatte ich bei VBS bislang nie ein Problem (wahrscheinlich weil der implizierte Wandlungswert ein LongInteger ist)
 
Bei Bit 31 war das Problem definitiv, bei Bit 15 war aber auch was, daß das maskieren mit &H8000 nicht richtig funktioniert. In meinem Urlaub habe ich jetzt aber nicht viel Lust, mit dem Smartphone nach dem Thread zu suchen. ;) Auf jeden Fall sind einige Beiträge von mir in dem Thread.
 
Bei Bit 31 war das Problem definitiv
Siemens FAQ: Welche Besonderheit ist in VBScript bei der bitweisen Verknüpfung von Variablen zu beachten und wie kann das höchstwertige Bit (Bit-31/Bit-32) in WinCC mit VBS gesetzt werden?

Bei Bit 31 war das Problem definitiv, bei Bit 15 war aber auch was, daß das maskieren mit &H8000 nicht richtig funktioniert....Auf jeden Fall sind einige Beiträge von mir in dem Thread.
SPS-Forum: VBS Laufzeitfehler Überlauf
 
Zuviel Werbung?
-> Hier kostenlos registrieren
also nochmal an dieser Stelle : der OP spricht von Bit 16 - also &h10000 ...

Die Sache mit dem Bit 31 kann ich (wie schon geschrieben) bestätigen - das Ganze mit Bit 15 nicht.
Die Bit15-Geschichte läßt sich nur durch implizierte INT-Verwendung erklären.
Naja ... leider schreibt der OP in der Sache nichts mehr
 
also nochmal an dieser Stelle : der OP spricht von Bit 16 - also &h10000 ...

Die Sache mit dem Bit 31 kann ich (wie schon geschrieben) bestätigen
Ich habe hier einen Forumsbeitrag in #14 verlinkt, dort wird das auch erwähnt:
Bei den Tests habe ich allerdings bemerkt, daß das VBS sich bei der automatischen Datentyp-Hopserei im Variant selber auf die Füße tritt und merkwürdige Ergebnisse produziert bei der Verwendung von hex-Konstanten wie &H8000, wenn das höchste gesetzte Bit das Bit 31 oder 15 ist.
 
... das habe ich gesehen und auch gelesen - ändert aber nichts daran, dass ich das selbst nicht bestätigen kann ... (also das mit Bit 15)

noch zur Ergänzung :
Ich muss hier und jetzt aber gestehen, dass ich zur Maskierung eigentlich immer 2^BitNr verwendet habe (in diesem Fall also 2^15). Hierbei wird es dann so sein, dass VBS daraus einen LongInteger macht ...
Leider kann ich dies augenblicklich nicht mehr nachstellen ...

weitere Ergänzung :
ich habe auch nie mit WinCC gearbeitet ...
 
Zuletzt bearbeitet:
Zurück
Oben